Created: 2018-10-16 Tue 21:55
Storybook Tutorial
Start with your existing react app
cd path/to/project
npm install -g @storybook/cli # - or - yarn global add @storybook/cli
getstorybook
npm run storybook # -or- yarn storybook
After creating your react app, add storybook for react:
yarn add @storybook/react
Create the configuration directory and files:
mkdir .storybook touch .storybook/config.js
This is how storybook finds stories.
<project_root>/ .storybook/ config.js src/ index.js App.js App.test.js App.story.js
// .storybook/config.js import { configure } from '@storybook/react'; function importAll(req) { req.keys().forEach(filename => req(filename)); } function loadStories() { let req; req = require.context('../src', true, /\.story\.js$/); importAll(req); } configure(loadStories, module);
Let's write the story for the main React App component
// src/App.story.js import React from "react"; import { storiesOf } from "@storybook/react"; import App from "./App"; storiesOf("Main React App", module).add("the app", () => <App />);
Add a script to package.json
to run storybook
"scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", "storybook": "start-storybook -p 9009 -c .storybook" },
Run the script and open your browser to http://localhost:9009
yarn run storybook # or just yarn storybook
Let's build a simple horizontal input field component.
This will be wrapped in a form in the application
export class HorizontalInputField extends React.Component { render() { const { id, label, name, onChange } = this.props; return ( <FormGroup> <label for={name}>{label}</label> <input className="form-control" id={id} type="text" name={name} onChange={onChange} /> </FormGroup> ); } }
The corresponding story wraps the component to display it properly
import HorizontalInputField from "./index"; storiesOf("components/HorizontalInputField", module) .add("basic example", () => ( <Wrapper> <Form> <HorizontalInputField id="email-input-field" name="email" label="Email:" onChange={noop} /> </Form> </Wrapper> ));
Besides the aforementioned actions
addon, storybook has many other addons:
yarn add @storybook/addon-actions
// .storybook/addons.js import "@storybook/addons/register"
// ... import { action } from "@storybook/addon-actions/register" // ... storiesOf("components/HorizontalInputField", module) .add("basic example", () => ( <Wrapper> <Form> <HorizontalInputField id="email-input-field" name="email" label="Email:" onChange={action("email field changed")} /> </Form> </Wrapper> ));
Every time the input field changes, an event is shown in the "Action Logger" area
Reuse test data from your specs by organizing it to share
Example:
class Consumer extends React.Component { render() { <Component {...this.props} /> } } storiesOf("Component", module) .add("example one", () => (<Consumer thing="one" /> )) .add("example two", () => (<Consumer thing="two" /> ))
Extract and display in story
Create component, spec, and story boilerplate