Skip to main content

Storybook コンポーネント実装・運用ベストプラクティス

本ドキュメントは、デザインシステムのコンポーネントをStorybook上でどう実装し、運用・テストしていくかに関するベストプラクティスを定めたものだ。
コンポーネント駆動開発を前提に、チーム全体で共通言語として機能するStorybookを構築・維持するためのルールだ。

1. ファイルの配置ルール (Co-location)

Storybookのファイル(.stories.tsx等)は、対象のコンポーネントと同じディレクトリ内に配置する(Co-location)。

✅ 推奨配置例:

src/components/ui/Button/
├── Button.tsx
├── Button.module.css (スタイルファイル)
├── Button.test.tsx (単体テスト)
└── Button.stories.tsx (Storybookファイル)

理由:

  • コンポーネントの実装とカタログを物理的に近づけることで、コンポーネント変更時のStory更新漏れを防ぐ。
  • コンポーネントを削除・移動する際に、関連ファイルをまとめて処理しやすくなる。

2. Story の網羅性基準 (5つの UI スタック)

「理想的にデータが入っている状態」だけをStoryに登録するのではなく、現実のプロダクトで起こりうるすべての状態 (UI Stack) を網羅してStoryを作成する。

  1. Ideal (理想状態): 全てのデータが理想的な文字数やフォーマットで入っている状態。
  2. Empty (空状態): データがない場合のプレースホルダーや案内表示。
  3. Loading (読込中): スケルトンスクリーンやスピナーなど、待機時の状態。
  4. Partial (部分欠損): 例: 名前はあるがアイコン画像がない場合のイニシャル表示(フォールバック)。
  5. Error (エラー): データの取得や操作に失敗した場合のエラー表示。

また、Interaction (インタラクション状態)(Hover等)も、Play function等を用いてStory上で確認できるようにする。


3. Props と Controls の設計基準 (直交性の担保)

Storybookの Controls パネルは、コンポーネントが受け付ける全バリエーションをチームに伝える役割を持つ。

  • 直交性の検証: Controlsで値を変更した際、他のプロパティが意図せず壊れないか(直交性が保たれているか)をStory上で検証する。
  • Enum と Boolean: 排他的な3つ以上の状態にはセレクトボックス(enum等)を用い、トグルスイッチの量産を避ける。
  • Slotの表現: PropsがSlotの場合、Storyでは単なるテキストだけでなく、アイコン等を差し込んだ複数パターンを用意して使い方を明示する。
  • 開発専用トグル: デバッグ用のPropsには _showDebug のように _ をプレフィックスにし、本番のProps体系と明確に区別する。

4. テストに関するガイドライン

Storybookをテストの起点 (Source of Truth) として活用する。特に、コンポーネントの「変更の安全性(後方互換性)」を担保するためにはテストの自動化が不可欠だ。

4-1. ビジュアルリグレッションテスト (VRT)

  • Chromatic などのVRTツールを導入し、デザインの意図しない崩れを防ぐ。
  • Storybookに登録されたすべてのStory(UIスタックの各状態を含む)がVRTの対象となる。そのため、Storyの網羅性(上記2)がテスト網羅率に直結する。

4-2. インタラクションテスト (Play function)

  • クリックアクション、フォーカス時の挙動、モーダルの展開などは、Storybookの play 関数を用いてコンポーネントのインタラクションテストとして記述する。
  • 汎用層のテスト: ui等の汎用コンポーネントでテストを徹底すれば、上位コンポーネントは詳細テストを省き、安全に振る舞いを再利用できる。

5. ライフサイクル管理とドキュメンテーション

コンポーネントは作るよりも「終わらせる」設計が重要だ。使われなくなった(あるいは設計が古くなった)コンポーネントが放置されると、新メンバーが誤って使用する原因になる。

5-1. コンポーネントの非推奨化 (Deprecation)

  • 当該コンポーネント名やStoryのタイトルに [Deprecated] を明記する。
  • Storybookのサイドバー上で Deprecated/Button のような別階層のフォルダに移動させる。

5-2. Storybook Docs (MDX) での理由の明文化

  • 単に「使うな」と言うのではなく、Docsタブ内に 「なぜ非推奨になったのか」 および 「移行先(代替品)は何か」 を記載したマイグレーションガイドを残す。

5-3. 意図的な妥協(技術的負債)の記録

  • 100% 理想の設計ができていない場合(例:「将来Enumにする予定だが、現状はStringで暫定実装している」など)、なぜ今の設計になっているかの経緯をDocsに一言残す。これにより、場当たり対応が「意図的な妥協(設計)」として正しくチームに共有される。