擴充套件主題切換

Storybook 擴充套件,用於在多個背景之間切換

在 Github 上檢視

Storybook 擴充套件主題切換

此擴充套件的靈感來自 @storybook/addon-backgroundsstorybook-addon-themes,並建立更流暢且功能更豐富的實作。另請參閱 storybook-addon-background-toggle

此擴充套件可用於將自訂 HTML 類別新增至一個或多個目標 HTML 元素。所有選項均在下方說明,請參閱下方的「參數」區段。

https://nickofthyme.github.io/storybook-addon-theme-toggle/ 試用看看

https://user-images.githubusercontent.com/19007109/128076049-7aca13a8-9e5e-4ce2-9bc0-9f82ab662418.mp4

相容性

此版本與 storybook 版本 >6.x 相容。

從 storybook 6.3.0 開始,全域參數會以查詢搜尋參數的形式與 URL 同步 (storybookjs/storybook#15056)。因此,這會鎖定預設全域設定,並在故事之間持續保留。如果您想避免此行為,可以使用 storybook@~6.2.0

安裝

yarn

yarn add -D storybook-addon-theme-toggle

npm

npm i -D storybook-addon-theme-toggle

開始使用

安裝完成後,將此擴充套件新增至 storybook main.js 檔案中的 addons 陣列

// main.js
module.exports = {
  addons: [
    'storybook-addon-theme-toggle'
  ],
};

如需更多資訊,請參閱 storybook 文件

參數

此外掛程式的參數位於 theme 鍵下,定義如下。

interface Parameters {
  /**
   * Ignores global values in url params
   *
   * @default true
   */
  ignoreQueryParams?: false;
  /**
   * Tefault theme id
   */
  default?: string;
  /**
   * Theme options to be applied
   */
  themes: Theme[];
  /**
   * Selected theme is clearable
   *
   * @default true
   */
  clearable?: boolean;
  /**
   * Disable addon at story level
   *
   * @default false
   */
  disable?: boolean;
  /**
   * Persist theme selection between stories
   *
   * @default false
   */
  persist?: boolean;
  /**
   * Blur tooltip on theme selection
   *
   * @default true
   */
  blurOnSelect?: boolean;
  /**
   * Override icon used in toolbar
   * See https://next--storybookjs.netlify.app/official-storybook/?path=/story/basics-icon--labels
   *
   * @default 'mirror'
   */
  icon?: IconsProps['icon'];
  /**
   * A callback that will be executed when the theme changes
   */
  onChange?: (theme: Theme) => void;
  /**
   * Target element selector(s) to apply class(es)
   *
   * @default 'body'
   */
  selector?: string | string[];
}

Theme 類型定義如下。

interface Theme {
  /**
   * id of the theme
   */
  id: string;
  /**
   * Title of the theme in theme selector ui
   *
   * @default {@link Theme#id}
   */
  title?: string;
  /**
   * Class or classes to be applied to targeted element(s) via selector(s)
   */
  class?: string | string[]
  /**
   * Badge color in the theme selector ui
   */
  color: string;
  /**
   * Url of image to display over color swatch on theme selector
   */
  imageUrl?: string
}

組態

全域層級

您可以在 storybook preview.(ts|js) 檔案中全域層級設定主題,如下所示。

// preview.ts

import type { ThemeParameter } from 'storybook-addon-theme-toggle';

type Parameters = ThemeParameter & {
  // other global parameter types
};

export const parameters: Parameters = {
  theme: {
    default: 'light',
    selector: 'body',
    onChange(theme) {
      // handle new theme
    },
    themes: [
      {
        id: 'light',
        title: 'Light',
        class: 'light',
        color: '#fff',
      },
      {
        id: 'dark',
        title: 'Dark',
        class: 'dark',
        color: '#000',
      },
    ],
  }
};

故事層級

ThemeParameter 中定義的所有屬性都可以在故事層級被覆寫。但是,建議只覆寫部分參數,以防止定義可能會對所有故事的擴充套件行為產生負面影響的參數。可接受的屬性包括 defaultblurOnSelectdisableignoreQueryParamsclearableThemeStoryParameter 類型是一個輔助工具,應該用於限制在故事層級覆寫哪些屬性;

// story1.stories.tsx

import type { ThemeStoryParameter } from 'storybook-addon-theme-toggle';

const Example = () => <span>Hello!</span>;

Example.parameters: ThemeStoryParameter = {
  theme: {
    default: 'dark',
  }
};

在裝飾器中使用

全域 storybook Decorators 可以用於多種用途。因此,在裝飾器內部存取選取的主題非常重要。這也是選擇使用 globals 來維護選取主題狀態的主要原因。

以下是一個簡單的範例,說明如何透過 context.globals 存取主題。

// preview.tsx

import React from "react";

import type { DecoratorFunction } from "@storybook/addons";
import type { ThemeGlobals } from 'storybook-addon-theme-toggle';

const Decorator: DecoratorFunction<JSX.Element> = (Story, context) => {
  const globals = context.globals as ThemeGlobals;
  const selectedTheme = globals.theme;

  return (
    <div>
      <Story {...context} />
      <br />
      <pre>
        Theme: {selectedTheme}
        {JSON.stringify(globals, null, 2)}
      </pre>
    </div>
  );
};

export const decorators = [Decorator];

.storybook/Decorator.tsx 中查看完整範例。

目前 storybook 未正確初始化全域設定,這表示它們始終會傳回 {} 作為初始值。為了修正此問題,如果它們不同,我們會在發出 SET_STORIES 事件後,使用預設/初始主題 ID 更新全域設定。

框架支援

React
  • nickofthyme
    nickofthyme 製作
與以下單位合作
    React
標籤