文件
Storybook 文件

Args

觀看影片教學

一個 story 是一個元件,帶有一組定義元件應如何渲染的參數。「Args」是 Storybook 用於在單一 JavaScript 物件中定義這些參數的機制。Args 可以用來動態變更 props、slots、styles、inputs 等。它允許 Storybook 及其附加元件即時編輯元件。您不需要修改底層元件程式碼即可使用 args。

當 arg 的值變更時,元件會重新渲染,讓您透過影響 args 的附加元件,在 Storybook 的 UI 中與元件互動。

了解如何在簡介中編寫 stories 以及為何要這樣做。如需 args 如何運作的詳細資訊,請繼續閱讀。

Args 物件

args 物件可以在story元件全域層級定義。它是一個 JSON 可序列化物件,由字串鍵和相符的有效值類型組成,可以傳遞到您框架的元件中。

Story args

若要定義單一 story 的 args,請使用 args CSF story 鍵

Button.stories.ts|tsx
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>;
 
export const Primary: Story = {
  args: {
    primary: true,
    label: 'Button',
  },
};

這些 args 只會套用至它們所附加的 story,但您可以透過 JavaScript 物件重複使用來重複使用它們

Button.stories.ts|tsx
// Replace your-framework with the name of your framework
import type { Meta, StoryObj } from '@storybook/your-framework';
 
import { Button } from './Button';
 
const meta: Meta<typeof Button> = {
  component: Button,
};
 
export default meta;
type Story = StoryObj<typeof Button>;
 
export const Primary: Story = {
  args: {
    primary: true,
    label: 'Button',
  },
};
 
export const PrimaryLongName: Story = {
  args: {
    ...Primary.args,
    label: 'Primary with a really long name',
  },
};

在以上範例中,我們使用了 ES 2015 的物件展開功能。

元件 args

您也可以在元件層級定義 args;它們將套用至元件的所有 stories,除非您覆寫它們。若要這麼做,請在 default CSF 匯出上使用 args

Button.stories.ts|tsx
import type { Meta } from '@storybook/react';
 
import { Button } from './Button';
 
const meta: Meta<typeof Button> = {
  component: Button,
  //👇 Creates specific argTypes
  argTypes: {
    backgroundColor: { control: 'color' },
  },
  args: {
    //👇 Now all Button stories will be primary.
    primary: true,
  },
};
 
export default meta;
type Story = StoryObj<typeof Button>;

全域 args

您也可以在全域層級定義 args;它們將套用至每個元件的 stories,除非您覆寫它們。若要這麼做,請在 preview.js|ts 的預設匯出中定義 args 屬性

.storybook/preview.ts
// Replace your-renderer with the renderer you are using (e.g., react, vue3, angular, etc.)
import { Preview } from '@storybook/your-renderer';
 
const preview: Preview = {
  // The default value of the theme arg for all stories
  args: { theme: 'light' },
};
 
export default preview;

對於全域 args 的大多數用途,全域變數是定義全域套用設定(例如主題)的更好工具。使用全域變數可讓使用者使用工具列選單變更值。

Args 組合

您可以分離 story 的參數,以在其他 stories 中組合。以下說明如何組合相同元件的多個 stories 的 args。

Button.stories.ts|tsx
// Replace your-framework with the name of your framework
import type { Meta, StoryObj } from '@storybook/your-framework';
 
import { Button } from './Button';
 
const meta: Meta<typeof Button> = {
  component: Button,
};
 
export default meta;
type Story = StoryObj<typeof Button>;
 
export const Primary: Story = {
  args: {
    primary: true,
    label: 'Button',
  },
};
 
export const Secondary: Story = {
  args: {
    ...Primary.args,
    primary: false,
  },
};

如果您發現自己為元件的大多數 stories 重複使用相同的 args,則應考慮使用元件層級 args

當為從其他元件組裝而成的複合元件編寫 stories 時,Args 非常有用。複合元件通常會將其參數不變地傳遞給其子元件,同樣地,它們的 stories 可以是其子元件 stories 的組合。透過 args,您可以直接組合參數

Page.stories.ts|tsx
import type { Meta, StoryObj } from '@storybook/react';
 
import { Page } from './Page';
 
//👇 Imports all Header stories
import * as HeaderStories from './Header.stories';
 
const meta: Meta<typeof Page> = {
  component: Page,
};
 
export default meta;
type Story = StoryObj<typeof Page>;
 
export const LoggedIn: Story = {
  args: {
    ...HeaderStories.LoggedIn.args,
  },
};

Args 可以修改元件的任何外觀

您可以在 stories 中使用 args 來設定元件的外觀,類似於您在應用程式中所做的事情。例如,以下說明如何使用 footer arg 來填入子元件

Page.stories.ts|tsx
import type { Meta, StoryObj } from '@storybook/react';
 
