加入直播:周四美国东部时间上午 11 点,Storybook 9 版本发布与 AMA

Facelift

Storybook 的主题、主题提供者和真正的暗模式

在 Github 上查看

Storybook 的主题、主题提供者和真正的暗模式

Storybook Facelift 是零配置的 - 它只会为原生主题提供一个亮/暗模式按钮

但你也可以

安装

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 时使用的默认主题 - 使用 theme 参数中的 key 作为引用

defaultVariant "light" | "dark"

用于你的 Storybook 主题的默认主题变体

docs ParamDocs

增强的 Docs 控制

// 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 默认主题选项上

此处添加的任何值都将包含在最终的主题输出中,除非该值稍后被覆盖(通常所有值都会被覆盖,除了 brandTitlebrandUrlbrandImage

"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 主题

函数的 key 将使得转换器通过主题的 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 添加一个 Styled 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',
          },
        },
      },
    ],
  },
}
由...制作
  • monkeyworks
    monkeyworks
支持框架
    React
标签