mcpField
C
canvas-styling-conventions

canvas-styling-conventions

github.com/drupal-canvas设计与 UI3216 次安装5 周前更新
代码仓库

关于 canvas-styling-conventions

为 Drupal Canvas 项目提供 React 与 Tailwind CSS 4 样式约定的技能,供实现或维护 Canvas 组件的开发者参考。内容涵盖主题令牌、类名合并和变体用法,并区分 Canvas Headless 与 React 项目规则。

主要功能

  1. 01识别 Canvas Headless 与 React 项目
  2. 02使用 Tailwind 主题令牌
  3. 03通过 cn() 合并样式类
  4. 04用 CVA 定义颜色变体
  5. 05避免组件使用原始颜色值

适用场景

  1. 01为 Canvas 组件编写一致样式
  2. 02将重复颜色值整理为主题令牌
  3. 03为组件定义受控的颜色方案

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/drupal-canvas/skills --skill canvas-styling-conventions

安装后在 Claude Code 中输入/canvas-styling-conventions确认已加载。

详细介绍

项目类型

应用此技能前,请检查 package.json 中是否有名为 @drupal-canvas/headless 或以 @drupal-canvas/headless- 开头的依赖。如果有, 这是一个 Canvas Headless 代码库——请先阅读 canvas-headless;其中的指导优先于下方 针对 React 的说明。本技能中关于 Tailwind 4 主题令牌的指导同样适用于 无头项目;cn() 和 className 部分仅针对 React。如果没有此类依赖, 则这是一个 Canvas 渲染的 React 代码库:组件采用 React(index.jsx/.tsx), 本技能中的所有内容均按原样适用。项目类型仅有这两种。

技术栈

技术用途
Tailwind CSS 4.1+样式
class-variance-authority (CVA)组件变体
通过 cn() 使用 clsx + tailwind-merge类名合并

样式仅使用这些依赖。不要添加第三方 CSS 库,也不要创建新的样式工具。

在 Canvas Headless 代码库中,不支持 drupal-canvas 包(及其 cn())。 只要项目安装了 CVA,它仍可用于任何框架;合并类名时,请使用框架自身的类组合惯例——参见 canvas-headless。

样式约定

  • 使用 global.css 中定义的 Tailwind 主题颜色(primary-*、gray-*)。
  • 避免使用硬编码颜色值,改用主题令牌。
  • 遵循示例中已有的焦点、悬停和激活状态样式模式。

cn() 工具

使用 cn() 合并 Tailwind 类。它将 clsx 用于条件类,并使用 tailwind-merge 解决冲突的工具类。可从以下任一来源导入:

import { cn } from '@/lib/utils';
// or
import { cn } from 'drupal-canvas';

用法示例:

const Button = ({ variant, className, children }) => (
  <button
    className={cn(
      'rounded px-4 py-2',
      variant === 'primary' && 'bg-primary-600 text-white',
      variant === 'secondary' && 'bg-gray-200 text-gray-800',
      className,
    )}
  >
    {children}
  </button>
);

接受 className 以自定义样式

此规则仅针对 React;在 Vue 和 Astro 组件中,如果使用方需要覆盖样式, 请依赖框架自身的类传递方式(Vue 中的属性透传,Astro 中的 class 属性)。

每个 React 组件都应接受 className 属性,以便覆盖样式。 将其作为最后一个参数传给 cn(),这样使用方的类就具有优先级。

const Card = ({ colorScheme, className, children }) => (
  <div className={cn(cardVariants({ colorScheme }), className)}>{children}</div>
);

className 是实现/组合属性,不是编辑器属性。不要将 className 添加到 component.yml,不要将其标记为必填,也不要在 Canvas 元数据中公开它。

Tailwind 4 主题变量

Canvas 项目使用 Tailwind CSS 4 的 @theme 指令在 global.css 中定义设计令牌。 在 @theme { } 中定义的变量会自动成为可用的 Tailwind 工具类。

务必检查 global.css 中可用的设计令牌。 @theme 块是颜色、字体、 断点及其他设计令牌的唯一事实来源。

主题变量如何映射到工具类

在 @theme 中定义 CSS 变量时,Tailwind 4 会根据变量的命名空间前缀自动生成 对应的工具类:

