Storybook事始め

巷でよく耳にするStorybook
私は近頃、Reactに入門し始めたのでアドベントカレンダーの機会にStorybookを調べてみました。
「Storybookとは何！？」レベルの方が読者想定で、とりあえず動かしてみたい方におすすです。

この記事では以下2点についてざっくり説明しています。
- Storybookの導入方法について
- 基本的な使い方について

Storybookのメリデメや運用してみた結果などについては触れておりません。

# Storybookとは
公式ページには以下のように書かれておりまして。
>Storybook is a frontend workshop for building UI components and pages in isolation. Thousands of teams use it for UI development, testing, and documentation. It’s open source and free.

https://storybook.js.org/

要するに、UIコンポーネントの管理・テストをすることが出来るオープンソースツールで、コンポーネントを組み込んだ画面ではなく、コンポーネント単位で確認やドキュメントとして利用することが可能だということです。

# Storybookの導入方法について
1. 必要なパッケージ(Storybook)をインストールして環境を構築しましょう
`$ npx sb@latest init`

2. 起動するためのスクリプトがpackage.jsonに記載されているので、Storybookを表示しましょう
`$ npm run storybook`

以下の愛らしい画面が表示されたら導入完了です。
![スクリーンショット 2022-11-25 19.01.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985760/6dce3c11-efd9-e08b-3932-2425b284e987.png)


# 基本的な使い方について
コンポーネントとそれに対応するストーリーを記述して進めていきます。
ストーリーとはコンポーネントをどのように描写するかのことです。
今回は例としてCustomeButtonコンポーネントを作成することにします。
コンポーネントに対してボタンのタイプ(色)と表示するテキストを渡すことで使える形にしています。

```react
import React from 'react';
import styled from 'styled-components';

const Button = styled.button`
    padding: 10px;
    color: #ffffff;
    border-radius: 10px;
`

const ButtonDanger = styled(Button)`
    background: #FF0000;
    border: 2px solid #FFABCE;
`

const ButtonWarning = styled(Button)`
    background: #FF4F02;
    border: 2px solid #FFAD90;
`

const ButtonPrimary = styled(Button)`
    background: #0000CD;
    border: 2px solid #A4C6FF;
`

const ButtonSuccess = styled(Button)`
    background: #00FF3B;
    border: 2px solid #CBFFD3;
`

const buttonLists = {
    danger: ButtonDanger,
    warning: ButtonWarning,
    primary: ButtonPrimary,
    success: ButtonSuccess
};

export default function CustomeButton({ style, title }) {
    const CustomeButton = buttonLists[style];
    return (
        <CustomeButton>
            {title}
        </CustomeButton>
    );
};

```

コンポーネントができたらそれに対応するストーリーを記載していきます。
ストーリーはストーリーファイルに記載していきます。`stories.js | ts | jsx | tsx | mdx`の拡張子を指定することでストーリファイルとして認識してくれます。


```react
import React from 'react';
import CustomeButton from './CustomeButton';

export default {
    component: CustomeButton,
    title: 'CustomeButton',
};

const Template = args => <CustomeButton {...args} />;
export const Danger = Template.bind({});
Danger.args = {
    type: 'danger',
    title: '削除する'
};

export const Warning = Template.bind({});
Warning.args = {
    type: 'warning',
    title: '修正する'
};

export const Primary = Template.bind({});
Primary.args = {
    type: 'primary',
    title: '保存する'
};

export const Success = Template.bind({});
Success.args = {
    type: 'success',
    title: '投稿する'
};
```
起動しているstorybookを確認してみると以下のように表示されます。
ストーリーファイルに記載した4つのストーリーが確認できますね。
![画面収録-2022-11-28-18.35.11.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985760/506f081a-473a-3f0a-be18-c2469da8def7.gif)

Controlsタブで引数の値を変更することが可能です。上記の動画では「保存する」の文字を「ログインする」に変更しています。またtypeの箇所では用意していないtypeの値を渡すとエラーになることが分かります。

またControlsタブで値の制御をすることも可能で、以下の例ではdefault exportにargTypesを持たせ、Controlsタブでの操作方法や選択させる値についても制限しています。
```react
import React from 'react';
import CustomeButton from './CustomeButton';

export default {
    component: CustomeButton,
    title: 'CustomeButton',
    argTypes: {
        type: {
          control: 'radio',
          options: ['danger', 'warning', 'primary', 'success']
        }
    }
}

const Template = args => <CustomeButton {...args} />;
export const Danger = Template.bind({});
Danger.args = {
    type: 'danger',
    title: '削除する'
};

```
![スクリーンショット 2022-11-28 19.12.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985760/b47ff4f6-1741-f0e5-7018-877a1ba5c4c1.png)

ここまで手を動かしてみて、なんとなくの操作方法は掴めたのではないでしょうか？
この記事は「Storybook "事始め"」ということですので、この辺りでおひらきにしようと思います。
ご閲覧ありがとうございました。