文件
Storybook 文件

主題

觀看影片教學

Storybook 可以使用輕量級主題 API 來設定主題。

全域主題

可以全域設定 Storybook 的主題。

Storybook 包含兩種開箱即用的主題:「淺色」和「深色」。除非您將偏好的配色方案設定為深色,否則 Storybook 會預設使用淺色主題。

請確定您已安裝 @storybook/manager-api@storybook/theming 套件。

npm install --save-dev @storybook/manager-api @storybook/theming

例如,您可以修改 .storybook/manager.js 來告知 Storybook 使用「深色」主題

.storybook/manager.js
import { addons } from '@storybook/manager-api';
import { themes } from '@storybook/theming';
 
addons.setConfig({
  theme: themes.dark,
});

設定主題時,請設定完整的主題物件。主題會被取代,而非合併。

主題文件

Storybook 文件使用與 Storybook UI 相同的主題系統,但會獨立於主要 UI 設定主題。

假設您在 .storybook/manager.js 中為主要 UI 定義了 Storybook 主題

.storybook/manager.js
import { addons } from '@storybook/manager-api';
import { themes } from '@storybook/theming';
 
addons.setConfig({
  theme: themes.dark,
});

以下是如何在 .storybook/preview.js 中為文件指定相同的主題

.storybook/preview.ts
// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';
 
import { themes } from '@storybook/theming';
 
const preview: Preview = {
  parameters: {
    docs: {
      theme: themes.dark,
    },
  },
};
 
export default preview;

如果您想瞭解如何建立自己的主題,請繼續閱讀。

建立主題快速入門

自訂 Storybook 最簡單的方式是使用 storybook/theming 中的 create() 函式產生新的主題。此函式包含最常見的主題變數的簡寫。以下是如何使用它

在您的 .storybook 目錄中,建立一個名為 YourTheme.js 的新檔案,並新增以下內容

.storybook/YourTheme.js
import { create } from '@storybook/theming';
 
export default create({
  base: 'light',
  brandTitle: 'My custom Storybook',
  brandUrl: 'https://example.com',
  brandImage: 'https://storybook.dev.org.tw/images/placeholders/350x150.png',
  brandTarget: '_self',
});

如果您使用 brandImage 來新增自訂標誌,您可以使用任何最常見的影像格式。

在上方,我們建立一個新的主題,其將

  • 使用 Storybook 的 light 主題作為基準。
  • 使用我們自己的標誌 (在 brandImage 變數中定義) 取代側邊欄中的 Storybook 標誌。
  • 新增自訂品牌資訊。
  • 透過 target 屬性,將品牌連結設定為在同一個視窗中開啟 (而不是在新視窗中開啟)。

最後,我們需要將主題匯入 Storybook。在您的 .storybook 目錄中建立一個名為 manager.js 的新檔案,並新增以下內容

.storybook/manager.js
import { addons } from '@storybook/manager-api';
import yourTheme from './YourTheme';
 
addons.setConfig({
  theme: yourTheme,
});

現在,您的自訂主題會取代 Storybook 的預設主題,而且您會在 UI 中看到類似的一組變更。

Storybook starter theme

讓我們看看更複雜的範例。複製下列程式碼,並將其貼到 .storybook/YourTheme.js 中。

.storybook/YourTheme.js
import { create } from '@storybook/theming/create';
 
export default create({
  base: 'light',
  // Typography
  fontBase: '"Open Sans", sans-serif',
  fontCode: 'monospace',
 
  brandTitle: 'My custom Storybook',
  brandUrl: 'https://example.com',
  brandImage: 'https://storybook.dev.org.tw/images/placeholders/350x150.png',
  brandTarget: '_self',
 
  //
  colorPrimary: '#3A10E5',
  colorSecondary: '#585C6D',
 
  // UI
  appBg: '#ffffff',
  appContentBg: '#ffffff',
  appPreviewBg: '#ffffff',
  appBorderColor: '#585C6D',
  appBorderRadius: 4,
 
  // Text colors
  textColor: '#10162F',
  textInverseColor: '#ffffff',
 
  // Toolbar default and active colors
  barTextColor: '#9E9E9E',
  barSelectedColor: '#585C6D',
  barHoverColor: '#585C6D',
  barBg: '#ffffff',
 
  // Form colors
  inputBg: '#ffffff',
  inputBorder: '#10162F',
  inputTextColor: '#10162F',
  inputBorderRadius: 2,
});

