一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

如何在Storybook中为CSS组件库编写交互式文档

时间:2026-07-16 08:46:56 编辑:袖梨 来源:一聚教程网

Storybook不直接渲染纯CSS库,需封装壳组件并全局引入CSS文件;否则因无JS模块导出而报错或空白。关键步骤:一、创建React壳组件映射原始类名;二、在preview.js中正确import CSS(路径须准确);三、通过props控制样式变量而非直接操作className。

Storybook 本身不渲染 CSS 组件——它渲染的是 JavaScript/TSX 组件。如果你的“CSS 组件库”(比如 Milligram、MDB UI Kit、css.gg)没有封装成可导入的 JS 模块,直接写 Button.stories.js 是跑不起来的,会报 ReferenceError 或空白页。

得先让 CSS 类名能被 Storybook 环境识别并生效,再配交互逻辑。下面分三步说清怎么做、为什么这么干、以及最容易卡住的地方。

怎么把纯 CSS 类名变成 Storybook 可用的组件?

纯 CSS 库(如 milligram.min.css)只提供类名,没导出函数或 React 组件。你不能直接 import { Button } from 'milligram' ——它根本没这个导出。

必须手动封装一层“壳组件”,哪怕只是个空 div 加 class:

例如 Milligram 的按钮:

立即学习“前端免费学习笔记(深入)”;

export const MilligramButton = ({ label, variant = 'default', disabled = false }) => (  <button    className={`button ${variant === 'outline' ? 'button-outline' : ''} ${disabled ? 'disabled' : ''}`}    disabled={disabled}  >    {label}  </button>);

关键点:

  • className 必须拼对原始库的 class 名(查官网或源码,比如 Milligram 是 button,不是 btn
  • 不要试图在 .stories.js 里直接写 HTML 字符串——Storybook 的 HTML 模式不支持 JSX,但你用 @storybook/react 就必须走 React 组件流
  • 如果库带 RTL 支持(如 mdb.rtl.min.css),记得在 .storybook/preview.js 中按需引入对应 CSS

如何让 class 变量实时可调,而不是写死?

argTypes 控制面板只对组件 props 生效,不是对 class 字符串生效。所以不能写 className: { control: 'text' } 然后指望它自动加到 DOM 上——那只是个字符串,没绑定逻辑。

正确做法是:把可变 class 映射为 prop,再在组件内做条件拼接。

比如 css.gg 的 Airplane 图标支持 sizecolor

export const Airplane = ({ size = '24px', color = '#000' }) => (  <svg style={{ width: size, height: size, color }} viewBox="0 0 24 24">    <path d="M..." />  </svg>);

对应 story 中这样配:

argTypes: {  size: { control: { type: 'text' } },  color: { control: { type: 'color' } }}

注意:

  • 别用 class 属性控制尺寸/颜色——CSS 图标库往往靠内联样式或 data 属性驱动,查 icons/tsx/Airplane.tsx 源码确认机制
  • 如果库用 data-* 属性(如 data-size),就得在壳组件里透传,不能只靠 class
  • control: 'select' 适合有限枚举值(如 ['sm', 'md', 'lg']),但要确保这些值真正在 CSS 中有对应规则

为什么 Storybook 启动后 CSS 不生效?

最常见原因是:CSS 文件没被 Storybook 加载,或者加载时机错位。

两个必查点:

  • .storybook/preview.js 中是否用了 import?比如:import 'milligram/dist/milligram.min.css' —— 这行必须存在,且路径准确(node_modules/milligram/... 或相对路径)
  • 如果用的是 @storybook/html 框架,import 语句无效,得改用 preview.jsparameters.docs.container 注入 <link> 标签,或在 main.jswebpackFinal 中手动注入 CSS
  • 检查浏览器 DevTools 的 Elements 面板:目标元素上有没有预期 class?有没有被其他样式覆盖?优先级冲突时,加 !important 仅用于调试,上线前必须删掉

MDX 文档里怎么直接展示原始 HTML + class 示例?

有些团队想让设计师复制粘贴原生 HTML,而不是 React 组件。这时用 .stories.mdx 更合适。

示例(Button.stories.mdx):

import { Meta } from '@storybook/blocks';import { Button } from './MilligramButton';<p><Meta title="Components/Button" /></p><h2>原生用法</h2><p><code><button class="button">Click me</button></code></p><h2>React 封装用法</h2><p><Button label="Click me" />

注意:

  • <code> 标签必须小写,且不能嵌套 HTML 标签——否则 MDX 解析失败
  • 如果想高亮语法,得用 {`<button class="button">`}</button> 包裹,而不是直接写 HTML 标签
  • @storybook/blocks 是 v7+ 推荐方式,旧版 @storybook/addon-docsCanvas / ArgsTable 块仍可用,但配置更琐碎

真正麻烦的从来不是写几个 story 文件,而是确认 CSS 类名与实际渲染结果的一致性——它不报错,但就是不生效。多开 DevTools 的 Elements 和 Console 面板,盯着 class 列表和 computed styles 看,比反复改 argTypes 有用得多。

热门栏目