标签徽章

在侧边栏和工具栏中以徽章形式显示 Storybook 标签。

在 Github 上查看

📔 目录

🤔 我应该使用哪个徽章附加组件?

一些其他项目已被编写用于在 Storybook 中显示徽章。此附加组件是 storybook-addon-badges 的重写版本,来自 Jim Drury,专注于利用 Storybook 标签。我们使用标签作为数据源来显示徽章,而不是专门的 故事参数,因为标签在 Storybook 中变得越来越流行,并且在功能方面与徽章有很大的重叠。

这种架构选择开辟了新的可能性,但也阻止了原始附加组件中的一些功能。下表总结了两个附加组件之间的差异。

storybook-addon-tag-badges storybook-addon-badges
在工具栏中显示徽章
在侧边栏中显示徽章 ⚠️ 仅限于当前故事
基于标签定义徽章
每个故事的自定义
工具提示支持 ⚠️ 仅在工具栏中
Storybook >= 8.4
Storybook < 8.3

📦 安装

yarn add -D storybook-addon-tag-badges
npm install -D storybook-addon-tag-badges
pnpm install -D storybook-addon-tag-badges

在您的 .storybook/main.ts 文件中,添加以下内容

// .storybook/main.ts
export default {
  addons: ['storybook-addon-tag-badges'],
}

🏁 默认配置

此附加组件附带一个默认配置,允许您通过在内容中添加标签立即开始使用。

预配置徽章

预览 标签模式 建议使用
new 最近添加的组件或属性/功能
alpha, beta, rc, experimental 警告组件或属性尚未稳定
deprecated 在新的代码中应避免的组件或属性
outdated 具有尚未实现的设计更改的组件,这可能会给您的用户带来额外的开发成本
danger 在配置时需要特别注意的组件(例如,涉及安全问题时)
code-only 仅存在于代码中,而不是设计中的组件
version:* 每个组件的版本控制

显示逻辑

默认情况下,所有标签始终显示在工具栏中,但它们仅显示在侧边栏中的组件条目中。

此外,附加组件限制每个侧边栏条目只有一个徽章。配置中首先放置的徽章将优先显示。例如,new 徽章将在 code-only 徽章之前显示。

👀 使用

要显示预配置徽章,请将相关标签添加到您的组件、故事或文档条目中。

组件徽章

要为组件(及其子故事)设置徽章,请在组件的元数据中定义 tags

// src/components/Button.stories.ts
import type { Meta, StoryObj } from '@storybook/react'
import { Button } from './Button'

const meta: Meta<typeof Button> = {
  title: 'Example/Button',
  component: Button,
  tags: ['autodocs', 'version:1.0.0', 'new'],
}

故事徽章

要向特定故事添加徽章,请将 tags 添加到故事对象本身

// src/components/Button.stories.ts
export const Tertiary: StoryObj<typeof Button> = {
  args: {
    variant: 'tertiary',
    size: 'md',
  },
  tags: ['experimental'],
}

文档徽章

要为文档条目设置徽章,请将 tags 数组传递给 docs 参数

// src/components/Button.stories.ts
import type { Meta, StoryObj } from '@storybook/react'
import { Button } from './Button'

const meta: Meta<typeof Button> = {
  title: 'Example/Button',
  component: Button,
  parameters: {
    docs: {
      tags: ['outdated'],
    },
  },
}

🛠️ 自定义徽章配置

在您的管理文件里,您可以重新定义用于将标签映射到徽章的配置对象。每个标签只渲染一次,使用它匹配的第一个徽章配置;因此,如果您还想保留默认配置,请确保将您的覆盖配置放在首位。

// .storybook/manager.ts
import { addons } from '@storybook/manager-api'
import {
  defaultConfig,
  type TagBadgeParameters,
} from 'storybook-addon-tag-badges'

addons.setConfig({
  tagBadges: [
    // Add an entry that matches 'frog' and displays a cool badge in the sidebar only
    {
      tags: 'frog',
      badge: {
        text: 'Frog 🐸',
        bgColor: '#001c13',
        fgColor: '#e0eb0b',
        tooltip: 'This component can catch flies!',
      },
      display: {
        sidebar: ['component'],
        toolbar: false,
      },
    },
    // Place the default config after your custom matchers.
    ...defaultConfig,
  ] satisfies TagBadgeParameters,
})

现在让我们逐步了解 tagBadges 的不同属性。tagBadges 中的每个对象代表一个要匹配的标签列表,并在找到匹配项时,使用一个徽章配置,以及徽章应显示的位置。

标签

tags 属性定义将显示徽章的标签模式。它可以是单个模式,也可以是模式数组。

