StoryBook 과 Styled Component 의 패턴

햄스터아저씨·2022년 9월 29일
0

Storybook 에 Styled-Component 를 적용했던 방법을 남깁니다

기본구성

1. 설치

사전 설정

  • React 설치 (npx create-react-app)
  • Style Component (npm install --save styled-components)

설치

입력 (기존 react 프로젝트 내에서)

npx @storybook/cli sb init
npm install @storybook/addon-a11y --save-dev
npm install storybook-addon-styled-component-theme --save-dev

npx sb 와 npx @storybook/cli storybook 은 동일한 듯

스토리북은 초기 설정방법이 좀 중구난방이라, 매번 공식페이지를 잘 읽어보는게 좋다
https://storybook.js.org/docs/react/get-started/install#troubleshooting
난 내 환경에 맞춰 다음과 같은 설정을 사용
npx sb init --type react --use-npm

결과

// package.json > devDependencies
  "devDependencies": {
    "@storybook/addon-a11y": "^6.5.12",
    "@storybook/addon-actions": "^6.5.12",
    "@storybook/addon-essentials": "^6.5.12",
    "@storybook/addon-interactions": "^6.5.12",
    "@storybook/addon-links": "^6.5.12",
    "@storybook/builder-webpack5": "^6.5.12",
    "@storybook/manager-webpack5": "^6.5.12",
    "@storybook/node-logger": "^6.5.12",
    "@storybook/preset-create-react-app": "^4.1.2",
    "@storybook/react": "^6.5.12",
    "@storybook/testing-library": "^0.0.13",
    "storybook-addon-styled-component-theme": "^2.0.0",
      ...
  }

2. 생성된 파일구조

project
┝ .storybook
│  ┝ main.js      # 스토리북 전체 설정 (addon, 빌드 등)
│  └ preview.js  # 스토리북에서 우측패널 부분의 전역설정 (decorator 등)
└ src
   └ stories
      └  각종 예시파일들
      
      	 3개가 하나의 세트로 구성된다.
         - .css        # styled-component를 사용하면 없어도 됨
         - .js         # 컴포넌트 파일
         - .stories.js # 스토리북 파일
   

3. 설정 파일 내용

main.js

module.exports = {
  stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
  addons: [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-interactions",
    "@storybook/preset-create-react-app",
    "@storybook/addon-a11y",
    "storybook-addon-styled-component-theme/dist/preset",
  ],
  framework: "@storybook/react",
  core: {
    builder: "@storybook/builder-webpack5",
  },
};

preview.js

최소 설정시

export const parameters = {
  actions: { argTypesRegex: "^on[A-Z].*" },
  controls: {
    matchers: {
      color: /(background|color)$/i,
      date: /Date$/,
    },
  },
};

styled-components 를 적용하고 싶다면

ThemeProvider 내용을 decorators 로 추가하면 됨

import React from "react";
import { ThemeProvider } from "styled-components";

const theme = {
  fonts: ["sans-serif", "Roboto"],
}

export const decorators = [
  (Story) => (
    <ThemeProvider theme={theme}>
      <Story />
    </ThemeProvider>
  ),
];

export const parameters = {
  actions: { argTypesRegex: "^on[A-Z].*" },
  controls: {
    matchers: {
      color: /(background|color)$/i,
      date: /Date$/,
    },
  },
};

4. 폴더 구조 정책 (자체정의)

  • 컨포넌트는src/components/ 아래에 폴더별로 격리
  • 위 컴포넌트에 대응되는 스토리파일은 src/stories 에 작성
    예시) footer를 구성한다면

project
└ src
   ┝ components
   │ └ Footer
   │   └ Footer.js # 컴포넌트 파일
   └ stories
      ㄴ Footer.stories.js # 스토리북 파일
   

파일 별 내용

Footer 를 구성한다고 가정하고 예시로 설명한다
만들어야 할 파일은 2개이다. Componentsstories 파일
각각 기본 형태를 먼저 설명하고 추가적인 설정을 먹인 형태를 공유

1. Components

1.1 최소 구성

// path: /project/src/components/Footer/Footer.js

const Footer = ({ label }) => {
  return <div>{label}</div>;
};

export { Footer };

1.2 styled-component 와 함께 구성시

// path: /project/src/components/Footer/Footer.js

import styled from "styled-components";

const FooterLayout = styled.div`
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100px;
  background-color: #aaa;
`;

const Footer = ({ label }) => {
  return (
    <FooterLayout>
      {label}
    </FooterLayout >
  );
};

export { Footer };

2. Stories

위에서 만든 컴포넌트 파일을 사용하여 스토리북으로 구성해 줄 파일이 필요하다.

2.1 최소 구성

// path: /project/src/stories/Footer.stories.js

import React from "react";
import { Footer } from "../components/Footer/Footer";

export default {
  title: "components/Footer",
  component: Footer,
};

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

export const Browser = Template.bind({});

Browser.args = {
  label: "이것은 브라우저 푸터",
};

2.2 react-router-dom 과 함께 구성

만일 제작한 component가 <Link> 태그나 그 외 react-router-dom 에서 제공하는 태그를 사용한다면 아래와 같은 에러가 발생한다

useHref() may be used only in the context of a <Router> component.

이런 컴포넌트는 MemoryRouter 를 데코레이터로 아래와 같이 감싸주면 정상적으로 동작한다

// path: /project/src/stories/Footer.stories.js

import React from "react";
import { MemoryRouter } from "react-router-dom";
import { Footer } from "../components/Footer/Footer";

export default {
  title: "components/Footer",
  component: Footer,
  parameters: {
    layout: 'fullscreen',
  },
  decorators: [
    (Story) => (
      <MemoryRouter>
        <Story />
      </MemoryRouter>
    ),
  ],
};

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

export const Browser = Template.bind({});

Browser.args = {
  label: "이것은 브라우저 푸터",
};
profile
서버도 하고 웹도 하고 시스템이나 인프라나 네트워크나 그냥 다 함.

0개의 댓글