Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Story Hierarchy improved UI #1356

Merged
merged 21 commits into from
Jun 29, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
a7a3900
Add left panel hierarchy support
Jun 21, 2017
ad32ffa
Fix a few related codebeat issues
Jun 21, 2017
6960d91
Add more tests for stories.js
Jun 21, 2017
3dbdb9e
Better UI for the hierarchy view + bugs fixes
Jun 22, 2017
6bfed5d
Merge remote-tracking branch 'origin/master' into left-panel-hierarchy
Jun 22, 2017
f27825d
Add shortcut to toggle hierarchy
Jun 23, 2017
9b00eb3
Extract hierarchy creation to the mapper
igor-dv Jun 23, 2017
06a4c54
Remove shortcuts for the hierarchy toggling + change leftPanelHierarc…
igor-dv Jun 23, 2017
c16cc2d
Rename resolveStoryHierarchyNamespace to resolveStoryHierarchy
igor-dv Jun 23, 2017
3fde529
Fix tests + Add tests for hierarchy
igor-dv Jun 23, 2017
17fb4f5
Fix the cases when the separator is not a "."
igor-dv Jun 24, 2017
87adce4
Add assertions to left_panel.test.js
igor-dv Jun 24, 2017
bbf6360
Fix warnings in stories.test.js
igor-dv Jun 25, 2017
1c33fda
Fix tests + Add tests
igor-dv Jun 25, 2017
df26718
Remove require.resolve from libs/ui webpack.config.js
igor-dv Jun 25, 2017
21d7173
Remove package-lock.json files
igor-dv Jun 25, 2017
f57a602
Merge pull request #1329 from igor-dv/left-panel-hierarchy
shilman Jun 25, 2017
dbb04c1
Repalce resolveStoryHierarchy func with hierarchySeparator
igor-dv Jun 26, 2017
279e198
Change the order of the atomic namespace
igor-dv Jun 29, 2017
43ca59b
Merge remote-tracking branch 'origin/release/3.2' into 151-story-hier…
igor-dv Jun 29, 2017
8262b7b
Revert code that was injected by aliens
igor-dv Jun 29, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion examples/cra-kitchen-sink/.storybook/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ setOptions({
showSearchBox: false,
downPanelInRight: true,
sortStoriesByKind: false,
})
hierarchySeparator: '\\/|\\.|¯\\\\_\\(ツ\\)_\\/¯'
});

setAddon(infoAddon);

Expand Down
40 changes: 40 additions & 0 deletions examples/cra-kitchen-sink/src/stories/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,43 @@ storiesOf('WithEvents', module)
</WithEvents>
)
.add('Logger', () => <Logger emiter={emiter} />);

storiesOf('component.base.Link')
.addDecorator(withKnobs)
.add('first', () => <a>{text('firstLink', 'first link')}</a>)
.add('second', () => <a>{text('secondLink', 'second link')}</a>);

storiesOf('component.base.Span')
.add('first', () => <span>first span</span>)
.add('second', () => <span>second span</span>);

storiesOf('component.common.Div')
.add('first', () => <div>first div</div>)
.add('second', () => <div>second div</div>);

storiesOf('component.common.Table')
.add('first', () => <table><tr><td>first table</td></tr></table>)
.add('second', () => <table><tr><td>first table</td></tr></table>);

storiesOf('component.Button')
.add('first', () => <button>first button</button>)
.add('second', () => <button>first second</button>);

// Atomic

storiesOf('Cells¯\\_(ツ)_/¯Molecules.Atoms/simple', module)
.addDecorator(withKnobs)
.add('with text', () => <Button>{text('buttonText', 'Hello Button')}</Button>)
.add('with some emoji', () => <Button>😀 😎 👍 💯</Button>);

storiesOf('Cells/Molecules/Atoms.more', module)
.add('with text2', () => <Button>Hello Button</Button>)
.add('with some emoji2', () => <Button>😀 😎 👍 💯</Button>);

storiesOf('Cells/Molecules', module)
.add('with text', () => <Button>Hello Button</Button>)
.add('with some emoji', () => <Button>😀 😎 👍 💯</Button>);

