加入直播会议:周四,东部时间上午 11 点,Storybook 9 发布 & 问答

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',
  }
};

在 Decorator 中的用法

全局 Storybook Decorators 可用于多种用途。因此,在 Decorator 中访问选定的主题非常重要。这是选择使用 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 未正确初始化全局变量(globals),这意味着它们始终返回 {} 作为初始值。为纠正此问题,一旦 SET_STORIES 事件触发,如果全局变量与默认/初始主题 ID 不同,我们将更新全局变量。

框架支持

React
:white_check_mark:
开发者
  • mikaelb
    mikaelb
合作
    React
标签