From a7a39002f951e2c3a4fd13aa141610958a2f5fb4 Mon Sep 17 00:00:00 2001 From: igor Date: Wed, 21 Jun 2017 10:15:27 +0300 Subject: [PATCH 01/14] Add left panel hierarchy support --- lib/ui/example/client/provider.js | 30 ++++- lib/ui/example/webpack.config.js | 2 +- lib/ui/package.json | 2 +- lib/ui/src/modules/api/index.js | 1 + .../modules/ui/components/left_panel/index.js | 8 +- .../ui/components/left_panel/stories.js | 114 +++++++++++++++++- .../src/modules/ui/containers/left_panel.js | 3 +- 7 files changed, 148 insertions(+), 12 deletions(-) diff --git a/lib/ui/example/client/provider.js b/lib/ui/example/client/provider.js index e95f76c55c00..20ce85d2c599 100644 --- a/lib/ui/example/client/provider.js +++ b/lib/ui/example/client/provider.js @@ -78,19 +78,43 @@ export default class ReactProvider extends Provider { this.api = api; this.api.setOptions({ name: 'REACT-STORYBOOK', + leftPanelHierarchy: true }); // set stories this.api.setStories([ { - kind: 'Component 1', + kind: 'some.name.Component 1', stories: ['State 1', 'State 2'], }, - { - kind: 'Component 2', + kind: 'some.name.Component 2', + stories: ['State a', 'State b'], + }, + { + kind: 'some.name2.Component 3', + stories: ['State a', 'State b'], + }, + { + kind: 'some.name2.Component 4', + stories: ['State a', 'State b'], + }, + { + kind: 'some2.name3.Component 5', stories: ['State a', 'State b'], }, + { + kind: 'some2.name3.Component 6', + stories: ['State a', 'State b'], + }, + { + kind: 'Bla 1', + stories: ['State 1', 'State 2'], + }, + { + kind: 'Bla 2', + stories: ['State 1', 'State 2'], + } ]); // listen to the story change and update the preview. diff --git a/lib/ui/example/webpack.config.js b/lib/ui/example/webpack.config.js index 83f56d360bb1..fb27dd1bbc4b 100644 --- a/lib/ui/example/webpack.config.js +++ b/lib/ui/example/webpack.config.js @@ -18,7 +18,7 @@ module.exports = { { test: /\.js$/, loader: require.resolve('babel-loader'), - query: { presets: ['react', 'es2015', 'stage-0'] }, + query: { presets: ['babel-preset-es2015', 'babel-preset-react', 'babel-preset-stage-0'].map(require.resolve) }, include: [path.join(__dirname, 'client'), path.resolve(__dirname, '../src')], }, ], diff --git a/lib/ui/package.json b/lib/ui/package.json index 4b8647250965..dfb4dc875187 100644 --- a/lib/ui/package.json +++ b/lib/ui/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/ui", - "version": "3.1.3", + "version": "3.1.4", "description": "Core Storybook UI", "license": "MIT", "main": "dist/index.js", diff --git a/lib/ui/src/modules/api/index.js b/lib/ui/src/modules/api/index.js index 704def8cde85..af946a11fc32 100755 --- a/lib/ui/src/modules/api/index.js +++ b/lib/ui/src/modules/api/index.js @@ -8,6 +8,7 @@ export default { name: 'STORYBOOK', url: 'https://github.com/storybooks/storybook', sortStoriesByKind: false, + leftPanelHierarchy: false, }, }, load({ clientStore, provider }, _actions) { diff --git a/lib/ui/src/modules/ui/components/left_panel/index.js b/lib/ui/src/modules/ui/components/left_panel/index.js index b38381643b21..3b659fc4fe0d 100755 --- a/lib/ui/src/modules/ui/components/left_panel/index.js +++ b/lib/ui/src/modules/ui/components/left_panel/index.js @@ -15,7 +15,13 @@ const mainStyle = { padding: '10px 0 10px 10px', }; -const storyProps = ['stories', 'selectedKind', 'selectedStory', 'onSelectStory']; +const storyProps = [ + 'stories', + 'selectedKind', + 'leftPanelHierarchy', + 'selectedStory', + 'onSelectStory', +]; const LeftPanel = props =>
diff --git a/lib/ui/src/modules/ui/components/left_panel/stories.js b/lib/ui/src/modules/ui/components/left_panel/stories.js index aba168aded2c..681af2655e36 100755 --- a/lib/ui/src/modules/ui/components/left_panel/stories.js +++ b/lib/ui/src/modules/ui/components/left_panel/stories.js @@ -9,13 +9,18 @@ const listStyle = { const listStyleType = { listStyleType: 'none', paddingLeft: 0, + margin: 0, }; const kindStyle = { fontSize: 15, padding: '10px 0px', cursor: 'pointer', - borderBottom: '1px solid #EEE', +}; + +const nestedListStyle = { + paddingLeft: '10px', + borderLeft: '1px solid #BBB', }; const storyStyle = { @@ -41,6 +46,53 @@ class Stories extends React.Component { if (onSelectStory) onSelectStory(selectedKind, story); } + fillHierarchy(namespaces, hierarchy, story) { + if (namespaces.length === 1) { + hierarchy.stories.push(story); + return; + } + + const namespace = namespaces[0]; + let childHierarchy = hierarchy.map.get(namespace); + + if (!childHierarchy) { + childHierarchy = { + stories: [], + current: namespace, + namespace: hierarchy.namespace ? `${hierarchy.namespace}${namespace}.` : `${namespace}.`, + firstKind: story.kind, + map: new Map(), + }; + + hierarchy.map.set(namespace, childHierarchy); + } + + this.fillHierarchy(namespaces.slice(1), childHierarchy, story); + } + + createStoriesHierarchy(stories) { + const groupedStories = stories.map(story => { + const namespaces = story.kind.split('.'); + + return { + namespaces, + name: namespaces[namespaces.length - 1], + ...story, + }; + }); + + const hierarchyRoot = { + stories: [], + namespace: '', + current: '', + map: new Map(), + }; + + groupedStories.forEach(story => this.fillHierarchy(story.namespaces, hierarchyRoot, story)); + + return hierarchyRoot; + } + renderStory(story) { const { selectedStory } = this.props; const style = { display: 'block', ...storyStyle }; @@ -67,17 +119,18 @@ class Stories extends React.Component { ); } - renderKind({ kind, stories }) { + renderKind({ kind, stories, name }) { const { selectedKind } = this.props; const style = { display: 'block', ...kindStyle }; const onClick = this.fireOnKind.bind(this, kind); + const displayName = name || kind; if (kind === selectedKind) { style.fontWeight = 'bold'; return (
  • - {kind} + {displayName}