๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
React

Storybook + React, ์žฅ์ ๋ถ€ํ„ฐ ์„ค์น˜์™€ ๋ฌธ์„œ ์ž‘์„ฑ๋ฒ• ๊ฐ€์ด๋“œ

by LasBe 2024. 3. 12.
๋ฐ˜์‘ํ˜•

๐Ÿ“’ 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 ์†์„ฑ๋“ค์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  1. Boolean
    • ์‚ฌ์šฉ์ž์—๊ฒŒ ์ฒดํฌ๋ฐ•์Šค๋ฅผ ์ œ๊ณตํ•˜์—ฌ, true/false ๊ฐ’์„ ํ† ๊ธ€ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.
    • ์˜ˆ: { control: { type: 'boolean' } }
  2. Text
    • ๋ฌธ์ž์—ด์„ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ๋Š” ํ…์ŠคํŠธ ํ•„๋“œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
    • ์˜ˆ: { control: { type: 'text' } }
  3. Number
    • ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ๋Š” ํ•„๋“œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ตœ์†Ÿ๊ฐ’, ์ตœ๋Œ“๊ฐ’, ์Šคํ…(์ฆ๊ฐ ๋‹จ์œ„)์„ ์˜ต์…˜์œผ๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์˜ˆ: { control: { type: 'number', min: 0, max: 100, step: 5 } }
  4. Color
    • ์ƒ‰์ƒ ์„ ํƒ๊ธฐ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์ปดํฌ๋„ŒํŠธ์˜ ์ƒ‰์ƒ์„ ์‰ฝ๊ฒŒ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ค๋‹ˆ๋‹ค.
    • ์˜ˆ: { control: { type: 'color' } }
  5. Object
    • ๊ฐ์ฒด๋ฅผ JSON ํ˜•ํƒœ๋กœ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ๋Š” ํ…์ŠคํŠธ ์˜์—ญ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ณต์žกํ•œ ๊ฐ์ฒด ๊ตฌ์กฐ๋ฅผ props๋กœ ์ „๋‹ฌํ•  ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.
    • ์˜ˆ: { control: { type: 'object' } }
  6. Select
    • ์‚ฌ์šฉ์ž๊ฐ€ ๋ชฉ๋ก์—์„œ ์—ฌ๋Ÿฌ ์˜ต์…˜ ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ๋“œ๋กญ๋‹ค์šด ๋ฉ”๋‰ด๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
    • ์˜ˆ: { control: { type: 'select', options: ['Option 1', 'Option 2'] } }
  7. Radio
    • ์—ฌ๋Ÿฌ ์˜ต์…˜ ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ผ๋””์˜ค ๋ฒ„ํŠผ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. select์™€ ์œ ์‚ฌํ•˜์ง€๋งŒ UI๊ฐ€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.
    • ์˜ˆ: { control: { type: 'radio', options: ['Option 1', 'Option 2'] } }
  8. InlineRadio
    • ๋ผ๋””์˜ค ๋ฒ„ํŠผ์„ ์ธ๋ผ์ธ(์ˆ˜ํ‰)์œผ๋กœ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์„ ํƒ ์˜ต์…˜์„ ์˜†์œผ๋กœ ๋‚˜์—ดํ•ฉ๋‹ˆ๋‹ค.
    • ์˜ˆ: { control: { type: 'inline-radio', options: ['Option 1', 'Option 2'] } }
  9. Check
    • ์‚ฌ์šฉ์ž๊ฐ€ ์—ฌ๋Ÿฌ ์˜ต์…˜์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” ์ฒดํฌ๋ฐ•์Šค ๊ทธ๋ฃน์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
    • ์˜ˆ: { control: { type: 'check', options: ['Option 1', 'Option 2'] } }
  10. InlineCheck
    • ์ฒดํฌ๋ฐ•์Šค๋ฅผ ์ธ๋ผ์ธ(์ˆ˜ํ‰)์œผ๋กœ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ์˜ต์…˜์„ ์˜†์œผ๋กœ ๋‚˜์—ดํ•ฉ๋‹ˆ๋‹ค.
    • ์˜ˆ: { control: { type: 'inline-check', options: ['Option 1', 'Option 2'] } }
  11. Range
    • ์Šฌ๋ผ์ด๋”๋ฅผ ํ†ตํ•ด ์ˆซ์ž ๊ฐ’์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” ์ปจํŠธ๋กค์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ตœ์†Ÿ๊ฐ’, ์ตœ๋Œ“๊ฐ’, ์Šคํ…์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์˜ˆ: { control: { type: 'range', min: 0, max: 100, step: 5 } }
  12. Date
    • ๋‚ ์งœ๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š” ๋‹ฌ๋ ฅ UI๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
    • ์˜ˆ: { control: { type: 'date' } }
  13. 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์„ ์ •ํ•ด์ฃผ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

 

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€


์˜คํ”ˆ ์ฑ„ํŒ