Storybook Addons는 개발자 경험을 향상시키는 플러그인입니다. 테스트, 문서화, 디버깅 등 다양한 기능을 제공합니다.
컴포넌트 문서를 자동 생성하고 MDX 지원
// .storybook/main.ts
addons: [
'@storybook/addon-essentials', // Docs 포함
]
// Story에서 autodocs 활성화
const meta: Meta<typeof Button> = {
title: 'UI/Button',
component: Button,
tags: ['autodocs'], // 자동 문서화
};이벤트 핸들러 호출을 Actions 패널에 로깅
// Story 정의
export const Default: Story = {
args: {
onClick: action('button-clicked'),
onHover: action('button-hovered'),
},
};
// 자동 액션 (naming convention)
const meta: Meta = {
argTypes: {
onClick: { action: 'clicked' },
onChange: { action: 'changed' },
},
};다양한 디바이스 크기에서 컴포넌트 테스트
// .storybook/preview.ts
export const parameters = {
viewport: {
viewports: {
mobile: {
name: 'Mobile',
styles: { width: '375px', height: '667px' },
},
tablet: {
name: 'Tablet',
styles: { width: '768px', height: '1024px' },
},
desktop: {
name: 'Desktop',
styles: { width: '1920px', height: '1080px' },
},
},
},
};다양한 배경색에서 컴포넌트 확인
// .storybook/preview.ts
export const parameters = {
backgrounds: {
default: 'light',
values: [
{ name: 'light', value: '#ffffff' },
{ name: 'dark', value: '#1a1a1a' },
{ name: 'blue', value: '#3b82f6' },
],
},
};
// Story별 설정
export const OnDark: Story = {
parameters: {
backgrounds: { default: 'dark' },
},
};Testing Library로 사용자 인터랙션 시뮬레이션
import { userEvent, within } from '@storybook/test';
export const FilledForm: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
// 입력 필드 찾기
const input = canvas.getByRole('textbox');
const button = canvas.getByRole('button');
// 사용자 인터랙션 시뮬레이션
await userEvent.type(input, 'Hello World');
await userEvent.click(button);
// 결과 확인
await expect(canvas.getByText('Success')).toBeInTheDocument();
},
};WCAG 접근성 기준 자동 검사
// 설치
npm install --save-dev @storybook/addon-a11y
// .storybook/main.ts
addons: ['@storybook/addon-a11y']
// .storybook/preview.ts
export const parameters = {
a11y: {
config: {
rules: [
{ id: 'color-contrast', enabled: true },
{ id: 'label', enabled: true },
],
},
},
};// LoginForm.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { userEvent, within, expect } from '@storybook/test';
import { LoginForm } from './LoginForm';
const meta: Meta<typeof LoginForm> = {
title: 'Forms/LoginForm',
component: LoginForm,
tags: ['autodocs'],
parameters: {
// Backgrounds 설정
backgrounds: {
default: 'light',
values: [
{ name: 'light', value: '#f5f5f5' },
{ name: 'dark', value: '#1a1a1a' },
],
},
// Viewport 설정
viewport: {
defaultViewport: 'mobile1',
},
// A11y 설정
a11y: {
config: {
rules: [
{ id: 'label', enabled: true },
{ id: 'color-contrast', enabled: true },
],
},
},
},
argTypes: {
// Actions 설정
onSubmit: { action: 'form-submitted' },
onError: { action: 'validation-error' },
},
};
export default meta;
type Story = StoryObj<typeof LoginForm>;
// 기본 Story
export const Default: Story = {};
// Interactions로 자동 입력
export const FilledForm: Story = {
play: async ({ canvasElement, args }) => {
const canvas = within(canvasElement);
// 필드 찾기
const emailInput = canvas.getByLabelText('Email');
const passwordInput = canvas.getByLabelText('Password');
const submitButton = canvas.getByRole('button', { name: /submit/i });
// 입력 시뮬레이션
await userEvent.type(emailInput, 'user@example.com');
await userEvent.type(passwordInput, 'password123');
// 제출
await userEvent.click(submitButton);
// 검증
await expect(args.onSubmit).toHaveBeenCalledWith({
email: 'user@example.com',
password: 'password123',
});
},
};
// 에러 상태
export const WithErrors: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
// 빈 상태로 제출
const submitButton = canvas.getByRole('button');
await userEvent.click(submitButton);
// 에러 메시지 확인
await expect(canvas.getByText(/email is required/i)).toBeInTheDocument();
},
};
// 다크모드
export const DarkMode: Story = {
parameters: {
backgrounds: { default: 'dark' },
},
};
// 모바일 뷰
export const MobileView: Story = {
parameters: {
viewport: {
defaultViewport: 'mobile1',
},
},
};npm install --save-dev @storybook/addon-a11y npx storybook add @storybook/addon-a11y
// .storybook/main.ts addons: [ '@storybook/addon-a11y', ]