Storybookとは
Componentをカタログのように管理したり、ビジュアルリグレッションテストをしたりすることができる、オープンソースツールです。
StorybookでComponentを管理することで、下記のようなメリットがあります。
-
コンポーネント駆動開発(CDD)ができる
- Componentの状態を網羅的に確認しやすい
- デザイナーとの認識合わせがしやすい
- ビジュアルリグレッションテストを通して、デグレを検知することができる
準備
インストール
npx sb init
### 起動
yarn run storybook
基本的な書き方
Storybookはアドオンを追加することで、さまざまな拡張ができますが、
ベースとなる基本的な書き方のみご紹介します。
ファイルの作成
基本的にコンポーネントファイルと同階層に、同じ名前のstories.tsx|jsx|ts|tsx
ファイルを作成します。
メタデータ
stories
ファイルでは、Storybookのメタデータをdefault export
します。
import React, { ComponentProps } from 'react';
import { Meta, Story } from '@storybook/react';
import { Component } from './Component';
type Props = ComponentProps<typeof Component>;
const meta: Meta<Props> = {
title: 'Component', // カタログのタイトルになる部分。 スラ(/)で区切ると階層ができる。
component: Component, // ストーリーブック化するComponent
};
export default meta;
ストーリー
ストーリーを作成するには、名前つきexportを用います。
変数名がそのままStorybookに表示されます。
export const Default: Story = () => <Component />;
名前を変える
Storybookに表示される名前を変更したい時は、Story.storyName
の値を書き換えることで変更できます。
export const Default: Story = () => <Component />;
Default.storyName = "My Component" // スペース含んでもok!
ストーリーに引数を渡す
メタデータ、もしくはストーリー自体に引数を渡すことができます。
const meta: Meta<Props> = {
title: 'Component',
component: Component,
args: {
title: "タイトル"
}
};
export const Default: Story = (args)=> <Component {...args} />;
export const Default: Story = () => <Component />;
Default.args = {
title: "タイトル"
}
コントロールパネルを変更する
storybookのessentials
アドオンを使うことで、引数をコントロールパネルで操作できるようにすることができます。
また、その操作パネルをカスタマイズし、コンポーネントの状態をカスタマイズしやすい状態にすることも可能です。
パラメーターを設定する
viewportやbackgroundなど、storybookが持っている状態に対するパラメーターを設定することができます。
const meta: Meta<Props> = {
title: 'Component',
component: Component,
args: {
title: "タイトル"
},
parameters: {
viewports: {
small: {
name: 'iphone5/SE',
styles: {
width: '320px',
height: '568px',
},
},
},
backgrounds: {
values: [
{ name: 'red', value: '#f00' },
{ name: 'green', value: '#0f0' },
],
},
}
};
export const Default: Story = (args)=> <Component {...args} />;
decoratorsを追加する
ストーリーをラップするスタイルの変更ができます。
const meta: Meta<Props> = {
title: 'Component',
component: Component,
args: {
title: "タイトル"
},
decorators: [
(story) => (
<div
style={{
background: '#eee',
padding: '16px',
maxWidth: '300px',
}}
>
{story()}
</div>
),
],
};
export const Default: Story = (args)=> <Component {...args} />;
Storybookはめんどくさい...? 大変?
そうでもないです。
基本的にどのComponentに対しても書くことは一緒です。
そのため、エディタの機能を用いてスニペット化すると良いでしょう!
snippetのコードはこちら
{
"storybook": {
"scope": "javascript,typescript,typescriptreact,javascriptreact",
"prefix": ["storybook"],
"body": [
"import React, { ComponentProps } from 'react';",
"import { Meta, Story } from '@storybook/react';",
"import { $TM_FILENAME_BASE } from './$TM_FILENAME_BASE'",
"",
"type Props = ComponentProps<typeof $TM_FILENAME_BASE>;",
"",
"const meta: Meta<Props> = {",
" component: $TM_FILENAME_BASE ,",
" title: '$TM_FILENAME_BASE' ,",
" args: {",
" // ",
" },",
"};",
"",
"const Template: Story<Props> = (args) => <$TM_FILENAME_BASE {...args} />",
"",
"export const Default = Template.bind({});",
"",
"export default meta;"
],
"description": "storybook"
}
}