Storybook: Why, When and How.
Tags: react, libraries, storybook
Published: 2019-06-27 18:45:09

---
published: true
title: "Storybook: Why, When and How."
tags:
  - React
  - Libraries
  - Storybook
---

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](https://storybook.js.org/).*

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.

```bash
$ create-react-app your_project && cd your_project
```

After that, we can set up the Storybook running the command:

```bash
$ npx -p @storybook/cli sb init
```

Now you only need to run:

```bash
$ yarn storybook
```

A local server will be created at **http://localhost:9009** and you will see something like that:

![Storybook Dashboard](https://thepracticaldev.s3.amazonaws.com/i/a1naaowbvrlww4i2u6df.png)

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:

```jsx
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.

```jsx
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.

```jsx
...
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.

![Storybook Dashboard Card Components](https://thepracticaldev.s3.amazonaws.com/i/12o67kkx0vwagtr1lzbz.png)

## 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](https://storybook.js.org/addons/).

Alright, let's update our `Card` component, now we'll add a button that will call a prop called `onButtonClicked`. Let's do it:

```jsx
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:

```jsx
...

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:

```bash
 $ yarn add @storybook/addon-knobs --dev
```

After that, you need to change your `.storybook/addons.js` file: 

```jsx
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**:

```jsx
...
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:

```jsx
...
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](https://storybook.js.org/).

That's all folks, thank you for your time!

Bye!