标签模式可以是

模式类型 描述 示例模式 匹配结果
string 完全匹配 'new' 'new'
RegExp 正则表达式 /v\d+\d+\d+/ 'v1.0.0'
{ prefix: string | RegExp } 匹配 : 分隔符之前标签的一部分 { prefix: 'status' } 'status:done'
{ prefix: string | RegExp } 匹配 : 分隔符之后标签的一部分 { suffix: 'a11y' } 'compliant:a11y'

显示

display 属性控制徽章在何处以及针对哪种类型的内容渲染。它有两个子属性:sidebartoolbar。在侧边栏中,标签可能显示在组件、文档或故事条目中。在工具栏中,它们可以设置为文档或故事条目(因为其他条目类型不可在侧边栏之外显示)。

这些子属性中的每一个都可以设置为

类型 描述 示例 侧边栏结果 工具栏结果
ø (未设置) 使用默认行为 ['component'] ['docs', 'story']
false 从不显示标签 false [] []
true 始终显示标签 true ['component', 'docs', 'story'] ['docs', 'story']
string 仅针对一种类型的条目显示 'docs' ['docs'] ['docs']
string[] 针对条目类型列表显示 ['docs'] ['docs'] ['docs']

徽章

badge 属性定义要显示的徽章的外观和内容。它可以是静态对象,也可以是根据匹配的内容和标签动态生成徽章的函数。

静态徽章对象

该对象具有以下属性

名称 类型 描述 示例
text string 在徽章中显示的文本(必填)。 'New'
bgColor string? 传递给 background-color 的 CSS 属性。 '#aea'
fgColor string? 传递给 color 的 CSS 属性。 '#2f2'
borderColor string? 边框颜色,以 CSS 盒阴影的形式渲染。 '#2f2'
tooltip string | TooltipMessageProps? 仅在工具栏中点击时显示的工具提示。 'This component is new!'{ title: 'New Component', desc: 'Recently added to the library' }

动态徽章函数

动态徽章函数允许您根据当前条目和匹配的标签来自定义徽章。它们必须返回如上所述的有效徽章对象。它们接收一个具有以下属性的对象参数

  • entry: 当前 HashEntry(组件、故事等),具有 id 和/或 name,一个 typetags
  • getTagParts, getTagPrefix, getTagSuffix: 用于提取标签部分的实用函数
  • tag: 匹配的标签字符串

动态徽章函数示例

// .storybook/manager.ts
import { addons } from '@storybook/manager-api'
import {
  defaultConfig,
  type TagBadgeParameters,
} from 'storybook-addon-tag-badges'

addons.setConfig({
  tagBadges: [
    {
      tags: { prefix: 'version' },
      badge: ({ entry, getTagSuffix, tag }) => {
        const version = getTagSuffix(tag)
        const isUnstable = version.startsWith('0')
        return {
          text: `v${version}`,
          bgColor: version.startsWith('0') ? '#f0ccff' : '#cce0ff',
          tooltip: `Version ${version}${isUnstable ? ' (unstable)' : ''}`,
        }
      },
    },
    ...defaultConfig,
  ] satisfies TagBadgeParameters,
})

工具提示

徽章在工具栏中显示时可能会有工具提示。工具提示在侧边栏中被禁用,以避免与侧边栏的功能冲突,尽管欢迎对此进行反馈。

您可以将字符串传递给工具提示以创建简单的工具提示。您也可以传递与 Storybook 的 TooltipMessage 相同的对象

  • title: 工具提示的标题 [string]
  • desc: 工具提示的辅助文本 [string]
  • links: 可选的链接对象数组,以按钮形式显示 [object[]]
    • title: 链接的标题
    • href: 链接指向的 URL(在当前位置导航)
    • onClick: 点击链接时的回调(可用于在新浏览器标签页中导航)

侧边栏标签自定义

此附加组件使用 侧边栏 renderLabel 功能 在侧边栏中显示徽章。如果您在 Storybook 实例中将其定义为其他目的,它将与该附加组件冲突,并且侧边栏徽章将不会显示。

要为未被您自己的 renderLabel 逻辑自定义的项目显示徽章,您可以导入附加组件自己的 renderLabel 函数并在您的函数末尾调用它。

// .storybook/manager.ts
import { addons } from '@storybook/manager-api'
import type { API_HashEntry } from '@storybook/types'
import { renderLabel, Sidebar } from 'storybook-addon-tag-badges'

