Addon 主题切换

Storybook 插件,用于在多个背景之间切换

在 Github 上查看

Storybook Addon 主题切换

此插件受 @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 正确初始化,这意味着它们始终返回 {} 作为初始值。为了纠正这一点,如果全局变量与默认/初始主题 ID 不同,则在发出 SET_STORIES 事件后,我们将使用默认/初始主题 ID 更新全局变量。

框架支持

React
:white_check_mark
作者
  • nickofthyme
    nickofthyme
协作
    React
标签