Felipe Sousa
Posted on June 27, 2019
Applications based at components aren't news for nobody, libraries like React, VueJS, and Angular are basically our first option when we're creating a new project, it's because they are really good for us developers.
The Storybook is a library that allows us to divide our components, simulating your behavior, actions, properties, etc.
Ps: all examples here will be based on React. If you wanna see how setup using another library, check out that link.
Alright, are you starting your project, you enter in your src
folder and create a new file called Button.js
, after that, you call this component inside your index.js
file and open your browser to check the component. You'll repeat it every time that create a new one! Ok, it's not a problem if you are working alone or in a small project, but imagine that the project is big, or you are working with a team (most common case). If someone else needs to use your component, this person will need to open your Button.js
file, check the properties, styles, actions, etc. It's a painful process that cost time and of course, patience!.
Setup
Alright, let's start a new create-react-app
project.
$ create-react-app your_project && cd your_project
After that, we can set up the Storybook running the command:
$ npx -p @storybook/cli sb init
Now you only need to run:
$ yarn storybook
A local server will be created at http://localhost:9009 and you will see something like that:
That's all you need to set up and run your storybook dashboard. Now, we'll check how you can add your own components on Storybook Dashboard.
Before we go to the next section, a folder called .storybook
was created in your root project, that folder contains all the setup generated by the Storybook CLI, don't care about it now, we'll talk about it later.
Adding your own components
Now, after setup, go to the file src/stories/index.js, you'll see that:
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';
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')}>
<span role="img" aria-label="so cool">
😀 😎 👍 💯
</span>
</Button>
));
Here you can check all the components that are showing at http://localhost:9009, all the components are registered here to be added on the Storybook Dashboard.
Ok, let's add a new component called Card.js
inside our src/components
folder.
import React from 'react';
import PropTypes from 'prop-types';
const Card = ({ title, description, }) => (
<div>
<h1>{title}</h1>
<p>{description}</p>
</div>
);
Card.propTypes = {
title: PropTypes.string,
description: PropTypes.string,
};
Card.defaultProps = {
title: 'Default Title',
description: 'Default Description',
};
export default Card;
Our Card
component is so simple, the component receives two optional properties, title
and description
, if the component doesn't receive the props, it will show your default values already defined.
Now let's add our Card
component to src/stories/index.js
file.
...
import Card from '../components/Card';
...
storiesOf('Card', module)
.add('default', () => (<Card />))
.add('with props', () => (<Card title="Lorem Impsum" description="Hi everyone" />))
The first thing that you need is to call the method storiesOf
, that receive two params, the first one is the name of your story (or component) and, the second one is a param provided by storybook called module
.
After that, I added a pipe called add
, that receive also two params, the first one is the story name about the component (or expected behavior), I added "default" because I'm not passing any param, so I expect to see the default state of the component, the second one is the component, in this case, only calling the component without props. The second add
pipe, receive a different name and in this case, I'm calling the component with their props, now, if I open my dashboard, I'll be able to see the 2 expected behaviors from my component.
Add-ons
Alright, Storybook works fine, you now can divide your components see one by one separately, but if you were able to edit within the dashboard itself the properties of your component? or see the actions log? that would be great, right?
Storybook can do more than only see our components divided, with it we are able also to do more things like: simulate actions, change our props on our dashboard, see jest updates, accessibility, change the state of your component (in React case), etc.
By now, I'll show how we can change our props and simulate actions. If you interest in others add-ons, you can check it here.
Alright, let's update our Card
component, now we'll add a button that will call a prop called onButtonClicked
. Let's do it:
import React from 'react';
import PropTypes from 'prop-types';
const Card = ({ onButtonClicked, title, description }) => (
<div>
<h1>{title}</h1>
<p>{description}</p>
<button onClick={onButtonClicked}>Click here</button>
</div>
);
Card.propTypes = {
title: PropTypes.string,
description: PropTypes.string,
onButtonClicked: PropTypes.func,
};
Card.defaultProps = {
title: 'Default Title',
description: 'Default Description',
onButtonClicked: () => null,
};
export default Card;
Now, let's back to our src/stories/index.js
file and add a new prop to our Card Stories:
...
import Card from '../components/Card';
...
storiesOf('Card', module)
.add('default', () => (<Card />))
.add('with props', () => (
<Card
title="Lorem Impsum"
description="Hi everyone"
onButtonClicked={() => {console.log("button was clicked")}}
/>))
Now, if you open the Dashboard and click on the button, the console will show the message button was clicked. Alright, no news so far, let's first able our props be edited using the dashboard.
The first thing that you need to do is install the addon-knobs
module:
$ yarn add @storybook/addon-knobs --dev
After that, you need to change your .storybook/addons.js
file:
import '@storybook/addon-actions/register';
import '@storybook/addon-links/register';
import '@storybook/addon-knobs/register';
Ok, now open you src/stories/index.js
file and import the module and change the props title and description:
...
import { withKnobs, text } from '@storybook/knobs';
...
storiesOf('Card', module)
.addDecorator(withKnobs)
.add('default', () => (<Card />))
.add('with props', () => (
<Card
title={text('title', 'lorem impsun')}
description={text('description', 'Hi everyone')}
onButtonClicked={() => {console.log("button was clicked")}}
/>))
If you check detailed, I added a new pipe after the storiesOf
method, the .addDecorator
add the support to use knobs. The title and description props now are receiving a method called text
, that receive as first param the name of the property, the second one is a default value, now, check your dashboard and on footer section, click on Knobs
tab, you'll see the that props are able to be edited! 🥳
Alright, let's track now the onButtonClicked
action, to do that, we need to use the action
module and change our prop on Card Component:
...
import { action } from '@storybook/addon-actions';
...
storiesOf('Card', module)
.addDecorator(withKnobs)
.add('default', () => <Card />)
.add('with props', () => (
<Card
title={text('title', 'lorem impsun')}
description={text('description', 'Hi everyone')}
onButtonClicked={action('button clicked')}
/>))
Now, back to your dashboard and select the table Actions and try to click on the button. 🚀
Alright, as you can see, Storybook is a super library that can help us to create more productive and smart apps, this post was only an introduction and you can check more things here.
That's all folks, thank you for your time!
Bye!
Posted on June 27, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.