Storybookの始め方、UIコンポーネント管理のやり方

## はじめに

フロントエンド開発において、UIコンポーネントの効率的な管理とチーム間での共有は、開発スピードやコードの品質に大きく影響します。
**Storybook**は、この課題を解決するための強力なツールで、コンポーネントの開発、ドキュメント化、テストを効率化できます。

実際弊社でも、Storybook導入前ではあるメンバーが作成したコンポーネントの使い方がよくわかっていなかったり、誰がどのコンポーネントを作ったか整理できていない状態でした。
ですが、導入してからはチーム間での開発が効率化されていったのが目に見えてわかりました。同じようなコンポーネントを重複して作成することがなくなったり、何より他の人が作ったコンポーネントのキャッチアップが格段に早くなりました。

この記事では、Storybookの基本、実際の導入・活用方法までを備忘として記載していこうかと思います！

### ちなみに、、

弊社では、フリーランスエンジニアの方を募集しており、
フロントエンド、サーバーサイド、ネイティブアプリ等、それぞれの領域で活躍できるプロジェクトがあります！
フロントエンドのプロジェクトでも対応言語・FWや案件種類も様々です。
（案件種類の例：toB向けの業務システムの画面構築、ECサイトの画面構築、クリエイティブ性の強いHP・LP等の制作など）

興味がある方は、ぜひ下記フォームに回答いただけますと幸いです。
👉 フォームは[こちら](https://docs.google.com/forms/d/e/1FAIpQLSfY9lckFjAJ_Ddc4rdHDSIFoV4NFHw1q2HriK2aa_jvVhp8QQ/formResponse)

## Storybookとは？

Storybookは、UIコンポーネントを独立して開発・テスト・ドキュメント化するためのツールです。

### 主な特徴

1. **独立したコンポーネント開発**
    - アプリケーション全体から切り離してコンポーネントを開発
2. **リアルタイムプレビュー**
    - 変更内容を即座に確認可能
3. **ドキュメント生成**
    - 自動生成されるインタラクティブなドキュメントでコンポーネントを共
4. **テストの統合**
    - UIのスナップショットテストやアクセシビリティテストをサポート
5. **フレームワーク対応**
    - React、Vue.js、Angular、Svelteなど、主要なフロントエンドフレームワークに対応

## Storybookのセットアップ

以下では、Reactプロジェクトを例にStorybookをセットアップする方法を解説します。

### 前提
* React + TypeScrptのプロジェクト
* 既にプロジェクトが作成済

### 1. Storybookをインストール
以下のコマンドでStorybookをプロジェクトに追加します：

```bash
npx storybook init
```

これにより、Storybookの基本設定が自動的に行われ、以下のフォルダが作成されます：

- `.storybook/`：Storybookの設定ファイル
- `src/stories/`：サンプルのコンポーネントとストーリーファイル

### 2. Storybookを起動

以下のコマンドでStorybookを起動します：

```bash
npm run storybook
```

ブラウザで`http://localhost:6006`を開くと、Storybookのインターフェースが表示されます。

## コンポーネント作成とストーリー定義
以下では、独自のコンポーネントをStorybookに追加する手順を説明します。
（説明のために、ここでは直接styleを記載してしまいます。）

### 1. ボタンコンポーネントの作成
src/components/Button.tsxに以下のコードを記述します。

```tsx:src/components/Button.tsx
import React from 'react';

export interface ButtonProps {
  label: string;
  onClick: () => void;
  variant?: 'primary' | 'secondary';
}

const Button: React.FC<ButtonProps> = ({ label, onClick, variant = 'primary' }) => {
  return (
    <button
      onClick={onClick}
      style={{
        padding: '10px 20px',
        fontSize: '16px',
        backgroundColor: variant === 'primary' ? '#007bff' : '#6c757d',
        color: '#fff',
        border: 'none',
        borderRadius: '4px',
        cursor: 'pointer',
      }}
    >
      {label}
    </button>
  );
};

export default Button;

```

### 2. ストーリーの作成
src/stories/Button.stories.tsxを作成し、以下のコードを記述します。
```tsx:src/stories/Button.stories.tsx
import React from 'react';
import { Meta, Story } from '@storybook/react';
import Button, { ButtonProps } from '../components/Button';

export default {
  title: 'Components/Button',
  component: Button,
  argTypes: {
    onClick: { action: 'clicked' },
    variant: {
      control: { type: 'select' },
      options: ['primary', 'secondary'],
    },
  },
} as Meta;

const Template: Story<ButtonProps> = (args) => <Button {...args} />;

export const Primary = Template.bind({});
Primary.args = {
  label: 'Primary Button',
  variant: 'primary',
};

export const Secondary = Template.bind({});
Secondary.args = {
  label: 'Secondary Button',
  variant: 'secondary',
};

```
これで、Storybookを再起動すると、ブラウザに新しいボタンコンポーネントのストーリーが表示されます。

## Storybookの+αの機能
### ドキュメント生成
Storybookでは、コンポーネントのプロパティをドキュメントとして自動生成できます。

Button.stories.tsxでargTypesを追加することで、各プロパティの説明を設定できます。
```typescript
argTypes: {
  label: {
    description: 'ボタンに表示されるテキスト',
  },
  variant: {
    description: 'ボタンのスタイル',
    control: { type: 'select' },
    options: ['primary', 'secondary'],
  },
  onClick: {
    description: 'ボタンがクリックされたときのイベントハンドラー',
  },
},

```
### アクセシビリティテスト
Storybookでは、アクセシビリティチェックを行うことができます。以下のコマンドでアドオンを追加します。
```
npm install @storybook/addon-a11y --save-dev
```
`.storybook/main.js`に以下を追加：

```typescript
module.exports = {
  addons: ['@storybook/addon-a11y'],
};
```

## まとめ

Storybookは、UIコンポーネントを効率的に管理し、開発プロセスを大幅に向上させるツールです。特に、チームでのフロントエンド開発において、その真価を発揮すると思います！
この記事を参考に、フロントエンド開発がより効率的にできるようになると幸いです。

## おわりに

繰り返しになりますが、弊社では、フリーランスエンジニアの方を募集しております！

熱意を持って新しいプロジェクトに挑戦したい方、様々な大規模開発プロジェクトに興味のある方は、下記フォームにてあなたの経歴をご回答ください！

👉 フォームは[こちら](https://docs.google.com/forms/d/e/1FAIpQLSfY9lckFjAJ_Ddc4rdHDSIFoV4NFHw1q2HriK2aa_jvVhp8QQ/formResponse)