이 글은 누구를 위한 것인가
- Storybook은 있는데 디자인 시스템 문서로 활용하지 못하는 팀
- Figma 토큰 변경이 코드에 자동으로 반영되길 원하는 팀
- 디자인 변경 시 컴포넌트 리그레션을 자동으로 감지하고 싶은 팀
들어가며
Storybook은 컴포넌트 샌드박스가 아니라 디자인 시스템의 "살아있는 문서"가 될 수 있다. Figma 토큰과 연동하면 디자이너가 토큰을 바꾸면 Storybook이 자동으로 업데이트된다.
이 글은 bluefoxdev.kr의 디자인 시스템 자동화 가이드 를 참고하여 작성했습니다.
1. Storybook 디자인 시스템 설정
// .storybook/main.ts
import type { StorybookConfig } from "@storybook/nextjs";
const config: StorybookConfig = {
stories: ["../src/**/*.stories.@(js|jsx|ts|tsx|mdx)"],
addons: [
"@storybook/addon-docs", // MDX 문서
"@storybook/addon-a11y", // 접근성 검사
"@storybook/addon-designs", // Figma 임베드
"storybook-design-token", // 디자인 토큰 뷰어
"@chromatic-com/storybook", // Chromatic 연동
],
framework: {
name: "@storybook/nextjs",
options: {},
},
};
export default config;
// .storybook/preview.ts
import type { Preview } from "@storybook/react";
import "../src/styles/globals.css"; // 디자인 토큰 CSS 변수
const preview: Preview = {
parameters: {
// Figma 디자인 자동 임베드
design: {
type: "figma",
url: "https://www.figma.com/file/...", // 프로젝트 URL
},
// 디자인 토큰 파일 위치
designToken: {
files: ["./public/design-tokens.json"],
},
},
globalTypes: {
theme: {
description: "테마",
defaultValue: "light",
toolbar: {
title: "Theme",
icon: "circlehollow",
items: ["light", "dark"],
dynamicTitle: true,
},
},
},
};
export default preview;
2. 컴포넌트 스토리 작성
// src/components/Button/Button.stories.tsx
import type { Meta, StoryObj } from "@storybook/react";
import { Button } from "./Button";
const meta: Meta<typeof Button> = {
title: "Components/Button",
component: Button,
// 자동 문서 생성
tags: ["autodocs"],
parameters: {
// 이 컴포넌트와 연결된 Figma 컴포넌트
design: {
type: "figma",
url: "https://www.figma.com/file/xxx?node-id=123",
},
// 접근성 규칙 설정
a11y: {
config: {
rules: [{ id: "color-contrast", enabled: true }],
},
},
},
argTypes: {
variant: {
control: "select",
options: ["primary", "secondary", "outline", "ghost"],
description: "버튼 스타일 변형",
table: {
type: { summary: "string" },
defaultValue: { summary: "primary" },
},
},
size: {
control: "radio",
options: ["sm", "md", "lg"],
},
loading: {
control: "boolean",
},
disabled: {
control: "boolean",
},
},
};
export default meta;
type Story = StoryObj<typeof Button>;
// 기본 스토리
export const Primary: Story = {
args: {
variant: "primary",
size: "md",
children: "주요 버튼",
},
};
// 모든 변형 한눈에 보기
export const AllVariants: Story = {
render: () => (
<div className="flex flex-wrap gap-4">
{(["primary", "secondary", "outline", "ghost"] as const).map((variant) => (
<Button key={variant} variant={variant}>{variant}</Button>
))}
</div>
),
};
// 로딩 상태
export const Loading: Story = {
args: { loading: true, children: "저장 중..." },
};
3. Figma → Style Dictionary → Storybook 자동화
# .github/workflows/design-tokens.yml
name: Sync Design Tokens
on:
push:
paths:
- 'design-tokens/**'
jobs:
sync-tokens:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: npm ci
- name: Build tokens
run: npx style-dictionary build
# tokens/global.json → dist/web/tokens.css, dist/ios/Tokens.swift, dist/android/colors.xml
- name: Run visual regression tests
run: npx chromatic --project-token=${{ secrets.CHROMATIC_TOKEN }}
- name: Create PR with token changes
uses: peter-evans/create-pull-request@v5
with:
title: "design-tokens: 토큰 자동 업데이트"
body: "Figma에서 동기화된 디자인 토큰 변경사항"
branch: "auto/design-token-sync"
마무리
Storybook + Figma 연동의 가장 큰 가치는 "Figma에서 보이는 것과 코드가 같은지 확인"하는 것이다. Chromatic으로 스크린샷을 비교하면 토큰 변경 시 의도치 않은 UI 변경을 PR 단계에서 잡을 수 있다. 이 파이프라인을 구축하면 "디자인 시스템과 프로덕션 UI의 괴리"를 자동으로 감지할 수 있다.