Create a component library using Storybook and create-react-app
Tags: react, design, webdev, javascript
Published: 2020-06-21 22:44:44

In this post we will look at how we can use Storybook to create a component library using Create React App (CRA). In the end, we will create a simple button with some variations.

## Setup
First we create the project using CRA. In this post, we will be using yarn but if you prefer to use npm, all commands should work as well so do feel free. In the CRA command below be sure to add the flag `--use-npm` to initialize as an npm project.

```bash
npx create-react-app component-lib
```

The next step is to add storybook to our project.
```bash
npx -p @storybook/cli sb init
```



You should see these new yarn scripts added to your `package.json`:
```json
"scripts": {
  ...
  "storybook": "start-storybook -p 9009 -s public",
  "build-storybook": "build-storybook -s public"
}
```

Note: at this time of writing the version of Storybook used is 5.3.

By default, Storybook will read all files in your `src/` directory that follows the `.stories.js` suffix (see `.storybook/main.js`)

```javascript
stories: ['../src/**/*.stories.js'],
```

For the purpose of this post, we will keep it simple and place all our stories in the `src/stories` folder. 

To run story book and you will be presented with the following dashboard:
```bash
yarn storybook
```

![Storybook running](https://dev-to-uploads.s3.amazonaws.com/i/sje6xg6z0qw3ev843tpt.png)

Storybook comes out of the box with demo buttons from their demo projects but we will be creating our own in the next step.

## Creating your own component
Now we will create a simple button component with a few variations as examples so we can create different stories for each.

```jsx
// src/components/Button.js
import React from 'react';
import './button.css';

const colors = {
  default: 'default',
  primary: 'primary',
  secondary: 'secondary',
};

const Button = ({ children, onClick, color, disabled }) => {
  const className = colors[color] ? `button ${colors[color]}` : 'button';
  return (
    <button className={className} onClick={onClick} disabled={disabled}>
      {children}
    </button>
  );
};

export default Button;
```

The styles for the component is defined below. Feel free to use your preferred method of styling your components. In this case we're just using plain CSS for simplicity's sake.

```css
/* src/components/button.css */
.button {
  font-family: 'Roboto', 'Helvetica', 'Arial', sans-serif;
  padding: 6px 16px;
  font-size: 12px;
  min-width: 64px;
  box-sizing: border-box;
  font-weight: 500;
  line-height: 1.75;
  letter-spacing: 2px;
  cursor: pointer;
  border-radius: 4px;
  box-shadow: 0px 8px 15px rgba(0, 0, 0, 0.1);
}

.button[disabled] {
  cursor: default;
  pointer-events: none;
  color: rgba(0, 0, 0, 0.26);
  box-shadow: none;
  background-color: rgba(0, 0, 0, 0.12);
}

.primary {
  color: #fff;
  background-color: #1976d2;
}

.secondary {
  color: #fff;
  background-color: #dc004e;
}
```

We create the following stories for each variation of our Button component.

```jsx
// src/stories/Button.stories.js
export const Primary = () => (
  <Button color="primary" onClick={action('clicked')}>
    Primary Button
  </Button>
);

export const Secondary = () => (
  <Button color="secondary" onClick={action('clicked')}>
    Secondary Button
  </Button>
);

export const Disabled = () => (
  <Button color="secondary" onClick={action('clicked')} disabled={true}>
    Disabled Button
  </Button>
);

export const WithEmojis = () => (
  <Button onClick={action('clicked')}>
    <span role="img" aria-label="so cool">
      With Emojis 😀 😎 👍 💯
    </span>
  </Button>
);
```

We should see the following in Storybook:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/jpdhth0qpewc2495oatu.gif)

## Building and exporting as a static app
Now that we have created our component library consisting of a single Button component. We now will think about building and exporting it. All we have to do is run the other yarn script:

```json
"build-storybook": "build-storybook -s public"
```

Running the following will create the static Storybook files in the `storybook-static` directory. 
```bash
yarn build-storybook
```
This can then be deployed as a static web app. In a follow-up post I will go through instructions how to do this. 
For now we can test deploying this using the npm library [http-server](https://www.npmjs.com/package/http-server) using the following command:

```bash
npx http-server storybook-static
```

## Closing notes
We have gone through creating a simple React component library using Storybook and CRA. Storybook provides us the tools to make it straightforward to achieve this. We are just touching the surface and Storybook provides much more though add-ons, testing and more. See more information [here](https://storybook.js.org/docs/guides/guide-react/). In a follow up post I will go through publishing deploying the static site and publishing our Button component as a library to a public npm registry so we can use it in other React apps so stay tuned.

Thanks for following and reading.✌🏼