mirror of
https://github.com/storybookjs/storybook.git
synced 2025-04-09 00:19:13 +08:00
Merge branch 'master' into patch-1
This commit is contained in:
commit
f1f73a68d4
@ -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);
|
||||
|
@ -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`] = `
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
style={
|
||||
Object {
|
||||
"paddingLeft": 33,
|
||||
"paddingRight": 3,
|
||||
}
|
||||
}
|
||||
>
|
||||
<span
|
||||
style={
|
||||
Object {
|
||||
"color": "#777",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
style={
|
||||
Object {
|
||||
|
@ -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>
|
||||
)
|
||||
|
@ -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
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -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 };
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -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 });
|
||||
|
@ -8,6 +8,6 @@ export default {
|
||||
},
|
||||
|
||||
selectDownPanel({ clientStore }, panelName) {
|
||||
clientStore.set('selectedDownPanel', panelName);
|
||||
clientStore.set('selectedAddonPanel', panelName);
|
||||
},
|
||||
};
|
||||
|
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -15,7 +15,7 @@ export function getUrlState(data) {
|
||||
downPanelInRight: panelRight,
|
||||
} = data.shortcutOptions;
|
||||
|
||||
const { selectedDownPanel: downPanel } = data;
|
||||
const { selectedAddonPanel: downPanel } = data;
|
||||
|
||||
const urlObj = {
|
||||
...customQueryParams,
|
||||
|
@ -23,7 +23,7 @@ describe('manager.ui.config.handle_routing', () => {
|
||||
showLeftPanel: true,
|
||||
downPanelInRight: true,
|
||||
},
|
||||
selectedDownPanel: 'pp',
|
||||
selectedAddonPanel: 'pp',
|
||||
};
|
||||
const clientStore = {
|
||||
getAll: () => state,
|
||||
|
@ -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,
|
||||
|
@ -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';
|
||||
|
Loading…
x
Reference in New Issue
Block a user