Storybook 即時範例外掛

Storybook 即時範例外掛

在 Github 上檢視
  • 🧑‍💻 無需像 codepen 等第三方服務即可玩轉程式碼
  • 👥 與他人分享範例
  • 🐛 與他人分享錯誤重現的連結
  • 🧱 檢查元件如何協同運作
  • 支援 Typescript

閱讀文件試用即時演示

開始使用

1. 安裝附加元件

yarn add -D storybook-addon-live-examples
# npm install --save-dev storybook-addon-live-examples

2. 在 main.js 中註冊附加元件

module.exports = {
    addons: ['storybook-addon-live-examples'],
};

3. 在 preview.js 中設定附加元件(可選步驟)

import { addons } from '@storybook/addons';
import { LIVE_EXAMPLES_ADDON_ID } from 'storybook-addon-live-examples';
import theme from 'prism-react-renderer/themes/github';

import AllComponents from '../packages';

addons.setConfig({
    [LIVE_EXAMPLES_ADDON_ID]: {
        // custom theme from prism-react-renderer (optional)
        editorTheme: theme,
        // internationalization (optional)
        copyText: ['Copy', 'Copied'],
        expandText: ['Show code', 'Hide code'],
        shareText: ['Share', 'Shared'],
        // scope (globally accessible components & functions) (optional)
        scope: {
            ...AllComponents,
            someFunction: () => 42
        },
    },
});

4. 設定 webpack (僅適用於 storybook 7)

const { patchWebpackConfig } = require('storybook-addon-live-examples/dist/cjs/utils');

module.exports = {
    webpackFinal: (config) => {
        patchWebpackConfig(config);
        
        return config;
    }
};

用法

CSF

即時範例將會取代預設的 addon-docs 畫布進行渲染。

您可以透過參數自訂範例

export default {
    title: 'Components/Button',
    parameters: {
        scope: {
            scopeValue,
        },
    }
};

const scopeValue = 42;

export const Primary = () => <button>{scopeValue}</button>;

Primary.parameters = {
    expanded: true
};

export const Secondary = () => <button>{scopeValue}</button>;

注意:安裝附加元件後,很可能會出現錯誤。別慌,只需將您故事中使用的所有變數傳遞到 scope

MDX

在基於 MDX 的故事中,您可以使用純 markdown 編寫程式碼範例。

只需將您的程式碼放在三引號內

|```tsx live
|<h4>Wow, so simple</h4>
|```

或渲染自訂畫布

// Import custom Canvas from addon
import { Canvas } from 'storybook-addon-live-examples';

<Canvas live={true} scope={{ value: 42 }}>
    <h4>Wow, so simple, {value}</h4>
</Canvas>

或直接使用 Example

import { Example } from 'storybook-addon-live-examples';

<Example live={true} code={`<h4>Wow, so simple</h4>`} />

具有 MDX 的 CSF

// Button.stories.js

import mdx from './Button.mdx';

export default {
    title: 'Components/Button',
    parameters: {
        docs: {
            page: mdx,
        },
    },
};

const scopeValue = 42;

export const Primary = () => <button>{scopeValue}</button>;

Primary.parameters = {
    scope: {
        scopeValue,
    },
};
// Button.mdx

import { ArgsTable, Story } from '@storybook/addon-docs';

import { Button } from './Button';

# Button

<ArgsTable of={Button} />

<Story id='components-button--primary' />

範例屬性

您可以使用屬性或元字串自訂範例的顯示

live

|```tsx live
|<span>This example can be edited</span>
|```
<span>This example can be edited</span>

expanded

|```tsx live expanded
|<span>This example will be rendered with expanded code sources</span>
|```
<span>This example will be rendered with expanded code sources</span>

複雜範例

render(() => {
    const [counter, setCounter] = React.useState(0);
    return (
        <>
            <h2>Super live counter: {counter}</h2>
            <button type='button' onClick={() => setCounter((c) => c + 1)}>
                Increment
            </button>
        </>
    );
});

Scope

Storybook-addon-live-examples 在底層使用了 react-live

Scope 允許您將一些全域變數傳遞到您的程式碼範例中。預設情況下,它只會注入 React,這表示您可以在程式碼中像這樣使用它

render(() => {
//                                ↓↓↓↓↓
    const [counter, setCounter] = React.useState(0);
    return counter;
}

- 透過屬性將您自己的元件傳遞到 scope

import { Canvas } from 'storybook-addon-live-examples';
import MyComponent from '../packages/my-component';

<Canvas live={true} scope={{ MyComponent }}>
    <MyComponent>Amazing</MyComponent>
</Canvas>

- 全域設定 scope

這是為整個專案設定 scope 最簡單的方法

//.storybook/manager.js

import { addons } from '@storybook/addons';
import { LIVE_EXAMPLES_ADDON_ID } from 'storybook-addon-live-examples';

addons.setConfig({
    [LIVE_EXAMPLES_ADDON_ID]: {
        scope: {
            MyComponent,
        },
    },
});
<MyComponent>Now, you can use MyComponent in all examples</MyComponent>

- 在 monorepo 內設定 scope

這是一個範例,說明如何將所有已使用的元件和 helpers 新增到 scope。

// .storybook/scope.ts

import { ComponentType } from 'react';

import * as icons from 'some-icons-pack';
import * as knobs from '@storybook/addon-knobs';

// packages/{componentName}/index.ts
const req = require.context('../packages', true, /^\.\/(.*)\/index.ts$/);

const components = req.keys().reduce((acc: Record<string, ComponentType>, key) => {
    Object.entries(req(key)).forEach(([componentName, component]: [string, any]) => {
        acc[componentName] = component;
    });

    return acc;
}, {});

export default {
    ...components,
    ...icons,
    ...knobs,
};

// .storybook/manager.js

import scope from './scope';

addons.setConfig({
    [LIVE_EXAMPLES_ADDON_ID]: {
        scope,
    },
});