返回博客

Styling Addon:在 Storybook 中配置样式和主题

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

loading
Shaun Evening
@Integrayshaun
最后更新

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

为了简化您的设置过程,我们推出了 Styling Addon。它是一个与框架无关的解决方案,可与 Tailwind、Material UI、Chakra、Emotion、Styled-components、SASS 和 PostCSS 配合使用。

  • 🌎 提供全局样式
  • 🎨 添加主题提供者
  • 🌗 一键切换主题
  • ‼️ 为组件覆盖主题
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 添加到插件数组中。

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

提供全局样式

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

// .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 组件提供。要使此组件可用于您的组件故事,您可以使用包含的 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 将获取该提供者和您的主题配置,并为您包装所有组件故事。

// .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,
  }),
];

切换主题

用户已习惯于期望他们喜欢的应用程序具有多种主题,例如暗模式和高对比度模式。您需要查看您的组件故事在每种模式下的外观。Styling Addon 会为您处理这个问题!🎉

当您使用多个主题配置 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。如果您是其中之一:不用担心!我们已经为您考虑到了!Styling Addon 包含另外两个装饰器,适用于那些根据父类或数据属性更改主题的用户。

例如,Tailwind 允许您在父元素具有 .dark 类时激活暗模式。在这种情况下,将您的主题类添加到 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 等工具,您可能会拥有带有不同主题的组件故事快照。为此,请将 parameters.theming.themeOverride 设置为您希望为组件故事应用的主题名称。

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,Styling Addon 提供了 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,并且您代码中的任何更改都将与您的组件故事一起重建您的 CSS。

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

总结

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

虽然这简化了您样式工具的配置,但我们希望使其更加容易!从 Tailwind 开始,我们正在寻找共享最受欢迎库的 codemod,以帮助您自动设置此配置,这样您就可以直接开始编写您的组件故事了。

您对 Styling Addon 感到兴奋吗?您还想看到哪些其他的 Storybook 集成?在 @storybookjs 上发推或在 Storybook Discord 服务器 上联系我们!我们迫不及待地想见到您 🤩

加入 Storybook 邮件列表

获取最新消息、更新和发布信息

7,468开发者及更多

我们正在招聘!

加入 Storybook 和 Chromatic 团队。构建被数十万开发人员在生产中使用的工具。远程优先。

查看职位

热门帖子

Storybook for React Native (6.5)

性能改进、支持组件故事格式、Controls 和 Args。此外,还新增了配置文件的格式,以与 Storybook 核心保持一致。
loading
Daniel Williams

Storybook 7.0

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

Storybook for SvelteKit

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

特别感谢 Netlify CircleCI