关于 ui4-review
ui4-review 是用于审查 CSS 变更并自动修复令牌违规的技能,面向维护 UI4 样式的开发者。它按优先级检查嵌套选择器、旧变量及硬编码值,并报告需人工判断的问题。
主要功能
- 01检查 CSS 嵌套与硬编码值
- 02替换旧变量和过时令牌
- 03将调色板值改为语义令牌
- 04按规则自动修复违规
- 05汇总修复项与待审项
适用场景
- 01提交前审查 CSS 变更
- 02迁移组件样式至 UI4 令牌
- 03定位无法确定替代令牌的问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ payloadcms/ payload --skill ui4-review安装后在 Claude Code 中输入/ui4-review确认已加载。
详细介绍
UI4 审查
审查 CSS 变更并自动修复令牌违规。
重要:调色板令牌 vs 语义令牌
--ramp-* 令牌是原始调色板(例如 --ramp-white-1000、--ramp-blue-500)。它们仅用于 colors.css 中定义语义令牌。
--color-* 令牌是上下文感知的语义令牌(例如 --color-bg、--color-text-brand)。它们会自动处理浅色/深色主题。
组件和元素应始终使用 --color-* 语义令牌,绝不直接使用 --ramp-* 调色板令牌。
/* ❌ BAD - using raw palette */
background: var(--ramp-white-1000);
/* ✅ GOOD - using semantic token */
background: var(--color-bg);
流程
步骤 1:获取变更的 CSS 文件
git status --porcelain | grep '\.css$'
或者如果提供了特定文件,则直接使用该文件。
步骤 2:并行违规检测
并行运行这些 grep 搜索,一次性检测所有违规类型:
# 1. SCSS Nesting Violations (BEM patterns that don't work in CSS)
grep -n '&__\|&--' "$FILE"
# 2. Hardcoded Spacing (px/rem values that should be tokens)
grep -nE ':\s*[0-9]+px|:\s*[0-9.]+rem' "$FILE"
# 3. Hardcoded Colors (hex, rgb, rgba - includes box-shadow)
grep -nE '#[0-9a-fA-F]{3,8}|rgba?\(' "$FILE"
# 4. Legacy Theme Variables
grep -nE 'var\(--theme-|var\(--style-|var\(--base\)' "$FILE"
# 5. Old Token Names (pre-UI4 naming)
grep -nE '\-\-bg-default|\-\-bg-secondary|\-\-text-default|\-\-text-secondary|\-\-icon-default|\-\-icon-secondary|\-\-border-default|\-\-border-strong' "$FILE"
# 6. Raw Palette Usage (should use semantic tokens instead)
# Skip this check for colors.css which defines the semantic tokens
grep -nE 'var\(--ramp-' "$FILE"
在单个并行批次中调用全部 6 个 grep 命令,然后分析结果。
注意: 原始 --ramp-* 违规仅在组件 CSS 文件中标记,不在用于定义语义令牌的 colors.css 中标记。
步骤 3:按优先级自动修复
- SCSS 嵌套(完全破坏 CSS)— 优先修复
- 旧版变量(已弃用)— 替换为新令牌
- 旧令牌名称(UI4 之前)— 转换为
--color-*命名 - 原始调色板使用(组件中的
--ramp-*)— 替换为语义--color-*令牌 - 硬编码值(间距、颜色、圆角)— 替换为令牌
步骤 4:报告
修复后,报告:
- 发现的违规总数
- 自动修复的违规
- 需要手动审查的违规(没有明确的令牌匹配)
违规参考
SCSS 嵌套(破坏 CSS)
| 模式 | 问题 | 修复 |
|---|---|---|
&__element | BEM 元素拼接 | 使用扁平 .block__element 选择器 |
&--modifier | BEM 修饰符拼接 | 使用扁平 .block--modifier 选择器 |
.child { .parent--mod & } | 父级引用 | 移动到 .parent--mod .child |
确实有效: &:hover、&:focus、&::before、& .child
间距令牌
| 值 | 令牌 |
|---|---|
| 4px / 0.25rem | --spacer-1 |
| 8px / 0.5rem | --spacer-2 |
| 12px / 0.75rem | --spacer-2-5 |
| 16px / 1rem | --spacer-3 |
| 24px / 1.5rem | --spacer-4 |
| 32px / 2rem | --spacer-5 |
| 40px / 2.5rem | --spacer-6 |
舍入规则 — 始终舍入到最近的令牌:
| 像素范围 | 令牌 | 备注 |
|---|---|---|
| 0-2px | --spacer-0 | 使用 0 |
| 3-6px | --spacer-1 (4px) | 5-6px 舍入到 4px |
| 7-10px | --spacer-2 (8px) | 10px 向下舍入到 8px |
| 11-14px | --spacer-2-5 (12px) | 13.33px 舍入到 12px |
| 15-20px | --spacer-3 (16px) | 15px、20px 均舍入到 16px |
| 21-28px | --spacer-4 (24px) | |
| 29-36px | --spacer-5 (32px) | 30px 舍入到 32px |
| 37-48px | --spacer-6 (40px) |
规则: 对于 ≤ 40px 的值,始终使用单个令牌(不使用 calc())。对于 > 40px 的值,使用带间距令牌的 calc()。
例外: 0、百分比、auto、inherit、-1px(用于裁剪偏移)
描边宽度令牌
| 值 | 令牌 |
|---|---|
| 1px | --stroke-width-small |
圆角令牌
| 值 | 令牌 |
|---|---|
| 2px / 0.125rem | --radius-small |
| 5px / 0.3125rem | --radius-medium |
| 13px / 0.8125rem | --radius-large |
| 9999px | --radius-full |
Elevation Token(盒阴影)
定义于 packages/ui/src/css/elevations.css。
切勿为盒阴影使用硬编码的 rgba()。 请改用 elevation token:
| Token | 使用场景 |
|---|---|
--elevation-300-tooltip | 工具提示、小型浮动元素 |
--elevation-400-menu-panel | 菜单、下拉菜单、浮动面板 |
--elevation-500-modal-window | 模态框、对话框、全屏浮层 |
/* ❌ BAD - hardcoded shadow */
box-shadow: 0 -2px 16px -2px rgba(0, 0, 0, 0.2);
/* ✅ GOOD - elevation token */
box-shadow: var(--elevation-400-menu-panel);
Elevation 会自动适配浅色/深色主题。
语义颜色 Token(UI4 命名)
所有语义颜色均使用 --color- 前缀。default 类别和变体是隐式的。
| 旧名称 | 新名称(UI4) |
|---|---|
--bg-default | --color-bg |
--bg-secondary | --color-bg-secondary |
--bg-hover | --color-bg-hover |
--bg-selected | --color-bg-selected |
--bg-brand | --color-bg-brand |
--bg-danger | --color-bg-danger |
--bg-success | --color-bg-success |
--bg-warning | --color-bg-warning |
--text-default | --color-text |
--text-secondary | --color-text-secondary |
--text-tertiary | --color-text-tertiary |
--text-brand | --color-text-brand |
--text-danger | --color-text-danger |
--text-success | --color-text-success |
--icon-default | --color-icon |
--icon-secondary | --color-icon-secondary |
--icon-tertiary | --color-icon-tertiary |
--icon-brand | --color-icon-brand |
--icon-danger | --color-icon-danger |
--border-default | --color-border |
--border-strong | --color-border-strong |
--border-selected | --color-border-selected |
--border-brand | --color-border-brand |
旧版变量(请立即替换)
| 旧版 | 替代 |
|---|---|
--theme-elevation-0 | --color-bg |
--theme-elevation-50 | --color-bg-secondary |
--theme-elevation-100 | --color-border |
--theme-text | --color-text |
--style-radius-m | --radius-medium |
var(--base) 转换: 旧版 token = 20px。使用以下方式转换:
| 原始 | 像素 | 替代 |
|---|---|---|
var(--base) * 0.4 | 8px | var(--spacer-2) |
var(--base) * 0.5 | 10px | calc(var(--spacer-1) * 2.5) |
var(--base) * 0.6 | 12px | var(--spacer-2-5) |
var(--base) | 20px | calc(var(--spacer-4) * 0.833) |
var(--base) * 2 | 40px | var(--spacer-6) |
完整转换表请参见 ui4 skill 第 1 步。
行为
不要只是报告违规项。请立即使用 replace_string_in_file 或 multi_replace_string_in_file 修复它们。
当违规项没有明确的 token 匹配时(例如 3px 或不常见的 rem 值),请将其标记为需要人工审查,但不要猜测。
对于每个违规项:
- 确定确切的行和值
- 确定正确的 token 替代项
- 使用
replace_string_in_file立即修复 - 报告修复内容
仅在以下情况下标记(而不修复):
- 不存在匹配的 token(例如 18px 徽章尺寸)
- 值是有意为之(例如
1px边框、0) - 替代项不明确
空 CSS 文件: 如果组件的 CSS 文件在迁移后变为空(所有样式现在都由 Button 等共享组件处理),请删除该 CSS 文件,并从组件中移除其 import。
输出格式
自动修复后,报告:
## Auto-Fixed
✅ Collapsible/index.css:9 — `height: 2rem` → `height: var(--spacer-5)`
✅ Collapsible/index.css:120 — `width: 2rem` → `width: var(--spacer-5)`
## Flagged (Manual Review)
⚠️ ErrorPill/index.css:15 — `height: 1.125rem` (18px) — no matching token
总结
完成所有修复后,提供一份简要总结:
| 文件 | 已修复 | 已标记 |
|---|---|---|
| Collapsible/index.css | 2 | 1 |
| ErrorPill/index.css | 0 | 2 |