@theme 中的 CSS 变量生成的工具类
--color-primary-600: #xxxbg-primary-600、text-primary-600、border-primary-600
--color-gray-100: #xxxbg-gray-100、text-gray-100、border-gray-100
--font-sans: ...font-sans
--breakpoint-md: 48remmd: 响应式前缀

规则是:--{namespace}-{name} 会变为 {utility}-{name}。

示例

在 global.css 中有以下定义:

@theme {
  --color-primary-600: #1899cb;
  --color-primary-700: #1487b4;
}

你可以将这些颜色用于任何接受颜色的工具类:

// Correct
<button className="bg-primary-600 hover:bg-primary-700 text-white">
  Click me
</button>

// Wrong
<button className="bg-[#1899cb] text-white hover:bg-[#1487b4]">Click me</button>

对于罕见的一次性场景,可以使用任意值(例如 bg-[#xxx]),因为这类情况添加主题变量显得过于繁琐。不过,如果某种颜色在多个地方出现,或代表品牌/设计系统的值,请将其添加到 @theme 中。

语义别名

主题变量可以引用其他变量,以创建语义别名:

@theme {
  --color-primary-700: #1487b4;
  --color-primary-dark: var(--color-primary-700);
}

bg-primary-700 和 bg-primary-dark 都可以使用。当语义别名能更好地表达意图时(例如,用 primary-dark 表示较深的品牌变体),请使用语义别名。

添加或更新主题变量

当设计需要主题中尚未定义的颜色、字体或其他值时,请将其添加到 global.css 中的 @theme 区块,而不是在组件中硬编码该值。

何时添加新的主题变量:

  • 设计引入了新的品牌颜色或色阶
  • 需要为现有值创建语义别名(例如 --color-accent)
  • 设计反复使用特定的间距、字体或断点值

何时更新现有主题变量:

  • 品牌颜色发生变化(更新十六进制值)
  • 需要调整整个系统中的设计令牌

示例 - 添加新颜色:

@theme {
  /* Existing tokens */
  --color-primary-600: #1899cb;

  /* New token for a success state */
  --color-success: #22c55e;
  --color-success-dark: #16a34a;
}

添加后,你可以立即使用 bg-success、text-success-dark 等。

保持主题井然有序。 将相关令牌归类,并添加注释说明其用途。遵循 global.css 中现有的命名约定(例如,从 primary-100 到 primary-900 的编号色阶,以及 primary-dark 这类语义名称)。

颜色属性必须使用变体,而非颜色代码

切勿创建允许用户传入颜色代码的属性(十六进制值、RGB、HSL 或任何原始颜色字符串)。应使用 CVA 定义一小组易于理解的变体,并将其映射到 global.css 中的设计令牌。

始终检查 global.css 中可用的设计令牌。 其中定义的令牌(例如 primary-*、gray-* 等)是颜色值的唯一依据。

错误 - 允许使用原始颜色值:

# Wrong
props:
  properties:
    backgroundColor:
      title: Background Color
      type: string
      examples:
        - '#3b82f6'
// Wrong
const Card = ({ backgroundColor }) => (
  <div style={{ backgroundColor }}>{/* ... */}</div>
);

正确 - 使用带有设计令牌的 CVA 变体:

# Correct
props:
  properties:
    colorScheme:
      title: Color Scheme
      type: string
      enum:
        - default
        - primary
        - muted
        - dark
      meta:enum:
        default: Default (White)
        primary: Primary (Blue)
        muted: Muted (Light Gray)
        dark: Dark
      examples:
        - default
// Correct
import { cva } from 'class-variance-authority';

const cardVariants = cva('rounded-lg p-6', {
  variants: {
    colorScheme: {
      default: 'bg-white text-black',
      primary: 'bg-primary-600 text-white',
      muted: 'bg-gray-100 text-gray-700',
      dark: 'bg-gray-900 text-white',
    },
  },
  defaultVariants: {
    colorScheme: 'default',
  },
});

const Card = ({ colorScheme, children }) => (
  <div className={cardVariants({ colorScheme })}>{children}</div>
);

这种方法可以确保:

  • 整个设计系统中的颜色保持一致
  • 用户从经过精选且有意义的选项中进行选择,而不是使用任意值
  • 只需修改 global.css 中的令牌,即可轻松更新主题
  • 通过经过测试的颜色组合,提升可访问性

评论

支持 Markdown