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

如何在 Storybook 中设置样式工具是社区中常见的疑问。有很多文章提供了说明,但这些说明并不总是最新的。这会导致您不必要的头痛和大量的试错。
为了简化您的设置过程,我们推出了 Styling Addon。它是一个与框架无关的解决方案,可与 Tailwind、Material UI、Chakra、Emotion、Styled-components、SASS 和 PostCSS 配合使用。
- 🌎 提供全局样式
- 🎨 添加主题提供者
- 🌗 一键切换主题
- ‼️ 为组件覆盖主题

入门
根据您使用的是 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 设置为您希望为组件故事应用的主题名称。

配置 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 (@storybookjs) 2023 年 3 月 23 日
我们全新的 Styling Addon 使您可以轻松地将 Storybook 配置为与 CSS 库配合使用,例如 @tailwindcss、@MaterialUI 和 @chakra_ui
🙆 框架无关
🌎 处理全局样式
🎨 主题提供者、覆盖和切换器https://#/bhBiqwer8g pic.twitter.com/Xj3ITPn6DK