From 28652d60f033254a33c17690409a0dafacb10f72 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Sun, 5 Aug 2018 19:55:47 +1000 Subject: [PATCH 1/5] =?UTF-8?q?Allow=20per-story=20setting=20of=20options?= =?UTF-8?q?=20via=20`{=20options:=20{=20=E2=80=A6=20}=20}`=20&=20`withOpti?= =?UTF-8?q?ons`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/options/preview.js | 1 - addons/options/src/preview/index.js | 50 ++++++++----------- .../addon-options.stories.storyshot | 13 +++++ .../stories/addon-options.stories.js | 25 ++++++++++ lib/ui/src/modules/api/actions/api.js | 5 +- lib/ui/src/modules/api/actions/api.test.js | 24 +++------ lib/ui/src/modules/api/defaultState.js | 11 ++++ lib/ui/src/modules/api/index.js | 13 +---- .../modules/shortcuts/actions/shortcuts.js | 7 +-- .../shortcuts/actions/shortcuts.test.js | 40 +++++---------- lib/ui/src/modules/shortcuts/defaultState.js | 16 ++++++ lib/ui/src/modules/shortcuts/index.js | 17 +------ 12 files changed, 115 insertions(+), 107 deletions(-) create mode 100644 examples/official-storybook/stories/__snapshots__/addon-options.stories.storyshot create mode 100644 examples/official-storybook/stories/addon-options.stories.js create mode 100644 lib/ui/src/modules/api/defaultState.js create mode 100644 lib/ui/src/modules/shortcuts/defaultState.js diff --git a/addons/options/preview.js b/addons/options/preview.js index bba63e0d5750..191b8b98a03c 100644 --- a/addons/options/preview.js +++ b/addons/options/preview.js @@ -2,5 +2,4 @@ const preview = require('./dist/preview'); exports.setOptions = preview.setOptions; exports.withOptions = preview.withOptions; - preview.init(); diff --git a/addons/options/src/preview/index.js b/addons/options/src/preview/index.js index 2a14838c5418..03af5f7ace6b 100644 --- a/addons/options/src/preview/index.js +++ b/addons/options/src/preview/index.js @@ -21,9 +21,7 @@ function withRegexProp(object, propName) { return hasOwnProp(object, propName) ? { [propName]: regExpStringify(object[propName]) } : {}; } -// setOptions function will send Storybook UI options when the channel is -// ready. If called before, options will be cached until it can be sent. -export function setOptions(newOptions) { +function emitOptions(options) { const channel = addons.getChannel(); if (!channel) { throw new Error( @@ -33,39 +31,33 @@ export function setOptions(newOptions) { // since 'undefined' and 'null' are the valid values we don't want to // override the hierarchySeparator or hierarchyRootSeparator if the prop is missing - const options = { - ...newOptions, - ...withRegexProp(newOptions, 'hierarchySeparator'), - ...withRegexProp(newOptions, 'hierarchyRootSeparator'), - }; + channel.emit(EVENT_ID, { + options: { + ...options, + ...withRegexProp(options, 'hierarchySeparator'), + ...withRegexProp(options, 'hierarchyRootSeparator'), + }, + }); +} - channel.emit(EVENT_ID, { options }); +// setOptions function will send Storybook UI options when the channel is +// ready. If called before, options will be cached until it can be sent. +let globalOptions = {}; +export function setOptions(options) { + globalOptions = options; + emitOptions(options); } export const withOptions = makeDecorator({ name: 'withOptions', parameterName: 'options', skipIfNoParametersOrOptions: false, - allowDeprecatedUsage: true, - wrapper: (getStory, context, { newOptions, parameters }) => { - const optionsIn = parameters || newOptions || {}; - - const channel = addons.getChannel(); - if (!channel) { - throw new Error( - 'Failed to find addon channel. This may be due to https://github.com/storybooks/storybook/issues/1192.' - ); - } - - // since 'undefined' and 'null' are the valid values we don't want to - // override the hierarchySeparator or hierarchyRootSeparator if the prop is missing - const options = { - ...optionsIn, - ...withRegexProp(optionsIn, 'hierarchySeparator'), - ...withRegexProp(optionsIn, 'hierarchyRootSeparator'), - }; - - channel.emit(EVENT_ID, { options }); + wrapper: (getStory, context, { options: inputOptions, parameters }) => { + emitOptions({ + ...globalOptions, + ...inputOptions, + ...parameters, + }); return getStory(context); }, diff --git a/examples/official-storybook/stories/__snapshots__/addon-options.stories.storyshot b/examples/official-storybook/stories/__snapshots__/addon-options.stories.storyshot new file mode 100644 index 000000000000..8baace00c276 --- /dev/null +++ b/examples/official-storybook/stories/__snapshots__/addon-options.stories.storyshot @@ -0,0 +1,13 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots Addons|Options withOptions hiding addon panel 1`] = ` +
+ This story should have changed the name of the storybook +
+`; + +exports[`Storyshots Addons|Options withOptions setting name 1`] = ` +
+ This story should have changed the name of the storybook +
+`; diff --git a/examples/official-storybook/stories/addon-options.stories.js b/examples/official-storybook/stories/addon-options.stories.js new file mode 100644 index 000000000000..df6ba771b745 --- /dev/null +++ b/examples/official-storybook/stories/addon-options.stories.js @@ -0,0 +1,25 @@ +import React from 'react'; +import { storiesOf } from '@storybook/react'; + +import { withOptions } from '@storybook/addon-options'; + +storiesOf('Addons|Options', module) + .addDecorator(withOptions) + .add( + 'withOptions setting name', + () =>
This story should have changed the name of the storybook
, + { + options: { + name: 'Custom Storybook', + }, + } + ) + .add( + 'withOptions hiding addon panel', + () =>
This story should have changed hidden the addons panel
, + { + options: { + showAddonPanel: false, + }, + } + ); diff --git a/lib/ui/src/modules/api/actions/api.js b/lib/ui/src/modules/api/actions/api.js index d871a3d9bcfe..b2a29b504d86 100755 --- a/lib/ui/src/modules/api/actions/api.js +++ b/lib/ui/src/modules/api/actions/api.js @@ -1,4 +1,5 @@ import pick from 'lodash.pick'; +import defaultState from '../defaultState'; export function jumpToStory(storyKinds, selectedKind, selectedStory, direction) { const flatteredStories = []; @@ -99,9 +100,9 @@ export default { setOptions(env, options) { const { clientStore, provider } = env; clientStore.update(state => { - const newOptions = pick(options, Object.keys(state.uiOptions)); + const newOptions = pick(options, Object.keys(defaultState.uiOptions)); const updatedUiOptions = { - ...state.uiOptions, + ...defaultState.uiOptions, ...newOptions, }; const otherOptions = {}; diff --git a/lib/ui/src/modules/api/actions/api.test.js b/lib/ui/src/modules/api/actions/api.test.js index 2b467cd2e660..06451ffa0167 100755 --- a/lib/ui/src/modules/api/actions/api.test.js +++ b/lib/ui/src/modules/api/actions/api.test.js @@ -209,16 +209,10 @@ describe('manager.api.actions.api', () => { describe('setOptions', () => { it('should update options', () => { const clientStore = new MockClientStore(); - actions.setOptions({ clientStore }, { abc: 10 }); + actions.setOptions({ clientStore }, { name: 'test' }); - const state = { - uiOptions: { bbc: 50, abc: 40 }, - }; - - const stateUpdates = clientStore.updateCallback(state); - expect(stateUpdates).toEqual({ - uiOptions: { bbc: 50, abc: 10 }, - }); + const stateUpdates = clientStore.updateCallback({}); + expect(stateUpdates.uiOptions).toMatchObject({ name: 'test' }); }); const provider = { @@ -274,16 +268,10 @@ describe('manager.api.actions.api', () => { it('should only update options for the key already defined', () => { const clientStore = new MockClientStore(); - actions.setOptions({ clientStore }, { abc: 10, notGoingToState: 20 }); + actions.setOptions({ clientStore }, { name: 'test', random: 'value' }); - const state = { - uiOptions: { bbc: 50, abc: 40 }, - }; - - const stateUpdates = clientStore.updateCallback(state); - expect(stateUpdates).toEqual({ - uiOptions: { bbc: 50, abc: 10 }, - }); + const stateUpdates = clientStore.updateCallback({}); + expect(stateUpdates.uiOptions).toMatchObject({ name: 'test' }); }); }); diff --git a/lib/ui/src/modules/api/defaultState.js b/lib/ui/src/modules/api/defaultState.js new file mode 100644 index 000000000000..8f0ef6ec3ace --- /dev/null +++ b/lib/ui/src/modules/api/defaultState.js @@ -0,0 +1,11 @@ +export default { + uiOptions: { + name: 'STORYBOOK', + url: 'https://github.com/storybooks/storybook', + sortStoriesByKind: false, + hierarchySeparator: '/', + hierarchyRootSeparator: null, + sidebarAnimations: true, + theme: null, + }, +}; diff --git a/lib/ui/src/modules/api/index.js b/lib/ui/src/modules/api/index.js index a8b9e22af2ab..a7ce6e1fc1fd 100755 --- a/lib/ui/src/modules/api/index.js +++ b/lib/ui/src/modules/api/index.js @@ -1,19 +1,10 @@ import actions from './actions'; import initApi from './configs/init_api'; +import defaultState from './defaultState'; export default { actions, - defaultState: { - uiOptions: { - name: 'STORYBOOK', - url: 'https://github.com/storybooks/storybook', - sortStoriesByKind: false, - hierarchySeparator: '/', - hierarchyRootSeparator: null, - sidebarAnimations: true, - theme: null, - }, - }, + defaultState, load({ clientStore, provider }, _actions) { initApi(provider, clientStore, _actions); }, diff --git a/lib/ui/src/modules/shortcuts/actions/shortcuts.js b/lib/ui/src/modules/shortcuts/actions/shortcuts.js index 3a498f734df6..faf5a5ce6844 100755 --- a/lib/ui/src/modules/shortcuts/actions/shortcuts.js +++ b/lib/ui/src/modules/shortcuts/actions/shortcuts.js @@ -1,6 +1,7 @@ import pick from 'lodash.pick'; import { features } from '../../../libs/key_events'; import apiActions from '../../api/actions'; +import defaultState from '../defaultState'; const deprecationMessage = (oldName, newName) => `The ${oldName} option has been renamed to ${newName} and will not be available in the next major Storybook release. Please update your config.`; @@ -57,10 +58,10 @@ export default { }, setOptions({ clientStore }, options) { - clientStore.update(state => { + clientStore.update(() => { const updatedOptions = { - ...state.shortcutOptions, - ...pick(options, Object.keys(state.shortcutOptions)), + ...defaultState.shortcutOptions, + ...pick(options, Object.keys(defaultState.shortcutOptions)), }; const withNewNames = Object.keys(renamedOptions).reduce((acc, oldName) => { diff --git a/lib/ui/src/modules/shortcuts/actions/shortcuts.test.js b/lib/ui/src/modules/shortcuts/actions/shortcuts.test.js index 81ad4b4a2257..22a854e8b5dc 100644 --- a/lib/ui/src/modules/shortcuts/actions/shortcuts.test.js +++ b/lib/ui/src/modules/shortcuts/actions/shortcuts.test.js @@ -10,30 +10,19 @@ describe('manager.shortcuts.actions.shortcuts', () => { describe('setOptions', () => { test('should update options', () => { const clientStore = new MockClientStore(); - actions.setOptions({ clientStore }, { abc: 10 }); + actions.setOptions({ clientStore }, { goFullScreen: true }); - const state = { - shortcutOptions: { bbc: 50, abc: 40 }, - }; - - const stateUpdates = clientStore.updateCallback(state); - expect(stateUpdates).toEqual({ - shortcutOptions: { bbc: 50, abc: 10 }, - }); + const stateUpdates = clientStore.updateCallback({}); + expect(stateUpdates.shortcutOptions).toMatchObject({ goFullScreen: true }); }); test('should only update options for the key already defined', () => { const clientStore = new MockClientStore(); - actions.setOptions({ clientStore }, { abc: 10, kki: 50 }); + actions.setOptions({ clientStore }, { goFullScreen: true, random: 'value' }); - const state = { - shortcutOptions: { bbc: 50, abc: 40 }, - }; - - const stateUpdates = clientStore.updateCallback(state); - expect(stateUpdates).toEqual({ - shortcutOptions: { bbc: 50, abc: 10 }, - }); + const stateUpdates = clientStore.updateCallback({}); + expect(stateUpdates.shortcutOptions).toMatchObject({ goFullScreen: true }); + expect(stateUpdates.shortcutOptions).not.toMatchObject({ random: 'value' }); }); test('should warn about deprecated option names', () => { @@ -48,17 +37,12 @@ describe('manager.shortcuts.actions.shortcuts', () => { } ); - const state = { - shortcutOptions: {}, - }; - const stateUpdates = clientStore.updateCallback(state); + const stateUpdates = clientStore.updateCallback({}); expect(spy).toHaveBeenCalledTimes(3); - expect(stateUpdates).toEqual({ - shortcutOptions: { - showStoriesPanel: 1, - showAddonPanel: 2, - addonPanelInRight: 3, - }, + expect(stateUpdates.shortcutOptions).toMatchObject({ + showStoriesPanel: 1, + showAddonPanel: 2, + addonPanelInRight: 3, }); spy.mockReset(); diff --git a/lib/ui/src/modules/shortcuts/defaultState.js b/lib/ui/src/modules/shortcuts/defaultState.js new file mode 100644 index 000000000000..63391ba31770 --- /dev/null +++ b/lib/ui/src/modules/shortcuts/defaultState.js @@ -0,0 +1,16 @@ +import checkIfMobileDevice from '../ui/libs/is_mobile_device'; + +const { userAgent } = global.window.navigator; +const isMobileDevice = checkIfMobileDevice(userAgent); + +export default { + isMobileDevice, + shortcutOptions: { + goFullScreen: false, + showStoriesPanel: !isMobileDevice, + showAddonPanel: true, + showSearchBox: false, + addonPanelInRight: false, + enableShortcuts: true, + }, +}; diff --git a/lib/ui/src/modules/shortcuts/index.js b/lib/ui/src/modules/shortcuts/index.js index dd89d0708cec..41358a73cf2f 100755 --- a/lib/ui/src/modules/shortcuts/index.js +++ b/lib/ui/src/modules/shortcuts/index.js @@ -1,20 +1,7 @@ import actions from './actions'; -import checkIfMobileDevice from '../ui/libs/is_mobile_device'; - -const { userAgent } = global.window.navigator; -const isMobileDevice = checkIfMobileDevice(userAgent); +import defaultState from './defaultState'; export default { actions, - defaultState: { - isMobileDevice, - shortcutOptions: { - goFullScreen: false, - showStoriesPanel: !isMobileDevice, - showAddonPanel: true, - showSearchBox: false, - addonPanelInRight: false, - enableShortcuts: true, - }, - }, + defaultState, }; From 9458fe95c7a795a7b673d8433364e5c1f29ca0b7 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 7 Aug 2018 11:15:09 +1000 Subject: [PATCH 2/5] Removed options stories from Marko This is just for simplicity. I think it is best if non-framework specific stories all live in official-storybook; that way they are easier to find in the future. cc @nm123github --- examples/marko-cli/src/stories/index.stories.js | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/examples/marko-cli/src/stories/index.stories.js b/examples/marko-cli/src/stories/index.stories.js index b2dfce908398..e7c3fb364575 100644 --- a/examples/marko-cli/src/stories/index.stories.js +++ b/examples/marko-cli/src/stories/index.stories.js @@ -1,5 +1,4 @@ import { storiesOf } from '@storybook/marko'; -import { withOptions } from '@storybook/addon-options'; import Hello from '../components/hello/index.marko'; import ClickCount from '../components/click-count/index.marko'; import StopWatch from '../components/stop-watch/index.marko'; @@ -8,17 +7,9 @@ import Welcome from '../components/welcome/index.marko'; storiesOf('Welcome', module).add('welcome', () => Welcome.renderSync({})); storiesOf('Hello', module) - .addDecorator(withOptions) - .addParameters({ options: { addonPanelInRight: false } }) .add('Simple', () => Hello.renderSync({ name: 'abc', age: 20 })) .add('with ERROR!', () => 'NOT A MARKO RENDER_RESULT'); -storiesOf('ClickCount', module) - .addDecorator(withOptions) - .addParameters({ options: { addonPanelInRight: true } }) - .add('Simple', () => ClickCount.renderSync({}), { hierarchyRootSeparator: /\|/ }); +storiesOf('ClickCount', module).add('Simple', () => ClickCount.renderSync({})); -storiesOf('StopWatch', module) - .addDecorator(withOptions) - .addParameters({ options: { addonPanelInRight: false } }) - .add('Simple', () => StopWatch.renderSync({})); +storiesOf('StopWatch', module).add('Simple', () => StopWatch.renderSync({})); From c865719d6951c7222dd822732379b8defa4a8a84 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Tue, 7 Aug 2018 11:18:00 +1000 Subject: [PATCH 3/5] Update Readme showing how `setOptions` can take arguments directly. cc @nm123github -- FYI -- we made this shortcut so you don't need to call `addDecorator` followed by `addParameters`. --- addons/options/README.md | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/addons/options/README.md b/addons/options/README.md index 05367e5d1961..ca3df05366f7 100644 --- a/addons/options/README.md +++ b/addons/options/README.md @@ -108,7 +108,7 @@ storybook.configure(() => require('./stories'), module); ### using withOptions options or parameters -The options-addon accepts story paramters to set options (as shown below). +The options-addon accepts story parameters if you use the `withOptions` decorator (as shown below). ```js import { storiesOf } from '@storybook/marko'; @@ -117,17 +117,20 @@ import { withOptions } from '@storybook/addon-options'; import Hello from '../components/hello/index.marko'; storiesOf('Addons|Knobs/Hello', module) - .addDecorator(withOptions) + // If you want to set the option for all stories in of this kind + .addDecorator(withOptions({ addonPanelInRight: true })) .addDecorator(withKnobs) - .addParameters({ options: { addonPanelInRight: true } }) - .add('Simple', () => { - const name = text('Name', 'John Doe'); - const age = number('Age', 44); - return Hello.renderSync({ - name, - age, - }); - }); + .add( + 'Simple', + () => { + const name = text('Name', 'John Doe'); + const age = number('Age', 44); + return Hello.renderSync({ + name, + age, + }); + }, + // If you want to set the options for a specific story + { options: { addonPanelInRight: false } } + ); ``` - -It is also possible to call `setOptions()` inside individual stories. Note that this will bring impact story render performance significantly. From ce3015df9eb58a9cfd2d367c0e7c21945e69735d Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Wed, 8 Aug 2018 20:09:17 +1000 Subject: [PATCH 4/5] Update snapshots --- .../stories/__snapshots__/addon-options.stories.storyshot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/official-storybook/stories/__snapshots__/addon-options.stories.storyshot b/examples/official-storybook/stories/__snapshots__/addon-options.stories.storyshot index 8baace00c276..6d859753bdf4 100644 --- a/examples/official-storybook/stories/__snapshots__/addon-options.stories.storyshot +++ b/examples/official-storybook/stories/__snapshots__/addon-options.stories.storyshot @@ -2,7 +2,7 @@ exports[`Storyshots Addons|Options withOptions hiding addon panel 1`] = `
- This story should have changed the name of the storybook + This story should have changed hidden the addons panel
`; From d309b918cc487a55bb29c21806fb38a00b05409e Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Sat, 8 Sep 2018 14:23:13 +1000 Subject: [PATCH 5/5] Deprecate `setOptions`, use `withOptions` as a decorator to solve resetting issue --- addons/options/README.md | 171 +++++++++--------- addons/options/package.json | 3 +- addons/options/src/preview/index.js | 5 +- examples/official-storybook/config.js | 14 +- .../stories/addon-options.stories.js | 3 - 5 files changed, 100 insertions(+), 96 deletions(-) diff --git a/addons/options/README.md b/addons/options/README.md index ca3df05366f7..46fc3ca9c3b6 100644 --- a/addons/options/README.md +++ b/addons/options/README.md @@ -20,105 +20,106 @@ Add this line to your `addons.js` file (create this file inside your storybook c import '@storybook/addon-options/register'; ``` -Import and use the `setOptions` function in your config.js file. +Import and use the `withOptions` decorator in your config.js file. ```js -import * as storybook from '@storybook/react'; -import { setOptions } from '@storybook/addon-options'; +import { addDecorator, configure } from '@storybook/react'; +import { withOptions } from '@storybook/addon-options'; // Option defaults: -setOptions({ - /** - * name to display in the top left corner - * @type {String} - */ - name: 'Storybook', - /** - * URL for name in top left corner to link to - * @type {String} - */ - url: '#', - /** - * show story component as full screen - * @type {Boolean} - */ - goFullScreen: false, - /** - * display panel that shows a list of stories - * @type {Boolean} - */ - showStoriesPanel: true, - /** - * display panel that shows addon configurations - * @type {Boolean} - */ - showAddonPanel: true, - /** - * display floating search box to search through stories - * @type {Boolean} - */ - showSearchBox: false, - /** - * show addon panel as a vertical panel on the right - * @type {Boolean} - */ - addonPanelInRight: false, - /** - * sorts stories - * @type {Boolean} - */ - sortStoriesByKind: false, - /** - * regex for finding the hierarchy separator - * @example: - * null - turn off hierarchy - * /\// - split by `/` - * /\./ - split by `.` - * /\/|\./ - split by `/` or `.` - * @type {Regex} - */ - hierarchySeparator: null, - /** - * regex for finding the hierarchy root separator - * @example: - * null - turn off multiple hierarchy roots - * /\|/ - split by `|` - * @type {Regex} - */ - hierarchyRootSeparator: null, - /** - * sidebar tree animations - * @type {Boolean} - */ - sidebarAnimations: true, - /** - * id to select an addon panel - * @type {String} - */ - selectedAddonPanel: undefined, // The order of addons in the "Addon panel" is the same as you import them in 'addons.js'. The first panel will be opened by default as you run Storybook - /** - * enable/disable shortcuts - * @type {Boolean} - */ - enableShortcuts: false, // true by default -}); - -storybook.configure(() => require('./stories'), module); +addDecorator( + withOptions({ + /** + * name to display in the top left corner + * @type {String} + */ + name: 'Storybook', + /** + * URL for name in top left corner to link to + * @type {String} + */ + url: '#', + /** + * show story component as full screen + * @type {Boolean} + */ + goFullScreen: false, + /** + * display panel that shows a list of stories + * @type {Boolean} + */ + showStoriesPanel: true, + /** + * display panel that shows addon configurations + * @type {Boolean} + */ + showAddonPanel: true, + /** + * display floating search box to search through stories + * @type {Boolean} + */ + showSearchBox: false, + /** + * show addon panel as a vertical panel on the right + * @type {Boolean} + */ + addonPanelInRight: false, + /** + * sorts stories + * @type {Boolean} + */ + sortStoriesByKind: false, + /** + * regex for finding the hierarchy separator + * @example: + * null - turn off hierarchy + * /\// - split by `/` + * /\./ - split by `.` + * /\/|\./ - split by `/` or `.` + * @type {Regex} + */ + hierarchySeparator: null, + /** + * regex for finding the hierarchy root separator + * @example: + * null - turn off multiple hierarchy roots + * /\|/ - split by `|` + * @type {Regex} + */ + hierarchyRootSeparator: null, + /** + * sidebar tree animations + * @type {Boolean} + */ + sidebarAnimations: true, + /** + * id to select an addon panel + * @type {String} + */ + selectedAddonPanel: undefined, // The order of addons in the "Addon panel" is the same as you import them in 'addons.js'. The first panel will be opened by default as you run Storybook + /** + * enable/disable shortcuts + * @type {Boolean} + */ + enableShortcuts: false, // true by default + }) +); + +configure(() => require('./stories'), module); ``` -### using withOptions options or parameters +### Using per-story options -The options-addon accepts story parameters if you use the `withOptions` decorator (as shown below). +The options-addon accepts story parameters on the `options` key: ```js import { storiesOf } from '@storybook/marko'; import { withKnobs, text, number } from '@storybook/addon-knobs'; -import { withOptions } from '@storybook/addon-options'; import Hello from '../components/hello/index.marko'; storiesOf('Addons|Knobs/Hello', module) // If you want to set the option for all stories in of this kind - .addDecorator(withOptions({ addonPanelInRight: true })) + .addParameters({ options: { addonPanelInRight: true } }) .addDecorator(withKnobs) .add( 'Simple', @@ -134,3 +135,5 @@ storiesOf('Addons|Knobs/Hello', module) { options: { addonPanelInRight: false } } ); ``` + +_NOTE_ that you must attach `withOptions` as a decorator (at the top-level) for this to work. diff --git a/addons/options/package.json b/addons/options/package.json index 54040d20073b..1c9cc7f536a6 100644 --- a/addons/options/package.json +++ b/addons/options/package.json @@ -19,7 +19,8 @@ "prepare": "node ../../scripts/prepare.js" }, "dependencies": { - "@storybook/addons": "4.0.0-alpha.21" + "@storybook/addons": "4.0.0-alpha.21", + "util-deprecate": "^1.0.2" }, "peerDependencies": { "react": "*" diff --git a/addons/options/src/preview/index.js b/addons/options/src/preview/index.js index 03af5f7ace6b..218f2d141346 100644 --- a/addons/options/src/preview/index.js +++ b/addons/options/src/preview/index.js @@ -1,3 +1,4 @@ +import deprecate from 'util-deprecate'; import addons, { makeDecorator } from '@storybook/addons'; import { EVENT_ID } from '../shared'; @@ -43,10 +44,10 @@ function emitOptions(options) { // setOptions function will send Storybook UI options when the channel is // ready. If called before, options will be cached until it can be sent. let globalOptions = {}; -export function setOptions(options) { +export const setOptions = deprecate(options => { globalOptions = options; emitOptions(options); -} +}, '`setOptions(options)` is deprecated. Please use the `withOptions(options)` decorator globally.'); export const withOptions = makeDecorator({ name: 'withOptions', diff --git a/examples/official-storybook/config.js b/examples/official-storybook/config.js index d8fca85056aa..520d9f5b50a9 100644 --- a/examples/official-storybook/config.js +++ b/examples/official-storybook/config.js @@ -2,7 +2,7 @@ import React from 'react'; import ThemeProvider from '@emotion/provider'; import { configure, addDecorator } from '@storybook/react'; import { themes } from '@storybook/components'; -import { setOptions } from '@storybook/addon-options'; +import { withOptions } from '@storybook/addon-options'; import { configureViewport, INITIAL_VIEWPORTS } from '@storybook/addon-viewport'; import 'react-chromatic/storybook-addon'; @@ -12,11 +12,13 @@ import extraViewports from './extra-viewports.json'; addHeadWarning('Preview head not loaded', 'preview-head-not-loaded'); addHeadWarning('Dotenv file not loaded', 'dotenv-file-not-loaded'); -setOptions({ - hierarchySeparator: /\/|\./, - hierarchyRootSeparator: /\|/, - theme: themes.dark, -}); +addDecorator( + withOptions({ + hierarchySeparator: /\/|\./, + hierarchyRootSeparator: /\|/, + theme: themes.dark, + }) +); addDecorator( (story, { kind }) => diff --git a/examples/official-storybook/stories/addon-options.stories.js b/examples/official-storybook/stories/addon-options.stories.js index df6ba771b745..bf7228591378 100644 --- a/examples/official-storybook/stories/addon-options.stories.js +++ b/examples/official-storybook/stories/addon-options.stories.js @@ -1,10 +1,7 @@ import React from 'react'; import { storiesOf } from '@storybook/react'; -import { withOptions } from '@storybook/addon-options'; - storiesOf('Addons|Options', module) - .addDecorator(withOptions) .add( 'withOptions setting name', () =>
This story should have changed the name of the storybook
,