Skip to content

Commit

Permalink
Merge pull request #3373 from storybooks/tmeasday/use-parameters-in-a…
Browse files Browse the repository at this point in the history
…ddons

Use per-story parameters in Notes addon
  • Loading branch information
Hypnosphi authored Apr 13, 2018
2 parents e8281ab + bd0eb7f commit 80c4bf5
Show file tree
Hide file tree
Showing 11 changed files with 181 additions and 140 deletions.
55 changes: 26 additions & 29 deletions addons/notes/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
[![Storybook Slack](https://now-examples-slackin-rrirkqohko.now.sh/badge.svg)](https://now-examples-slackin-rrirkqohko.now.sh/)
[![Backers on Open Collective](https://opencollective.com/storybook/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/storybook/sponsors/badge.svg)](#sponsors)

* * *
---

Storybook Addon Notes allows you to write notes (text or HTML) for your stories in [Storybook](https://storybook.js.org).

Expand All @@ -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 { storiesOf } from '@storybook/react';
// 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 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
Expand All @@ -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
Expand All @@ -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>
));
`} }
);
```
31 changes: 29 additions & 2 deletions addons/notes/src/__tests__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
60 changes: 36 additions & 24 deletions addons/notes/src/index.js
Original file line number Diff line number Diff line change
@@ -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) => {
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);
};
};
function renderMarkdown(text, options) {
marked.setOptions({ ...marked.defaults, options });
return marked(text);
}

export const withNotes = textOrOptions => {
const decorator = options => {
const channel = addons.getChannel();
const options = typeof textOrOptions === 'string' ? { text: textOrOptions } : textOrOptions;
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 => {
// send the notes to the channel before the story is rendered
channel.emit('storybook/notes/add_notes', options.text);
return getStory(context);
};
};

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'
),
});
const hoc = options => story => context => decorator(options)(story, 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]);
};
9 changes: 2 additions & 7 deletions app/mithril/src/client/preview/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 = {
Expand Down
25 changes: 14 additions & 11 deletions examples/angular-cli/src/stories/addon-notes.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: () => {},
},
}))
}
);
15 changes: 8 additions & 7 deletions examples/cra-kitchen-sink/src/stories/index.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -32,6 +31,7 @@ const InfoButton = () => (
);

storiesOf('Button', module)
.addDecorator(withNotes)
.add('with text', () => (
<Button onClick={action('clicked')}>
{setOptions({ selectedAddonPanel: 'storybook/actions/actions-panel' })}
Expand All @@ -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.',
Expand Down
27 changes: 15 additions & 12 deletions examples/mithril-kitchen-sink/src/stories/addon-notes.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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>
Expand All @@ -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! 😇
`,
}
);
Original file line number Diff line number Diff line change
@@ -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>
`;

Expand All @@ -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>
`;
Loading

0 comments on commit 80c4bf5

Please sign in to comment.