π Storybook
Storybookμ UI μ»΄ν¬λνΈλ₯Ό κ°λ°, ν μ€νΈ λ° λ¬ΈμννκΈ° μν μ€ν μμ€ λꡬμ λλ€.
κ°λ°ν κ³΅ν΅ μ»΄ν¬λνΈ νΉμ λμμΈ μμ€ν μ ν μ€νΈνκ³ μκ°μ μΌλ‘ νμΈν μ μλ νκ²½μ μ 곡ν©λλ€.
μ΄λ²μ μ μ¬ κ³΅ν΅ μ»΄ν¬λνΈλ₯Ό μ€κ³νκ³ μ¬λ¬ λ¬Έμν ν΄μ κ³ λ―Όνλ€ κ²°κ΅ μ€ν 리λΆμ μ ννκ² λμμ΅λλ€.
λ¨ ν λ²λ§ μ€ν 리 νμΌκ³Ό mdx λ¬Έμ μμ λ₯Ό μμ±ν΄ λκ³ λ°°ν¬ μλνκΉμ§ ν΄λμΌλ μκ°νλ κ²λ³΄λ€ ν° μ΄λ €μμ μμκ³ λ§μ‘±λλ κ΅μ₯ν λμμ΅λλ€.
κ·ΈλΌ μ€ν 리λΆμ μ₯μ κ³Ό μ¬μ©λ°©λ²μ λν΄ μκ°ν©λλ€.
π Storybook μ₯μ
π μκ°μ ν μ€νΈ
λ°±λ¬Έμ΄ λΆμ΄μΌκ²¬.
κ°κ°μ μ€ν 리λ₯Ό ν΅ν΄ μ»΄ν¬λνΈλ€μ propsλ₯Ό μ§μ μ‘°μνλ©° μκ°μ μΌλ‘ νμΈν μ μλ νκ²½μ μ 곡ν©λλ€.
λ€μν μνμμ μ»΄ν¬λνΈκ° μ΄λ»κ² 보μ΄λμ§ λ―Έλ¦¬ νμΈνμ¬ λμμΈμ μΌκ΄μ±μ μ μ§ν μ μλλ‘ λμ΅λλ€.
λν νλ‘ νΈ κ°λ°μ΄ μ ννκ² λ¬΄μμΈμ§ λͺ¨λ₯΄λ μΈμμκ² νΉμ μ»΄ν¬λνΈλ₯Ό κ°λ°νλ€κ³ μ€λͺ νλ κ²μ΄ λκ°ν λκ° νλ λ²μ΄ μλμλλ°, κ·Έλ₯ μ€λͺ μμ΄ λ λμΌλ‘ νμΈμμΌ μ€ μ μλ€λ μ₯μ λ μμ΅λλ€.
π λ 립μ μΈ λΆλ¦¬
μ¬λ΄μμ 곡ν΅μ μΌλ‘ μ¬μ©νλ μ»΄ν¬λνΈλ€μ μ μν΄ Storybookμ λ±λ‘νλ € νλ€λ©΄, λλ©μΈμ μκ΄μμ΄ μ΄λ ν νλ‘μ νΈμμλ μ¬μ©ν μ μμ΄μΌ ν©λλ€.
κ·Έλ¬κΈ° μν΄μ μ»΄ν¬λνΈλ νΉμ κ΄μ¬μ¬μ μμ‘΄μ±λ€μ λͺ¨λ μ κ±°ν΄ λ²μ©μ±μ΄ λκ³ λ 립μ μ΄μ΄μΌ ν©λλ€.
μ΄λ κ² μ»΄ν¬λνΈλ€μ μ€κ³νλ€ λ³΄λ©΄ μμ°μ€λ μ¬μ¬μ©μ±μ΄ λμ μ»΄ν¬λνΈλ₯Ό λ§λ€ μ μλ μ¬κ³ λ ₯κ³Ό μ€λ ₯μ΄ μ μ°¨ ν₯μλ©λλ€.
π μ μ§λ³΄μ
μ»΄ν¬λνΈκ° λ 립μ μ΄λΌλ κ²μ μ½λλ₯Ό μ§μ€νν΄, ν κ³³μμ κ΄λ¦¬ν μ μλ€λ μμ²λ μ₯μ μ΄ μμ΅λλ€.
μ΄μ μ§μ€ν λ μ½λλ₯Ό λ°°ν¬ ν μ² μ ν λ²μ κ΄λ¦¬λ₯Ό ν¨μΌλ‘μ¨ μΌκ΄μ± μλ μ μ§λ³΄μκ° κ°λ₯ν΄μ§λλ€.
π λ¬Έμν
μ€ν 리λΆμ μ»΄ν¬λνΈμ λν λ¬Έμλ₯Ό μλμΌλ‘ μμ±νλ©°, μ¬μ©μμκ² μ»΄ν¬λνΈμ Propsμ μ¬μ©λ², μμ λ₯Ό μ½κ² μ 곡ν μ μμ΅λλ€.
λλΆμ λ΄κ° λ§λ€κ±°λ λ€λ₯Έ μ¬λμ΄ λ§λ μ»΄ν¬λνΈλ€μ λ μ½κ² νμΈνκ³ μ¬μ©ν μ μκ² λ©λλ€.
π Storybook μ€μΉ
$ npx storybook@latest init
μ λͺ λ Ήμ΄λ‘ νλ‘μ νΈ λ£¨νΈμμ μ€ν 리λΆμ μ€μΉνλ©΄ λ€μκ³Ό κ°μ ν΄λ κ΅¬μ‘°κ° μλμΌλ‘ ꡬμ±λ©λλ€.
package.json νμΌμλ μ€ν 리λΆμ μ€ννκ³ λΉλν μ μλ λͺ λ Ήμ΄λ€μ΄ μΆκ°λ©λλ€.
κ·Έλ¦¬κ³ .storybook
ν΄λ μλμλ μ€ν 리λΆμ ꡬμ±νλ μ€μ νμΌμ΄ μμΉνκ² λ©λλ€.
μ¬κΈ°μ stories
μμ±μ λ°°μ΄ κ°μλ μ€ν 리 νμΌμ μΈμν κ²½λ‘λ₯Ό μ κ³΅ν΄ μ£Όλ©΄ λ©λλ€.
π Story μμ± λ°©λ²
μμμ src κ²½λ‘μ μλ μ€ν 리 νμΌλ€μ μ½μ΄μ€λλ‘ μ€μ ν΄μ ν΄λΉ μμΉμ μ»΄ν¬λνΈμ μ€ν 리 νμΌμ μμ±ν΄ μ£Όμμ΅λλ€.
κ·Έ ν κ°λ¨νκ² childrenκ³Ό backgroundColorλ₯Ό propsλ‘ λ°λ λ²νΌ μ»΄ν¬λνΈλ₯Ό λ§λ€μ΄ μ£Όμμ΅λλ€.
// src/components/Mybutton.tsx
import React from 'react';
export const MyButton = (props: {
children: React.ReactNode;
backgroundColor?: string;
}) => {
return (
<button style={{ backgroundColor: props.backgroundColor }}>
{props.children}
</button>
);
};
κ·Έλ€μ ν΄λΉ μ»΄ν¬λνΈμ μ€ν 리 νμΌμ λ€μκ³Ό κ°μ΄ μμ±νμ΅λλ€.
import { MyButton } from './MyButton';
const meta = {
title: 'MyComponent/MyButton',
component: MyButton,
argTypes: {
backgroundColor: { control: 'color' },
},
};
export default meta;
export const Primary = {
args: {
children: 'Button',
backgroundColor: '#fff',
},
};
μμ±μ λ§μΉ ν npm run storybook
λͺ
λ Ήμ΄λ‘ μ€ν 리λΆμ μ€ννλ©΄ μμ±ν μ»΄ν¬λνΈ μ€ν 리 λ¬Έμλ₯Ό νμΈν μ μμ΅λλ€.
μμμ μμ±ν μ€ν 리 λ¬Έμμ μ£Όμν κ°μ²΄μ μμ±λ€μ λ€μκ³Ό κ°μ΅λλ€.
π const meta = { ... };
meta
κ°μ²΄λ μ€ν 리μ λ©ν μ 보λ₯Ό μ μν©λλ€.title: 'MyComponent/MyButton'
: νμ¬ μ€ν 리μ μ λͺ©μ μ μν©λλ€.
μ΄λ Storybookμμ μ€ν 리μ μμΉ λ° κ΅¬μ‘°λ₯Ό κ²°μ νλ λ° μ¬μ©λ©λλ€./
λ‘ μ€ν 리 κ° κ³μΈ΅ ꡬ쑰λ₯Ό μ€μ ν μ μμ΅λλ€.component: MyButton
: νμ¬ μ€ν 리μμ μ¬μ©λλ μ»΄ν¬λνΈλ₯Ό μ§μ ν©λλ€.argTypes: { ... }
: μ»΄ν¬λνΈμ μΈμ(Props)λ₯Ό μ§μ μ‘°μν μ μλλ‘ μ€μ ν μ μμ΅λλ€.
π export const Primary = { ... };
Primary
λΌλ μ€ν 리λ₯Ό μ μν©λλ€.args: { children: 'Button', backgroundColor: '#fff' }
:Primary
μ€ν 리μ κΈ°λ³Έ μΈμλ₯Ό μ μν©λλ€. μ¦,MyButton
μ»΄ν¬λνΈμ μ λ¬λλ Props κ°μ λλ€. μ¬κΈ°μλchildren
μ 'Button' λ¬Έμμ΄μ,backgroundColor
μλ#fff
λ₯Ό κΈ°λ³Έ κ°μΌλ‘ μ€μ νκ³ μμ΅λλ€.
π argTypes Control Types
λ²νΌ μ»΄ν¬λνΈμμ argTypesμ control μμ±μ colorλ₯Ό μ§μ ν΄ μμ κ°μ΄ μ»¬λ¬ νΌμ»€λ₯Ό μ¬μ©ν΄ propsλ₯Ό μ‘°μν μ μμμ΅λλ€.
μ΄μ κ°μ΄ μ»΄ν¬λνΈλ₯Ό μ§κ΄μ μΌλ‘ μ‘°μν μ μλλ‘ λλ μ¬λ¬ κ°μ§ control μμ±λ€μ λ€μκ³Ό κ°μ΅λλ€.
- Boolean
- μ¬μ©μμκ² μ²΄ν¬λ°μ€λ₯Ό μ 곡νμ¬, true/false κ°μ ν κΈ ν μ μκ² ν©λλ€.
- μ:
{ control: { type: 'boolean' } }
- Text
- λ¬Έμμ΄μ μ λ ₯ν μ μλ ν μ€νΈ νλλ₯Ό μ 곡ν©λλ€.
- μ:
{ control: { type: 'text' } }
- Number
- μ«μλ₯Ό μ λ ₯ν μ μλ νλλ₯Ό μ 곡ν©λλ€. μ΅μκ°, μ΅λκ°, μ€ν (μ¦κ° λ¨μ)μ μ΅μ μΌλ‘ μ€μ ν μ μμ΅λλ€.
- μ:
{ control: { type: 'number', min: 0, max: 100, step: 5 } }
- Color
- μμ μ νκΈ°λ₯Ό μ 곡ν©λλ€. μ¬μ©μκ° μ»΄ν¬λνΈμ μμμ μ½κ² λ³κ²½ν μ μκ² ν΄ μ€λλ€.
- μ:
{ control: { type: 'color' } }
- Object
- κ°μ²΄λ₯Ό JSON ννλ‘ μ λ ₯ν μ μλ ν μ€νΈ μμμ μ 곡ν©λλ€. 볡μ‘ν κ°μ²΄ ꡬ쑰λ₯Ό propsλ‘ μ λ¬ν λ μ μ©ν©λλ€.
- μ:
{ control: { type: 'object' } }
- Select
- μ¬μ©μκ° λͺ©λ‘μμ μ¬λ¬ μ΅μ μ€ νλλ₯Ό μ νν μ μκ² νλ λλ‘λ€μ΄ λ©λ΄λ₯Ό μ 곡ν©λλ€.
- μ:
{ control: { type: 'select', options: ['Option 1', 'Option 2'] } }
- Radio
- μ¬λ¬ μ΅μ
μ€ νλλ₯Ό μ νν μ μλ λΌλμ€ λ²νΌμ μ 곡ν©λλ€.
select
μ μ μ¬νμ§λ§ UIκ° λ€λ¦ λλ€. - μ:
{ control: { type: 'radio', options: ['Option 1', 'Option 2'] } }
- μ¬λ¬ μ΅μ
μ€ νλλ₯Ό μ νν μ μλ λΌλμ€ λ²νΌμ μ 곡ν©λλ€.
- InlineRadio
- λΌλμ€ λ²νΌμ μΈλΌμΈ(μν)μΌλ‘ νμν©λλ€. μ ν μ΅μ μ μμΌλ‘ λμ΄ν©λλ€.
- μ:
{ control: { type: 'inline-radio', options: ['Option 1', 'Option 2'] } }
- Check
- μ¬μ©μκ° μ¬λ¬ μ΅μ μ μ νν μ μλ 체ν¬λ°μ€ κ·Έλ£Ήμ μ 곡ν©λλ€.
- μ:
{ control: { type: 'check', options: ['Option 1', 'Option 2'] } }
- InlineCheck
- 체ν¬λ°μ€λ₯Ό μΈλΌμΈ(μν)μΌλ‘ νμν©λλ€. μ¬λ¬ μ΅μ μ μμΌλ‘ λμ΄ν©λλ€.
- μ:
{ control: { type: 'inline-check', options: ['Option 1', 'Option 2'] } }
- Range
- μ¬λΌμ΄λλ₯Ό ν΅ν΄ μ«μ κ°μ μ νν μ μλ 컨νΈλ‘€μ μ 곡ν©λλ€. μ΅μκ°, μ΅λκ°, μ€ν μ μ€μ ν μ μμ΅λλ€.
- μ:
{ control: { type: 'range', min: 0, max: 100, step: 5 } }
- Date
- λ μ§λ₯Ό μ νν μ μλ λ¬λ ₯ UIλ₯Ό μ 곡ν©λλ€.
- μ:
{ control: { type: 'date' } }
- File
- νμΌμ μ λ‘λν μ μλ μ λ ₯ νλλ₯Ό μ 곡ν©λλ€. νμ©νλ νμΌ νμ μ μ€μ ν μ μμ΅λλ€.
- μ:
{ control: { type: 'file', accept: '.png,.jpg' } }
π mdxλ‘ λ¬Έμ μμ±
.storybook/main.ts νμΌμ mdx νμΌλ μΈμν μ μλλ‘ νμ΅λλ€.
μ€ν 리λΆμ Story νμΌλΏ μλλΌ mdx νμ₯μ νμΌλ‘λ λ¬Έμνλ₯Ό ν μ μλ κΈ°λ₯μ μ 곡ν©λλ€.
μ°μ μμν μ μμΌλ mdx νμΌμ λν μ€λͺ μ λ€μκ³Ό κ°μ΅λλ€.
π mdx νμΌμ΄λ
MDXλ Markdown κΈ°λ°μ λ¬Έμλ₯Ό νμ₯ν κ²μΌλ‘, React μ»΄ν¬λνΈλ₯Ό ν¬ν¨ν μ μλ λ§ν¬λ€μ΄ λ¬Έμ νμμ λλ€.
MDX νμΌμ JavaScriptμ JSX μ½λλ₯Ό ν¬ν¨νμ¬ λ λμ μ΄κ³ μΈν°λν°λΈ ν μ½ν μΈ λ₯Ό μμ±ν μ μκ² ν΄ μ€λλ€.
μ£Όλ‘ λ¬Έμ, λΈλ‘κ·Έ ν¬μ€νΈ, νλ‘μ νΈμ μ¬μ© μ€λͺ μ λ±μ μμ±ν λ μ¬μ©λ©λλ€.
νλ§λλ‘ λ§ν¬λ€μ΄ νμμ μ¬μ©νλ©΄μ 리μ‘νΈ μ»΄ν¬λνΈλ₯Ό λ λλ§ ν μ μλ λ¬Έμμ λλ€.
μ€ν λ¦¬λΆ νκ²½μ μ체μ μΌλ‘ μ€νλκΈ° λλ¬Έμ νΉμ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©ν μ»΄ν¬λνΈλ₯Ό μ€ν λ¦¬λ‘ λ§λλ € ν λ μ€λ₯κ° λ°μν μ μμ΅λλ€.
κ·Έλ΄ λ λ€λ₯Έ λ¬Έμν νλ μμν¬λ₯Ό μ¬μ©νμ§ μκ³ mdx νμμ μ΄μ©ν΄ μ€ν λ¦¬λΆ νκ²½ λ΄μμ λ¬Έμλ₯Ό νμΈν μ μλλ‘ ν©λλ€.
μμ κ°μ΄ μμ±νκ³ Metaμ μμ κ°μ΄ κ³μΈ΅κ΅¬μ‘°λ₯Ό μ ν΄ titleμ μ ν΄μ£Όλ©΄ λ€μκ³Ό κ°μ΄ νμλ©λλ€.
λκΈ