Storybook基礎
Storybook基礎
Section titled “Storybook基礎”Storybookは、UIコンポーネントを独立して開発・テスト・ドキュメント化するためのツールです。
なぜStorybookが必要なのか
Section titled “なぜStorybookが必要なのか”従来の開発プロセスの課題
Section titled “従来の開発プロセスの課題”問題のある開発プロセス:
// アプリケーション内でコンポーネントを開発function App() { return ( <div> <Button>通常のボタン</Button> <Button variant="primary">プライマリボタン</Button> {/* 問題点: - アプリケーション全体を起動する必要がある - 他のコンポーネントに影響を受ける - コンポーネントの状態を簡単に確認できない - ドキュメントが別途必要 */} </div> );}Storybookの解決:
// Storybookでコンポーネントを独立して開発export default { title: 'Components/Button', component: Button,};
export const Default = { args: { children: '通常のボタン', },};
export const Primary = { args: { variant: 'primary', children: 'プライマリボタン', },};// メリット:// - アプリケーション全体を起動する必要がない// - コンポーネントを独立して開発・テストできる// - 様々な状態を簡単に確認できる// - ドキュメントが自動生成されるメリット:
- 独立した開発: アプリケーション全体を起動せずにコンポーネントを開発
- 視覚的なテスト: 様々な状態を簡単に確認
- ドキュメント化: コンポーネントの使用方法を自動生成
- チーム協業: デザイナーと開発者の連携が容易
Storybookのインストール
Section titled “Storybookのインストール”# ReactプロジェクトにStorybookを追加npx storybook@latest init
# 手動インストールnpm install --save-dev @storybook/react @storybook/react-webpack5npm install --save-dev storybook基本的なストーリー
Section titled “基本的なストーリー”import type { Meta, StoryObj } from '@storybook/react';import { Button } from './Button';
const meta: Meta<typeof Button> = { title: 'Components/Button', component: Button, tags: ['autodocs'], argTypes: { variant: { control: 'select', options: ['primary', 'secondary', 'danger'], }, size: { control: 'select', options: ['small', 'medium', 'large'], }, },};
export default meta;type Story = StoryObj<typeof Button>;
export const Default: Story = { args: { children: 'Button', },};
export const Primary: Story = { args: { variant: 'primary', children: 'Primary Button', },};
export const Secondary: Story = { args: { variant: 'secondary', children: 'Secondary Button', },};コンポーネントの実装
Section titled “コンポーネントの実装”import React from 'react';
interface ButtonProps { variant?: 'primary' | 'secondary' | 'danger'; size?: 'small' | 'medium' | 'large'; children: React.ReactNode; onClick?: () => void; disabled?: boolean;}
export const Button: React.FC<ButtonProps> = ({ variant = 'primary', size = 'medium', children, onClick, disabled = false,}) => { const baseStyles = 'font-semibold rounded transition-colors'; const variantStyles = { primary: 'bg-blue-500 text-white hover:bg-blue-600', secondary: 'bg-gray-200 text-gray-800 hover:bg-gray-300', danger: 'bg-red-500 text-white hover:bg-red-600', }; const sizeStyles = { small: 'px-2 py-1 text-sm', medium: 'px-4 py-2 text-base', large: 'px-6 py-3 text-lg', };
return ( <button className={`${baseStyles} ${variantStyles[variant]} ${sizeStyles[size]}`} onClick={onClick} disabled={disabled} > {children} </button> );};インタラクションのテスト
Section titled “インタラクションのテスト”import { expect, userEvent, within } from '@storybook/test';import { Button } from './Button';
export const WithInteraction: Story = { args: { children: 'Click me', }, play: async ({ canvasElement }) => { const canvas = within(canvasElement); const button = canvas.getByRole('button');
await userEvent.click(button); await expect(button).toHaveTextContent('Clicked!'); },};デコレーターの使用
Section titled “デコレーターの使用”export const decorators = [ (Story) => ( <div style={{ padding: '20px', backgroundColor: '#f5f5f5' }}> <Story /> </div> ),];
// グローバルパラメータexport const parameters = { actions: { argTypesRegex: '^on[A-Z].*' }, controls: { matchers: { color: /(background|color)$/i, date: /Date$/, }, },};実践例: 複雑なコンポーネント
Section titled “実践例: 複雑なコンポーネント”import type { Meta, StoryObj } from '@storybook/react';import { Card } from './Card';
const meta: Meta<typeof Card> = { title: 'Components/Card', component: Card, tags: ['autodocs'],};
export default meta;type Story = StoryObj<typeof Card>;
export const Default: Story = { args: { title: 'Card Title', description: 'This is a card description', image: 'https://via.placeholder.com/300', },};
export const WithAction: Story = { args: { title: 'Card with Action', description: 'This card has an action button', image: 'https://via.placeholder.com/300', actionLabel: 'Learn More', onAction: () => alert('Action clicked!'), },};
export const Loading: Story = { args: { loading: true, },};Storybookのポイント:
- 独立した開発: アプリケーション全体を起動せずにコンポーネントを開発
- 視覚的なテスト: 様々な状態を簡単に確認
- ドキュメント化: コンポーネントの使用方法を自動生成
- チーム協業: デザイナーと開発者の連携が容易
Storybookは、コンポーネント駆動開発(CDD)を実現するための強力なツールです。