Skip to content

Commit

Permalink
REFACTOR state management
Browse files Browse the repository at this point in the history
  • Loading branch information
ndelangen committed Dec 11, 2018
1 parent 2761750 commit a8bf858
Show file tree
Hide file tree
Showing 36 changed files with 322 additions and 341 deletions.
8 changes: 3 additions & 5 deletions addons/options/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import '@storybook/addon-options/register';

###Set options globally

Import and use the `withOptions` decorator in your `config.js` file.
Import and use the `addParameters` + `options`-key in your `config.js` file.

```js
import { addParameters, configure } from '@storybook/react';
Expand Down Expand Up @@ -128,15 +128,13 @@ storiesOf('Addons|Custom options', module)
);
```

_NOTE_ that you must attach `withOptions` as a decorator (at the top-level) for this to work.

## Typescript

To install type definitions: `npm install -D @types/storybook__addon-options`
To install type definitions: `yarn add @types/storybook__addon-options --dev`

Make sure you also have the type definitions installed for the following libs:

- node
- react

You can install them using `npm install -D @types/node @types/react`, assuming you are using Typescript >2.0.
You can install them using `yarn add @types/node @types/react --dev`, assuming you are using Typescript >2.0.
3 changes: 0 additions & 3 deletions addons/options/manager.js

This file was deleted.

2 changes: 1 addition & 1 deletion addons/options/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"url": "https://github.com/storybooks/storybook.git"
},
"license": "MIT",
"main": "preview.js",
"main": "dist/index.js",
"scripts": {
"prepare": "node ../../scripts/prepare.js"
},
Expand Down
5 changes: 0 additions & 5 deletions addons/options/preview.js

This file was deleted.

4 changes: 1 addition & 3 deletions addons/options/register.js
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
// NOTE: loading addons using this file is deprecated!
// please use manager.js and preview.js files instead
require('./manager');
require('./dist/register');
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// addons, panels and events get unique names using a prefix
export const ADDON_ID = 'storybooks/options';
export const EVENT_ID = `${ADDON_ID}/options-event`;

export default {
SET: `${ADDON_ID}/options-event`,
};
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import deprecate from 'util-deprecate';
import addons, { makeDecorator } from '@storybook/addons';
import { EVENT_ID } from '../shared';

// init function will be executed once when the storybook loads for the
// first time. This is a good place to add global listeners on channel.
export function init() {
// NOTE nothing to do here
}
import EVENTS from './constants';

