Adding Storybook Style Guide to a Create React App
22 Feb 2018In this post (and the above 6 minute embedded video) weāll look at how to add the Storybook style guide to a React web app boostrapped by create-react-app
.
This is the third post in a series about
create-react-app
.
Installing Storybook
Letās quickly bootstrap a web app with create-react-app
. From the command line weāll use npx
to kick off create-react-app
and name our project playground
. create-react-app
will then generate our app and proceed to install all its necessary node dependencies. Once thatās done, weāll change directories to our new app and proceed to install storybook
into the app by typing npx storybook
. At this point, storybook detects the type of app, notices that it was bootstraped by create-react-app
, and then proceeds to install its necessary dependencies.
ā npx create-react-app playground-storybook
ā cd playground-storybook
ā npx storybook
Investigating Generated Storybook Files
Once storybook has finished, we can open up VS Code and check out what has changed. You can notice a hidden folder called .storybook
that contains 2 files.
.storybook/addons.js
import '@storybook/addon-actions/register';
import '@storybook/addon-links/register';
The addons.js
file imports any addons that you might need. In this case, itās importing the actions
and links
addons. We will look at how those are used in another file.
.storybook/config.js
Next, we have the config.js
file. This is where we tell storybook
where to find our story definitions, in this case they are in the ../src/stories
folder.
import { configure } from '@storybook/react';
function loadStories() {
require('../src/stories');
}
configure(loadStories, module);
src/stories/index.js
Now, letās take a look at the index.js
file that storybook
created in our src/stories
folder. At the top, we import
several items from storybook
and our related addons.
import React from "react";
import { storiesOf } from "@storybook/react";
import { action } from "@storybook/addon-actions";
import { linkTo } from "@storybook/addon-links";
import { Button, Welcome } from "@storybook/react/demo";
import App from "../App";
storiesOf("Welcome", module).add("to Storybook", () => (
<Welcome showApp={linkTo("Button")} />
));
storiesOf("Button", module)
.add("with text", () => (
<Button onClick={action("clicked")}>
Hello Button
</Button>
))
.add("with some emoji", () => (
<Button onClick={action("clicked")}>š š š šÆ</Button>
));
We have stories for two main components listed in this file, Welcome
and Button
. Both of these are samples that came from the storybook
repo to get you started.
In the Button
ās case, there are two examples stories listed for the Button
component.
The linkTo
addon can redirect to other components (such as the Button
listed here) and the action
addon lets you log actions of a component to a custom panel (in our case Button
clicks will be logged).
package.json
Letās briefly switch gears to the package.json
file before we kick up the web server. Youāll notice that storybook
added a couple of npm scripts
for us to use. There is a storybook
script thatāll kick up a developer server and a build-storybook
script thatāll build a version of the style guide that you can host somewhere. As for dependencies, storybook
added storybook/react
, storybook/addon-actions
, and storybook/addon-links
to our devDependencies
.
{
"name": "playground",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-scripts": "1.1.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject",
+ "storybook": "start-storybook -p 9009 -s public",
+ "build-storybook": "build-storybook -s public"
},
"devDependencies": {
+ "@storybook/react": "^3.3.13",
+ "@storybook/addon-actions": "^3.3.13",
+ "@storybook/addon-links": "^3.3.13"
}
}
Kicking up the Storybook Dev Server
Okay, letās move on to see what the style guide looks like. Back in our terminal we can type npm run
to see all the scripts we have available, and as I mentioned earlier there is a storybook
entry. So, to kick off a developer server we will execute npm run storybook
. This will use webpack
to build your react app and then start a web server on port 9009.
And now, you can open up a browser to navigate the style guide. The welcome page has some summary information with helpful information to get started. As we noted earlier, the links addon should redirect us to the Button component when we click on the āstoriesā link. Also, as we saw before, when we click on the Buttonā¦ we will see the event logged in the panel below as a result of the action addon. Here we have another story for Button that shows using emojis instead of text. If we click on the button, itāll also log itās action in the panel below.
Adding a New Component Story
Now, letās try adding our own story to storybook
. Seeing that we just created our React app, there arenāt many components, however, there is the main App
component that create-react-app
generated, so letās use that.
We will start by importing App from the App compoennt. And then weāll copy the Welcome set of stories and rename it to āAppā instead. Letās name our first story as ādefaultā and instead of the Welcome component we will reander the App
component.
src/stories/index.js
import App from "../App";
// ... more code ...
storiesOf("App", module)
.add("default", () => <App />);
Now, when we come back to the browser we should see our new App
component, and if we open it, weāll see our App
rendered!
However, the App
component doesnāt support any customizable props
, so letās fix that. Weāll come back over to VS Code and edit our App
component. Letās destructure the title
prop from the componentās props
and use it to dynamically render the title
, instead of always saying āWelcome to Reactā. Before we move on we will give title
a default value in case one is not passed to the component.
import React, { Component } from "react";
import logo from "./logo.svg";
import "./App.css";
class App extends Component {
render() {
+ const { title } = this.props;
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcome to {title}</h1>
</header>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and
save to reload.
</p>
</div>
);
}
}
+ App.defaultProps = {
+ title: "React"
+ };
export default App;
Now, weāll switch back over to our src/stories/index.js
file and add another story to the App
component. Weāll call this one, ātitleā and pass it a title prop of āMy Worldā.
import App from "../App";
// ... more code ...
storiesOf("App", module)
.add("default", () => <App />)
+ .add("with title", () => <App title="My World" />);
If we come back to the browse, we will see a new entry under the App
component listing hte new āwith titleā story and itāll show āWelcome to My Worldā.
At this point, the stories are pretty static, but there are ways you can make your stories much more interactive. However, we wonāt go into those in this blog post. If that interests you, please let me know on Twitter at @elijahmanor.
Building Storybook and Serving Locally
Now, letās focus on building our style guide. We will cancel our dev server and type npm run build-storybook
in the terminal. This will build a version of the style guide to a folder called storybook-static
. Once itās done you can kick up a simple http server to run the web app. In our case running npx serve storybook-static
will suffice. And now we can navigate to localhost:5000
to see our static style guide. And sure enough, it works just great!
ā npm run build-storybook
ā npx serve storybook-static
Conclusion
Thanks for reading this third post in the create-react-app
series. If you donāt already have a style guide solution, storybook is a nice and easy way to quickly get started building an interactive style guide.