mirror of
https://github.com/storybookjs/storybook.git
synced 2025-04-02 05:03:44 +08:00
Merge pull request #3373 from storybooks/tmeasday/use-parameters-in-addons
Use per-story parameters in Notes addon
This commit is contained in:
commit
80c4bf57b9
@ -7,7 +7,7 @@
|
||||
[](https://now-examples-slackin-rrirkqohko.now.sh/)
|
||||
[](#backers) [](#sponsors)
|
||||
|
||||
* * *
|
||||
---
|
||||
|
||||
Storybook Addon Notes allows you to write notes (text or HTML) for your stories in [Storybook](https://storybook.js.org).
|
||||
|
||||
@ -29,16 +29,25 @@ Add following content to it:
|
||||
import '@storybook/addon-notes/register';
|
||||
```
|
||||
|
||||
Then write your stories like this:
|
||||
Then add the `withNotes` decorator to all stories in your `config.js`:
|
||||
|
||||
```js
|
||||
// Import from @storybook/X where X is your framework
|
||||
import { configure, addDecorator } from '@storybook/react';
|
||||
import { withNotes } from '@storybook/addon-notes';
|
||||
|
||||
addDecorator(withNotes);
|
||||
```
|
||||
|
||||
You can use the `notes` parameter to add a note to each story:
|
||||
|
||||
```js
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { withNotes } from '@storybook/addon-notes';
|
||||
|
||||
import Component from './Component';
|
||||
|
||||
storiesOf('Component', module)
|
||||
.add('with some emoji', withNotes('A very simple component')(() => </Component>));
|
||||
.add('with some emoji', () => </Component>, { notes: 'A very simple component' });
|
||||
```
|
||||
|
||||
#### Using Markdown
|
||||
@ -47,25 +56,27 @@ To use markdown in your notes simply import a markdown file and use that in your
|
||||
|
||||
```js
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { withNotes } from '@storybook/addon-notes';
|
||||
import Component from './Component';
|
||||
import someMarkdownText from './someMarkdownText.md';
|
||||
|
||||
storiesOf('Component', module)
|
||||
.add('With Markdown', withNotes(someMarkdownText)(() => <Component/>));
|
||||
|
||||
storiesOf('Component', module).add(
|
||||
'With Markdown',
|
||||
() => <Component />
|
||||
{ notes: someMarkdownText }
|
||||
);
|
||||
```
|
||||
|
||||
If you want to use Github flavored markdown inline, use `withMarkdownNotes`:
|
||||
If you want to use Github flavored markdown inline, use `notes: { markdownText: 'your md' }`:
|
||||
|
||||
```js
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { withMarkdownNotes } from '@storybook/addon-notes';
|
||||
import Component from './Component';
|
||||
|
||||
storiesOf('Component', module)
|
||||
.add('With Markdown', withMarkdownNotes(`
|
||||
# Hello World
|
||||
storiesOf('Component', module).add(
|
||||
'With Markdown',
|
||||
() => <Component />
|
||||
{ notes: { markdown: `
|
||||
# Hello World
|
||||
|
||||
This is some code showing usage of the component and other inline documentation
|
||||
|
||||
@ -75,20 +86,6 @@ This is some code showing usage of the component and other inline documentation
|
||||
<Component/>
|
||||
</div>
|
||||
~~~
|
||||
`)(() => <Component/>));
|
||||
|
||||
```
|
||||
|
||||
### Deprecated API
|
||||
This API is slated for removal in 4.0
|
||||
|
||||
```js
|
||||
import { WithNotes } from '@storybook/addon-notes';
|
||||
|
||||
storiesOf('Addon Notes', module)
|
||||
.add('using deprecated API', () => (
|
||||
<WithNotes notes="Hello">
|
||||
<BaseButton onClick={action('clicked')} label="😀 😎 👍 💯" />
|
||||
</WithNotes>
|
||||
));
|
||||
`} }
|
||||
);
|
||||
```
|
||||
|
@ -4,12 +4,39 @@ import { withNotes } from '..';
|
||||
jest.mock('@storybook/addons');
|
||||
|
||||
describe('Storybook Addon Notes', () => {
|
||||
it('should inject info', () => {
|
||||
it('should inject text from `notes` parameter', () => {
|
||||
const channel = { emit: jest.fn() };
|
||||
addons.getChannel.mockReturnValue(channel);
|
||||
|
||||
const getStory = jest.fn();
|
||||
const context = {};
|
||||
const context = { parameters: { notes: 'hello' } };
|
||||
|
||||
withNotes(getStory, context);
|
||||
expect(channel.emit).toHaveBeenCalledWith('storybook/notes/add_notes', 'hello');
|
||||
expect(getStory).toHaveBeenCalledWith(context);
|
||||
});
|
||||
|
||||
it('should inject markdown from `notes.markdown` parameter', () => {
|
||||
const channel = { emit: jest.fn() };
|
||||
addons.getChannel.mockReturnValue(channel);
|
||||
|
||||
const getStory = jest.fn();
|
||||
const context = { parameters: { notes: { markdown: '# hello' } } };
|
||||
|
||||
withNotes(getStory, context);
|
||||
expect(channel.emit).toHaveBeenCalledWith(
|
||||
'storybook/notes/add_notes',
|
||||
expect.stringContaining('<h1 id="hello">hello</h1>')
|
||||
);
|
||||
expect(getStory).toHaveBeenCalledWith(context);
|
||||
});
|
||||
|
||||
it('should inject info (deprecated API)', () => {
|
||||
const channel = { emit: jest.fn() };
|
||||
addons.getChannel.mockReturnValue(channel);
|
||||
|
||||
const getStory = jest.fn();
|
||||
const context = { parameters: {} };
|
||||
|
||||
const decoratedStory = withNotes('hello')(getStory);
|
||||
decoratedStory(context);
|
||||
|
@ -1,34 +1,46 @@
|
||||
import deprecate from 'util-deprecate';
|
||||
import addons from '@storybook/addons';
|
||||
import marked from 'marked';
|
||||
import { WithNotes as ReactWithNotes } from './react';
|
||||
|
||||
export const withMarkdownNotes = (text, options) => {
|
||||
function renderMarkdown(text, options) {
|
||||
marked.setOptions({ ...marked.defaults, options });
|
||||
return marked(text);
|
||||
}
|
||||
|
||||
const decorator = options => {
|
||||
const channel = addons.getChannel();
|
||||
return getStory => context => {
|
||||
marked.setOptions({ ...marked.defaults, options });
|
||||
// send the notes to the channel before the story is rendered
|
||||
channel.emit('storybook/notes/add_notes', marked(text));
|
||||
return (getStory, context) => {
|
||||
const { parameters: { notes } } = context;
|
||||
const storyOptions = notes || options;
|
||||
|
||||
if (storyOptions) {
|
||||
const { text, markdown, markdownOptions } =
|
||||
typeof storyOptions === 'string' ? { text: storyOptions } : storyOptions;
|
||||
|
||||
if (!text && !markdown) {
|
||||
throw new Error('You must set of one of `text` or `markdown` on the `notes` parameter');
|
||||
}
|
||||
|
||||
channel.emit('storybook/notes/add_notes', text || renderMarkdown(markdown, markdownOptions));
|
||||
}
|
||||
|
||||
return getStory(context);
|
||||
};
|
||||
};
|
||||
|
||||
export const withNotes = textOrOptions => {
|
||||
const channel = addons.getChannel();
|
||||
const options = typeof textOrOptions === 'string' ? { text: textOrOptions } : textOrOptions;
|
||||
const hoc = options => story => context => decorator(options)(story, context);
|
||||
|
||||
return getStory => context => {
|
||||
// send the notes to the channel before the story is rendered
|
||||
channel.emit('storybook/notes/add_notes', options.text);
|
||||
return getStory(context);
|
||||
};
|
||||
export const withMarkdownNotes = (text, options) =>
|
||||
hoc({
|
||||
markdown: text,
|
||||
markdownOptions: options,
|
||||
});
|
||||
|
||||
export const withNotes = (...args) => {
|
||||
// Used without options as .addDecorator(withNotes)
|
||||
if (typeof args[0] === 'function') {
|
||||
return decorator()(...args);
|
||||
}
|
||||
|
||||
// Input are options, ala .add('name', withNotes('note')(() => <Story/>))
|
||||
return hoc(args[0]);
|
||||
};
|
||||
|
||||
Object.defineProperty(exports, 'WithNotes', {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get: deprecate(
|
||||
() => ReactWithNotes,
|
||||
'@storybook/addon-notes WithNotes Component is deprecated, use withNotes() instead. See https://github.com/storybooks/storybook/tree/master/addons/notes'
|
||||
),
|
||||
});
|
||||
|
@ -44,7 +44,7 @@ export function renderMain(data, storyStore, forceRender) {
|
||||
const noPreview = <NoPreview />;
|
||||
const { selectedKind, selectedStory } = data;
|
||||
|
||||
const story = storyStore.getStory(selectedKind, selectedStory);
|
||||
const story = storyStore.getStoryWithContext(selectedKind, selectedStory);
|
||||
if (!story) {
|
||||
m.mount(rootEl, { view: () => noPreview });
|
||||
return;
|
||||
@ -57,12 +57,7 @@ export function renderMain(data, storyStore, forceRender) {
|
||||
previousKind = selectedKind;
|
||||
previousStory = selectedStory;
|
||||
|
||||
const context = {
|
||||
kind: selectedKind,
|
||||
story: selectedStory,
|
||||
};
|
||||
|
||||
const element = story(context);
|
||||
const element = story();
|
||||
|
||||
if (!element) {
|
||||
const error = {
|
||||
|
@ -3,31 +3,34 @@ import { withNotes } from '@storybook/addon-notes';
|
||||
import { Button } from '@storybook/angular/demo';
|
||||
|
||||
storiesOf('Addon|Notes', module)
|
||||
.addDecorator(withNotes)
|
||||
.add(
|
||||
'Simple note',
|
||||
withNotes({ text: 'My notes on some button' })(() => ({
|
||||
() => ({
|
||||
component: Button,
|
||||
props: {
|
||||
text: 'Notes on some Button',
|
||||
onClick: () => {},
|
||||
},
|
||||
}))
|
||||
}),
|
||||
{ notes: 'My notes on some button' }
|
||||
)
|
||||
.add(
|
||||
'Note with HTML',
|
||||
withNotes({
|
||||
text: `
|
||||
() => ({
|
||||
component: Button,
|
||||
props: {
|
||||
text: 'Notes with HTML',
|
||||
onClick: () => {},
|
||||
},
|
||||
}),
|
||||
{
|
||||
notes: `
|
||||
<h2>My notes on emojis</h2>
|
||||
|
||||
<em>It's not all that important to be honest, but..</em>
|
||||
|
||||
Emojis are great, I love emojis, in fact I like using them in my Component notes too! 😇
|
||||
`,
|
||||
})(() => ({
|
||||
component: Button,
|
||||
props: {
|
||||
text: 'Notes with HTML',
|
||||
onClick: () => {},
|
||||
},
|
||||
}))
|
||||
}
|
||||
);
|
||||
|
@ -3,8 +3,7 @@ import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import { setOptions } from '@storybook/addon-options';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
// eslint-disable-next-line import/named
|
||||
import { withNotes, WithNotes } from '@storybook/addon-notes';
|
||||
import { withNotes } from '@storybook/addon-notes';
|
||||
import centered from '@storybook/addon-centered';
|
||||
import { withInfo } from '@storybook/addon-info';
|
||||
import { Button } from '@storybook/react/demo';
|
||||
@ -32,6 +31,7 @@ const InfoButton = () => (
|
||||
);
|
||||
|
||||
storiesOf('Button', module)
|
||||
.addDecorator(withNotes)
|
||||
.add('with text', () => (
|
||||
<Button onClick={action('clicked')}>
|
||||
{setOptions({ selectedAddonPanel: 'storybook/actions/actions-panel' })}
|
||||
@ -46,15 +46,16 @@ storiesOf('Button', module)
|
||||
</span>
|
||||
</Button>
|
||||
))
|
||||
.add('with notes', () => (
|
||||
// deprecated usage
|
||||
<WithNotes notes="A very simple button">
|
||||
.add(
|
||||
'with notes',
|
||||
() => (
|
||||
<Button>
|
||||
{setOptions({ selectedAddonPanel: 'storybook/notes/panel' })}
|
||||
Check my notes in the notes panel
|
||||
</Button>
|
||||
</WithNotes>
|
||||
))
|
||||
),
|
||||
{ notes: 'A very simple button' }
|
||||
)
|
||||
.addWithInfo(
|
||||
'with some info',
|
||||
'Use the [info addon](https://github.com/storybooks/storybook/tree/master/addons/info) with its painful API.',
|
||||
|
@ -7,9 +7,10 @@ import { storiesOf } from '@storybook/mithril';
|
||||
import { withNotes } from '@storybook/addon-notes';
|
||||
|
||||
storiesOf('Addons|Notes', module)
|
||||
.addDecorator(withNotes)
|
||||
.add(
|
||||
'Simple note',
|
||||
withNotes({ text: 'My notes on some bold text' })(() => ({
|
||||
() => ({
|
||||
view: () => (
|
||||
<p>
|
||||
<strong>
|
||||
@ -22,19 +23,12 @@ storiesOf('Addons|Notes', module)
|
||||
</strong>
|
||||
</p>
|
||||
),
|
||||
}))
|
||||
}),
|
||||
{ notes: 'My notes on some bold text' }
|
||||
)
|
||||
.add(
|
||||
'Note with HTML',
|
||||
withNotes({
|
||||
text: `
|
||||
<h2>My notes on emojies</h2>
|
||||
|
||||
<em>It's not all that important to be honest, but..</em>
|
||||
|
||||
Emojis are great, I love emojis, in fact I like using them in my Component notes too! 😇
|
||||
`,
|
||||
})(() => ({
|
||||
() => ({
|
||||
view: () => (
|
||||
<p>
|
||||
<span>🤔😳😯😮</span>
|
||||
@ -44,5 +38,14 @@ storiesOf('Addons|Notes', module)
|
||||
<span>🤓😑😶😊</span>
|
||||
</p>
|
||||
),
|
||||
}))
|
||||
}),
|
||||
{
|
||||
notes: `
|
||||
<h2>My notes on emojies</h2>
|
||||
|
||||
<em>It's not all that important to be honest, but..</em>
|
||||
|
||||
Emojis are great, I love emojis, in fact I like using them in my Component notes too! 😇
|
||||
`,
|
||||
}
|
||||
);
|
||||
|
@ -1,8 +1,14 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Storyshots Addons|Notes using deprecated API 1`] = `
|
||||
exports[`Storyshots Addons|Notes using decorator arguments, withMarkdownNotes 1`] = `
|
||||
<button>
|
||||
😀 😎 👍 💯
|
||||
Button with notes - check the notes panel for details
|
||||
</button>
|
||||
`;
|
||||
|
||||
exports[`Storyshots Addons|Notes using decorator arguments, withNotes 1`] = `
|
||||
<button>
|
||||
Button with notes - check the notes panel for details
|
||||
</button>
|
||||
`;
|
||||
|
||||
@ -20,6 +26,6 @@ exports[`Storyshots Addons|Notes withNotes rendering imported markdown 1`] = `
|
||||
|
||||
exports[`Storyshots Addons|Notes withNotes rendering inline, github-flavored markdown 1`] = `
|
||||
<button>
|
||||
Button with notes from inline github-flavored markdown - check the notes panel for details
|
||||
Button with notes - check the notes panel for details
|
||||
</button>
|
||||
`;
|
||||
|
@ -1,28 +1,15 @@
|
||||
import React from 'react';
|
||||
import { storiesOf } from '@storybook/react';
|
||||
|
||||
// eslint-disable-next-line import/named
|
||||
import { withNotes, WithNotes, withMarkdownNotes } from '@storybook/addon-notes';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { withNotes, withMarkdownNotes } from '@storybook/addon-notes';
|
||||
import BaseButton from '../components/BaseButton';
|
||||
import markdownNotes from './notes/notes.md';
|
||||
|
||||
storiesOf('Addons|Notes', module)
|
||||
.add(
|
||||
'withNotes',
|
||||
withNotes(
|
||||
'This is the notes for a button. This is helpful for adding details about a story in a separate panel.'
|
||||
)(() => <BaseButton label="Button with notes - check the notes panel for details" />)
|
||||
)
|
||||
.add(
|
||||
'withNotes rendering imported markdown',
|
||||
withNotes(markdownNotes)(() => (
|
||||
<BaseButton label="Button with notes - check the notes panel for details" />
|
||||
))
|
||||
)
|
||||
.add(
|
||||
'withNotes rendering inline, github-flavored markdown',
|
||||
withMarkdownNotes(`
|
||||
const baseStory = () => (
|
||||
<BaseButton label="Button with notes - check the notes panel for details" />
|
||||
);
|
||||
|
||||
const markdownString = `
|
||||
# Documentation
|
||||
|
||||
This is inline github-flavored markdown!
|
||||
@ -37,12 +24,20 @@ storiesOf('Addons|Notes', module)
|
||||
))
|
||||
)
|
||||
~~~
|
||||
`)(() => (
|
||||
<BaseButton label="Button with notes from inline github-flavored markdown - check the notes panel for details" />
|
||||
))
|
||||
)
|
||||
.add('using deprecated API', () => (
|
||||
<WithNotes notes="Hello">
|
||||
<BaseButton onClick={action('clicked')} label="😀 😎 👍 💯" />
|
||||
</WithNotes>
|
||||
));
|
||||
`;
|
||||
|
||||
storiesOf('Addons|Notes', module)
|
||||
.addDecorator(withNotes)
|
||||
.add('withNotes', baseStory, {
|
||||
notes:
|
||||
'This is the notes for a button. This is helpful for adding details about a story in a separate panel.',
|
||||
})
|
||||
.add('withNotes rendering imported markdown', baseStory, { notes: markdownNotes })
|
||||
.add('withNotes rendering inline, github-flavored markdown', baseStory, {
|
||||
notes: { markdown: markdownString },
|
||||
})
|
||||
.add('using decorator arguments, withNotes', withNotes('Notes into withNotes')(baseStory))
|
||||
.add(
|
||||
'using decorator arguments, withMarkdownNotes',
|
||||
withMarkdownNotes(markdownString)(baseStory)
|
||||
);
|
||||
|
@ -2,22 +2,21 @@ import { storiesOf } from '@storybook/polymer';
|
||||
import { withNotes } from '@storybook/addon-notes';
|
||||
|
||||
storiesOf('Addon|Notes', module)
|
||||
.addDecorator(withNotes)
|
||||
.add(
|
||||
'Simple note',
|
||||
withNotes({ text: 'My notes on some bold text' })(
|
||||
() =>
|
||||
'<p><strong>Etiam vulputate elit eu venenatis eleifend. Duis nec lectus augue. Morbi egestas diam sed vulputate mollis. Fusce egestas pretium vehicula. Integer sed neque diam. Donec consectetur velit vitae enim varius, ut placerat arcu imperdiet. Praesent sed faucibus arcu. Nullam sit amet nibh a enim eleifend rhoncus. Donec pretium elementum leo at fermentum. Nulla sollicitudin, mauris quis semper tempus, sem metus tristique diam, efficitur pulvinar mi urna id urna.</strong></p>'
|
||||
)
|
||||
() =>
|
||||
'<p><strong>Etiam vulputate elit eu venenatis eleifend. Duis nec lectus augue. Morbi egestas diam sed vulputate mollis. Fusce egestas pretium vehicula. Integer sed neque diam. Donec consectetur velit vitae enim varius, ut placerat arcu imperdiet. Praesent sed faucibus arcu. Nullam sit amet nibh a enim eleifend rhoncus. Donec pretium elementum leo at fermentum. Nulla sollicitudin, mauris quis semper tempus, sem metus tristique diam, efficitur pulvinar mi urna id urna.</strong></p>',
|
||||
{
|
||||
notes: 'My notes on some bold text',
|
||||
}
|
||||
)
|
||||
.add(
|
||||
'Note with HTML',
|
||||
withNotes({
|
||||
text: `
|
||||
.add('Note with HTML', () => '<p>🤔😳😯😮<br/>😄😩😓😱<br/>🤓😑😶😊</p>', {
|
||||
notes: `
|
||||
<h2>My notes on emojies</h2>
|
||||
|
||||
<em>It's not all that important to be honest, but..</em>
|
||||
|
||||
Emojis are great, I love emojis, in fact I like using them in my Component notes too! 😇
|
||||
`,
|
||||
})(() => '<p>🤔😳😯😮<br/>😄😩😓😱<br/>🤓😑😶😊</p>')
|
||||
);
|
||||
});
|
||||
|
@ -2,24 +2,27 @@ import { storiesOf } from '@storybook/vue';
|
||||
import { withNotes } from '@storybook/addon-notes';
|
||||
|
||||
storiesOf('Addon|Notes', module)
|
||||
.addDecorator(withNotes)
|
||||
.add(
|
||||
'Simple note',
|
||||
withNotes({ text: 'My notes on some bold text' })(() => ({
|
||||
() => ({
|
||||
template:
|
||||
'<p><strong>Etiam vulputate elit eu venenatis eleifend. Duis nec lectus augue. Morbi egestas diam sed vulputate mollis. Fusce egestas pretium vehicula. Integer sed neque diam. Donec consectetur velit vitae enim varius, ut placerat arcu imperdiet. Praesent sed faucibus arcu. Nullam sit amet nibh a enim eleifend rhoncus. Donec pretium elementum leo at fermentum. Nulla sollicitudin, mauris quis semper tempus, sem metus tristique diam, efficitur pulvinar mi urna id urna.</strong></p>',
|
||||
}))
|
||||
}),
|
||||
{ notes: 'My notes on some bold text' }
|
||||
)
|
||||
.add(
|
||||
'Note with HTML',
|
||||
withNotes({
|
||||
text: `
|
||||
() => ({
|
||||
template: '<p>🤔😳😯😮<br/>😄😩😓😱<br/>🤓😑😶😊</p>',
|
||||
}),
|
||||
{
|
||||
notes: `
|
||||
<h2>My notes on emojies</h2>
|
||||
|
||||
<em>It's not all that important to be honest, but..</em>
|
||||
|
||||
Emojis are great, I love emojis, in fact I like using them in my Component notes too! 😇
|
||||
`,
|
||||
})(() => ({
|
||||
template: '<p>🤔😳😯😮<br/>😄😩😓😱<br/>🤓😑😶😊</p>',
|
||||
}))
|
||||
}
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user