主题化
观看视频教程
Storybook 可以使用轻量级主题 API 进行主题化。
全局主题化
可以全局主题化 Storybook。
Storybook 包含两个开箱即用的主题:“light” 和 “dark”。除非您已将首选配色方案设置为深色,否则 Storybook 将默认使用浅色主题。
请确保您已安装 @storybook/manager-api
和 @storybook/theming
包。
npm install --save-dev @storybook/manager-api @storybook/theming
例如,您可以修改 .storybook/manager.js
来告诉 Storybook 使用 “dark” 主题
import { addons } from '@storybook/manager-api';
import { themes } from '@storybook/theming';
addons.setConfig({
theme: themes.dark,
});
设置主题时,请设置完整的主题对象。主题会被替换,而不是合并。
主题化文档
Storybook 文档 使用与 Storybook UI 相同的主题系统,但其主题与主 UI 独立。
假设您在 .storybook/manager.js
中为主 UI 定义了 Storybook 主题
import { addons } from '@storybook/manager-api';
import { themes } from '@storybook/theming';
addons.setConfig({
theme: themes.dark,
});
以下是如何在 .storybook/preview.js
中为文档指定相同主题的方法
// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';
import { themes } from '@storybook/theming';
const preview: Preview = {
parameters: {
docs: {
theme: themes.dark,
},
},
};
export default preview;
如果您想学习如何创建自己的主题,请继续阅读。
创建主题快速入门
自定义 Storybook 最简单的方法是使用 storybook/theming
中的 create()
函数生成新主题。此函数包含最常见主题变量的简写。以下是如何使用它
在您的 .storybook
目录中,创建一个名为 YourTheme.js
的新文件,并添加以下内容
import { create } from '@storybook/theming';
export default create({
base: 'light',
brandTitle: 'My custom Storybook',
brandUrl: 'https://example.com',
brandImage: 'https://storybook.org.cn/images/placeholders/350x150.png',
brandTarget: '_self',
});
如果您使用 brandImage
添加自定义徽标,则可以使用任何最常见的图像格式。
在上面,我们正在创建一个新主题,它将
- 使用 Storybook 的
light
主题作为基线。 - 将侧边栏中的 Storybook 徽标替换为我们自己的徽标(在 brandImage 变量中定义)。
- 添加自定义品牌信息。
- 通过
target
属性,将品牌链接设置为在同一窗口中打开(而不是新窗口)。
最后,我们需要将主题导入 Storybook。在您的 .storybook
目录中创建一个名为 manager.js
的新文件,并添加以下内容
import { addons } from '@storybook/manager-api';
import yourTheme from './YourTheme';
addons.setConfig({
theme: yourTheme,
});
现在,您的自定义主题将替换 Storybook 的默认主题,并且您将在 UI 中看到一组类似的更改。
让我们看一个更复杂的示例。复制以下代码并将其粘贴到 .storybook/YourTheme.js
中。
import { create } from '@storybook/theming/create';
export default create({
base: 'light',
// Typography
fontBase: '"Open Sans", sans-serif',
fontCode: 'monospace',
brandTitle: 'My custom Storybook',
brandUrl: 'https://example.com',
brandImage: 'https://storybook.org.cn/images/placeholders/350x150.png',
brandTarget: '_self',
//
colorPrimary: '#3A10E5',
colorSecondary: '#585C6D',
// UI
appBg: '#ffffff',
appContentBg: '#ffffff',
appPreviewBg: '#ffffff',
appBorderColor: '#585C6D',
appBorderRadius: 4,
// Text colors
textColor: '#10162F',
textInverseColor: '#ffffff',
// Toolbar default and active colors
barTextColor: '#9E9E9E',
barSelectedColor: '#585C6D',
barHoverColor: '#585C6D',
barBg: '#ffffff',
// Form colors
inputBg: '#ffffff',
inputBorder: '#10162F',
inputTextColor: '#10162F',
inputBorderRadius: 2,
});
在上面,我们正在使用以下更改更新主题
- 自定义调色板(在
app
和color
变量中定义)。 - 自定义字体(在
font
和text
变量中定义)。
随着新更改的引入,自定义主题应产生类似的结果。
许多主题变量是可选的,但 base
属性是必需的。
@storybook/theming
包是使用 TypeScript 构建的,这应该有助于为 TypeScript 用户创建有效的主题。这些类型是包本身的一部分。
CSS 逃生舱口
Storybook 主题 API 在设计上是狭窄的。如果您想对 CSS 进行细粒度的控制,则所有 UI 和文档组件都标有类名,从而使其成为可能。使用风险自负,因为这是一项高级功能。
要设置这些元素的样式,请将样式标签插入到
- 对于 Storybook UI,请使用
.storybook/manager-head.html
- 对于 Storybook 文档,请使用
.storybook/preview-head.html
与您可以调整 预览的 head 标签 的方式相同,Storybook 允许您通过 .storybook/manager-head.html
修改管理器端的代码。当添加以 Storybook HTML 为目标的 theme 样式时,它可能会有所帮助,但它会带来成本,因为 Storybook 的内部 HTML 可能会在发布周期中随时更改。
MDX 组件覆盖
如果您正在使用 MDX 进行文档编写,则还有另一个级别的“主题化”。MDX 允许您使用 components
参数完全覆盖 Markdown 中渲染的组件。这是一种高级用法,我们在 Storybook 中不正式支持它,但如果您需要它,它是一个强大的构造。
以下是如何在 .storybook/preview.js
中为页面上的 code
块插入自定义代码渲染器的方法
// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';
import { CodeBlock } from './CodeBlock';
const preview: Preview = {
parameters: {
docs: {
components: {
code: CodeBlock,
},
},
},
};
export default preview;
您甚至可以覆盖 Storybook 块组件。
以下是如何插入自定义 <Canvas />
块的方法
// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';
import { MyCanvas } from './MyCanvas';
const preview: Preview = {
parameters: {
docs: {
components: {
Canvas: MyCanvas,
},
},
},
};
export default preview;
插件和主题创建
某些插件需要 Storybook 用户必须添加的特定主题变量。如果您与社区分享您的主题,请确保支持官方 API 和其他流行的插件,以便您的用户获得一致的体验。
例如,流行的 Actions 插件使用 react-inspector,它本身也有主题。提供额外的主题变量来设置其样式,如下所示
addonActionsTheme: {
...chromeLight,
BASE_FONT_FAMILY: typography.fonts.mono,
BASE_BACKGROUND_COLOR: 'transparent',
}
为插件作者使用主题
为了获得原生的 Storybook 开发人员体验,请重用上面的主题变量。主题引擎依赖于 CSS-in-JS 库 emotion。
import { styled } from '@storybook/theming';
在对象表示法中使用主题变量
const Component = styled.div(({ theme }) => ({
background: theme.background.app,
width: 0,
}));
或使用模板字面量
const Component = styled.div`
background: `${props => props.theme.background.app}`
width: 0;
`;