文件
Storybook 文件

模擬提供器

元件可以從 context providers 接收資料或設定。例如,styled component 可能會從 ThemeProvider 存取其主題,或者 Redux 使用 React context 來提供元件存取應用程式資料。若要模擬 provider,您可以將元件包裝在包含必要 context 的裝飾器中。

.storybook/preview.tsx
import React from 'react';
 
import { Preview } from '@storybook/react';
 
import { ThemeProvider } from 'styled-components';
 
const preview: Preview = {
  decorators: [
    (Story) => (
      <ThemeProvider theme="default">
        {/* 👇 Decorators in Storybook also accept a function. Replace <Story/> with Story() to enable it  */}
        <Story />
      </ThemeProvider>
    ),
  ],
};
 
export default preview;

請注意上面的檔案副檔名 (.tsx.jsx)。您可能需要調整預覽檔案的副檔名以允許使用 JSX,具體取決於專案的設定。

另一個範例,請參考 Storybook 教程簡介的 Screens 章節,其中我們使用模擬資料模擬 Redux provider。

設定模擬提供器

模擬 provider 時,可能需要設定 provider 為個別 stories 提供不同的值。例如,您可能想要使用不同的主題或使用者角色來測試元件。

一種方法是為每個 story 個別定義裝飾器。但如果您想像一個情境,您希望在淺色和深色主題中為每個元件建立 stories,這種方法很快就會變得繁瑣。

為了有更好的方法,並減少重複性,您可以使用裝飾器函數的第二個「context」參數來存取 story 的參數,並調整提供的值。這樣,您可以定義一次 provider,並為每個 story 調整其值。

例如,我們可以調整上面的裝飾器,從 parameters.theme 讀取以確定要提供哪個主題

.storybook/preview.tsx
import React from 'react';
 
import type { Preview } from '@storybook/react';
import { ThemeProvider } from 'styled-components';
 
// themes = { light, dark }
import * as themes from '../src/themes';
 
const preview: Preview = {
  decorators: [
    // 👇 Defining the decorator in the preview file applies it to all stories
    (Story, { parameters }) => {
      // 👇 Make it configurable by reading the theme value from parameters
      const { theme = 'light' } = parameters;
      return (
        <ThemeProvider theme={themes[theme]}>
          <Story />
        </ThemeProvider>
      );
    },
  ],
};
 
export default preview;

現在,您可以在 stories 中定義 theme 參數,以調整裝飾器提供的主題

Button.stories.ts
import type { Meta, StoryObj } from '@storybook/react';
 
import { Button } from './Button';
 
const meta: Meta<typeof Button> = {
  component: Button,
};
export default meta;
 
type Story = StoryObj<typeof Button>;
 
// Wrapped in light theme
export const Default: Story = {};
 
// Wrapped in dark theme
export const Dark: Story = {
  parameters: {
    theme: 'dark',
  },
};

這種強大的方法讓您能夠以彈性且可維護的方式,為元件提供任何值(主題、使用者角色、模擬資料等)。