OPEN HYPER STEP
← 목록으로 (stack-analysis)
STACK-ANALYSIS · 26 / 90
stack-analysis
CHAPTER 26 / 90
읽기 약 2
FUNCTION

스토리북 디자인 시스템: 컴포넌트 카탈로그


핵심 개념

Storybook 7+·디자인 토큰·시각 회귀·Chromatic — 프로덕션 디자인 시스템.

본문

Storybook 7+ 셋업

BASH📋 코드 (2줄)
pnpm dlx storybook@latest init
pnpm add -D @storybook/addon-a11y @chromatic-com/storybook
TYPESCRIPT📋 코드 (15줄)
// .storybook/main.ts
import type { StorybookConfig } from '@storybook/nextjs';

const config: StorybookConfig = {
  stories: ['../{components,app}/**/*.stories.@(ts|tsx|mdx)'],
  addons: [
    '@storybook/addon-essentials',
    '@storybook/addon-a11y',
    '@chromatic-com/storybook',
  ],
  framework: '@storybook/nextjs',
  docs: { autodocs: 'tag' },
};

export default config;

디자인 토큰 페이지

TSX📋 코드 (27줄)
// stories/Tokens/Colors.mdx
import { Meta, ColorPalette, ColorItem } from '@storybook/blocks';

<Meta title="Design Tokens / Colors" />

# 색상 토큰

<ColorPalette>
  <ColorItem
    title="Brand"
    subtitle="브랜드 색상"
    colors={{
      'brand-50':  '#eef2ff',
      'brand-500': '#6366f1',
      'brand-900': '#312e81',
    }}
  />
  <ColorItem
    title="Semantic"
    subtitle="의미 색상"
    colors={{
      success: '#10b981',
      warning: '#f59e0b',
      danger:  '#ef4444',
    }}
  />
</ColorPalette>

컴포넌트 Story

TYPESCRIPT📋 코드 (73줄)
// components/Button.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { Button } from './Button';

const meta = {
  title: 'Components/Button',
  component: Button,
  parameters: {
    layout: 'centered',
    docs: {
      description: {
        component: '주요 액션 버튼. 4가지 variant + 3가지 size.',
      },
    },
  },
  tags: ['autodocs'],
  argTypes: {
    variant: {
      control: 'select',
      options: ['primary', 'secondary', 'danger', 'ghost'],
      description: '시각적 강도',
    },
    size: {
      control: 'radio',
      options: ['sm', 'md', 'lg'],
    },
  },
} satisfies Meta<typeof Button>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Primary: Story = {
  args: { variant: 'primary', children: '주요' },
};

export const AllVariants: Story = {
  render: (args) => (
    <div className="flex gap-2">
      <Button variant="primary">Primary</Button>
      <Button variant="secondary">Secondary</Button>
      <Button variant="danger">Danger</Button>
      <Button variant="ghost">Ghost</Button>
    </div>
  ),
};

export const AllSizes: Story = {
  render: () => (
    <div className="flex items-center gap-2">
      <Button size="sm">Small</Button>
      <Button size="md">Medium</Button>
      <Button size="lg">Large</Button>
    </div>
  ),
};

export const Loading: Story = {
  args: { variant: 'primary', isLoading: true, children: '저장 중' },
};

export const A11yTest: Story = {
  args: { variant: 'primary', children: '확인' },
  parameters: {
    a11y: {
      config: {
        rules: [
          { id: 'color-contrast', enabled: true },
        ],
      },
    },
  },
};

Interaction Tests (play function)

TYPESCRIPT📋 코드 (12줄)
import { userEvent, within, expect } from '@storybook/test';

export const ClickTest: Story = {
  args: { variant: 'primary', children: '클릭' },
  play: async ({ canvasElement, args }) => {
    const canvas = within(canvasElement);
    const btn = canvas.getByRole('button');

    await userEvent.click(btn);
    expect(btn).toHaveFocus();
  },
};

Chromatic — 시각 회귀

BASH📋 코드 (11줄)
# 자동 배포 + 스냅샷 비교
pnpm dlx chromatic --project-token=<token>


# CI/CD 통합
# .github/workflows/chromatic.yml
- name: Publish to Chromatic
  uses: chromaui/action@v1
  with:
    projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
    onlyChanged: true   # 변경된 컴포넌트만

Decorators (Provider 래핑)

TYPESCRIPT📋 코드 (29줄)
// .storybook/preview.tsx
import type { Preview } from '@storybook/react';
import { ThemeProvider } from 'next-themes';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

const queryClient = new QueryClient();

const preview: Preview = {
  decorators: [
    (Story) => (
      <ThemeProvider attribute="class">
        <QueryClientProvider client={queryClient}>
          <Story />
        </QueryClientProvider>
      </ThemeProvider>
    ),
  ],
  globalTypes: {
    theme: {
      description: '테마',
      defaultValue: 'light',
      toolbar: {
        items: ['light', 'dark'],
      },
    },
  },
};

export default preview;

다음 모듈

CH.27~30 "번들링·도구" — Vite·ESLint·모노레포.


AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude

무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6

내 코드의 Storybook 디자인 시스템 부분을 분석해서
실전 분석 + 개선 우선순위를 알려줘.
ChatGPT

무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro

Storybook 디자인 시스템 관련 인기 라이브러리/패턴 5개를
비교 분석해서 패턴 추출를 알려줘.
Gemini

무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro

내 프로젝트 전체에서 Storybook 디자인 시스템
최적화 가능 위치를 보고해줘.
Grok

무료: Grok 4.1 / SuperGrok $30/mo

2026년 한국 프론트엔드 시장의
Storybook 디자인 시스템 트렌드를 솔직히 알려줘.

⭐ 이것만 기억하세요
스토리북 디자인 시스템: 컴포넌트 카탈로그 이 3가지만 확실히 잡으세요
1.Storybook = 컴포넌트 카탈로그 + 디자인 토큰 + 인터랙션 테스트
2.Chromatic으로 시각 회귀 자동화 — PR마다 스냅샷 비교
3.Decorators로 Provider 래핑 — 실제 앱과 동일 환경


공유하기
진행도 26 / 90