Storybook에서 Icon 카탈로그 만들기

개시하다


storybook과 디자이너를 사용하여 구성 요소 관리를 하는 과정에서 아이콘처럼 행동하지만 외관이 다른 대량의 구성 요소를 각각 구성 요소로 등록하고 페이지마다 아이콘으로 표시하는 것을 파악하여 확인하는 것은 매우 불편하다.
따라서 일람표를 통해 표현하면 행동은 다른 페이지에서 확인할 수 있다.

카탈로그


먼저 결과를 보여 드리겠습니다.실제 storybook은여기.

카탈로그 섹션


사용 방법을 설명하는 동시에 모든 아이콘을 확장합니다.

행위 확인 부분


아이콘, 색상 및 크기를 전환하여 모든 어셈블리의 동작을 확인할 수 있습니다.

프로그램 만들기


여기서storybook의 환경 설정이 완료되었고src/ 밑에 등록하고 싶은 모든 아이콘이 있다는 구상으로 제작됩니다.
사용@storybook/addon-docs@storybook/addon-controls.

1. manfest 스크립트 만들기


create-manifest.js
const fs = require('fs');
const path = require('path');
// indexファイルはアイコンでないので除外する
const exclusionList = ['index.ts'];
// 対象dirを読む
const files = fs.readdirSync(path.resolve(process.cwd(), `./src`));
// (必要であれば)種類ごとにfieldを分けてdataを作成します。
const data = {
  Icons: files
    .filter((file) => !exclusionList.includes(file))
    .map((file) => file.replace('.tsx', '')),
};
// jsonに書き出します。
fs.writeFileSync('./docs/manifest.json', JSON.stringify(data, null, '    '));

2. 스크립트 실행


package.json
 "build:manifest": "node ./scripts/createManifest.js",
 "storybook": "yarn build:manifest && start-storybook -p 6006",
스토리 업데이트를 잊지 않기 위해 github action도 만들었습니다.
check-manifest-update.yml
- name: Generate story
 run: yarn build:manifest
- name: '`yarn build:manifest` changes committed?'
 run: git diff --exit-code

3. MDx 파일 만들기


아이콘 사용법과 주의사항 등이 있으면 여기에 기재한다.<Icons /> 섹션은 아이콘이 나열된 구성 요소입니다.
Icons.stories.mdx
import { Meta } from '@storybook/addon-docs/blocks';
import Icons from './Icons';

<Meta title="Icons" />

# Feather Icons

[Feather Svg Icons](https://github.com/feathericons/feather) converted to [Material-UI](https://github.com/mui-org/material-ui) React components. You can install the package by running the following command in your project:

'''sh
# With yarn:
yarn add mui-feather
# With npm:
npm install mui-feather
'''

<Icons />

4. 카탈로그 만들기


생성된 manfest를 사용하여 제목을 종류별로 구분하고 아이콘과 구성 요소 이름을 펼치고 표시합니다.
Icons.tsx
import * as React from 'react';
import * as iconComponents from '../src';
import manifest from './manifest.json';

const Icons = () => {
  return Object.keys(manifest).map((key) => {
    const files = manifest[key];
    if (!Array.isArray(files)) return null;

    return (
      <div key={key}>
        <h3>{key}</h3>
        <div style={{ display: 'flex', flexWrap: 'wrap' }}>
          {files.map((file) => {
            const Icon = iconComponents[`${file}`];

            if (!Icon) {
              console.log(`could not find icon...: ${file}`);
              return null;
            }

            return (
              <div
                key={file}
                style={{
                  width: '7.5rem',
                  display: 'flex',
                  flexDirection: 'column',
                  alignItems: 'center',
                  backgroundColor: '#d8d8d8',
                  color: 'black',
                  borderRadius: '4px',
                  marginRight: '8px',
                  marginBottom: '8px',
                  padding: '16px',
                }}
              >
                <Icon />
                <label htmlFor="id" style={{ marginTop: '8px' }}>
                  {file}
                </label>
              </div>
            );
          })}
        </div>
      </div>
    );
  });
};

export default Icons;

5. 행동확인이 가능한 스토리 만들기


Icons.stories.tsx
import { SvgIconProps } from '@material-ui/core/SvgIcon';
import * as React from 'react';
import * as iconComponents from '../src';
import manifest from './manifest.json';

// manifestから全コンポーネント名を取り出す
const allIcons = Object.values(manifest)
  .map((value) => value)
  .reduce((a, b) => a.concat(b), []);

// controlできるfieldを設定します。
// @storybook/addon-controlsが必要
export default {
  title: 'Icon/Basic',
  argTypes: {
    component: { control: { type: 'select', options: allIcons } },
    fontSize: { control: { type: 'select', options: ['default', 'small', 'large'] } },
    color: {
      control: {
        type: 'select',
        options: ['inherit', 'primary', 'secondary', 'disabled', 'error'],
      },
    },
  },
};

interface Props extends SvgIconProps {
  component: string;
}

export const Control = (args: Props) => {
  const Component = iconComponents[args.component];
  return <Component fontSize={args.fontSize} color={args.color} />;
};

Control.args = { component: 'User', fontSize: 'default', color: 'inherit' };

끝말


간단한 스크립트와mdx 파일을 조합하여 아이콘 디렉터리를 만들었습니다.
디자인/개발자의 소통은 간단하지만 너무 많은 비용을 들이지 말고 스토리북을 순조롭게 활용하시기 바랍니다.🤔

좋은 웹페이지 즐겨찾기