본문 바로가기

FRONTEND

[Storybook] Storybook에 대해서

출처: https://unsplash.com/ko/%EC%82%AC%EC%A7%84/K3x_AkLVTAo

해당 문서의 목적은 스토리북을 작성하는 방법에 대한 이해를 돕는데 있습니다.

프로젝트 설치

yarn install

 

프로젝트 실행

yarn storybook

 

스토리북 공식문서

 

Install Storybook

Storybook is a frontend workshop for building UI components and pages in isolation. Thousands of teams use it for UI development, testing, and documentation. It’s open source and free.

storybook.js.org

 


1. Story는 무엇인가?

스토리는 UI 컴포넌트가 특정 상태로 렌더링 된 형태를 말합니다. 즉, 하나의 컴포넌트는 상태(arguments) 값에 따라 여러 개의 스토리를 가질 수 있습니다.

 

예를 들어 다음의 Checkbox 컴포넌트는 label, checked, appearance 등의 arguments에 따라 3개의 스토리를 갖습니다. 각각의 경우를 Checkbox 컴포넌트에 대한 개별 스토리라고 할 수 있습니다.

 

UI 컴포넌트에 대한 다양한 스토리를 모은 문서는 파일 형태로 작성하며 *.stories.mdx, *.stories.tsx 등과 같은 이름으로 설정합니다.

 

실행 화면과 코드를 통해 살펴보겠습니다.

Checkbox 컴포넌트에 대한 각각의 스토리가 렌더링 된 화면

 

<!-- Checkbox.stories.mdx -->

import { Canvas, Meta, Story, ArgsTable } from '@storybook/addon-docs';
import Checkbox from './Checkbox';

<Meta title="MDX/Checkbox" component={Checkbox} />

export const Template = (args) => <Checkbox {...args} />;

<Canvas>
  <Story
    name="Unchecked"
    args={{
      label: 'Unchecked',
    }}>
    {Template.bind({})}
  </Story>
  <Story
    name="Checked"
    args={{
      label: 'Checked',
      checked: true
    }}>
    {Template.bind({})}
  </Story>
  <Story
    name="Secondary"
    args={{
      label: 'Secondary',
      checked: true,
      appearance: 'secondary',
    }}>
    {Template.bind({})}
  </Story>
</Canvas>

2. Story 문서 작성하기

기본적으로 스토리 파일은 두 가지 형태로 작성할 수 있습니다. MDXDocs Page[각주:1]입니다.

 

해당 프로젝트에서는 주로 MDX 형식을 사용할 것이므로 MDX에 대해 설명하겠습니다.

 

MDX

MDX는 JSX와 Markdown을 결합한 표준 파일 형식으로 Markdown 문서와 스토리를 하나의 페이지에서 작성할 수 있습니다.

 

전체 코드는 다음과 같습니다.

<!-- FillButton.stories.mdx -->

import { ArgsTable, Canvas, Meta, Story } from '@storybook/addon-docs';
import { FillButton } from './FillButton';

<Meta
  title="dkui/FillButton"
  component={FillButton}
  argTypes={{
    status: {
      control: {
        type: 'inline-radio',
      },
      description: 'Available options available to the Badge',
      options: ['enabled', 'disabled']
    },
    full: {
      control: {
        type: "boolean",
      },
    },
    outlined: {
      control: {
        type: "boolean",
      }
    },
    type: {
      control: {
        type: "inline-radio",
        options: ['button', 'submit'],
      },
    },
    preventEvent: {
      control: {
        type: "boolean",
      }
    },
    children: {
      control: {
        type: 'text',
      }
    },
    onClick: {
      action: 'clicked'
    }
  }}
/>

export const Template = (args) => <FillButton {...args} />


# Fill Button

특정 사용자에게 액션이나 콘텐츠를 제공하기 위해 Avatar를 사용합니다.

Avatar를 사용할 때는 사용자 이름이 _항상_ Avatar의 옆이나 툴팁에 보입니다.

<Canvas>
  <Story
    name="standard"
    args={{
      status: 'enabled',
      full: true,
      children: 'Fill Button',
      outlined: false,
      type: 'button',
      preventEvent: false
    }}
    parameters={{
      design: {
        type: 'figma',
        url: 'https://www.figma.com/file/Tt3Zu0zMhQ6nIVhIB6R2Ff/%EB%8C%80%EC%B6%9C%EB%B9%84%EA%B5%90-%EB%94%94%EC%9E%90%EC%9D%B8-%EC%8B%9C%EC%8A%A4%ED%85%9C?node-id=1555-6255&t=YboksdJ0pWOQHhFm-4',
        allowFullscreen: true,
      }
    }}
  >
    {Template.bind({})}
  </Story>