import { Page } from './Page';
 
type PagePropsAndCustomArgs = React.ComponentProps<typeof Page> & { footer?: string };
 
const meta: Meta<PagePropsAndCustomArgs> = {
  component: Page,
  render: ({ footer, ...args }) => (
    <Page {...args}>
      <footer>{footer}</footer>
    </Page>
  ),
};
export default meta;
 
type Story = StoryObj<PagePropsAndCustomArgs>;
 
export const CustomFooter: Story = {
  args: {
    footer: 'Built with Storybook',
  },
};

透過 URL 設定 args

您也可以透過將 args 查詢參數新增至 URL 來覆寫作用中 story 的初始 args 集。通常您會使用控制項附加元件來處理此問題。例如,以下說明如何在 Storybook 的 URL 中設定 sizestyle arg

?path=/story/avatar--default&args=style:rounded;size:100

為了防範 XSS 攻擊,URL 中提供的 arg 的鍵和值僅限於英數字元、空格、底線和破折號。任何其他類型都會被忽略並從 URL 中移除,但您仍然可以使用控制項附加元件和 在您的 story 內使用它們。

args 參數始終是一組以分號 ; 分隔的 鍵: 值 配對。值將被強制轉換為其各自的 argTypes(可能已自動推斷)。支援物件和陣列。特殊值 nullundefined 可以透過在前面加上驚嘆號 ! 來設定。例如,args=obj.key:val;arr[0]:one;arr[1]:two;nil:!null 將被解讀為

{
  obj: { key: 'val' },
  arr: ['one', 'two'],
  nil: null
}

同樣地,特殊格式也適用於日期和顏色。Date 物件將編碼為 !date(value),其中 value 表示為 ISO 日期字串。顏色編碼為 !hex(value)!rgba(value)!hsla(value)。請注意,rgb(a) 和 hsl(a) 不應在 URL 中包含空格或百分比符號。

透過 URL 指定的 Args 將擴展並覆寫在 story 上設定的任何 args 預設值。

從 story 內設定 args

互動式元件通常需要由其包含的元件或頁面控制,以回應事件、修改其狀態並在 UI 中反映這些變更。例如,當使用者切換開關元件時,應選取開關,且 Storybook 中顯示的 arg 應反映變更。若要啟用此功能,您可以使用 @storybook/preview-api 匯出的 useArgs API

my-component/component.stories.ts|tsx
import { StoryObj, Meta } from '@storybook/react';
import { useArgs } from '@storybook/preview-api';
import { Checkbox } from './checkbox';
 
const meta: Meta<typeof Checkbox> = {
  title: 'Inputs/Checkbox',
  component: Checkbox,
};
export default meta;
 
type Story = StoryObj<typeof Checkbox>;
 
export const Example: Story = {
  args: {
    isChecked: false,
    label: 'Try Me!',
  },
  /**
   * 👇 To avoid linting issues, it is recommended to use a function with a capitalized name.
   * If you are not concerned with linting, you may use an arrow function.
   */
  render: function Render(args) {
    const [{ isChecked }, updateArgs] = useArgs();
 
    function onChange() {
      updateArgs({ isChecked: !isChecked });
    }
 
    return <Checkbox {...args} onChange={onChange} isChecked={isChecked} />;
  },
};

對應至複雜 arg 值

複雜值(例如 JSX 元素)無法序列化到管理器(例如,控制項附加元件)或與 URL 同步。可以使用 argTypes 中的 mapping 屬性,將 Arg 值從簡單字串「對應」到複雜類型,以解決此限制。它適用於任何 arg,但在與 select 控制項類型搭配使用時最合理。

Example.stories.ts|tsx
// Replace your-renderer with the renderer you are using (e.g., react, vue3, angular, etc.)
import type { Meta } from '@storybook/your-renderer';
 
import { Example } from './Example';
 
const meta: Meta<typeof Example> = {
  component: Example,
  argTypes: {
    label: {
      options: ['Normal', 'Bold', 'Italic'],
      mapping: {
        Bold: <b>Bold</b>,
        Italic: <i>Italic</i>,
      },
    },
  },
};
 
export default meta;

請注意,mapping 不必詳盡無遺。如果 arg 值不是 mapping 的屬性,則將直接使用該值。mapping 中的鍵始終對應於 arg ,而不是它們在 options 陣列中的索引。

在附加元件中使用 args

如果您正在編寫想要讀取或更新 args 的附加元件,請使用 @storybook/manager-api 匯出的 useArgs Hook

my-addon/src/manager.js|ts
import { useArgs } from '@storybook/manager-api';
 
const [args, updateArgs, resetArgs] = useArgs();
 
// To update one or more args:
updateArgs({ key: 'value' });
 
// To reset one (or more) args:
resetArgs((argNames: ['key']));
 
// To reset all args
resetArgs();