Merge branch 'master' into patch-1

This commit is contained in:
Norbert de Langen 2017-08-13 01:24:43 +02:00 committed by GitHub
commit f1f73a68d4
12 changed files with 140 additions and 16 deletions

View File

@ -93,6 +93,12 @@ setOptions({
* @type {Boolean}
*/
sidebarAnimations: true,
/**
* id to select an addon panel
* @type {String}
*/
selectedAddonPanel: undefined, // The order of addons in the "Addons Panel" is the same as you import them in 'addons.js'. The first panel will be opened by default as you run Storybook
});
storybook.configure(() => require('./stories'), module);

View File

@ -260,6 +260,22 @@ exports[`Storyshots Button addons composition 1`] = `
>
</span>
</div>
<div
style={
Object {
"paddingLeft": 33,
"paddingRight": 3,
}
}
>
<span
style={
Object {
"color": "#777",
}
}
/>
</div>
<div
style={
Object {
@ -709,6 +725,22 @@ exports[`Storyshots Button with new info 1`] = `
&gt;
</span>
</div>
<div
style={
Object {
"paddingLeft": 33,
"paddingRight": 3,
}
}
>
<span
style={
Object {
"color": "#777",
}
}
/>
</div>
<div
style={
Object {

View File

@ -2,6 +2,7 @@ import React from 'react';
import EventEmiter from 'eventemitter3';
import { storiesOf } from '@storybook/react';
import { setOptions } from '@storybook/addon-options';
import { action } from '@storybook/addon-actions';
import { withNotes, WithNotes } from '@storybook/addon-notes';
import { linkTo } from '@storybook/addon-links';
@ -56,14 +57,28 @@ const InfoButton = () =>
storiesOf('Button', module)
.addDecorator(withKnobs)
.add('with text', () => <Button onClick={action('clicked')}>Hello Button</Button>)
.add('with some emoji', () => <Button onClick={action('clicked')}>😀 😎 👍 💯</Button>)
.add('with text', () =>
<Button onClick={action('clicked')}>
{setOptions({ selectedAddonPanel: 'storybook/actions/actions-panel' })}
Hello Button
</Button>
)
.add('with some emoji', () =>
<Button onClick={action('clicked')}>
{setOptions({ selectedAddonPanel: 'storybook/actions/actions-panel' })}
😀 😎 👍 💯
</Button>
)
.add('with notes', () =>
<WithNotes notes={'A very simple button'}>
<Button>Check my notes in the notes panel</Button>
<Button>
{setOptions({ selectedAddonPanel: 'storybook/notes/panel' })}
Check my notes in the notes panel
</Button>
</WithNotes>
)
.add('with knobs', () => {
setOptions({ selectedAddonPanel: 'storybooks/storybook-addon-knobs' });
const name = text('Name', 'Storyteller');
const age = number('Age', 70, { range: true, min: 0, max: 90, step: 5 });
const fruits = {
@ -130,6 +145,7 @@ storiesOf('Button', module)
'Use the [info addon](https://github.com/storybooks/storybook/tree/master/addons/info) with its new painless API.'
)(context =>
<Container>
{setOptions({ selectedAddonPanel: 'storybook/info/info-panel' })}
click the <InfoButton /> label in top right for info about "{context.story}"
</Container>
)
@ -139,6 +155,7 @@ storiesOf('Button', module)
withInfo('see Notes panel for composition info')(
withNotes('Composition: Info(Notes())')(context =>
<div>
{setOptions({ selectedAddonPanel: 'storybook/notes/panel' })}
click the <InfoButton /> label in top right for info about "{context.story}"
</div>
)

View File

@ -87,9 +87,8 @@ import { Provider } from '@storybook/ui';
class ReactProvider extends Provider {
handleAPI(api) {
api.setOptions({
name: 'My Component', // change the name displayed in the left top portion
url: 'https://github.com/user/my-component', // change its URL
sortStoriesByKind: true // Sort the list of stories by their "kind"
// see available options in
// https://github.com/storybooks/storybook/tree/master/addons/options#getting-started
});
}
};

View File

@ -47,6 +47,17 @@ export function ensureStory(storyKinds, selectedKind, selectedStory) {
return kindInfo.stories[0];
}
export function ensurePanel(panels, selectedPanel, currentPanel) {
if (Object.keys(panels).indexOf(selectedPanel) >= 0) return selectedPanel;
// if the selected panel is non-existant, select the current panel
// and output to console all available panels
const logger = console;
logger.group('Available Panels ID:');
Object.keys(panels).forEach(panelID => logger.log(`${panelID} (${panels[panelID].title})`));
logger.groupEnd('Available Panels ID:');
return currentPanel;
}
export default {
setStories({ clientStore }, stories) {
clientStore.update(state => {
@ -77,15 +88,23 @@ export default {
);
},
setOptions({ clientStore }, options) {
setOptions(env, options) {
const { clientStore, provider } = env;
clientStore.update(state => {
const newOptions = pick(options, Object.keys(state.uiOptions));
const updatedOptions = {
const updatedUiOptions = {
...state.uiOptions,
...newOptions,
};
return { uiOptions: updatedOptions };
const otherOptions = {};
if (Object.keys(pick(options, ['selectedAddonPanel'])).length) {
otherOptions.selectedAddonPanel = ensurePanel(
provider.getPanels(),
options.selectedAddonPanel,
state.selectedAddonPanel
);
}
return { uiOptions: updatedUiOptions, ...otherOptions };
});
},

View File

@ -189,6 +189,57 @@ describe('manager.api.actions.api', () => {
});
});
const provider = {
getPanels: () => ({
'storybook/actions/actions-panel': {
title: 'Action logger',
},
'storybooks/storybook-addon-knobs': {
title: 'Knobs',
},
}),
};
it('should update selectedAddonPanel', () => {
const clientStore = new MockClientStore();
actions.setOptions(
{ clientStore, provider },
{ selectedAddonPanel: 'storybooks/storybook-addon-knobs' }
);
const state = {
uiOptions: {},
selectedAddonPanel: 'storybook/actions/actions-panel',
};
const stateUpdates = clientStore.updateCallback(state);
expect(stateUpdates.selectedAddonPanel).toEqual('storybooks/storybook-addon-knobs');
});
it('should keep current downPanel and output panel IDs', () => {
const clientStore = new MockClientStore();
actions.setOptions({ clientStore, provider }, { selectedAddonPanel: null });
global.console = {
log: jest.fn(),
group: jest.fn(),
groupEnd: jest.fn(),
};
const logger = console;
const state = {
uiOptions: {},
selectedAddonPanel: 'storybook/actions/actions-panel',
};
const stateUpdates = clientStore.updateCallback(state);
expect(stateUpdates.selectedAddonPanel).toEqual('storybook/actions/actions-panel');
expect(logger.log.mock.calls).toEqual([
['storybook/actions/actions-panel (Action logger)'],
['storybooks/storybook-addon-knobs (Knobs)'],
]);
});
it('should only update options for the key already defined', () => {
const clientStore = new MockClientStore();
actions.setOptions({ clientStore }, { abc: 10, notGoingToState: 20 });

View File

@ -8,6 +8,6 @@ export default {
},
selectDownPanel({ clientStore }, panelName) {
clientStore.set('selectedDownPanel', panelName);
clientStore.set('selectedAddonPanel', panelName);
},
};

View File

@ -32,7 +32,7 @@ describe('manager.ui.actions.ui', () => {
const panelName = 'kkkind';
actions.selectDownPanel({ clientStore }, panelName);
expect(clientStore.set).toHaveBeenCalledWith('selectedDownPanel', panelName);
expect(clientStore.set).toHaveBeenCalledWith('selectedAddonPanel', panelName);
});
});
});

View File

@ -15,7 +15,7 @@ export function getUrlState(data) {
downPanelInRight: panelRight,
} = data.shortcutOptions;
const { selectedDownPanel: downPanel } = data;
const { selectedAddonPanel: downPanel } = data;
const urlObj = {
...customQueryParams,

View File

@ -23,7 +23,7 @@ describe('manager.ui.config.handle_routing', () => {
showLeftPanel: true,
downPanelInRight: true,
},
selectedDownPanel: 'pp',
selectedAddonPanel: 'pp',
};
const clientStore = {
getAll: () => state,

View File

@ -5,7 +5,7 @@ import compose from '../../../compose';
export function mapper(state, props, { context, actions }) {
const panels = context().provider.getPanels();
const actionMap = actions();
const selectedPanel = state.selectedDownPanel;
const selectedPanel = state.selectedAddonPanel;
return {
panels,

View File

@ -4,7 +4,7 @@ describe('manager.ui.containers.down_panel', () => {
describe('mapper', () => {
test('should give correct data', () => {
const state = {
selectedDownPanel: 'sdp',
selectedAddonPanel: 'sdp',
};
const selectDownPanel = () => 'selectDownPanel';