KAKEHASHI Tech Blog

カケハシのEngineer Teamによるブログです。

Storybook Addon Contexts を使って、ワンランク上のコンポーネントカタログを作ろう

概要

コンポーネントのカタログを作成することができる storybook。利用している開発者は多いのではないでしょうか?

この記事では、Storybook Addon Contexts を利用して、storybook 環境をちょっと便利にする方法を書きます。

Storybook Addon Contexts とは

Storybook Addon Contexts とは、storybook に対してコンテキストを注入する機能を提供します。コンテキストとはつまり、ロケールのような、コンポーネントよりも上位の状態のことです。

例えばアプリケーションが多言語対応しているような場合。念のため、コンポーネントの見た目が言語によって変わることを確認したいです。しかし、すべてのストーリーに言語切り替えを付与するのはかなり面倒です。そこで、すべてのストーリーで使い回せるような、状態のスイッチャーとして Storybook Addon Contexts が利用できます。

あまり日本語の情報がないこちらの Addon ですが、以下、具体的なコードを交えて解説していきます。利用しているライブラリは React ですが、Angular や Vue でも問題なく動くと思います。

環境構築

Storybook 公式のチュートリアルを参照すると、簡単に環境を構築することができます。

# 雛形をクローン
npx degit chromaui/intro-storybook-react-template taskbox

cd taskbox

# パッケージインストール
yarn

# あるいは
npm i 

# npm v7 以上を使っている場合は
npm i --legacy-peer-deps

この記事を執筆している時点でのパッケージのバージョンは以下のとおりです。

  "dependencies": {
    "@testing-library/jest-dom": "^5.11.4",
    "@testing-library/react": "^11.1.0",
    "@testing-library/user-event": "^12.1.10",
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "react-scripts": "4.0.1",
    "web-vitals": "^0.2.4"
  },
  "devDependencies": {
    "@storybook/addon-actions": "^6.3.0",
    "@storybook/addon-essentials": "^6.3.0",
    "@storybook/addon-links": "^6.3.0",
    "@storybook/node-logger": "^6.3.0",
    "@storybook/preset-create-react-app": "^3.1.7",
    "@storybook/react": "^6.3.0",
    "@storybook/testing-react": "^0.0.17"
  }

Storybook の起動

環境ができたので、storybook を起動させます。

# 起動
yarn storybook

# あるいは
npm run storybook

storybookが立ち上がった様子

起動できたことを確認。

Storybook Addon Contexts 追加

ここからは、コンテキスト追加の例として、ダークテーマを追加するための設定を入れてみます。

まずは、Storybook Addon Contexts パッケージを追加します。

yarn add -D @storybook/addon-contexts

# あるいは
npm i --save-dev @storybook/addon-contexts

.storybook/main.js に追記します。

module.exports = {
  addons: [
    // ...既存のアドオン
    '@storybook/addon-contexts/register' // 追加
  ]
}

.storybook/preview.js に追記します。

import { addDecorator } from '@storybook/react';
import { withContexts } from '@storybook/addon-contexts/react';
import { contexts } from './configs/contexts'; // 後ほど作成します。
 
addDecorator(withContexts(contexts));

コンテキストの設定は、.storybook/config/contexts.js ファイルを新規作成して記載します。(ファイル名は何でもよいです)

export const contexts = [
  {
    icon: "box", // コンテキストの種類をよく表しているアイコンを選択
    title: "Themes", // コンテキスト名(ユニーク)
    components: [
      // ストーリーをラップするコンポーネントを列挙
      // <ThemeProvider /> など
    ],
    params: [
      // コンポーネントに注入するパラメータの配列
      { name: "Light Theme", props: { baseColor: "#fff" } },
      { name: "Dark Theme", props: { baseColor: "#333" }, default: true },
    ],
    // 設定値(詳細は https://www.npmjs.com/package/@storybook/addon-contexts#options
    options: {
      deep: true, // pass the `props` deeply into all wrapping components
      disable: false, // disable this contextual environment completely
      cancelable: false, // allow this contextual environment to be opt-out optionally in toolbar
    },
  },

  // さらに複数のコンテキストが設定可能!
];

以上でベーシックな設定が完了しました。

実際の動作は以下の通り。コンテキストメニューが追加され、theme が選べるようになっていますね!(storybook の再起動が必要かもしれません)

自作のコンテキストメニューが追加されました!

コンテキストメニューを再選択するたびに設定値が流れてくるので、それを受け取るラッパーコンポーネントを作成して、配下のストーリーに渡してやると良いと思います。

より詳細な設定は、公式の README を参照してください。story レベルでのコンテキスト設定も可能です。

また、すべてのコードは以下のレポジトリで公開しています。

まとめ

ちょっと便利な Storybook Addon Contexts の紹介をしました。

ちなみに自分は、React プロジェクトでのルーティング切り替えに Storybook Addon Contexts を利用しました。コンテキストメニューから、設定したルート一覧が選択できるような感じです。ルーティングに応じて見た目が変わるコンポーネントがあったので。