storybook 1

介绍

组件开发环境,可以更直观、无依赖地开发和展示组件

Writing Stories

一个组件对应一个story

a story is a function that returns something that can be rendered to screen.

import React from 'react';
import { action } from '@storybook/addon-actions';
import Button from './Button';

export default {
  component: Button,  // 组件
  title: 'Button', // storybook启动后界面左边展示地文案
};

export const text = () => <Button onClick={action('clicked')}>Hello Button</Button>;

export const emoji = () => (
  <Button onClick={action('clicked')}>
    <span role="img" aria-label="so cool">
      😀 😎 👍 💯
    </span>
  </Button>
);

Story file location

  • 组件文件同一路径
  • src同路径

Loading stories

Stories are loaded in the .storybook/main.js file or .storybook/preview.js file.

  • 通过文件名引入stories(如果你的stories文件放在src/components文件下,你可以使用下面方式引用)
// .storybook/main.js
module.exports = {
stories: ['../src/components/**/*.stories.js'],
};
  • 你也可以在 .storybook/preview.js中引入所有的stories
import { configure } from '@storybook/react';
configure(require.context('../src/components', true, /\.stories\.js$/), module);

如果stories放在多个路径,可以使用数组

import { configure } from '@storybook/react';

configure(
  [
    require.context('../src/components', true, /\.stories\.js$/),
    require.context('../lib', true, /\.stories\.js$/),
  ],
  module
);

枚举引入

import { configure } from '@storybook/react';
const loaderFn = () => [
  require('./welcome.stories.js'),
  require('./prelude.stories.js'),
  require('./button.stories.js'),
  require('./input.stories.js'),
];
configure(loaderFn, module);

混合引入

import { configure } from '@storybook/react';

const loaderFn = () => {
  const allExports = [require('./welcome.stories.js')];
  const req = require.context('../src/components', true, /\.stories\.js$/);
  req.keys().forEach(fname => allExports.push(req(fname)));
  return allExports;
};

configure(loaderFn, module);

If you are using the storiesOf API directly, or are using @storybook/react-native where CSF is unavailable, you should use a loader function with no return value:

import { configure } from '@storybook/react';

const loaderFn = () => {
  // manual loading
  require('./welcome.stories.js');
  require('./button.stories.js');

  // dynamic loading, unavailable in react-native
  const req = require.context('../src/components', true, /\.stories\.js$/);
  req.keys().forEach(fname => req(fname));
};

configure(loaderFn, module);

Decorators

  • global decorator : applied in the Storybook config files
    // .storybook/preview.js:
import React from 'react';
import { addDecorator } from '@storybook/react';

addDecorator(storyFn => <div style={{ textAlign: 'center' }}>{storyFn()}</div>);

  • component/local decorators
import React from 'react';
import MyComponent from './MyComponent';

export default {
  title: 'MyComponent',
  decorators: [storyFn => <div style={{ backgroundColor: 'yellow' }}>{storyFn()}</div>],
};

export const normal = () => <MyComponent />;
export const special = () => <MyComponent text="The Boss" />;
special.story = {
  decorators: [storyFn => <div style={{ border: '5px solid red' }}>{storyFn()}</div>],
};

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。