</Canvas>

<ArgsTable story="standard" />

### outlined

<Story
  name="outlined"
  args={{
    status: 'enabled',
    full: true,
    children: 'Fill Button',
    outlined: true,
    type: 'button',
    preventEvent: false
  }}
>
  {Template.bind({})}
</Story>

<ArgsTable story="outlined" />

 

MDX에서 스토리 작성은 Doc Blocks를 통해 가능합니다. 기본적으로 Doc Blocks은 스토리북에 내장되어 있는 addon-docs를 통해 가져올 수 있으며 Meta, Canvas, Story, ArgsTable 등이 있습니다.

 

해당 내용을 실행 화면과 코드를 통해 알아보겠습니다. 위의 코드를 실행시키면 다음과 같은 화면을 볼 수 있습니다. (실행 화면을 부분으로 나누어 각각에 대해 설명하였습니다.)

Storybook 실행 화면

① Markdown

Markdown 문법을 사용하여 스토리와 더불어 long-term 형태의 문서를 작성할 수 있습니다. 코드 블록은 제외한 어느곳에서나 Markdown 문법을 사용할 수 있습니다.

# Fill Button

특정 사용자에게 액션이나 콘텐츠를 제공하기 위해 Avatar를 사용합니다.

Avatar를 사용할 때는 사용자 이름이 _항상_ Avatar의 옆이나 툴팁에 보입니다.

 

② Meta

<Meta /> Doc Block에서는 스토리를 작성하는데 필요한 title, component, argsTypes, prameters, decorators 등의 값을 설정할 수 있습니다.

<Meta
  title="dkui/FillButton"
  component={FillButton}
  argTypes={{
    status: {
      control: {
        type: 'inline-radio',
      },
      description: 'Available options available to the Badge',
      options: ['enabled', 'disabled']
    },
    full: {
      control: {
        type: "boolean",
      },
    },
    outlined: {
      control: {
        type: "boolean",
      }
    },
    type: {
      control: {
        type: "inline-radio",
        options: ['button', 'submit'],
      },
    },
    preventEvent: {
      control: {
        type: "boolean",
      }
    },
    children: {
      control: {
        type: 'text',
      }
    },
    onClick: {
      action: 'clicked'
    }
  }}
/>

 

- title 

스토리북 실행 시 왼쪽 사이드바에 나타나는 컴포넌트에 대한 계층 구조를 나타냅니다. 선택 값이며 고유해야 합니다. 지정하지 않으면 자동으로 생성됩니다.

 

- component

필수 값입니다. 해당 스토리 파일에서 사용할 컴포넌트를 말합니다.

 

- argsTypes

argsTypes은 스토리북의 args(arguments)를 구체화하는 일급객체를 활용한 프로퍼티 입니다. 주로 ArgsTable Doc Block를 구현하는데 사용합니다. argsTypes 객체의 키(key)가 argsTable Doc Block의 Name 칼럼이 됩니다. argsTypes 객체의 값(value)은 description, default, controls 등을 키(key)로 하는 또다른 객체가 포함됩니다.

 

- decorators

스토리를 렌더링 할 때, 추가적으로 적용해야할 필요가 있을 때 사용합니다. 주로 여백을 추가하는 것과 같이 markup을 위해 사용하거나 styled-components 와 같은 특정 프레임워크 라이브러리의 추가적인 기능을 적용하기 위해 사용합니다.(예를들어, styled-components ThemeProvider 적용하는 경우) 적용되는 범위에 따라 3개의 계층으로 나뉩니다.(story decorators, component decorators, global decorators)

 

- prameters

스토리에 대한 정적 메타데이터 집합입니다. 구체적으로 툴바의 background color, viewport, design 등을 설정할 수 있습니다. decorators와 마찬가지로 적용되는 범위에 따라 3개의 계층으로 나뉩니다.(story parameters, component parameters, global parameters)

 

③ Canvas & Story & Template

<Canvas>
  <Story
    name="standard"
    args={{
      status: 'enabled',
      full: true,
      children: 'Fill Button',
      outlined: false,
      type: 'button',
      preventEvent: false
    }}
    parameters={{
      design: {
        type: 'figma',
        url: 'https://www.figma.com/file/Tt3Zu0zMhQ6nIVhIB6R2Ff/%EB%8C%80%EC%B6%9C%EB%B9%84%EA%B5%90-%EB%94%94%EC%9E%90%EC%9D%B8-%EC%8B%9C%EC%8A%A4%ED%85%9C?node-id=1555-6255&t=YboksdJ0pWOQHhFm-4',
        allowFullscreen: true,
      }
    }}
  >
    {Template.bind({})}
  </Story>
