Removed usages of hoc-style addons from the docs

This commit is contained in:
Tom Coleman 2018-07-06 14:51:23 +10:00
parent fa9779ed28
commit d1d8138fa7
4 changed files with 165 additions and 166 deletions

View File

@ -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 Info Addon will show additional information for your stories in [Storybook](https://storybook.js.org).
Useful when you want to display usage or other types of documentation alongside your story.
@ -25,7 +25,8 @@ npm i -D @storybook/addon-info
```
## Basic usage
Then, add `withInfo` as a decarator to your book of stories.
Then, add `withInfo` as a decarator to your book of stories.
It is possible to add `info` by default to all or a subsection of stories by using a global or story decorator.
It is important to declare this decorator as **the first decorator**, otherwise it won't work well.
@ -33,7 +34,9 @@ It is important to declare this decorator as **the first decorator**, otherwise
```js
addDecorator(withInfo); // Globally in your .storybook/config.js.
```
or
```js
storiesOf('Component', module)
.addDecorator(withInfo) // At your stories directly.
@ -53,12 +56,13 @@ storiesOf('Component', module)
.addParameters({
info: {
// Your settings
}
},
})
.add('with some emoji', () => <Component/>);
.add('with some emoji', () => <Component />);
```
...or for each story individually:
```js
import { storiesOf } from '@storybook/react';
@ -67,12 +71,12 @@ import Component from './Component';
storiesOf('Component', module)
.add(
'with some emoji',
() => <Component emoji/>,
{ info : { inline: false, header: false } } // Make your component render inline with the additional info
() => <Component emoji />,
{ info: { inline: false, header: false } } // Make your component render inline with the additional info
)
.add(
'with no emoji',
() => <Component/>,
() => <Component />,
{ info: '☹️ no emojis' } // Add additional info text directly
);
```
@ -86,41 +90,36 @@ import Component from './Component';
storiesOf('Component', module)
.addParameters({
info: { // Make a default for all stories in this book,
inline: true, // where the components are inlined
info: {
// Make a default for all stories in this book,
inline: true, // where the components are inlined
styles: {
header: {
h1: {
color: 'red' // and the headers of the sections are red.
}
}
color: 'red', // and the headers of the sections are red.
},
},
},
}
},
})
.add(
'green version',
() => <Component green/>,
{
info: {
styles: stylesheet => ({ // Setting the style with a function
...stylesheet,
header: {
...stylesheet.header,
h1: {
...stylesheet.header.h1,
color: 'green' // Still inlined but with green headers!
}
}
})
}
})
.add(
'something else',
() => <Component different/>,
{
info: "This story has additional text added to the info!" // Still inlined and with red headers!
}
);
.add('green version', () => <Component green />, {
info: {
styles: stylesheet => ({
// Setting the style with a function
...stylesheet,
header: {
...stylesheet.header,
h1: {
...stylesheet.header.h1,
color: 'green', // Still inlined but with green headers!
},
},
}),
},
})
.add('something else', () => <Component different />, {
info: 'This story has additional text added to the info!', // Still inlined and with red headers!
});
```
It is also possible to disable the `info` addon entirely.
@ -135,27 +134,22 @@ Depending on the scope at which you want to disable the addon, pass the followin
```
## Markdown
The `info` addon also supports markdown.
To use markdown as additional textual documentation for your stories, either pass it directly as a String to the `info` parameters, or use the `text` option.
```js
storiesOf('Button', module)
.add(
'Button Component',
() => <Button />,
{
info: {
text: `
storiesOf('Button', module).add('Button Component', () => <Button />, {
info: {
text: `
description or documentation about my component, supports markdown
~~~js
<Button>Click Here</Button>
~~~
`
}
}
);
`,
},
});
```
## Setting Global Options
@ -166,9 +160,11 @@ To configure default options for all usage of the info addon, pass a option obje
// config.js
import { withInfo } from '@storybook/addon-info';
addDecorator(withInfo({
header: false, // Global configuration for the info addon across all of your stories.
}));
addDecorator(
withInfo({
header: false, // Global configuration for the info addon across all of your stories.
})
);
```
Configuration parameters can be set at 3 different locations: passed as default options along the `addDecorator` call, passed as an object of parameters to a book of stories to the `addParameters` call, and passed as direct parameters to each individual story.
@ -274,40 +270,40 @@ Example:
```js
// button.js
// @flow
import React from 'react'
import React from 'react';
const paddingStyles = {
small: '4px 8px',
medium: '8px 16px'
}
medium: '8px 16px',
};
const Button = ({
size,
...rest
}: {
/** The size of the button */
size: 'small' | 'medium'
size: 'small' | 'medium',
}) => {
const style = {
padding: paddingStyles[size] || ''
}
return <button style={style} {...rest} />
}
padding: paddingStyles[size] || '',
};
return <button style={style} {...rest} />;
};
Button.defaultProps = {
size: 'medium'
}
size: 'medium',
};
export default Button
export default Button;
```
```js
// stories.js
import React from "react";
import React from 'react';
import { storiesOf } from "@storybook/react";
import { withInfo } from "@storybook/addon-info";
import Button from "./button";
import { storiesOf } from '@storybook/react';
import Button from './button';
const Red = props => <span style={{ color: "red" }} {...props} />;
const Red = props => <span style={{ color: 'red' }} {...props} />;
const TableComponent = ({ propDefinitions }) => {
const props = propDefinitions.map(
@ -341,12 +337,11 @@ const TableComponent = ({ propDefinitions }) => {
);
};
storiesOf("Button", module).add(
"with text",
withInfo({
TableComponent
})(() => <Button>Hello Button</Button>)
);
storiesOf('Button', module).add('with text', () => <Button>Hello Button</Button>, {
info: {
TableComponent,
},
});
```
### React Docgen Integration
@ -359,10 +354,11 @@ import React from 'react';
import PropTypes from 'prop-types';
/** Button component description */
const DocgenButton = ({ disabled, label, style, onClick }) =>
const DocgenButton = ({ disabled, label, style, onClick }) => (
<button disabled={disabled} style={style} onClick={onClick}>
{label}
</button>;
</button>
);
DocgenButton.defaultProps = {
disabled: false,

View File

@ -32,13 +32,13 @@ Now when you are writing a story it like this and add some notes:
```js
import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import { withNotes } from '@storybook/addon-notes';
import Button from './Button';
storiesOf('Button', module)
.add('with some emoji', () => (
withNotes('A very simple component')(() => <Button onClick={action('clicked')}><span role="img" aria-label="so cool">😀 😎 👍 💯</span></Button>));
() => <Button onClick={action('clicked')}><span role="img" aria-label="so cool">😀 😎 👍 💯</span></Button>),
{ notes: 'A very simple component' }
));
```

View File

@ -31,11 +31,13 @@ import { action } from '@storybook/addon-actions';
import Button from '../components/Button';
storiesOf('Button', module)
.add('with text', () => (
<Button onClick={action('clicked')}>Hello Button</Button>
))
.add('with text', () => <Button onClick={action('clicked')}>Hello Button</Button>)
.add('with some emoji', () => (
<Button onClick={action('clicked')}><span role="img" aria-label="so cool">😀 😎 👍 💯</span></Button>
<Button onClick={action('clicked')}>
<span role="img" aria-label="so cool">
😀 😎 👍 💯
</span>
</Button>
));
```
@ -54,10 +56,10 @@ For example, you may write stories for your app inside the `src/components` dire
```js
import { configure } from '@storybook/react';
const req = require.context('../src/components', true, /\.stories\.js$/)
const req = require.context('../src/components', true, /\.stories\.js$/);
function loadStories() {
req.keys().forEach((filename) => req(filename))
req.keys().forEach(filename => req(filename));
}
configure(loadStories, module);
@ -65,7 +67,7 @@ configure(loadStories, module);
Here we use Webpack's [require.context](https://webpack.js.org/guides/dependency-management/#require-context) to load modules dynamically. Have a look at the relevant Webpack [docs](https://webpack.js.org/guides/dependency-management/#require-context) to learn more about how to use require.context.
The **React Native** packager resolves all the imports at build-time, so it's not possible to load modules dynamically. If you don't want to import all your stories manually you can use [react-native-storybook-loader](https://github.com/elderfo/react-native-storybook-loader) to automatically create the import statements for all of your stories.
The **React Native** packager resolves all the imports at build-time, so it's not possible to load modules dynamically. If you don't want to import all your stories manually you can use [react-native-storybook-loader](https://github.com/elderfo/react-native-storybook-loader) to automatically create the import statements for all of your stories.
## Using Decorators
@ -77,13 +79,9 @@ import { storiesOf } from '@storybook/react';
import MyComponent from '../my_component';
storiesOf('MyComponent', module)
.addDecorator(story => (
<div style={{textAlign: 'center'}}>
{story()}
</div>
))
.addDecorator(story => <div style={{ textAlign: 'center' }}>{story()}</div>)
.add('without props', () => <MyComponent />)
.add('with some props', () => <MyComponent text="The Comp"/>);
.add('with some props', () => <MyComponent text="The Comp" />);
```
Here we only add the decorator for the current set of stories. (In this example, we add it just for the **MyComponent** story group.)
@ -94,13 +92,9 @@ But, you can also add a decorator **globally** and it'll be applied to all the s
import React from 'react';
import { configure, addDecorator } from '@storybook/react';
addDecorator(story => (
<div style={{textAlign: 'center'}}>
{story()}
</div>
));
addDecorator(story => <div style={{ textAlign: 'center' }}>{story()}</div>);
configure(function () {
configure(function() {
// ...
}, module);
```
@ -109,16 +103,15 @@ configure(function () {
As of storybook 3.3, [Markdown](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) can be used in storybook by default. All you need to do is import a markdown file, which extracts the raw markdown content into a string. You can then use that string in any addon that supports markdown (such as notes).
```js
import React from 'react';
import { storiesOf } from '@storybook/react';
import { withMarkdownNotes } from '@storybook/addon-notes';
import MyComponent from './MyComponent';
import someMarkdownText from './someMarkdownText.md';
storiesOf('Component', module)
.add('With Markdown', withMarkdownNotes(someMarkdownText)(() => <MyComponent/>));
storiesOf('Component', module).add('With Markdown', () => <MyComponent />, {
notes: { markdown: someMarkdownText },
});
```
## Nesting stories
@ -132,22 +125,25 @@ import React from 'react';
import { storiesOf } from '@storybook/react';
import Button from '../components/Button';
storiesOf('My App/Buttons/Simple', module)
.add('with text', () => (
<Button onClick={action('clicked')}>Hello Button</Button>
));
storiesOf('My App/Buttons/Simple', module).add('with text', () => (
<Button onClick={action('clicked')}>Hello Button</Button>
));
storiesOf('My App/Buttons/Emoji', module)
.add('with some emoji', () => (
<Button onClick={action('clicked')}><span role="img" aria-label="so cool">😀 😎 👍 💯</span></Button>
));
storiesOf('My App/Buttons/Emoji', module).add('with some emoji', () => (
<Button onClick={action('clicked')}>
<span role="img" aria-label="so cool">
😀 😎 👍 💯
</span>
</Button>
));
```
## Generating nesting path based on __dirname
## Generating nesting path based on \_\_dirname
The name is just a javascript string, by using a template literal, you can easily interpolate data.
One example would be to use `base` from [`paths.macro`](https://github.com/storybooks/paths.macro):
```js
import React from 'react';
import base from 'paths.macro';
@ -161,7 +157,7 @@ storiesOf(`Other|${base}/Dirname Example`, module)
.add('story 2', () => <BaseButton label="Story 2" />);
```
*This uses [babel-plugin-macros](https://github.com/kentcdodds/babel-plugin-macros)*.
_This uses [babel-plugin-macros](https://github.com/kentcdodds/babel-plugin-macros)_.
## Run multiple storybooks
@ -169,9 +165,9 @@ You can run multiple storybooks for different kinds of stories (or components).
```json
{
"scripts": {
"start-storybook-for-theme": "start-storybook -p 9001 -c .storybook-theme",
"start-storybook-for-app": "start-storybook -p 8001 -c .storybook-app"
}
"scripts": {
"start-storybook-for-theme": "start-storybook -p 9001 -c .storybook-theme",
"start-storybook-for-app": "start-storybook -p 8001 -c .storybook-app"
}
}
```

View File

@ -21,15 +21,15 @@ We have had the best experience using `awesome-typescript-loader`, but other tut
We first have to use the [custom Webpack config in full control mode, extending default configs](/configurations/custom-webpack-config/#full-control-mode--default):
```js
const path = require("path");
const TSDocgenPlugin = require("react-docgen-typescript-webpack-plugin");
const path = require('path');
const TSDocgenPlugin = require('react-docgen-typescript-webpack-plugin');
module.exports = (baseConfig, env, config) => {
config.module.rules.push({
test: /\.(ts|tsx)$/,
loader: require.resolve("awesome-typescript-loader")
loader: require.resolve('awesome-typescript-loader'),
});
config.plugins.push(new TSDocgenPlugin()); // optional
config.resolve.extensions.push(".ts", ".tsx");
config.resolve.extensions.push('.ts', '.tsx');
return config;
};
```
@ -74,17 +74,17 @@ This is for the default configuration where `/stories` is a peer of `src`. If yo
The very handy [Storybook Info addon](https://github.com/storybooks/storybook/tree/master/addons/info) autogenerates prop tables documentation for each component, however it doesn't work with Typescript types. The current solution is to use [react-docgen-typescript-loader](https://github.com/strothj/react-docgen-typescript-loader) to preprocess the Typescript files to give the Info addon what it needs. The webpack config above does this, and so for the rest of your stories you use it as per normal:
```js
import React from "react";
import { storiesOf } from "@storybook/react";
import { withInfo } from "@storybook/addon-info";
import { action } from "@storybook/addon-actions";
import TicTacToeCell from "./TicTacToeCell";
import React from 'react';
import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import TicTacToeCell from './TicTacToeCell';
const stories = storiesOf("Components", module);
const stories = storiesOf('Components', module);
stories.add(
"TicTacToeCell",
withInfo({ inline: true })(() => <TicTacToeCell value="X" position={{ x: 0, y: 0 }} onClick={action("onClick")} />)
'TicTacToeCell',
() => <TicTacToeCell value="X" position={{ x: 0, y: 0 }} onClick={action('onClick')} />,
{ info: { inline: true } }
);
```
@ -92,48 +92,59 @@ stories.add(
Please refer to the [react-docgen-typescript-loader](https://github.com/strothj/react-docgen-typescript-loader) docs for writing prop descriptions and other annotations to your Typescript interfaces.
Additional annotation can be achieved by creating a `wInfo` higher order component:
Additional annotation can be achieved by setting a default set of info parameters:
```js
import { withInfo } from "@storybook/addon-info";
const wInfoStyle = {
header: {
h1: {
marginRight: "20px",
fontSize: "25px",
display: "inline"
// Globally in your .storybook/config.js, or alternatively, per-chapter
addDecorator({
styles: {
header: {
h1: {
marginRight: '20px',
fontSize: '25px',
display: 'inline',
},
body: {
paddingTop: 0,
paddingBottom: 0,
},
h2: {
display: 'inline',
color: '#999',
},
},
body: {
paddingTop: 0,
paddingBottom: 0
infoBody: {
backgroundColor: '#eee',
padding: '0px 5px',
lineHeight: '2',
},
h2: {
display: "inline",
color: "#999"
}
},
infoBody: {
backgroundColor: "#eee",
padding: "0px 5px",
lineHeight: "2"
}
};
export const wInfo = text => withInfo({ inline: true, source: false, styles: wInfoStyle, text: text });
inline: true,
source: false,
});
```
This can be used like so:
```js
import React from "react";
import React from 'react';
import { storiesOf } from "@storybook/react";
import { PrimaryButton } from "./Button";
import { wInfo } from "../../utils";
import { text, select, boolean } from "@storybook/addon-knobs/react";
import { storiesOf } from '@storybook/react';
import { PrimaryButton } from './Button';
import { text, select, boolean } from '@storybook/addon-knobs/react';
storiesOf("Components/Button", module).addWithJSX(
"basic PrimaryButton",
wInfo(`
storiesOf('Components/Button', module).addWithJSX(
'basic PrimaryButton',
() => (
<PrimaryButton
label={text('label', 'Enroll')}
disabled={boolean('disabled', false)}
onClick={() => alert('hello there')}
/>
),
{
info: {
text: `
### Notes
@ -148,13 +159,9 @@ storiesOf("Components/Button", module).addWithJSX(
/>
~~~
`)(() => (
<PrimaryButton
label={text("label", "Enroll")}
disabled={boolean("disabled", false)}
onClick={() => alert("hello there")}
/>
))
`,
},
}
);
```
@ -215,5 +222,5 @@ You will need to set up some scripts - these may help:
## Related Issues and Helpful Resources
* [Storybook, React, TypeScript and Jest](https://medium.com/@mtiller/storybook-react-typescript-and-jest-c9059ea06fa7)
* [React, Storybook & TypeScript](http://www.joshschreuder.me/react-storybooks-with-typescript/)
- [Storybook, React, TypeScript and Jest](https://medium.com/@mtiller/storybook-react-typescript-and-jest-c9059ea06fa7)
- [React, Storybook & TypeScript](http://www.joshschreuder.me/react-storybooks-with-typescript/)