Storybook 的主题、主题提供者和真正的深色模式
Storybook Facelift 是零配置的 - 它将只为原生主题返回一个亮/暗模式按钮
但您也可以
- 添加可以使用 Storybook 内置主题支持对 Storybook 进行主题化的主题
- Storybook 主题
- Material UI 主题
- 或者,如果您提供主题转换器,则可以提供自定义主题
- 添加可以使用 Storybook 内置主题提供者来装饰组件的主题
- 真正的深色模式
- 为 @storybook/addon-docs 和更多 UI 控件解锁深色模式和列控制
安装
npm i -D storybook-facelift
配置插件
将插件添加到您的 Storybook main.js
文件(或 main.ts
- 从现在开始,我们将只假设为 js...)
module.exports = {
addons: ['storybook-facelift'],
}
为了充分利用插件,您可能希望通过 preview.js
中的参数对其进行配置。
export const parameters = {
facelift: {...},
}
TypeScript 支持示例
Storybook Facelift 提供了一个自定义的 Parameters
类型来帮助您在参数中获得类型安全。
它接受一个泛型,让您可以从其他插件添加更多参数类型并保留 Storybook 参数类型安全
import type { Parameters } from 'storybook-facelift'
import type { OtherAddonParam } from 'other-addon'
export const parameters: Parameters<{
otherAddon: OtherAddonParam,
}> = {
actions: { argTypesRegex: '^on[A-Z].*' },
otherAddon: {...},
facelift: {...},
}
配置 Story
您也可以在 Story 级别配置 Storybook Facelift,例如,在 Story 级别而不是全局级别启用使用主题提供者的自动主题化,甚至可能为此 Story 添加一个特殊的主题提供者
import React from 'react'
import { Tag } from './Tag'
export default {
title: 'UI/Tag',
component: Tag,
parameters: {
facelift: {
addProvider: true,
provider: 'styled',
providerTheme: 'theme-1',
},
},
}
const Template = (args) => <Tag {...args} />
export const Controllable = Template.bind({})
Controllable.args = {
label: 'Tag',
}
TypeScript 支持示例
Storybook Facelift 提供了一个自定义的 Meta 类型来帮助您在 Story 参数中获得类型安全。
此类型接受 2 个泛型参数,额外的参数类型和 Storybook 自己的 Args
(遗憾的是,如果您希望应用 Args
泛型并且没有额外的插件参数类型需要提供,则必须提供一个空对象作为第一个泛型)
import React from 'react'
import { Tag } from './Tag'
import type { Story } from '@storybook/react'
import type { Meta } from 'storybook-facelift'
import type { TagProps } from './Tag'
import type { OtherAddonParam } from 'other-addon'
export default {
title: 'UI/Tag',
component: Tag,
parameters: {
otherAddon: {...},
facelift: {...},
},
} as Meta<{otherAddon: OtherAddonParam}>
const Template: Story<TagProps> = (args) => <Tag {...args} />
export const Controllable = Template.bind({})
Controllable.args = {
label: 'Tag',
}
插件参数
"addProvider"?: boolean
"autoThemeStory"?: boolean // deprecated - use addProvider
"defaultTheme"?: string
"defaultVariant"?: "light" | "dark"
"docs"?: ParamDocs
"enhanceUi"?: boolean
"includeNative"?: boolean
"native"?: ParamNative
"override"?: ThemeOptionsOverride
"provider"?: "mui" | "styled" | "emotion"
"providerTheme"?: string
"themeConverters"?: Record<string, ThemeConverterFn>
"themes"?: ParamTheme[]
"ui"?: ParamUi
addProvider boolean
启用主题提供者(全局或 Story 级别)
defaultTheme string
Storybook 启动时使用的默认主题 - 主题参数中的键用作参考
defaultVariant "light" | "dark"
用于 Storybook 主题的默认主题变体
docs ParamDocs
增强的文档控制
// Set to true to hide the column borders in docs table
"hidePropertyBorders"?: boolean
// Set to true to hide description column in docs table
"hideDescription"?: boolean
// Set to true to hide default value column in docs table
"hideDefaults"?: boolean
// Set to true to hide the controls column in docs
"hideControls"?: boolean
// Set to true to hide the sibling stories shown below property table
"hideStories"?: boolean
// Set to either full or simple - full is default, and simple will ONLY show docs table
"type"?: "full" | "simple"
enhanceUi boolean
修复一些轻微的 CSS 错误,并允许使用 ui
参数
includeNative boolean
如果提供了自定义主题,则将此参数设置为 true
以包含原生 Storybook 主题
override ThemeOptionsOverride
Storybook 主题选项对象,它将扩展到用作所有主题创建默认值的默认 Storybook 主题选项上
此处添加的任何值都将在最终主题输出中,除非值稍后被覆盖(通常所有值都除外 brandTitle
、brandUrl
和 brandImage
)
"colorPrimary"?: string
"colorSecondary"?: string
"appBg"?: string
"appContentBg"?: string
"appBorderColor"?: string
"appBorderRadius"?: number
"fontBase"?: string
"fontCode"?: string
"textColor"?: string
"textInverseColor"?: string
"textMutedColor"?: string
"barTextColor"?: string
"barSelectedColor"?: string
"barBg"?: string
"inputBg"?: string
"inputBorder"?: string
"inputTextColor"?: string
"inputBorderRadius"?: number
"brandTitle"?: string
"brandUrl"?: string
"brandImage"?: string
"gridCellSize"?: number
native ParamNative
一些简单的方便参数来调整原生主题,以及通过 override
进行完全控制
// Title to show in the menu picker
"title"?: string
// Control which theme variants are available - defaults to ["light", "dark"]
"variants"?: ("light" | "dark")[]
// Control the usage of Storybooks theme values in the backgrounds
"background"?: "normal" | "reverse" | "equal" | "equal-reverse" | "equal-app" | "equal-content"
// Override any default native theme options from Storybook
"override"?: ThemeOptionsOverride
themeConverters Record<string, ThemeConverterFn>
提供自定义转换器函数,将您的自定义主题转换为 Storybook 主题
函数的键将使转换器可以通过主题的 converter
选项访问
转到 示例 以了解如何实现自定义主题
[key]: (props: {
"override"?: ThemeOptionsOverride
"theme": ThemeOptions
"variant": "light" | "dark"
"background"?: "normal" | "reverse" | "equal" | "equal-reverse" | "equal-app" | "equal-content"
"responsiveFontSizes"?: boolean
}) => {
"storybook": StorybookThemeOptions
"instanciated": ThemeInstanciated
"options": ThemeOptions
} | null
themes ParamTheme[]
主题配置
// Unique key for this theme entry
"key": string
// Use the built in support of Storybook or Material UI
// Or indicate you are providing a custom theme
"type": "native" | "mui" | "custom"
// The title used in the theme picker
"title": string
// The name of the converter function to use - if the theme type
// is "mui" or "native" you do not need to set this
"converter"?: string
// The theme provider to use for this theme if "addProvider" for story is true
"provider"?: "mui" | "styled" | "emotion"
// The key of the theme to use for the theme provider if "addProvider" is true
"providerTheme"?: string
// Indicate that this theme is only to be used for theme providers - not to theme Storybook
"providerOnly"?: boolean
// These are the theme options for light and/or dark mode.
"variants": {
"light"?: ThemeOptions
"dark"?: ThemeOptions
}
// Override any Storybook theme options value for this theme
"override"?: ThemeOptionsOverride
// Ability to configure how backgrounds are used in the Storybook theme
// 'reverse' will swap between app and content etc..
"background"?: "normal" | "reverse" | "equal" | "equal-reverse" | "equal-app" | "equal-content"
// This is for typography - use responsive font sizes or not (only MUI support)
"resposiveFontSizes"?: boolean
ui ParamUi
// How much to elevate the content panel
"elevation"?: 0 | 1 | 2 | 3 | 4
// Ability to override SB's own preview panel padding
"padding"?: string
// Ability to use a custom css box-shadow string for content elevation
"shadow"?: string
示例
仅包含亮变体的最小原生 Storybook 主题
export const parameters = {
facelift: {
themes: [
{
key: 'native-1',
type: 'native',
title: 'Custom Storybook theme',
variants: {
light: {
colorPrimary: '#0000ff',
},
},
},
],
},
}
带有默认 Material UI 亮/暗主题的示例
使用默认 Material UI 主题的 Storybook 主题,并为所有 Story 添加具有相同主题的 Material UI 主题提供者
export const parameters = {
facelift: {
addProvider: true,
themes: [
{
type: 'mui',
key: 'mui-1',
title: 'Default Material UI theme',
variants: {
light: {},
dark: {},
},
},
],
},
}
带有自定义亮主题和 Styled Components 主题提供者的示例
这个非常简单的示例将以一个最小的自定义主题对 Storybook 进行主题化,并向 Story 添加一个 Style Components 主题提供者
export const parameters = {
facelift: {
addProvider: true,
themeConverters: {
myCustomConverter: ({ theme, variant }) => ({
storybook: {
base: variant,
colorPrimary: theme.primary,
colorSecondary: theme.secondary,
},
options: theme,
instanciated: theme,
}),
},
themes: [
{
type: 'custom',
key: 'custom-1',
title: 'Custom UI theme',
converter: 'myCustomConverter',
provider: 'styled',
variants: {
light: {
primary: '#ff0000',
secondary: '#0000ff',
},
},
},
],
},
}