</Canvas>

 

Canvas

<Canvas /> Doc Block은 컴포넌트와 상호작용 할 수 있는 래퍼(Wrapper) 역할을 하는 빌딩 블록입니다. 소스코드를 제공하는 스니펫을 제공합니다. 이외에도 columns, isColumn, withToolbar, withSource 등의 옵션도 설정할 수 있습니다.

 

Story

<Story /> Doc Block은 기본적으로 스토리가 렌더링 되는 빌딩 블록입니다. 스토리를 렌더링하는 것 뿐 아니라 어떻게 정의할 것인지에 대한 방식도 제공합니다. 렌더링할 컴포넌트를 Story 빌딩 블록 사이에 넣습니다.

 

- name

스토리북 실행 시 왼쪽 사이드바에 나타나는 개별 스토리에 이름을 나타냅니다.

 

- args

해당 스토리가 갖는 구체적인 개별 arguments를 의미하고 객체 형태로 작성합니다. 

 

- 스토리 Figma와 연결하기

design-addson(디자인 애드온)을 통해 스토리에 해당하는 Figma 컴포넌트를 연결할 수 있습니다.

Story Doc Block의 parameters arguments에 design을 키(key)로 하는 객체를 전달합니다. 해당 객체는 type, url, allowFullscreen 등의 설정을 할 수 있고 아래와 같이 작성합니다.

<Story 
  parameters={{
    design: {
      type: 'figma',
      url: 'https://www.figma.com/file/Tt3Zu0zMhQ6nIVhIB6R2Ff/%EB%8C%80%EC%B6%9C%EB%B9%84%EA%B5%90-%EB%94%94%EC%9E%90%EC%9D%B8-%EC%8B%9C%EC%8A%A4%ED%85%9C?node-id=1555-6255&t=YboksdJ0pWOQHhFm-4',
      allowFullscreen: true,
    }
  }}
>
  {Template.bind({})}
</Story>

 

실행하게 되면 다음과 같이 Canvas 탭의 Design에서 해당 스토리에 대한 Figma 디자인을 확인할 수 있습니다.

Storybook 내에 Figma 연결한 모습

 

 

※ Figma 내 컴포넌트 주소 복사하는 방법

더보기

Figma 내에 정의된 컴포넌트의 주소를 복사하는 방법은 다음과 같습니다.

 

1. Figma 내 컴포넌트를 클릭한다.

2. 오른쪽 상단에 share 버튼을 누른다.

3. 공유 모달창 하단에 copy link 클릭하여 복사한다.

4. 복사한 주소를 Story Doc Block 내에 url argument에 붙여 넣는다.

 

 

 

Template

하나의 스토리에서 템플릿을 활용하여 arguments에 따라 달라지는 다양한 스토리를 만들 수 있습니다. Template을 설정하고 JavaScript의 bind 메서드를 사용합니다. bind 메서드는 함수를 복사하는 용도로 사용합니다. Template을 사용하여 개별 arguments를 적용할 수 있습니다.

export const Template = (args) => <FillButton {...args} />

//...

<Canvas>
  <Story>
    {Template.bind({})}
  </Story>
</Canvas>

 

④ ArgsTable

ArgsTable

컴포넌트의 arguments에 대한 테이블을 나타냅니다. 스토리북 Docs는 특정 컴포넌트에 대한 테이블을 자동적으로 생성합니다. 위에서 살펴본 Meta Doc Block에서 argsType을 지정하지 않는다면 arguments에 대한 타입 추론을 하여 자동적으로 만들어냅니다.

 

story arguments를 활용해서 특정 story에 대한 테이블은 표현할 수 있습니다. <Story /> Doc Block 의 name과 동일하게 작성하여 매핑합니다.

<Canvas>
  <Story
    name="standard"
//..생략
  >
  </Story>
</Canvas>

<ArgsTable story="standard" />

3. 참고사항

Storybook 실행 화면 둘러보기

 


  1. Docs Page는 CSF을 사용하여 스토리북에서 기본적으로 제공하는 문서 형식입니다.(the zero-config default documentation, out of the box) [본문으로]

'FRONTEND' 카테고리의 다른 글

[NextJS] config 파일 및 폴더  (0) 2023.04.10
[NextJS] Next.js 초기 세팅 테스트  (0) 2023.04.03
[Storybook] Storybook 설명  (0) 2023.03.29
React 상태 불변성  (0) 2022.09.21
[React] Learning React Chapter 6 - 상태 관리  (0) 2022.08.23