当前位置: 首页 > news >正文

语义化主题 Token:品牌色、深浅色与组件一致性

先描述一种熟悉的腐烂过程:第一个页面里写了'#FF6B35',第二个页面复制了它,第十个页面里有人凭记忆写成了'#FF6835'。半年后产品说"填充词的橙色微调一下",你打开全局搜索,发现这个色值有四种写法、三个变体,其中两个还藏在三元表达式里。再叠加深色模式适配——恭喜,进入还债期。

我们的解法是把"颜色"拆成三层,每层都有明确的住处和禁令,然后用脚本守住边界。

1. 三层结构:HEX 的法定住处只有 color.json

resources/{base,dark}/element/color.json ← HEX 字面量唯一合法住处 ↓ 按资源名引用 common/theme/SpeakLabThemeTokens.ets ← 语义角色 → 资源的映射(唯一映射层) ↓ 只许调 token 函数 pages / sheets / common/components ← 业务 UI,零 HEX、零裸尺寸

第一层,资源文件。base/element/color.json里是全部色值,dark/element/color.json是深色模式覆盖。HEX 只允许出现在这里:

{ "name": "sl_color_transcript_filler", "value": "#FF6B35" }, { "name": "sl_color_transcript_hesitation", "value": "#FFD000" }, { "name": "sl_color_transcript_vague", "value": "#FFC107" }, { "name": "sl_color_transcript_encouragement", "value": "#45A020" }

第二层,token 文件。SpeakLabThemeTokens.ets是唯一允许碰资源名的地方,把稳定资源名映射成语义角色

export function SpeakLabTranscriptFiller(): ResourceColor { return $r('app.color.sl_color_transcript_filler'); } export function SpeakLabPageBackground(): ResourceColor { return $r('sys.color.ohos_id_color_sub_background'); }

第三层,业务 UI。组件里只出现SpeakLabTranscriptFiller()这样的调用——读代码的人看到的是"填充词色"而不是一个色值,改色值时只动 color.json 一处。

这个结构的关键设计是:token 文件里没有任何状态。文件头写明No theme state, no business state——它不是主题引擎,只是一张纯映射表。深浅色切换不由它处理,而是交给资源系统本身。

2. 深浅色:能借系统的就不自己造

注意到上面两个例子的区别:$r('app.color.…')$r('sys.color.…')。这是我们的第二条规则:结构色优先用系统 token,品牌/语义色才用自定义资源

页面背景、卡片面、正文/次要/三级文字、分割线——这些"结构性"颜色直接映射到sys.color.ohos_id_color_*。好处是深浅色适配零成本:系统 token 跟随系统色彩模式自动解析,dark/color.json 里甚至不需要为它们写覆盖。

只有两类颜色进 app 自己的 color.json:

  1. 冻结的品牌/语义色:品牌主色#7BB358(开口练的品牌绿)、逐字稿四色。它们在 base 和 dark 里是同一个值——填充词的橙红在深色模式下依然是那个橙红,因为它是业务语义不是界面氛围。

  2. 确需自定义的结构补充:品牌色按钮前景、卡片阴影、遮罩等系统 token 覆盖不到的角色,在 base/dark 两份 color.json 里分别取值。

固定黄色系语义色带来一个真机问题:犹豫词的#FFD000在浅色页面上几乎不可读。解法不是动摇语义色,而是给它一个沉浸底色——逐字稿区域固定用近黑底#0A0A0A衬白字,语义色在两种系统模式下都保持可读:

{ "name": "sl_color_transcript_surface", "value": "#0A0A0A" }, { "name": "sl_color_transcript_on_surface", "value": "#FFFFFF" }

token 注释里写明了设计意图:Immersive dark surface so fixed yellow transcript colors stay readable in light mode。语义色的可读性问题,用承载面解决,而不是修改语义色本身——这条思路在任何"彩色标注"型产品里都通用。

3. 语义隔离:四套色族,谁也不许客串谁

token 文件里其实有四个独立的色族,这是最容易被忽略、也最值得抄的设计:

色族

用途

例子

transcript

逐字稿高亮(业务语义,冻结)

filler 橙红 / hesitation 黄 / vague 黄 / encouragement 绿

report

AI 报告批注

highlight-soft / positive / underline / dashed

feedback

操作反馈状态

info / success / warning / error(各有 soft 变体)

structure

页面结构

背景 / 卡片 / 文字 / 边框 / 阴影

为什么要分开?因为"绿"在不同语境下语义完全不同:逐字稿里的绿是"这句说得好,鼓励",反馈里的绿是"操作成功"。如果共用一个SpeakLabGreen(),哪天设计师调整成功色的绿,逐字稿的鼓励语义就跟着变了。

这条红线有一个真实的反例教训:词库数据里情绪词有polarity=positive字段,开发时有人顺手想用"正向情绪词"染鼓励绿。被拦下了——本地文本分析不能推导"好句子",只有 AI 返回的显式ENCOURAGEMENT标注才允许用绿色。色族的边界本质是业务语义的边界:颜色是产品语言,不是视觉糖。

4. 尺寸同理:float.json + 禁裸数字

颜色之外,尺寸走同样的三层:float.json存数值资源,token 函数按角色引用(SpeakLabSpacingM()这类),UI 里禁止.fontSize(14).padding(8)裸数字。理由和颜色一致——裸数字没有语义,无法统一调整,也无法审查"这里为什么比设计稿大了 2vp"。

5. 五条门禁:把规范从"共识"变成"强制"