在上方,我們使用下列變更來更新主題

  • 自訂調色盤 (在 appcolor 變數中定義)。
  • 自訂字型 (在 fonttext 變數中定義)。

引入新變更後,自訂主題應該會產生類似的結果。

Storybook custom theme loaded

許多主題變數是選用的,base 屬性則不是

@storybook/theming 套件是使用 TypeScript 建立的,這應該有助於為 TypeScript 使用者建立有效的主題。這些類型是套件本身的一部分。

CSS 逸出方法

Storybook 的主題 API 在設計上範圍較窄。如果您想要對 CSS 進行更細緻的控制,所有 UI 和 Docs 元件都標記了類別名稱,讓這一切成為可能。請自行承擔風險使用,因為這是一項進階功能。

若要設定這些元素的樣式,請將 style 標籤插入到

  • 針對 Storybook 的 UI,請使用 .storybook/manager-head.html
  • 針對 Storybook Docs,請使用 .storybook/preview-head.html
注意

如同您可以調整預覽的 head 標籤,Storybook 也允許您透過 .storybook/manager-head.html 修改管理端的程式碼。當您要新增針對 Storybook HTML 的主題樣式時,這會很有幫助,但這會帶來一些成本,因為 Storybook 的內部 HTML 可能會在發布週期中隨時變更。

MDX 元件覆寫

如果您使用 MDX 撰寫文件,則還有另一層「主題化」的選項。MDX 允許您使用 components 參數完全覆寫從 Markdown 呈現的元件。這是一個進階用法,我們在 Storybook 中不正式支援它,但如果您需要,這是一個強大的架構。

以下是如何在 .storybook/preview.js 中為頁面上的 code 區塊插入自訂程式碼渲染器的範例

.storybook/preview.ts
// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';
 
import { CodeBlock } from './CodeBlock';
 
const preview: Preview = {
  parameters: {
    docs: {
      components: {
        code: CodeBlock,
      },
    },
  },
};
 
export default preview;

您甚至可以覆寫 Storybook 的區塊元件。

以下是如何插入自訂的 <Canvas /> 區塊的範例

.storybook/preview.ts
// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';
 
import { MyCanvas } from './MyCanvas';
 
const preview: Preview = {
  parameters: {
    docs: {
      components: {
        Canvas: MyCanvas,
      },
    },
  },
};
 
export default preview;

外掛程式和主題建立

有些外掛程式需要 Storybook 使用者必須新增的特定主題變數。如果您與社群分享您的主題,請務必支援官方 API 和其他熱門外掛程式,讓您的使用者擁有一致的體驗。

例如,熱門的 Actions 外掛程式使用 react-inspector,它本身也有主題。提供額外的主題變數來設定其樣式,如下所示

addonActionsTheme: {
  ...chromeLight,
  BASE_FONT_FAMILY: typography.fonts.mono,
  BASE_BACKGROUND_COLOR: 'transparent',
}

為外掛程式作者使用主題

將上述的主題變數重複用於原生的 Storybook 開發人員體驗。主題引擎依賴 emotion,一個 CSS-in-JS 函式庫。

YourTheme.js
import { styled } from '@storybook/theming';

在物件表示法中使用主題變數

MyComponent.js|jsx
const Component = styled.div(({ theme }) => ({
  background: theme.background.app,
  width: 0,
}));

或使用樣板字串

MyComponent.js|jsx
const Component = styled.div`
  background: `${props => props.theme.background.app}`
  width: 0;
`;