type story = (context) => renderable
type decorator = (story, context) => renderable
For example:
storiesOf('kindName', module)
.addDecorator(withKnobs)
.add('storyName', (context) => <Comp name={context.story} />)
type story = (context) => renderable
type wrapper = story => story
type makewrapper = (options) => wrapper
# purely for backwards compatibility
type decorator = (story, context) => renderable
We can also create an adapter to use HOC's in the existing decorator API:
const makeDecorator = (wrapper) => {
return (story, context) =>
wrapper(story)(context)
}
For example:
storiesOf('foo', module)
.addDecorator(makeDecorator(withNotes({ text: 'notes for foo' })))
.addDecorator(makeDecorator(withInfo({ text: 'info for foo' })))
.add('story1', () => <Comp {...props1} />)
.add('story2', () => <Comp {...props2} />)
.add('story3', compose(
withNotes({ text: 'notes for story3' }),
withInfo({ text: 'info for story3'})
)((context) => <Comp {...props3} />))
withX
functions are a simple and well-understood building block, but they should also be easy to use. Therefore, we propose the following convention for options types:
withInfo({ text: 'some info text', option1: someVal, option2: someVal })(storyFn)
This makes it easy to extend addons with named options in a future-proof way. However, it's not very convenient if you've already set up the default options elsewhere in your code. Therefore, addons can support whatever options they want, for example, withInfo
also supports:
withInfo('some info text')(storyFn)
In the future, we propose to support a simpler API to addons, such as the following:
registerAddon({ info: withInfo, notes: withNotes })
storiesOf(...)
.add('story', storyFn, { info: 'some info text', notes: 'some notes text' })
Or, more verbose:
registerAddon({ info: withInfo, notes: withNotes })
storiesOf(...)
.add('story', storyFn, {
info: { text: 'some info text', option1: val1, .... }
notes: 'some notes text'
})
Today's withKnobs
is a decorator which screws things up. Proposal:
const withKnobs = (options) => (story) => ...;
const withKnobsDeprecated = deprecate(makeDecorator(withKnobs))
export { withKnobsDeprecated as withKnobs };
export default withKnobs;
For example (new code):
import withKnobs from '@storybook/addon-knobs';
import { makeDecorator } from '@storybook/addons';
addDecorator(makeDecorator(withKnobs()));
For example (legacy code):
import { withKnobs } from '@storybook/addon-knobs';
addDecorator(withKnobs);