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

如何在 Storybook 中设置样式工具是社区中一个常见的问题。有大量的文章提供指导,但这些文章并不总是最新的。这最终会给您带来不必要的麻烦和大量的试错。
为了简化设置过程,我们推出了样式插件。它是一个与框架无关的解决方案,适用于 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
添加到 addons 数组中。
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,
}),
];
切换主题
用户已经习惯了他们喜爱的应用程序提供多种主题——例如深色模式和高对比度模式。您需要查看您的故事在每种主题下的外观。样式插件为您处理了这个问题!🎉
当您使用多个主题配置 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 这样通过 data 属性设置主题的工具,您可以将您的主题、默认主题和属性名称提供给 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 的功能,以便您可以使用更少的代码获得更多样式效果。这就是为什么我们添加了选项,以便您可以将 Sass 和 Postcss 包含在 Storybook 的 webpack 配置中。如果您使用的是 Storybook 7 并配合 Vite 或 Next.js framework,则已经为您处理了这一点。
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,
},
},
],
};
如果您需要用于 Tailwind 的 Postcss 8,请确保安装它,然后将该实现传递给设置中
// .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,请查看插件文档。
总结
样式插件简化了 Storybook 的配置,以满足您的所有样式需求,例如全局样式、主题提供程序和 CSS 处理工具。该插件允许在主题之间切换以及覆盖特定故事的主题,最棒的是它与框架无关,帮助您以任何您选择的方式交付最佳作品!
虽然这简化了您的样式工具配置,但我们希望让它变得更简单!从 Tailwind 开始,我们正在探索为最流行的库共享 codemods,帮助您自动设置此配置,以便您可以直接开始编写故事。
您对样式插件感到兴奋吗?您还希望看到 Storybook 与其他哪些集成?请在 Twitter 上@storybookjs 或在 Storybook Discord 服务器上与我们联系!我们迫不及待想见到您 🤩
告别配置的烦恼!
— Storybook (@storybookjs) 2023年3月23日
我们新的样式插件让 Storybook 轻松与像 @tailwindcss、@MaterialUI 和 @chakra_ui 这样的 CSS 库协同工作
🙆 与框架无关
🌎 处理全局样式
🎨 主题提供程序、覆盖和切换器https://#/bhBiqwer8g pic.twitter.com/Xj3ITPn6DK