OEMサービスのUIをStorybookで管理する

はじめまして。フロントエンドエンジニア兼サーバーサイドエンジニアの片柳です。

先日、トラストバンクから「Bonchiふるさと納税」がリリースされました!

www.trustbank.co.jp

ふるさとチョイスのOEMサービスとは、パートナー企業がブランドデザインを維持しながら、寄付申込や決済など、ふるさと納税サイトに必要な機能を包括的に提供できるサービスです。

パートナー企業ごとに異なるブランド・レイアウトを提供するためには、柔軟性に優れたUIパーツとそれを管理するためのツールが必要不可欠です。
本プロジェクトではStorybookを導入し、デザイナーやパートナーとのコミュニケーションを取りました。
簡単な導入方法と、実際に利用してみての良し悪しを紹介します。

導入

npmからインストール。

npx sb init

ディレクトリはこんな感じ。本プロジェクトにはNextJSを採用しています。

├ components/
│ └ tsx/
│   └ styled/
│     └ Button.tsx
└ stories/
  └ components/
    └ Button.stories.tsx

components/tsx/styled/にファイルを作ったら、その流れでstories/にもペタリ。
よりコンポーネントの追加を楽にするため、独自の拡張クラスを作成しました。

export class Storybook<T extends keyof JSX.IntrinsicElements | JSXElementConstructor<any>> {
  /**
   * メタ情報
   */
  protected meta: ComponentMeta<T>;

  /**
   * コンポーネントのテンプレート
   */
  protected template: ComponentStory<T>;

  constructor(title: string, Component: ComponentType<any>) {
    this.meta = {
      title,
      component: Component,
    };
    this.template = (args) => <Component {...args} />;
  }

  /**
   * メタ情報を取得
   */
  public getMeta(): ComponentMeta<T> {
    return this.meta;
  }

  /**
   * コンポーネントのテンプレートを取得
   */
  public getTemplate(): ComponentStory<T> {
    return this.template;
  }
}

これを

import { Storybook } from '@/components/tsx/plugins/Storybook';
import { Button } from '@/components/tsx/styled/button/Button';

const storybook = new Storybook<typeof Button>('basic/button', Button);

export default storybook.getMeta();

export const Fill = storybook.getTemplate().bind({});

Fill.args = {
  children: 'ボタンテキスト',
  radius: 4,
};

こう。
型付けもできて、見た目もスッキリです。

ボタンコンポーネントを小さくしたり、丸くしたり、青くしたり

良かったこと

何より簡単。シンプル

どんなに綺麗にコンポーネント一覧を作っても、更新を忘れてしまえば意味がないですよね。
作成したReactコンポーネントをただ貼り付けるだけで作成でき、細かい出し分けはStorybookに任せればいいので手間になりません。

無駄なコンポーネント開発を避けることができる

似てるようで少し違うコンポーネントをつい量産してしまうこと、ありませんか? 私はあります。
デザイン確認後、まずStorybookを見る癖をつけたことで、「このコンポーネント、Stroybookのあのコンポーネントと似てるな・・・デザイナーに相談しよう!」と、同じパーツの大量生産を避けることができました。
逆に、「このパーツは似ているけれど、使われ方が異なるから分けておこう」といった対応も簡単です。

イマイチだったこと

色味の一括変換ができない

「全てのコンポーネントの赤色を、青色に変えて確認したい」といった、全体を見て確認するような調整がStorybookは苦手です。
環境変数を持たせることもできないので、ページ全体のトンマナやアクセントになるような色遣いを検討するには不向きだと感じました。

NextJSとの相性がイマイチ?

NextJS独自の<Image>useRouterが含まれるコンポーネントだと、うまく機能しない場合がありました。
コンポーネントに基本的なスタイル以外の情報を持たせない運用を徹底すれば解決しそうですが、なかなか難しいですね。

まとめ

Storybookというツール自体は前から知っていて、「便利そう!使ってみたい!」と思ったいたため、実際にプロジェクトに活用できたのは良い経験になりました。
一長一短はありますが、従来の静的なコンポーネント管理と比べると、圧倒的にシンプルで運用しやすい印象です。
工夫次第ではstories.tsxファイルの自動生成や、環境変数に類似した機能も実装できそうですし、今後もどんどんカスタマイズしていきたいですね。

弊社トラストバンクでは様々な職種で絶賛採用中です!
気になった方、是非お気軽にご連絡ください!

www.wantedly.com