Storybook은 UI 컴포넌트를 독립적으로 개발, 테스트, 문서화할 수 있는 도구
기본적인 구조는 다음과 같다.
1) 프로젝트 용 컴포넌트 ui를 구현한다.
2) .stories.tsx 파일을 선언 후 해당 컴포넌트를 import 한 후, 상태별 시나리오를 작성한다.
3)
npm run storybook으로 실행하고 결과를 확인한다.
버튼 컴포넌트를 제작 후 스토리북으로 관리한다고 가정하자.
아래와 같은 구조를 통해 구현할 수 있다.
import type { Meta, StoryObj } from "@storybook/react"; // Storybook 타입 정의
import { 예시 } from "./Button"; // 우리가 만든 실제 컴포넌트 불러오기
// 1. 컴포넌트에 대한 공통 설정
const meta: Meta<typeof 예시> = {
title: "Category/예시", // 사이드바에 표시될 이름
component: 예시, // 어떤 컴포넌트를 보여줄 건지
tags: ["autodocs"], // 자동 문서화 지원
argTypes: {...}, // props 제어 설정
parameters: {...}, // 환경 설정 (옵션)
decorators: [...], // 공통 감싸기
};
export default meta; // 꼭 export 해야 Storybook이 이 파일을 인식함
// 2. 스토리 타입 정의 (StoryObj로부터 파생)
type Story = StoryObj<typeof 예시>;
// 3. 개별 스토리(상태) 정의: props 조합마다 하나씩
export const Default: Story = {
// 각 Story(상태)에서 컴포넌트에 전달할 props 값
args: {
...
},
};
밑으로는 각 항목에 대한 사용법이다.
// 1. 컴포넌트에 대한 공통 설정
const meta: Meta<typeof 예시> = {
title: "Category/예시", // 사이드바에 표시될 이름
component: 예시, // 어떤 컴포넌트를 보여줄 건지
tags: ["autodocs"], // 자동 문서화 지원
argTypes: {...}, // props 제어 설정
parameters: {...}, // 환경 설정 (옵션)
decorators: [...], // 공통 감싸기
};
export default meta; // 꼭 export 해야 Storybook이 이 파일을 인식함
meta 객체에 들어가는 항목 및 사용 방식은 다음과 같다.
| 항목 | 필수 | 설명 |
|---|---|---|
title | ✅ | 사이드바에 표시될 컴포넌트 이름 (그룹/이름 형태로 계층 구조 가능) |
component | ✅ | 어떤 컴포넌트를 테스트할 건지 (React 컴포넌트) |
tags | ❌ | "autodocs"를 넣으면 Docs 탭 자동 생성됨 |
argTypes | ❌ | 각 props를 어떻게 제어할지 (예: select, color, boolean 등) |
parameters | ❌ | 각 스토리의 동작 방식 제어 (예: 배경색, layout 등) |
decorators | ❌ | 모든 스토리에 공통적으로 적용할 감싸는 컴포넌트 |
args | ❌ | 모든 스토리에 기본으로 들어갈 props 값을 미리 지정 가능 |
아래의 항목들은 다양한 설정을 요구하기 때문에, 상세 내용을 별도로 정리하였다.
Storybook UI에서 props 값을 쉽게 바꿔볼 수 있도록 UI 컨트롤을 제공하는 부분이다.
실제 props에 해당하는 내용을 주로 적용하기 때문에 다양한 타입을 설정할 수 있다.
타입별 argTypes 설정 예시
1. string (문자열)
argTypes: {
label: {
control: "text",
},
}
| 결과 | 텍스트 입력창으로 label 값을 직접 입력 가능 |
2. boolean (불리언)
argTypes: {
disabled: {
control: "boolean",
},
}
| 결과 | 체크박스로 true / false 선택 가능 |
3. "union" (고정된 선택지)
argTypes: {
type: {
control: "select",
options: ["default", "second", "disable"],
},
}
| 결과 | 드롭다운으로 선택 가능 (select) |
💡 참고: "radio"로 바꾸면 라디오 버튼 형태로도 가능
control: "radio"
4. number (숫자)
argTypes: {
size: {
control: "number",
},
}
| 결과 | 숫자 조절 필드 + 화살표 버튼으로 값 변경 |
5. color (색상 선택)
argTypes: {
backgroundColor: {
control: "color",
},
}
| 결과 | 컬러 피커로 색상 선택 가능 |
6. action (함수 콜백)
argTypes: {
onClick: { action: "clicked" },
}
| 결과 | 버튼 클릭 시, Storybook Actions 탭에서 "clicked" 로그 표시 |
🔥 UI 상호작용을 추적할 때 매우 유용함
7. object, array
argTypes: {
user: {
control: "object",
},
items: {
control: "array",
},
}
| 결과 | 객체나 배열을 직접 조작할 수 있는 JSON 형태의 필드 제공 |
최종 정리
| 타입 | control | 설명 |
|---|---|---|
string | "text" | 텍스트 입력 |
boolean | "boolean" | 체크박스 |
| `"a" | "b"` | "select" / "radio" |
number | "number" | 숫자 필드 |
color | "color" | 색상 선택기 |
function | { action: "name" } | 클릭 이벤트 추적용 |
object | "object" | JSON 구조 |
array | "array" | 배열 형태 입력 |
Storybook에서 각 스토리마다 화면의 배치 방식, 배경색, 행동 기록 설정 등을 지정할 수 있는 옵션 객체이다.
예를 들어, 다크 모드의 배경과 기본 모드 두 가지에서 ui가 적용되는 모습을 보고 싶을 때,
parameters로 배경색을 자유롭게 지정하면 된다.
가장 많이 사용되는 layout 종류
| 옵션 값 | 설명 |
|---|---|
"centered" | 컴포넌트를 가운데 정렬 |
"padded" | 여백(padding)을 줘서 주변에 공간 추가 |
"fullscreen" | 여백 없이 꽉 채우는 레이아웃 (기본값) |
모든 스토리를 특정 컴포넌트로 감싸서 공통 스타일이나 기능을 적용할 수 있도록 하는 설정
컴포넌트를 Storybook에 보여줄 때, 공통 레이아웃, 테마, Context Provider 등을 자동으로 감싸주는 래퍼(wrapper) 기능
사용 예시
import { lightTheme } from "../src/themes";
const meta: Meta<typeof Button> = {
title: "Components/Button",
component: Button,
decorators: [
(Story) => (
<ThemeProvider theme={lightTheme}>
<Story />
</ThemeProvider>
),
],
};
이렇게 하면 실제 앱에서 쓰는 테마 설정을 Storybook에서도 그대로 반영 가능하다.(wa!)
개별 스토리에서 사용할 props 값을 설정하는 객체이다.
공통 props나 설정은 meta에서 지정하고,
각 스토리에서는 바뀌는 값만 args로 덮어쓰기(override)한다.
예를 들어, 각 타입 별로 배경색만 변하는 경우
진행하면 된다.