自動文件和 Storybook
觀看影片教學
Storybook 自動文件是一個強大的工具,可以幫助您快速為 UI 元件產生全面的文件。透過利用自動文件,您正在將您的 stories 轉化為動態文件,可以使用 MDX 和 文件區塊 進一步擴充,以清楚簡潔地了解元件的功能。
Storybook 會推斷相關的中繼資料(例如,args
、argTypes
、parameters
),並自動產生一個文件頁面,其中包含此資訊,並位於側邊欄中元件樹狀結構的根層級。
設定自動化文件
自動文件透過標籤設定。如果 CSF 檔案包含至少一個標記為 autodocs
的 story,則會為該元件產生一個文件頁面。
若要為專案中的所有 stories 啟用自動文件,請將其新增至 .storybook/preview.js|ts
檔案中的 tags
// Replace your-renderer with the renderer you are using (e.g., react, vue3)
import type { Preview } from '@storybook/your-renderer';
const preview: Preview = {
// ...rest of preview
//👇 Enables auto-generated documentation for all stories
tags: ['autodocs'],
};
export default preview;
您也可以在元件(或 story)層級啟用它
// Replace your-framework with the framework you are using (e.g., nextjs, vue3-vite)
import type { Meta } from '@storybook/your-framework';
import { Button } from './Button';
const meta: Meta<typeof Button> = {
component: Button,
//👇 Enables auto-generated documentation for this component and includes all stories in this file
tags: ['autodocs'],
};
export default meta;
您可以透過移除標籤來停用特定元件的自動文件
// Replace your-framework with the framework you are using (e.g., nextjs, vue3-vite)
import type { Meta, StoryObj } from '@storybook/your-framework';
import { Page } from './Page';
const meta: Meta<typeof Page> = {
component: Page,
// 👇 Disable auto-generated documentation for this component
tags: ['!autodocs'],
};
export default meta;
同樣地,您可以透過移除標籤,將特定 story 從自動文件頁面中排除
// Replace your-framework with the framework you are using (e.g., nextjs, vue3-vite)
import type { Meta, StoryObj } from '@storybook/your-framework';
import { Button } from './Button';
const meta: Meta<typeof Button> = {
component: Button,
//👇 Enables auto-generated documentation for this component and includes all stories in this file
tags: ['autodocs'],
};
export default meta;
type Story = StoryObj<typeof Button>;
export const UndocumentedStory: Story = {
// 👇 Removes this story from auto-generated documentation
tags: ['!autodocs'],
};
設定
除了使用 tags
啟用功能之外,您還可以擴充 Storybook 設定檔(即 .storybook/main.js|ts|cjs
),並提供其他選項來控制文件的建立方式。以下列出可用的選項以及如何使用它們的範例。
// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
import type { StorybookConfig } from '@storybook/your-framework';
const config: StorybookConfig = {
framework: '@storybook/your-framework',
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: ['@storybook/addon-essentials'],
docs: {
//👇 See the table below for the list of supported options
defaultName: 'Documentation',
},
};
export default config;
選項 | 描述 |
---|---|
defaultName | 重新命名自動產生的文件頁面 預設值: docs: { defaultName: 'Documentation' } |
撰寫自訂範本
觀看影片教學
若要取代 Storybook 使用的預設文件範本,您可以擴充您的 UI 設定檔(即 .storybook/preview.js|ts
),並引入 docs
參數。此參數接受一個 page
函式,該函式會傳回 React 元件,您可以使用它來產生所需的範本。例如
// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';
import { Title, Subtitle, Description, Primary, Controls, Stories } from '@storybook/blocks';
const preview: Preview = {
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
docs: {
page: () => (
<>
<Title />
<Subtitle />
<Description />
<Primary />
<Controls />
<Stories />
</>
),
},
},
};
export default preview;
在內部,Storybook 使用類似的實作來產生預設範本。請參閱文件區塊API 參考,以深入了解文件區塊的運作方式。
更詳細地檢視程式碼片段。當 Storybook 啟動時,它會使用由以下內容組成的自訂範本覆寫預設範本
- 一個標頭,其中包含由
Title
、Subtitle
和Description
文件區塊擷取的元件中繼資料。 - 檔案中透過
Primary
文件區塊定義的第一個 story,具有一組方便的 UI 控制項,可縮放元件。 - 一個互動式表格,其中包含 story 中透過
Controls
文件區塊定義的所有相關args
和argTypes
。 - 透過
Stories
文件區塊概述其餘的 stories。
使用 MDX
您也可以使用 MDX 來產生文件範本。這在未設定 JSX 處理的非 React 專案中非常有用。通常,當您在專案中建立 MDX 檔案時,它會被視為一般文件。若要指示 MDX 檔案為文件範本,請將 isTemplate
屬性提供給其 Meta
Doc Block。例如:
{/* DocumentationTemplate.mdx */}
import { Meta, Title, Primary, Controls, Stories } from '@storybook/blocks';
{/*
* 👇 The isTemplate property is required to tell Storybook that this is a template
* See https://storybook.dev.org.tw/docs/api/doc-blocks/doc-block-meta
* to learn how to use
*/}
<Meta isTemplate />
<Title />
# Default implementation
<Primary />
## Inputs
The component accepts the following inputs (props):
<Controls />
---
## Additional variations
Listed below are additional variations of the component.
<Stories />
然後,您可以透過匯入的方式,在您的 .storybook/preview.js
或個別的 Story 檔案中使用它。
import DocumentationTemplate from './DocumentationTemplate.mdx';
export default {
parameters: {
docs: {
page: DocumentationTemplate,
},
},
};
如果您只需要覆寫單一元件的文件頁面,我們建議建立一個 MDX 檔案,並透過 <Meta of={} />
Doc Block 直接參照它。
產生目錄
Storybook 自動產生的文件頁面可能會很長且難以瀏覽。為了協助解決這個問題,您可以啟用目錄功能,以快速概覽文件頁面,並允許使用者跳至特定章節。若要啟用此功能,請擴充您的 Storybook UI 設定檔(即 .storybook/preview.js
),並提供具有 toc
屬性的 docs
參數。
// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';
const preview: Preview = {
parameters: {
docs: {
toc: true, // 👈 Enables the table of contents
},
},
};
export default preview;
設定目錄
預設情況下,文件頁面上的目錄只會顯示自動產生的 h3
標題。但是,如果您想要自訂目錄,可以在 toc
屬性中新增更多參數。以下是可用的選項和使用範例。
選項 | 描述 |
---|---|
contentsSelector | 定義用於搜尋標題的容器 CSS 選擇器toc: { contentsSelector: '.sbdocs-content' } |
disable | 隱藏文件頁面的目錄toc: { disable: true } |
headingSelector | 定義要在目錄中顯示的標題清單toc: { headingSelector: 'h1, h2, h3' } |
ignoreSelector | 設定目錄以忽略特定標題或 Story。預設情況下,目錄會忽略所有放置在 Story 區塊內的內容toc: { ignoreSelector: '.docs-story h2' } |
title | 為目錄定義標題說明。 接受下列其中一種: string 、null 、React 元素toc: { title: '目錄' } |
unsafeTocbotOptions | 提供額外的 TocBot 設定選項toc: { unsafeTocbotOptions: { orderedList: true } } |
contentsSelector
、headingSelector
和 ignoreSelector
屬性允許額外的自訂。如需有關使用它們的詳細資訊,請參閱 Tocbot
文件。
// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';
const preview: Preview = {
parameters: {
docs: {
toc: {
contentsSelector: '.sbdocs-content',
headingSelector: 'h1, h2, h3',
ignoreSelector: '#primary',
title: 'Table of Contents',
disable: false,
unsafeTocbotOptions: {
orderedList: false,
},
},
},
},
};
export default preview;
元件層級設定
如果您想要為特定的 Story 自訂目錄,可以在 Story 的預設匯出中包含 toc
屬性,並提供所需的設定。例如,如果您需要隱藏特定 Story 的目錄,請如下調整您的 Story:
// Replace your-framework with the name of your framework
import type { Meta } from '@storybook/your-framework';
import { MyComponent } from './MyComponent';
const meta: Meta<typeof MyComponent> = {
component: MyComponent,
tags: ['autodocs'],
parameters: {
docs: {
toc: {
disable: true, // 👈 Disables the table of contents
},
},
},
};
export default meta;
自訂元件文件
使用 Storybook 的 Autodocs 建立自動化文件,為您提供了建構可持續文件模式的起點。然而,它可能不適合所有情況,您可能想要擴充它並提供額外資訊。我們建議結合 MDX 和 Storybook 的 Doc Blocks,以便在這種情況下撰寫您的文件。
進階設定
為多個元件建立文件
有時,將多個元件一起建立文件會很有幫助。例如,元件庫的 ButtonGroup 和 Button 元件如果沒有彼此,可能沒有意義。
Autodocs 允許您建立由 component
屬性定義的「主要」元件的文件,以及一個或多個與其相關的 subcomponents
。
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { List } from './List';
import { ListItem } from './ListItem';
const meta: Meta<typeof List> = {
component: List,
subcomponents: { ListItem }, //👈 Adds the ListItem component as a subcomponent
};
export default meta;
type Story = StoryObj<typeof List>;
export const Empty: Story = {};
export const OneItem: Story = {
render: (args) => (
<List {...args}>
<ListItem />
</List>
),
};
主要元件及其子元件將會顯示在 ArgTypes
doc block 的索引標籤版本中。索引標籤標題將對應於 subcomponents
物件的鍵。
如果您想要以不同的方式組織元件群組的文件,我們建議使用 MDX。它可以讓您完全控制元件的顯示方式,並支援任何設定。
自訂文件容器
文件容器是包裝文件頁面的元件。它負責在 Storybook 的 UI 中呈現文件頁面。您可以建立自己的元件並更新 Storybook UI 設定檔(即 .storybook/preview.js
)以參照它,藉此自訂它。
import * as React from 'react';
// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';
import { DocsContainer } from '@storybook/blocks';
const ExampleContainer = ({ children, ...props }) => {
return <DocsContainer {...props}>{children}</DocsContainer>;
};
const preview: Preview = {
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
docs: {
container: ExampleContainer,
},
},
};
export default preview;
覆寫預設主題
預設情況下,Storybook 為 UI 提供兩個主題:light
和 dark
。如果您需要自訂文件所使用的主題以符合現有的主題,您可以更新 Storybook UI 設定檔(即 .storybook/preview.js
)並套用它。
// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';
import { themes, ensure } from '@storybook/theming';
const preview: Preview = {
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
docs: {
theme: ensure(themes.dark), // The replacement theme to use
},
},
};
export default preview;
使用自訂 MDX 元件
Storybook 開箱即用提供了一組可用於自訂文件頁面的元件。如果您正在使用設計系統或元件庫,並希望將它們新增至您的文件頁面,您可以使用自己的元件覆寫繼承自 @mdx-js/react
的 MDXProvider
元件。然而,這裡有一個注意事項,元件替換只會在您使用 Markdown 語法撰寫文件時(例如,#
代表標題)才會生效。原生 HTML 元素,例如 <h1>
,將不會被您的自訂實作取代。
// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';
import { MDXProvider } from '@mdx-js/react';
import { DocsContainer } from '@storybook/blocks';
import * as DesignSystem from 'your-design-system';
export const MyDocsContainer = (props) => (
<MDXProvider
components={{
h1: DesignSystem.H1,
h2: DesignSystem.H2,
}}
>
<DocsContainer {...props} />
</MDXProvider>
);
const preview: Preview = {
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
docs: {
container: MyDocsContainer,
},
},
};
export default preview;
這不是 Storybook 的問題,而是 MDX 如何運作的細節。從他們的遷移指南中得知
「我們現在『沙箱化』元件,因為找不到更好的名稱。這表示當您傳遞一個 h1 的元件時,它確實會用於 # hi
,但不會用於 <h1>hi</h1>
」
疑難排解
目錄未如預期呈現
當使用 Autodocs 的目錄時,您可能會遇到目錄顯示與預期不同的情況。為了幫助您解決這些問題,我們編寫了一份可能導致問題發生的情境列表。
使用簡單的文件頁面
如果您的文件頁面只有一個相符的標題,並為其建立目錄,則預設情況下目錄不會被隱藏。這個問題的一個潛在解決方案是新增第二個標題或完全關閉目錄。
使用小螢幕
如果螢幕寬度小於 1200px,目錄將預設為隱藏。目前,沒有內建的解決方案可以在不影響文件頁面樣式相容性的情況下解決此問題。
使用 MDX
如果您使用 MDX 撰寫未附加的文件,您將無法自訂目錄,主要是因為目前實作不支援定義基於當前實作的參數。因此,目錄將始終恢復為全域提供的預設設定。
自動產生的文件未在單一儲存庫設定中顯示
Storybook 的 Autodocs 功能開箱即用,可以為您的 stories 自動產生文件。不過,如果您正在使用單一儲存庫設定 (例如,Yarn Workspaces
、pnpm Workspaces
),您可能會遇到部分文件未為您產生的問題。為了幫助您排除這些問題,我們準備了一些可能對您有幫助的建議。
更新您的 import 語句以直接參照元件,而不是套件的根目錄。例如
// Replace your-framework with the name of your framework
import type { Meta } from '@storybook/your-framework';
// ❌ Don't use the package's index file to import the component.
import { MyComponent } from '@component-package';
// ✅ Use the component's export to import it directly.
import { MyComponent } from '@component-package/src/MyComponent';
const meta: Meta<typeof MyComponent> = {
/* 👇 The title prop is optional.
* See https://storybook.dev.org.tw/docs/configure/#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'MyComponent',
component: MyComponent,
};
export default meta;
此外,如果您使用 TypeScript 開發,您可能需要更新 Storybook 的設定檔(即 .storybook/main.js|ts
)以包含以下內容
// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
import type { StorybookConfig } from '@storybook/your-framework';
const config: StorybookConfig = {
framework: '@storybook/your-framework',
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
typescript: {
// Overrides the default Typescript configuration to allow multi-package components to be documented via Autodocs.
reactDocgen: 'react-docgen',
check: false,
},
};
export default config;
如果您仍然遇到問題,我們建議您使用預設的溝通管道(例如,GitHub 討論)與社群聯繫。
控制項未在自動產生的文件中更新 story
如果您透過 inline
設定選項關閉了您 stories 的內嵌渲染,您會遇到相關控制項未更新文件頁面內 story 的情況。這是目前實作的已知限制,將在未來版本中解決。
進一步了解 Storybook 文件
- Autodocs 可為您的 stories 建立文件
- MDX 可自訂您的文件
- Doc Blocks 可編寫您的文件
- 發佈文件可自動化發佈文件流程