Storybook上でPropsの値を変更して表示などの確認を行う際にはaddon-knobsをインポートして使っていましたが、今後廃止予定となるため今後はControlsを使って実装するようになっていくかと思います。
既にaddon-knobsは deprecated となっています。
そのため、Controlsに書き直してみます。
Storybook公式サイトにドキュメントがあります。
まずは以下のような OriginalComponent
というコンポーネントがあるとします。
src/components/OriginalComponent/OriginalComponent.tsx const OriginalComponent = ({ hoge, fuga, ref }: {hoge: string; fuga: boolean; ref: MutableRefObject<HTMLElement | undefined>}) => { return (<OriginalSubComponent hoge={hoge} fuga={fuga} ref={ref}/>) }
これをKnobsを使って作成したStrorybookは以下になります。
src/components/OriginalComponent/OriginalComponent.stories.tsx import { withKnobs, text, boolean } from '@storybook/addon-knobs'; ・・・省略 export default { title: 'originl component' component: OriginalComponent, decorators: [withKnobs], } export const Default: Story<OriginalProps> = (args) => { return ( <OriginalComponent hoge={text('hoge', 'abcdefg')} fuga={boolean('fuga', false)} ref={{} as MutableRefObject<HTMLElement | undefined>} /> ); }; Default.storyName = 'OriginalComponent'
ではControlsを使ったStorybookに書き換えてみましょう。
src/components/OriginalComponent/OriginalComponent.stories.tsx export default { title: 'originl component' component: OriginalComponent, } export const Default: Story<OriginalProps> = (args) => { return ( <OriginalComponent {...args} ref={{} as MutableRefObject<HTMLElement | undefined>} /> ); }; Default.args = { hoge: "", fuga: false, }; Default.storyName = 'OriginalComponent'
このように書き換えられます。
ここでControlsに書き換える上でいくつかの問題にあたりました。
1つ目はDefault関数の中で OriginalComponent
に ref
だけは Default.args
から受け取らず別で渡しているという点です。
これを Default.args
に渡して <OriginalComponent {...args} />
のようにしてしまうと画面から値を変更しようとしたときに Uncaught TypeError: Converting circular structure to JSON
という内容でJSON循環参照エラーが発生してしまい画面が表示されなくなってしまいました。
そのため上記コード例のように <OriginalComponent {...args} ref={{} as MutableRefObject<HTMLElement | undefined>} />
としてあげる必要があります。
念のためダメなパターンのコード全体を挙げておきます。
src/components/OriginalComponent/OriginalComponent.stories.tsx export default { title: 'originl component' component: OriginalComponent, } export const Default: Story<OriginalProps> = (args) => { return ( <OriginalComponent {...args} /> ); }; Default.args = { hoge: "", fuga: false, ref: {} as MutableRefObject<HTMLElement | undefined> }; Default.storyName = 'OriginalComponent'
このようにするとエラーでStorybookが表示されません。
なので分けるようにして対応しました。
2つ目はDefault.argsに渡すオブジェクトのプロパティに更にobjectを渡すとその中のbooleanがいい感じになってくれません。
例えば
Default.args = { fuga: false, };
のようにすると、Storybookが fuga
を boolean
と判断してトグルのUIとして表示してくれます。
しかし以下のようにすると、そうなってくれません。
Default.args = { fuga: { fuga2: false }, };
文字列として認識されてしまいます。
おそらくこれに関してはControls単体では上手くできず argTypes
というStorybookに型を推論させるための設定を行うことでできるのではないかなと考えてます。
個人的には簡単な構造であればKnobsと比べると比較的楽に実装でき、複雑な構造の型の値を変更して表示を確認したいとなると少しコーディングが増えるなというような印象でした。
もう少し色々と触ってみてControls周りの知見を増やしていきたいなと思います。