title | date | author | category |
---|---|---|---|
storybook |
2020-11-25 16:00:00 -0800 |
chjjh0 |
S2_Round1 |
- bootstrap, materialUI 같은 CSS 프레임워크에서 제공하는 요소 팔레트와 유사하게 컴포넌트를 관리
- 컴포넌트 문서화를 통해 테스트, 유지보수에 유용
- 다양한 환경에서 활용 가능 (HTML, React, Vue, Svelte 등)
기본 사용법
// CRA로 React Project 생성
npx create-react-app taskbox
// 생성된 프로젝트에 스토리북 추가 & 초기화
npx -p @storybook/cli sb init
// 스토리북 실행
npm run storybook
sb init, 스토리북 초기화 (링크)
- 사용자가 직접 작성해야할 것들이 자동으로 추가됨
- package.json에 dependencies, scripts 추가
"devDependencies": {
"@storybook/addon-actions": "^6.1.3",
"@storybook/addon-essentials": "^6.1.3",
"@storybook/addon-links": "^6.1.3",
"@storybook/node-logger": "^6.1.3",
"@storybook/preset-create-react-app": "^3.1.5",
"@storybook/react": "^6.1.3"
}
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"storybook": "start-storybook -p 6006 -s public",
"build-storybook": "build-storybook -s public"
},
...
예제
Button.js
export const Button = ({ primary, backgroundColor, size, label, ...props }) => {
// primary or secondary 모드
const mode = primary ? 'storybook-button--primary' : 'storybook-button--secondary';
return (
<button
type="button"
className={['storybook-button', `storybook-button--${size}`, mode].join(' ')}
style={backgroundColor && { backgroundColor }}
{...props}
>
{label}
</button>
);
};
Button.css
.storybook-button {
font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-weight: 700;
border: 0;
border-radius: 3em;
cursor: pointer;
display: inline-block;
line-height: 1;
}
.storybook-button--primary {
color: white;
background-color: #1ea7fd;
}
.storybook-button--secondary {
color: #333;
background-color: transparent;
box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset;
}
.storybook-button--small {
font-size: 12px;
padding: 10px 16px;
}
.storybook-button--medium {
font-size: 14px;
padding: 11px 20px;
}
.storybook-button--large {
font-size: 16px;
padding: 12px 24px;
}
Button.stories.js
import React from 'react';
import { Button } from './Button';
export default {
title: 'Example/Button',
component: Button,
argTypes: {
backgroundColor: { control: 'color' },
},
};
const Template = (args) => <Button {...args} />;
export const Primary = Template.bind({});
Primary.args = {
primary: true,
label: 'Button',
};
export const Secondary = Template.bind({});
Secondary.args = {
label: 'Button',
};
export const Large = Template.bind({});
Large.args = {
size: 'large',
label: 'Button',
};
export const Small = Template.bind({});
Small.args = {
size: 'small',
label: 'Button',
};
실행 결과
실행결과 Sample
- Preview 영역: Manager영역에서 선택한 story를 보여줌, iframe으로 되어있음
- Manager 영역: story들을 폴더구조로 볼 수 있음
- Preview, Manager 영역은 Storybook Communication Channel을 통해 데이터 전달
- manager 영역에 폴더 구조로 관리
( stories 파일에서 선언한 title: Example/Button )
- stories파일과 컴포넌트의 props prototype을 참고하여 자동으로 아래와 같은 UI가 만들어짐