storiesOf('Cells.Molecules.Atoms', module)
.add('with text2', () => <Button>Hello Button</Button>)
.add('with some emoji2', () => <Button>😀 😎 👍 💯</Button>);
57 changes: 47 additions & 10 deletions lib/ui/example/client/provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,25 +78,62 @@ export default class ReactProvider extends Provider {
this.api = api;
this.api.setOptions({
name: 'REACT-STORYBOOK',
sortStoriesByKind: true,
hierarchySeparator: '/'
});

// set stories
this.api.setStories([
this.api.setStories(this.createStories());

// listen to the story change and update the preview.
this.api.onStory((kind, story) => {
this.globalState.emit('change', kind, story);
});
}

createStories() {
return [
{
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'],
},
]);

// listen to the story change and update the preview.
this.api.onStory((kind, story) => {
this.globalState.emit('change', kind, story);
});
{
kind: 'some/name2/Component 3',
stories: ['State a', 'State b'],
},
{
kind: 'some/name2',
stories: ['State a', 'State b'],
},
{
kind: 'some/name2/Component 4',
stories: ['State a', 'State b'],
},
{
kind: 'another/name3/Component 5',
stories: ['State a', 'State b'],
},
{
kind: 'another/name3/Component 6',
stories: ['State a', 'State b'],
},
{
kind: 'Bla 1',
stories: ['State 1', 'State 2'],
},
{
kind: 'Bla 2',
stories: ['State 1', 'State 2'],
},
{
kind: 'anotherComponent in the middle',
stories: ['State a', 'State b'],
},
]
}

_handlePreviewEvents() {
Expand Down
1 change: 1 addition & 0 deletions lib/ui/src/modules/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export default {
name: 'STORYBOOK',
url: 'https://github.com/storybooks/storybook',
sortStoriesByKind: false,
hierarchySeparator: '',
},
},
load({ clientStore, provider }, _actions) {
Expand Down
18 changes: 14 additions & 4 deletions lib/ui/src/modules/ui/components/left_panel/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@ const mainStyle = {
padding: '10px 0 10px 10px',
};

const storyProps = ['stories', 'selectedKind', 'selectedStory', 'onSelectStory'];
const storyProps = [
'storiesHierarchy',
'selectedKind',
'selectedHierarchy',
'selectedStory',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we need to have selectedStory and selectedKind in propTypes?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think linter cries that they are not in use in here. these props just passed further to stories.js where they are actually defined in prop types.

'onSelectStory',
];

const LeftPanel = props =>
<div style={mainStyle}>
Expand All @@ -26,12 +32,12 @@ const LeftPanel = props =>
onChange={text => props.onStoryFilter(text)}
/>
<div style={scrollStyle}>
{props.stories ? <Stories {...pick(props, storyProps)} /> : null}
{props.storiesHierarchy ? <Stories {...pick(props, storyProps)} /> : null}
</div>
</div>;

LeftPanel.defaultProps = {
stories: null,
storiesHierarchy: null,
storyFilter: null,
onStoryFilter: () => {},
openShortcutsHelp: null,
Expand All @@ -40,7 +46,11 @@ LeftPanel.defaultProps = {
};

LeftPanel.propTypes = {
stories: PropTypes.arrayOf(PropTypes.object),
storiesHierarchy: PropTypes.shape({
namespaces: PropTypes.arrayOf(PropTypes.string),
current: PropTypes.string,
map: PropTypes.object,
}),
storyFilter: PropTypes.string,
onStoryFilter: PropTypes.func,

Expand Down
14 changes: 10 additions & 4 deletions lib/ui/src/modules/ui/components/left_panel/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import LeftPanel from './index';
import Header from './header';
import TextFilter from './text_filter';
import Stories from './stories';
import { createHierarchy } from '../../libs/hierarchy';

describe('manager.ui.components.left_panel.index', () => {
test('should render Header and TextFilter by default', () => {
Expand All @@ -22,17 +23,22 @@ describe('manager.ui.components.left_panel.index', () => {
expect(wrap.find(Stories)).toBeEmpty();
});

test('should render stories only if stories prop exists', () => {
test('should render stories only if storiesHierarchy prop exists', () => {
const selectedKind = 'kk';
const selectedStory = 'bb';
const stories = [{ kind: 'kk', stories: ['bb'] }];
const storiesHierarchy = createHierarchy([{ kind: 'kk', stories: ['bb'] }]);
const wrap = shallow(
<LeftPanel stories={stories} selectedKind={selectedKind} selectedStory={selectedStory} />
<LeftPanel
storiesHierarchy={storiesHierarchy}
selectedKind={selectedKind}
selectedStory={selectedStory}
selectedHierarchy={['kk']}
/>
);

const header = wrap.find(Stories).first();
expect(header.props()).toMatchObject({
stories,
storiesHierarchy,
selectedKind,
selectedStory,
});
Expand Down
Loading