Storybook 附加组件 SDC

Drupal 单目录组件作为故事

在 Github 上查看

Storybook SDC 附加组件文档

此附加组件简化了 Drupal 单目录组件 (SDC) 与 Storybook 的集成,允许动态加载 YAML 配置的组件(例如:*.component.yml)作为 Storybook 中的故事。

Demo GIF

目录


概述

此 Storybook 附加组件使用 YAML 配置和 Twig 模板,使 Drupal 单目录组件 (SDC) 与 Storybook 的集成变得轻而易举。它会动态加载组件,使您能够快速创建和管理故事,而无需进行复杂配置。

为什么要选择 SDC Storybook 而不是其他方案?

虽然 SDC StyleguideDrupal Storybook 等解决方案很有价值,但 SDC Storybook 附加组件提供了独特的优势。

1. 组件独立性和模块化

  • 遵循 BEM (块元素修饰符) 方法,组件应该在不同环境中独立工作。
  • 组件的功能不应依赖于 Drupal 版本 或活动的 Drupal 主题 — 它应该可以移植到 任何 系统。

2. 无需复杂的 Drupal 设置

  • 无需为组件开发安装或配置 Drupal 依赖项。
  • 在 Storybook 中开发前端组件时,无需运行繁重的 Drupal 实例,可以更快地工作。

3. 简化 DevOps 和 CI/CD 管道

  • 由于组件是隔离的,因此 测试和部署 会变得更加简单。
  • 您可以在 CI 管道中 避免 Drupal 特定配置,从而实现更高效且易于维护的工作流程。

4. 使用 Faker.js 和 JSON Schema 实现可扩展性和灵活性

  • Faker.js 等工具允许您为组件生成测试数据,而无需实际内容。
  • JSON Schema 清晰且一致地定义组件数据,有助于维护数据完整性。

5. 前端开发的行业标准工具

  • Storybook 在前端开发中得到广泛采用,这使得即使是那些不熟悉 Drupal 的开发人员也能更容易地上手。
  • JSON Schema 允许在没有深入了解 Drupal 的情况下处理组件,从而将项目开放给更广泛的开发者群体。

6. 将 Drupal 特定行为嵌入组件

  • Drupal 行为(如 Drupal.attachBehaviors())直接嵌入到 Storybook 预览中,确保 Storybook 和生产环境中组件行为的一致性。
  • 支持 drupalSettingsonce.js,使 Storybook 中的组件的行为与 Drupal 中的组件完全相同。

7. Twig.js 与 Drupal Twig

虽然使用 Drupal 渲染组件可以实现更紧密的集成,但在许多情况下,仍有充分的理由继续在许多情况下使用 Twig.js。

  • 许多组件 不需要完整的 Drupal 逻辑。基本组件(按钮、卡片、列表)依赖于简单的 HTML 和 CSS,而不是复杂的模板逻辑。对于此类组件,Twig.js 提供了足够的渲染,无需完整的 Drupal 预处理。
  • Twig.js 非常适合面向前端的用例。
  • 可以在 Drupal 实现阶段分别管理样式和行为不匹配。

附加组件的功能

  • 用于加载基于 YAML 的 SDC 配置的 Vite 插件。
  • 基于命名空间的动态路径解析,便于发现组件。
  • 直接从 YAML 文件创建故事的故事生成器。
  • 基于 JSON schema 的属性,支持 Drupal 行为。

依赖项

快速入门指南

  1. 在主题或模块中,或只是空目录(如果尚未存在 package.json):

    npm init
    echo "node_modules/" >> .gitignore
    
  2. 安装依赖项:

    npm i vite twig storybook-addon-sdc --save-dev
    
  3. 初始化 Storybook:

    npx storybook@latest init --builder vite --type html --no-dev
    
  4. 删除默认的 storybook 样板故事(可选):

    rm -rf ./stories
    
  5. 按照 配置 中的说明进行配置。.

  6. 将组件添加到 components 目录(或从此 仓库 中复制)。

  7. 启动 Storybook:

    npm run storybook
    

配置

要配置附加组件,请更新 .storybook/main.js,如下所示

import { join } from "node:path"; // 1. Add path dependency.

const config = {
  stories: ["../components/**/*.component.yml"], // 2. Set components glob.
  addons: [
    {
      name: "storybook-addon-sdc", // 3. Configure addon.
      options: {
        sdcStorybookOptions: {
          namespace: "umami", // Your namespace.
        },
        vitePluginTwigDrupalOptions: { // vite-plugin-twig-drupal options.
          namespaces: {
            umami: join(__dirname, "/components")  // Your namespace and path to components.
          }
        },
        jsonSchemaFakerOptions: {}, // json-schema-faker options.
      }
    },
    // Any other addons.
    "@storybook/addon-essentials",
    "@chromatic-com/storybook",
    "@storybook/addon-interactions",
  ],
  framework: {
    name: "@storybook/html-vite",
    options: {},
  },
};
export default config;

设置默认值

要使 json-schema-faker 生成可靠的数据,请在 SDC 架构中使用 defaultexamples

props:
  type: object
  properties:
    html_tag:
      type: string
      enum:
        - article
        - div
      default: article
slots:
  content:
    title: Content
    examples:
      - Hello! I'm card content

参考

创建实验性故事

默认情况下,附加组件仅为每个组件生成一个基本故事。要添加更多故事,请在 SDC YAML 文件中使用 thirdPartySettings

thirdPartySettings:
  sdcStorybook:
    stories:
      preview:
        title: Preview
        props:
          html_tag: "div"
        slots:
          content:
            - type: component
              component: "umami:title"
              props:
                label: test
      preview2:
        title: Preview2
        props:
          html_tag: "div"
        slots:
          content:
            - type: component
              component: "umami:title"
              props:
                label: test2

为什么故事是实验性的?

社区需要决定 YAML 故事应该采用什么格式。

常规 Storybook

所有 storybook 功能照常工作,您可以将 SDC YAML 导入 .stories.js

示例

import header, {
  preview as HeaderPreview,
} from '../components/header/header.component.yml'
import banner, {
  preview as BannerPreview,
} from '../components/banner/banner.component.yml'

export default {
  title: 'Regular Storybook Page',
  render: () => {
    return `
      ${header.component({ ...HeaderPreview.args })}
      ${banner.component({ ...BannerPreview.args })}
    `
  },
  play: async ({ canvasElement }) => {
    Drupal.attachBehaviors(canvasElement, window.drupalSettings)
  },
}

export const Basic = {}

已知问题

  • $ref: json-schema-definitions:// 不支持来自体验构建器的 SDC。
  • 附加组件依赖于 实验性索引器.

UI 模式

作者
  • finnsky
    finnsky
与之配合使用
    HTML
标签