function emitOptions(options) {
const channel = addons.getChannel();
Expand All @@ -18,7 +13,7 @@ function emitOptions(options) {

// since 'undefined' and 'null' are the valid values we don't want to
// override the hierarchySeparator or hierarchyRootSeparator if the prop is missing
channel.emit(EVENT_ID, {
channel.emit(EVENTS.SET, {
options,
});
}
Expand All @@ -35,7 +30,7 @@ export const withOptions = makeDecorator({
name: 'withOptions',
parameterName: 'options',
skipIfNoParametersOrOptions: false,
wrapper: (getStory, context, { options: inputOptions, parameters }) => {
wrapper: deprecate((getStory, context, { options: inputOptions, parameters }) => {
// do not send hierachy related options over the channel
const { hierarchySeparator, hierarchyRootSeparator, ...change } = {
...globalOptions,
Expand Down Expand Up @@ -67,7 +62,7 @@ export const withOptions = makeDecorator({
...parameters,
},
});
},
}, 'withOptions is deprecated, use addParameters({ options: {} }) instead'),
});

if (module && module.hot && module.hot.decline) {
Expand Down
13 changes: 0 additions & 13 deletions addons/options/src/manager/index.js

This file was deleted.

10 changes: 10 additions & 0 deletions addons/options/src/register.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import addons from '@storybook/addons';
import EVENTS, { ADDON_ID } from './constants';

addons.register(ADDON_ID, api => {
const channel = addons.getChannel();

channel.on(EVENTS.SET, data => {
api.setOptions(data.options);
});
});
3 changes: 1 addition & 2 deletions docs/src/pages/addons/using-addons/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ Then you'll be able to see those notes when you are viewing the story.
Sometimes you might want to configure an addon globally, as in the case of collocating stories with components, or just simply to keep your stories file cleaner. To do that, you can add your decorators to a config file, typically in `.storybook/config.js`. Here's an example of how you might do that.

```js
import { configure, addDecorator } from '@storybook/react';
import { withOptions } from '@storybook/addon-options';
import { configure, addParameters } from '@storybook/react';

addParameters({
options: {
Expand Down
6 changes: 2 additions & 4 deletions docs/src/pages/configurations/theming/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ import '@storybook/addon-options/register';

Then, modify `.storybook/config.js` to include your new options:
```js
import { addDecorator, configure } from '@storybook/react';
import { withOptions } from '@storybook/addon-options';
import { addParameters, configure } from '@storybook/react';

addParameters({
options: {
Expand All @@ -37,8 +36,7 @@ We have created 2 themes for you: "normal" (a light theme) and "dark" (a dark th
You can get these themes like so:

```js
import { addDecorator, configure } from '@storybook/react';
import { withOptions } from '@storybook/addon-options';
import { addParameters, configure } from '@storybook/react';
import { themes } from '@storybook/components';

// Option defaults.
Expand Down
1 change: 0 additions & 1 deletion examples/angular-cli/.storybook/config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { configure, addParameters } from '@storybook/angular';
import { withOptions } from '@storybook/addon-options';
import addCssWarning from '../src/cssWarning';

addCssWarning();
Expand Down
4 changes: 1 addition & 3 deletions examples/marko-cli/src/stories/addon-knobs.stories.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
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)
.addDecorator(withOptions)
.addDecorator(withKnobs)
.addParameters({ options: { addonPanelInRight: true } })
.addDecorator(withKnobs)
.add('Simple', () => {
const name = text('Name', 'John Doe');
const age = number('Age', 44);
Expand Down
1 change: 1 addition & 0 deletions examples/official-storybook/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ addDecorator((story, { kind }) =>
addParameters({
a11y: {},
options: {
name: 'Storybook',
hierarchySeparator: /\/|\./,
hierarchyRootSeparator: '|',
// theme: themes.dark,
Expand Down
16 changes: 6 additions & 10 deletions examples/official-storybook/stories/addon-options.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,13 @@ import React from 'react';
import { storiesOf } from '@storybook/react';

storiesOf('Addons|Options', module)
.add('setting name', () => <div>This story should have changed the name of the storybook</div>, {
options: {
name: 'Custom Storybook',
},
})
.add(
'withOptions setting name',
() => <div>This story should have changed the name of the storybook</div>,
{
options: {
name: 'Custom Storybook',
},
}
)
.add(
'withOptions hiding addon panel',
'hiding addon panel',
() => <div>This story should have changed hidden the addons panel</div>,
{
options: {
Expand Down
10 changes: 6 additions & 4 deletions examples/svelte-kitchen-sink/.storybook/config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { configure, addDecorator } from '@storybook/svelte';
import { withOptions } from '@storybook/addon-options';
import { configure, addParameters } from '@storybook/svelte';

// Used with @storybook/addon-options/register
addDecorator(withOptions({ hierarchyRootSeparator: /\|/ }));
addParameters({
options: {
hierarchyRootSeparator: /\|/,
},
});

function loadStories() {
require('../src/stories');
Expand Down
2 changes: 1 addition & 1 deletion lib/ui/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const App = () => (
},
],
options: {
...state.ui,
...state.layout,
},
viewMode: state.viewMode,
componentId: state.componentId,
Expand Down
7 changes: 4 additions & 3 deletions lib/ui/src/containers/nav.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,19 +95,20 @@ const createMenu = memoize(1)(

export const mapper = ({ state, api }) => {
const {
uiOptions: { name, url },
ui: { name, url },
notifications,
viewMode,
componentId,
ui: { isFullscreen, showPanel, showNav, panelPosition },
layout: { isFullscreen, showPanel, showNav, panelPosition },
storiesHash,
} = state;

const shortcutKeys = get('shortcutKeys') || serializableKeyboardShortcuts;
return {
title: name,
url,
notifications,
stories: state.storiesHash,
stories: storiesHash,
componentId,
viewMode,
menu: createMenu(api, shortcutKeys, isFullscreen, showPanel, showNav, panelPosition),
Expand Down
12 changes: 6 additions & 6 deletions lib/ui/src/containers/nav.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ describe('manager.ui.containers.stories_panel', () => {
const selectedKind = 'sk';
const selectedStory = 'dd';
const selectedHierarchy = ['sk'];
const uiOptions = {
const ui = {
name: 'foo',
url: 'bar',
};
Expand All @@ -29,7 +29,7 @@ describe('manager.ui.containers.stories_panel', () => {
stories,
selectedKind,
selectedStory,
uiOptions,
ui,
};
const result = mapper(state, props, env);

Expand Down Expand Up @@ -65,7 +65,7 @@ describe('manager.ui.containers.stories_panel', () => {
];
const selectedKind = 'pk';
const selectedStory = 'dd';
const uiOptions = {
const ui = {
name: 'foo',
url: 'bar',
};
Expand All @@ -89,7 +89,7 @@ describe('manager.ui.containers.stories_panel', () => {
stories,
selectedKind,
selectedStory,
uiOptions,
ui,
};
const result = mapper(state, props, env);

Expand Down Expand Up @@ -131,7 +131,7 @@ describe('manager.ui.containers.stories_panel', () => {
];
const selectedKind = 'pk';
const selectedStory = 'dd';
const uiOptions = {
const ui = {
name: 'foo',
url: 'bar',
sortStoriesByKind: true,
Expand All @@ -156,7 +156,7 @@ describe('manager.ui.containers.stories_panel', () => {
stories,
selectedKind,
selectedStory,
uiOptions,
ui,
};
const result = mapper(state, props, env);

Expand Down
2 changes: 1 addition & 1 deletion lib/ui/src/containers/panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default props => (
const customProps = {
panels: api.getPanels(),
selectedPanel: state.selectedPanel,
panelPosition: state.ui.panelPosition,
panelPosition: state.layout.panelPosition,
actions: createPanelActions(api),
};

Expand Down
2 changes: 1 addition & 1 deletion lib/ui/src/containers/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default React.memo(props => (
channel: api.getChannel(),
getElements: api.getElements,
actions: createPreviewActions(api),
options: state.ui,
options: state.layout,
};
return <Preview {...props} {...customProps} />;
}}
Expand Down
2 changes: 1 addition & 1 deletion lib/ui/src/containers/themeProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ import ThemeProvider from '@emotion/provider';
import { Consumer } from '../core/context';

export default props => (
<Consumer>{({ state }) => <ThemeProvider {...props} theme={state.uiOptions.theme} />}</Consumer>
<Consumer>{({ state }) => <ThemeProvider {...props} theme={state.ui.theme} />}</Consumer>
);
35 changes: 35 additions & 0 deletions lib/ui/src/core/addons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { types } from '@storybook/addons';

export function ensurePanel(panels, selectedPanel, currentPanel) {
const keys = Object.keys(panels);

if (keys.indexOf(selectedPanel) >= 0) {
return selectedPanel;
}

if (keys.length) {
return keys[0];
}
return currentPanel;
}

export default ({ provider, store }) => {
const api = {
getElements: type => provider.getElements(type),
getPanels: () => api.getElements(types.PANEL),
getSelectedPanel: () => {
const { selectedPanel } = store.getState();
return ensurePanel(api.getPanels(), selectedPanel, selectedPanel);
},
setSelectedPanel: panelName => {
store.setState({ selectedPanel: panelName });
},
};

return {
api,
state: {
selectedPanel: ensurePanel(api.getPanels()),
},
};
};
26 changes: 26 additions & 0 deletions lib/ui/src/core/channel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { STORY_CHANGED } from '@storybook/core-events';

export default ({ provider }) => {
const api = {
getChannel: () => provider.channel,
on: (type, cb, peer = true) => {
if (peer) {
provider.channel.addPeerListener(type, cb);
} else {
provider.channel.addListener(type, cb);
}

return () => provider.channel.removeListener(type, cb);
},
off: (type, cb) => {
provider.channel.removeListener(type, cb);
},
emit: (type, event) => {
provider.channel.emit(type, event);
},

// TODO: deprecate this
onStory: cb => api.on(STORY_CHANGED, cb),
};
return { api };
};
Loading

0 comments on commit a8bf858

Please sign in to comment.