返回博客

样式插件:在 Storybook 中配置样式和主题

使用样式插件来配置你的样式工具,并为你的 UI 组件提供主题。

loading
Shaun Evening
@Integrayshaun
最后更新

如何在 Storybook 中设置样式工具是社区中常见的问题。有很多文章提供了说明,但这些文章并不总是最新的。这最终会导致你不必要的麻烦和大量的试错。

为了简化你的设置过程,我们推出了样式插件。这是一个框架无关的解决方案,适用于 Tailwind、Material UI、Chakra、Emotion、Styled-components、SASS 和 PostCSS。

  • 🌎 提供全局样式
  • 🎨 添加主题提供器
  • 🌗 一键切换主题
  • ‼️ 为 Story 覆盖主题
Switching between light and dark mode using the Styling Addon's theme switcher

入门

根据你使用的是 Storybook 6 还是 Storybook 7,有不同的版本可用。

# For Storybook 6
yarn add -D @storybook/addon-styling

# For Storybook 7
yarn add -D @storybook/addon-styling@next

安装完成后,打开你的 .storybook/main.js 文件,并将 @storybook/addon-styling 添加到 addons 数组中。

module.exports = {
  stories: [
    "../stories/**/*.mdx",
    "../stories/**/*.stories.@(js|jsx|ts|tsx)",
  ],
  addons: [
    "@storybook/addon-essentials",
    "@storybook/addon-styling",
  ],
};

提供全局样式

如果你的全局样式在 CSS 文件中定义,你可以在 .storybook/preview.js 文件中导入你的样式表。Storybook 将在每次 story 渲染时加载此处导入的任何文件。

// .storybook/preview.js

import '../src/styles.css'; // Your local styles
import 'bootstrap/dist/css/bootstrap.min.css'; // Styles from node_modules

React 的 UI 库(如 Material UI)将其全局样式作为 React 组件提供。为了使这个组件可用于你的组件 stories,你可以使用包含的 withThemeFromJSXProvider 装饰器。

// .storybook/preview.js
import { CssBaseline } from "@mui/material";
import { withThemeFromJSXProvider } from "@storybook/addon-styling";

/* snipped for brevity */

export const decorators = [
  withThemeFromJSXProvider({
    GlobalStyles: CssBaseline,
  }),
];

添加主题提供器

React 库通常附带一个 ThemeProvider 组件,这是一个将其主题与其子组件共享的包装器。withThemeFromJSXProvider 将获取该提供器和你的主题配置,并为你包装所有的 stories。

// .storybook/preview.js
import { CssBaseline, ThemeProvider } from "@mui/material";
import { withThemeFromJSXProvider } from "@storybook/addon-styling";
import { myCustomTheme } from "../src/theme.js";

/* snipped for brevity */

export const decorators = [
  withThemeFromJSXProvider({
    themes: { myCustomTheme },
    Provider: ThemeProvider,
    GlobalStyles: CssBaseline,
  }),
];

切换主题

用户已经开始期望他们最喜欢的应用程序具有多种主题——例如暗黑模式和高对比度。你需要查看你的 stories 在每个主题中的外观。样式插件为你处理了这一切!🎉

当你使用多个主题配置 withThemeFromJSXProvider 时,它将在 Storybook 工具栏中添加一个下拉菜单,让你一键切换每个主题。

// .storybook/preview.js
import { CssBaseline, ThemeProvider } from "@mui/material";
import { withThemeFromJSXProvider } from "@storybook/addon-styling";
import {
  myCustomTheme,
  myCustomDarkTheme,
  myCustomHighContrastTheme,
} from "../src/theme.js";

/* snipped for brevity */

export const decorators = [
  withThemeFromJSXProvider({
    themes: {
      light: myCustomTheme,
      dark: myCustomDarkTheme,
      highContrast: myCustomHighContrastTheme,
    },
    defaultTheme: "light",
    Provider: ThemeProvider,
    GlobalStyles: CssBaseline,
  }),
];

不使用 React 或 JSX?没问题!

很大一部分 Storybook 用户不使用 JSX 或 React。如果你是其中之一:别担心!我们已经为你考虑到了!样式插件包含了另外两个装饰器,适用于那些基于父类或数据属性更改主题的人。

例如,当父元素具有 .dark 类时,Tailwind 允许你激活暗黑模式。在这种情况下,将你的主题类添加到 withThemeFromClassName 并选择一个默认主题来设置主题选择器。

// .storybook/preview.js
import { withThemeByClassName } from "@storybook/addon-styling";

import "../src/tailwind.css";

export const decorators = [
  withThemeByClassName({
    themes: {
      light: "light",
      dark: "dark",
    },
    defaultTheme: "light",
  }),
];

如果你正在使用像 Bootstrap 这样使用数据属性设置主题的工具,你可以将你的主题、默认主题和属性名称提供给 withThemeFromDataAttribute 来设置主题选择器。