addons.setConfig({
  sidebar: {
    renderLabel: (item: API_HashEntry) => {
      // Customise your own items, with no badge support.
      if (item.name === 'Support') {
        return '🛟 Get Support'
      }

      // Customise items with badge support by wrapping in Sidebar.
      if (item.type === 'docs') {
        return <Sidebar item={item}>{item.name} [doc]</Sidebar>
      }

      // Badges for every item not customised by you.
      return renderLabel(item)
    },
  }
})

📝 工作流示例

此仓库包含关于如何使用 Storybook 徽章支持各种工作流的示例

  • 市场细分
  • 将功能组件与品牌组件分离
  • 对于 a11y、品牌、QA 等检查的合规状态
  • 组件组合模式
  • 外部依赖项的使用
  • 智能组件

要查看这些示例的实际效果,请查看该仓库并运行本地 Storybook 实例

git clone https://github.com/Sidnioulz/storybook-addon-tag-badges.git
cd storybook-addon-tag-badges
pnpm i
pnpm start

🐌 局限性

每个故事的配置

此附加组件不支持更改特定故事的徽章配置,并且永远不会支持。这是因为 Storybook UI 的某些部分(如侧边栏)是在没有加载故事数据的情况下渲染的。为了提高性能,Storybook 在 v7 中停止了预加载所有故事数据。

因此,我们需要在没有访问故事特定数据的情况下创建侧边栏标签。此附加组件使用 核心附加组件 API 读取您的配置,因此自定义特定徽章渲染的方法是使用 动态徽章函数。这些函数可以利用故事的 ID、标题或标签内容来自定义渲染的徽章,正如以下示例所示。

组件标签

在 Storybook 中,您的 MDX 和 CSF 文件将被转换为 `docs`、`component`、`group` 和 `story` 条目以渲染侧边栏,每个条目都有其自身的语义。`docs` 和 `story` 条目直接继承在 `parameters.docs.tags` 中定义的标签,以及在 CSF meta 中定义的标签。

对于 `component` 条目,标签是间接计算的:它们是组件所有故事中存在的标签的交集。例如,对于一个在 meta 中定义了 `version:1.2.0` 标签,并且有一个故事定义了额外的标签 `deprecated` 的组件,该组件条目将只定义 `version:1.2.0` 标签。

特别地,如果一个组件 meta 定义了两个标签 `outdated` 和 `version:1.1.0`,但一个故事明确地删除了 `outdated` 标签(通过添加 `!outdated`),那么该组件条目将只包含 `version:1.1.0` 标签。

👩🏽‍💻 贡献

行为准则

请先阅读 行为准则

开发者证书

为了确保贡献者在法律上被允许根据本项目的许可条款共享他们贡献的内容,贡献者必须遵守 开发者证书 (DCO)。所有做出的贡献都必须经过签名以满足 DCO。这是由拉取请求检查处理的。

通过签署您的提交,您证实以下内容

  1. 该贡献是由您全部或部分创建的,并且您有权根据文件中指定的开源许可协议提交它;或
  2. 该贡献基于之前的工作,据您所知,该工作已在适当的开源许可协议下进行,并且您有权根据该许可协议提交该工作,无论是由您全部或部分创建的,都在同一个开源许可协议下(除非您被允许在不同的许可协议下提交),如文件中所述;或
  3. 该贡献是由其他人员直接提供给您的,他们已经认证了 1、2 或 3,并且您没有修改它。
  4. 您理解并同意,本项目和贡献是公开的,并且贡献的记录(包括您随其提交的所有个人信息,包括您的签署)将无限期地维护,并且可以根据本项目或相关的开源许可协议重新分发。

入门

本项目使用 PNPM 作为包管理器,使用 Turbo 作为单仓库提供者。

有用命令

  • pnpm start 启动本地 Storybook
  • pnpm build 构建并打包附加组件代码
  • pnpm pack:local 创建一个本地 tarball,以便在其他地方用作 NPM 依赖项
  • pnpm test 运行单元测试

迁移到更高版本的 Storybook

如果您想将附加组件迁移到支持最新版本的 Storyboook,您可以查看 附加组件迁移指南

发布系统

此包在推送到 `main` 时使用 semantic-release 自动发布。没有维护更改日志,package.json 中的版本号不会同步。

🆘 支持

打开一个问题 以报告错误或提出代码建议。确保为错误报告包含一个有效的最小工作示例。您可以使用 storybook.new 来引导一个复制环境。

✉️ 联系

Steve Dodier-Lazaro · 在 Storybook Discord 上的 @Frog - LinkedIn

项目链接:https://github.com/Sidnioulz/storybook-addon-tag-badges

💛 致谢

感谢

构建工具

Dependabot ESLint GitHub Prettier Semantic-Release Storybook tsup TypeScript Vitest