Storybook の Controls を触ってみる

こんにちは、Gaji-Labo アシスタントエンジニアの石垣です。

今回は、Storybook 6 で追加された Controls という addon を触る機会があったため、使い方をまとめてみたいと思います。

本記事でご紹介する機能は Storybook 6.3 をベースとしています。

Controls とは?

Controls は、Storybook 6 で追加された Essential addons (初期設定時にデフォルトで追加されている addon)の一つです。

追加でコードを記述することなく、コンポーネントの props を動的に操作してその場で確認できるUIを提供してくれる機能です。

以前は、 addon-knobs という同じ機能の addon がサードパーティ製で用意されていましたが、同様の機能が公式で提供されることとなりました。

以下、実際に使い方を見てみます。

Controls を実際に使う

サンプルとして、以下のようなボタンコンポーネントを作成しました。

青い角丸のボタンコンポーネントのキャプチャ画像
import classNames from 'classnames'

import styles from './Button.module.scss'

interface Props {
  className?: string
  color: 'primary' | 'secondary'
  href?: string
  label?: string
  onClick?: () => void
  withArrow?: boolean
}

const Button = ({
  className,
  color,
  onClick,
  href,
  withArrow,
  label,
}: Props): JSX.Element => {
  const classes = classNames(
    styles.Button,
    className,
    color === 'primary' && '-colorPrimary',
    color === 'secondary' && '-colorSecondary',
    withArrow && '-withArrow'
  )
  return href ? (
    <a href={href} className={classes}>
      {label}
    </a>
  ) : (
    <button type="button" className={classes} onClick={onClick}>
      {label}
    </button>
  )
}

export default Button

Controls を使うには、 stories ファイルで引数に args を渡し、コンポーネントの props に与えます。

import { ComponentStory } from '@storybook/react'
import Button from './Button'

export default {
  title: 'components/common/Button',
  component: Button,
}

const Template: ComponentStory<typeof Button> = (props) => {
  return <Button {...props} />
}

export const Default = Template.bind({})

Storybook で確認すると、props ごとに Controls が表示されています。

ボタンコンポーネントのStorybook のスクリーンショット。Controls のUIが表示されている

Controls の大きな利点として、 knobs のように props に渡したい値を一つ一つ設定する必要がなく、コンポーネントの props から自動的に推論して渡されるべき値を Controls で操作できるという点が挙げられます。

また、 Controls の初期値は、Story に追記することで設定することができます。

import { ComponentStory } from '@storybook/react'
import Button from './Button'

export default {
  title: 'components/common/Button',
  component: Button,
  // Stories 全体で初期値を指定する場合
  args: {
    className: "",
    color: "primary",
    href: "",
    withArrow: false,
    label: "Button"
  },
}

const Template: ComponentStory<typeof Button> = (props) => {
  return <Button {...props} />
}

export const Default = Template.bind({})

// Story 個別で初期値を指定する場合
Default.args = {
  className: "",
  color: "primary",
  href: "",
  withArrow: false,
  label: "Button"
}

まとめ

今回は Storybook 6 で追加された Controls という addons をご紹介しました。

非常に設定が簡単で便利かつ、初期設定の際に標準で入っている addon ということでとても便利だなと感じました。

引き続き Storybook の addon について情報をキャッチアップしていけたらと思っています。

Gaji-Laboでは、React経験が豊富なフロントエンドエンジニアを募集しています

弊社ではReactの知見で事業作りに貢献したいフロントエンドエンジニアを募集しています。大きな制作会社や事業会社とはひと味もふた味も違うGaji-Laboを味わいに来ませんか?

もちろん、一緒にお仕事をしてくださるパートナーさんも随時募集中です。まずはお気軽に声をかけてください。お仕事お問い合わせや採用への応募、共に大歓迎です!

求人応募してみる!

投稿者 Ishigaki Shotaro

アシスタントエンジニアとしてHTML/CSS/JavaScriptの実装やRailsの組み込み、スタイルガイドの構築などを担当しています。 業務の中でさまざまな学びを吸収しながら、文書構造やアクセシビリティに目を向けたマークアップの学習やJavaScriptの学習などを行っています。チームに貢献できるエンジニアとなるために日々奮闘中です。