// .storybook/preview.js
import { withThemeByDataAttribute } from "@storybook/addon-styling";
import "bootstrap/dist/css/bootstrap.min.css";

export const decorators = [
  withThemeByDataAttribute({
    themes: {
      light: "light",
      dark: "dark",
    },
    defaultTheme: "light",
    attributeName: "data-bs-theme",
  }),
];

覆盖主题

如果你正在使用像 Chromatic 这样的工具,你可能需要对应用了不同主题的 stories 进行快照。为此,请将 parameters.theming.themeOverride 设置为你想要应用于你的 story 的主题名称。

Switching to the "Primary Dark" story for the story component overrides the theme to dark

配置 CSS 处理工具

CSS 处理工具扩展了 CSS 的功能,以便你可以用更少的代码获得更多的样式。这就是为什么我们添加了选项,以便在你的 Storybook 的 webpack 配置中包含 Sass 和 Postcss。如果你正在使用 Storybook 7 和 Vite 或 Next.js 框架,这已经为你处理好了。

Sass

为了替换已弃用的 @storybook/preset-sass,样式插件为 Sass 提供了配置选项。

首先安装一些额外的依赖项

yarn add -D style-loader sass sass-loader resolve-url-loader

然后更新 .storybook/main.js 中的 @storybook/addon-styling 配置以包含 sass

// .storybook/main.js
module.exports = {
  stories: ["../stories/**/*.mdx", "../stories/**/*.stories.@(js|jsx|ts|tsx)"],
  addons: [
    "@storybook/addon-essentials",
    {
      name: "@storybook/addon-styling",
      options: {
        sass: {
          implementation: require("sass"),
        },
      },
    },
  ],
};

现在你可以将你的 Sass 文件导入到 .storybook/preview.js 中。

// .storybook/preview.js

import '../src/styles.scss';

需要更高级的 Sass 配置?在插件文档中了解有关 options.sass 的完整 API。

PostCSS

为了替换已弃用的 @storybook/preset-postcss,addon-styling 为 PostCSS 提供了配置选项。更新 .storybook/main.js 中的 @storybook/addon-styling 配置以包含 postCss,它将使用在你的 postcss.config.js 文件中设置的选项。

// .storybook/main.js
module.exports = {
  stories: ["../stories/**/*.mdx", "../stories/**/*.stories.@(js|jsx|ts|tsx)"],
  addons: [
    "@storybook/addon-essentials",
    {
      name: "@storybook/addon-styling",
      options: {
        postCss: true,
      },
    },
  ],
};

如果你需要 Postcss 8 用于 Tailwind,请确保安装它,然后在设置中传递该实现。

// .storybook/main.js
module.exports = {
  stories: ["../stories/**/*.mdx", "../stories/**/*.stories.@(js|jsx|ts|tsx)"],
  addons: [
    "@storybook/addon-essentials",
    {
      name: "@storybook/addon-styling",
      options: {
        postCss: {
          implementation: require("postcss"),
        },
      },
    },
  ],
};

配置完成后,你现在可以将你的 Tailwind CSS 文件导入到 .storybook/preview.js 中,并且对你代码的任何更改都将与你的 stories 一起重建你的 CSS。

要了解有关 options.postCss 的完整 API,请查看插件文档

总结一下

样式插件简化了 Storybook 的配置,以满足你所有的样式需求,例如全局样式、主题提供器和 CSS 处理工具。该插件允许在主题之间切换和为特定 stories 覆盖主题,最棒的是它是框架无关的,帮助你以你选择的任何方式交付最好的工作!

虽然这简化了你的样式工具的配置,但我们希望使其更加容易!从 Tailwind 开始,我们正在考虑为最流行的库分享 codemods,以帮助你自动设置此配置,以便你可以直接开始编写你的 stories。

你对样式插件感到兴奋吗?你还想看到哪些 Storybook 集成?在 Twitter 上发推文给 @storybookjs 或在 Storybook Discord 服务器上联系我们!我们迫不及待想见到你 🤩

加入 Storybook 邮件列表

获取最新的新闻、更新和发布

6,730位开发者及更多

我们正在招聘!

加入 Storybook 和 Chromatic 背后的团队。构建被成千上万开发者在生产环境中使用的工具。远程优先。

查看职位

热门文章

Storybook for React Native (6.5)

性能改进,支持组件 Story Format、controls 和 args。以及新的配置文件格式,以与 Storybook 核心对齐。
loading
Daniel Williams

Storybook 7.0

下一代组件开发和测试
loading
Michael Shilman

Storybook for SvelteKit

使用我们的新框架为 SvelteKit 1.0 提供零配置支持
loading
Jeppe Reinhold
加入社区
6,730位开发者及更多
为什么为什么选择 Storybook组件驱动的 UI
文档指南教程更新日志遥测
社区插件参与进来博客
展示探索项目组件词汇表
开源软件
Storybook - Storybook 中文

特别感谢 Netlify CircleCI