规范写在 Wiki 里等于没有规范。scripts/check-theme-boundaries.sh用 ripgrep + python 实现了五条硬规则,每次验收必跑:

  1. 正式 ArkTS 拒绝结构性 HEX。扫描common/ pages/ sheets/ entryability/下所有.ets,出现#RRGGBB字面量即违规(spike 目录在扫描范围之外,故意放一马)。

  2. 拒绝裸数字尺寸,包括多行对象形式。.fontSize(14)会抓,拆成多行写的{ fontSize: 14 }也抓——这条是吃过"换行绕过单行正则"的亏之后补强的。

  3. 冻结色精确校验。品牌色和逐字稿四色在 base 和 dark 两份 color.json 里必须同时存在且值精确相等——防止有人"顺手优化"深色模式下的填充词颜色,把冻结语义改了。

  4. float 尺寸资源必须齐备。token 引用的尺寸档位必须真实存在于 float.json,防止 token 引用悬空资源运行时炸。

  5. token 映射锁定 + 语义样本锁定。token 文件必须映射到冻结资源名;另有一个专门的样本组件SpeakLabTranscriptSemanticSample.ets把"哪种词用什么颜色、什么装饰(实色/虚线下划线)"写成活的规范,门禁校验它与 token 一致——文档会被遗忘,能被校验的代码不会。

脚本本身还有一个值得一提的细节:资源契约永远对真实仓库解析,即使SCAN_ROOT指向 mutation 测试的临时夹具树。这是为了配合 B18 会讲的变异测试——变异体会故意"破坏"源码来验证门禁能否抓住,而 color.json 这种基线数据必须锚定真仓库,否则变异测试就在跟自己玩过家家。

6. 落地清单

如果你要给自家项目建这套体系,按这个顺序来:

  1. 把全工程现有 HEX 收敛进color.json(base + dark 两份),起稳定资源名

  2. 建一个零状态的 token 文件,按语义角色命名函数,不按颜色命名(要SpeakLabTranscriptFiller不要SpeakLabOrange

  3. 结构色能映射sys.color.*的全映射过去,深色模式适配瞬间减半

  4. 按业务语义分色族,写下来"什么才允许用这个色"(我们的鼓励绿 = 仅显式 ENCOURAGEMENT)

  5. 写门禁脚本:禁 HEX、禁裸尺寸、冻结色精确校验、资源存在性、样本锁定

  6. 把门禁挂进验收流程,让违规在本地就炸

7. 小结

  • 三层:color.json 是 HEX 唯一住处 → token 纯映射(零状态)→ UI 只用语义函数。

  • 结构色借系统 token,深浅色零成本;冻结语义色 base/dark 同值。

  • 固定语义色的可读性问题用承载面解决,不改语义色。

  • 色族按业务语义隔离;颜色是产品语言,边界即语义边界。

  • 规范必须配门禁脚本,且门禁自身要被变异测试验证。

http://www.jsqmd.com/news/1251536/

相关文章:

  • 2026年GRS认证是什么,你了解吗? - 品牌排行榜
  • 深入解析MSP432E4 Bootloader:从原理到实战的固件更新指南
  • C语言网络编程2026:高性能服务器与协议栈开发实战
  • AI公司为何抢购旧书?高质量数据如何解决AI幻觉与模型退化
  • AI Agent落地困境与数据底座建设实践
  • 2026年Disney验厂服务公司哪家性价比高?看这篇就够了! - 品牌排行榜
  • AI短剧创作全流程:从剧本到视频的自动化生成
  • 宁波本地防水补漏精选TOP5推荐:正规漏水检测维修公司上门师傅推荐:厕所/棚顶/屋面/飘窗/阳台/地下室/厨房渗漏水精准测漏维修(2026最新) - 即刻修防水
  • 2026黑龙江软质快速卷帘门/工业卷帘门哪家好?本地优质厂家选购指南:4个常见坑与5条硬标准 - mobible
  • ChatGPT邮件日历插件实战:从权限配置到批量处理技巧
  • 基于Transformer的智能人才匹配引擎架构与实践
  • 帝舵2026年7月最新地址公布:宁波客户售后服务中心热线 - 帝舵中国官方服务中心
  • 2026还在用的去水印工具:在线免费去水印软件哪个好用 - 免费软件工具方法教程
  • Unity开发中LitJson解析失败的元凶:UTF-8 BOM问题深度解析与解决方案
  • 语音交互在LLM应用中的技术实现与场景分析
  • 2026哈尔滨长途物流到山西物流专线哪家口碑好|哈尔滨到山西物流公司推荐 - mobible
  • C语言在AI与机器学习底层加速中的应用
  • 2026年新能源充电桩加盟品牌推荐指南 - 品牌排行榜
  • 彻底搞懂API安全:2026年漏洞数量第一、新人最容易忽略的高薪赛道
  • Codex自定义代码审查规则:从基础配置到团队落地实践
  • AI技术在绿色数据中心节能优化中的实践与突破
  • Claude Code实战:AI辅助老项目从JS到TS+Bun迁移指南
  • AI指令合集:提升内容创作效率的实战指南
  • 亲身到店探访上海萧邦售后服务中心|服务热线及完整地址(2026年7月最新) - 萧邦中国官方服务中心
  • 2026 年当下,河北有实力的防火玻璃隔断施工公司电话,办公室火灾,这道玻璃能救你吗?-锦庭玻璃隔断 - 企业推荐官【认证】
  • AutoResearch与Gemini Agent架构的协同设计与实现
  • AI眼镜为什么都在采用霍尔检测?MH231在AI智能眼镜中的应用
  • AI科技热点日报 | 2026年7月23日
  • 2026 年当下,郎溪热门的技术标书制作企业深度解析,揭秘:标书赢单的关键底层逻辑-棣秦咨询 - 行业甄选官
  • 基于YOLOv10的固体废物智能识别系统设计与优化