# React:
npx create-react-app taskbox
cd taskbox
# 加入 Storybook:
npx -p @storybook/cli sb init
# 啟動 storybook
npm run storybook
webpack
"scripts": {
// localhost:9009
"storybook": "start-storybook -p 9009",
"build-storybook": "build-storybook"
},
.storybook
src/stories
1. addon.js
引入 storybook 內建 function
2. config.js
引入 src/stories 的檔案
寫各種你想測試的元件
"自下而上"開始構建 UI 的過程,從元件開始到整個頁面結束。
React component 開發模式
Storybook就是用來幫助我們完整這套模式的測試工具
1.利於合作,並行開發
(工程 ←→ 工程)
2.元件內控管所有狀態,並同步更新
(設計 ←→ 工程)
3.創建組件庫(component library)
Button
→ButtonList
→TextButton
4.可視化測試(Visual TDD)
運用 component explorer 產生prototype
ex: storybook
分成 stories 和 child story
如:Task.js & Task.stories.js
將每個 story 視為stories component的排列
可以根據需要為每個stories 建 child story
linkto()
action()
// @flow
import React from 'react';
import { css } from 'emotion';
import { action } from '@storybook/addon-actions';
import { linkTo } from '@storybook/addon-links';
function Modal({state}) {
return (
<div className={classes.wrapper}>
<h3>{state}</h3>
<p>Modal</p>
<button
onClick={state === 'NORMAL' ? linkTo('TASK') : action('clicked')}
type="button">
按鈕
</button>
</div>
);
}
export default Modal;
storiesOf()
add()
addDecorator()
import React from 'react';
import { storiesOf } from '@storybook/react';
import { task, actions } from './Task.stories';
import TaskList from './TaskList';
export const defaultTasks = [
{ ...task, id: '1', title: 'Task 1' },
{ ...task, id: '2', title: 'Task 2' },
{ ...task, id: '3', title: 'Task 3' },
{ ...task, id: '4', title: 'Task 4' },
{ ...task, id: '5', title: 'Task 5' },
{ ...task, id: '6', title: 'Task 6' },
];
export const withPinnedTasks = [
...defaultTasks.slice(0, 5),
{ id: '6', title: 'Task 6 (pinned)', state: 'TASK_PINNED' },
];
storiesOf('TaskList', module)
.addDecorator(story => <div style={{ padding: '3rem' }}>{story()}</div>)
.add('default', () => <TaskList tasks={defaultTasks} {...actions} />)
.add('withPinnedTasks', () => <TaskList tasks={withPinnedTasks} {...actions} />)
.add('loading', () => <TaskList loading tasks={[]} {...actions} />)
.add('empty', () => <TaskList tasks={[]} {...actions} />)
DEMO 時間!
參考資料