自动化组件状态推导:利用大模型补充 Hover、Active 与 Disabled Token
在企业级设计系统的日常交付中,前端工程师最常面对的一个尴尬局面是:设计师在 Figma 里只精心绘制了一个按钮的“默认态(Default)”,而把悬停(Hover)、按下(Active)、聚焦(Focus)以及禁用(Disabled)等交互状态抛在脑后。到了前端实现阶段,工程师只能凭感觉随手写一个opacity: 0.8或者自己去调深 10% 的色值,导致同一个产品里不同组件的交互手感极其割裂。
如果每个状态都要设计师逐一手工配置,不仅费时费力,而且很容易因为主观调色破坏 WCAG 对比度。本文将介绍如何利用现代感知色彩空间(OKLCH)结合大模型的语义推理能力,搭建一套全自动化的组件交互状态 Token 推导管线。
为什么不能简单使用传统 RGB / HSL 加减法?
很多初级自动化脚本喜欢用 HSL 空间直接修改亮度:L = L - 10%。
这种基于 sRGB 几何模型的做法存在严重的感知缺陷:
- 感知明度不均匀(Helmholtz-Kohlrausch 效应):在 sRGB 中,纯黄色(
#FFFF00)在人眼看来极其刺眼,而纯蓝色(#0000FF)非常暗淡。如果给黄底和蓝底同时加减 10% 的 HSL 亮度,黄色按钮在 Hover 时几乎看不出变化,而蓝色按钮会瞬间变黑。 - 色相漂移(Hue Shift):在调整高饱和度颜色时,简单的加减法会导致颜色变脏(如橙色变成泥褐色)。
现代国际标准推荐采用OKLCH 感知色彩空间(由 Björn Ottosson 提出)。在 OKLCH 中,明度 $L$、色度 $C$ 和色相 $H$ 是严格按照人类视网膜感知线性解耦的。
// 利用 OKLCH 色彩空间计算精确的感知交互态 export interface DerivedStateTokens { default: string; hover: string; active: string; disabled: string; focusRing: string; } // 模拟 OKLCH 状态推导逻辑 export function deriveInteractiveStates(baseHex: string, isLightMode: boolean = true): DerivedStateTokens { // 将 HEX 转化为 OKLCH 矢量 (L: 0~1, C: 0~0.4, H: 0~360) const oklch = hexToOKLCH(baseHex); let hoverL: number; let activeL: number; if (isLightMode) { // 浅色模式下:Hover 适度加深 (感知明度下降 6%),Active 进一步加深 (下降 12%) hoverL = Math.max(0.1, oklch.l - 0.06); activeL = Math.max(0.05, oklch.l - 0.12); } else { // 深色模式下:Hover 适度提亮 (感知明度上升 8%),Active 进一步提亮 hoverL = Math.min(0.95, oklch.l + 0.08); activeL = Math.min(0.98, oklch.l + 0.14); } return { default: baseHex, hover: oklchToHex({ l: hoverL, c: oklch.c * 1.02, h: oklch.h }), active: oklchToHex({ l: activeL, c: oklch.c * 0.98, h: oklch.h }), // Disabled 状态:强制降低色度 (去色) 并拉高/拉低明度 disabled: oklchToHex({ l: isLightMode ? 0.88 : 0.25, c: 0.015, h: oklch.h }), focusRing: oklchToHex({ l: oklch.l, c: oklch.c, h: oklch.h, alpha: 0.35 }), }; } // 辅助转换占位声明 function hexToOKLCH(hex: string): { l: number; c: number; h: number } { // 标准色彩转换实现 return { l: 0.62, c: 0.18, h: 260 }; } function oklchToHex(obj: any): string { return '#4338CA'; }大模型在状态推导中的语义决策
色彩数学公式解决了“色调如何科学加深/提亮”的问题,而大模型则负责解决更高维度的语义场景匹配:
- 判断操作破坏性(Destructive Intent):
当大模型识别出某个按钮的语义是“危险删除(Danger Action)”时,它不仅会自动生成偏红色的状态阶梯,还会智能注入更强烈的视觉警告状态(如 Hover 时边框加粗、Focus 时带有醒目的双层光环)。 - 幽灵按钮(Ghost / Outline Button)的特殊推导:
对于无背景的幽灵按钮,Hover 态不能简单改字色,而是应该自动派生出一个带 8% 透明度的浅色背景底板(bg-opacity-10)。大模型能够准确识别这种组件结构,并生成对应的层级 Token。
/* 大模型自动化输出的完整 DTCG 交互状态包 */ { "component": { "button": { "danger": { "background": { "default": { "$value": "#dc2626", "$type": "color" }, "hover": { "$value": "#b91c1c", "$type": "color" }, "active": { "$value": "#991b1b", "$type": "color" }, "disabled": { "$value": "#fecaca", "$type": "color" } }, "text": { "default": { "$value": "#ffffff", "$type": "color" }, "disabled": { "$value": "#fca5a5", "$type": "color" } } } } } }前端无缝消费:CSS 变量与现代伪类
自动化推导出的状态 Token 在前端组件中以最标准的形式消费:
.btn-primary { background-color: var(--button-primary-bg-default); color: var(--button-primary-text-default); transition: all 180ms cubic-bezier(0.16, 1, 0.3, 1); } .btn-primary:hover:not(:disabled) { background-color: var(--button-primary-bg-hover); } .btn-primary:active:not(:disabled) { background-color: var(--button-primary-bg-active); transform: translateY(1px); /* 配合极微物理按压反馈 */ } .btn-primary:focus-visible { outline: none; box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px var(--button-primary-focus-ring); } .btn-primary:disabled { background-color: var(--button-primary-bg-disabled); color: var(--button-primary-text-disabled); cursor: not-allowed; }总结
交互状态是组件灵魂的栖息地。利用 OKLCH 感知色彩模型把控生理光学的严谨性,配合大模型理解业务上下文的语义智能,我们彻底消灭了设计系统交付中长期存在的状态残缺与手感割裂。让每一个按钮在被鼠标触碰、被指尖按下的瞬间,都能传递出精准、自洽且富有弹性的交互质感。