AionUi 主题色迁移指南:从硬编码 Hex 到 UnoCSS 语义化原子类与 CSS 变量
【免费下载链接】AionUiOpen-source 24/7 Cowork app for OpenClaw, Hermes, Claude Code, Codex, OpenCode and 20+ more CLI Agent | Customize your assistants | Team them up|Star if you like it!项目地址: https://gitcode.com/GitHub_Trending/ai/AionUi
导读
本指南面向 AionUi Desktop 渲染层的前端开发与主题定制者,系统讲解如何将组件中硬编码的颜色值(如bg-#EFF0F6、text-#1D2129)迁移到语义化的 UnoCSS 原子类或 CSS 变量体系。通过本文你可以掌握 AionUi 基于 uno.config.ts 的完整语义色板、明暗双主题的 CSS 变量映射关系,以及一套可复制、可验证的四步迁移流程,让界面颜色自动跟随明暗主题与用户自定义主题。
为什么需要迁移:从"固定色"到"主题令牌"
AionUi 的界面采用统一的主题系统:所有颜色最终都由 CSS 自定义属性(CSS Variables)承载,并随data-theme(light/dark)与data-color-scheme属性切换。如果组件里直接写死十六进制颜色,就会出现两类问题:
- 明暗主题无法自适应:硬编码的浅色背景在暗色模式下仍然保持原色,造成刺眼或不可读。
- 用户自定义主题失效:AionUi 支持通过「设置 → 外观」添加自定义主题(详见 docs/guides/custom-theme.md),自定义主题只覆盖契约内的 CSS 变量,硬编码颜色永远不会被覆盖。
从源码结构看,迁移的核心是packages/desktop/src/renderer/styles/目录下的三份基线文件:
- themes/default-color-scheme.css:明暗两套 CSS 变量(AOU 品牌色、背景、文字、边框、语义色等)的定义源头;
- themes/base.css:与主题无关的基础样式与动画;
- themes/index.css:主题系统入口,依次
@import上述两份文件。
一、使用方式
1. UnoCSS 原子类(推荐)
UnoCSS 原子类在编译期解析,类名即颜色语义,最简洁直观:
// ✅ 背景色 - 简洁直观 <div className="bg-base"> // 主背景 (白色/黑色) <div className="bg-1"> // 次级背景 (#F7F8FA) <div className="bg-2"> // 三级背景 (#F2F3F5) <div className="bg-brand"> // 品牌色背景 (#7583B2) // ✅ 文本色 - 语义化 <div className="text-t-primary"> // 主要文字 (#1D2129) <div className="text-t-secondary"> // 次要文字 (#86909C) <div className="text-brand"> // 品牌色文字 // ✅ 边框色 <div className="border-b-base"> // 基础边框 (#E5E6EB) <div className="border-b-light"> // 浅色边框 // ✅ 品牌色系列 <div className="bg-aou-1"> // AOU 色板 1-10 <div className="hover:bg-brand-hover"> // 品牌色悬停2. 内联样式(CSS 变量)
当必须使用内联样式(例如动态计算颜色、非布局类样式)时,直接引用语义化 CSS 变量:
<div style={{ backgroundColor: 'var(--bg-base)' }}> <div style={{ color: 'var(--text-primary)' }}> <div style={{ borderColor: 'var(--border-base)' }}> <div style={{ backgroundColor: 'var(--brand)' }}>需要动态读取变量计算值时,可使用 styles/colors.ts 中提供的getCSSVar辅助函数(内部通过getComputedStyle(document.documentElement).getPropertyValue(...)取值)。
二、常见颜色映射表
下表是迁移时最常用的对照依据,完整覆盖了 MIGRATION 指南中列出的全部映射关系:
| 旧值 (Hex) | UnoCSS 类 | CSS 变量 | 说明 |
|---|---|---|---|
#FFFFFF | bg-base | var(--bg-base) | 主背景 |
#F7F8FA | bg-1 | var(--bg-1) | 次级背景/填充色 |
#F2F3F5 | bg-2 | var(--bg-2) | 三级背景 |
#E5E6EB | bg-3或border-b-base | var(--border-base) | 边框/分隔线 |
#7583B2 | bg-brand/text-brand | var(--brand) | 品牌色 |
#EFF0F6 | bg-aou-1/bg-brand-light | var(--aou-1) | 品牌浅色背景 |
#E5E7F0 | bg-aou-2 | var(--aou-2) | AOU 色板 2 |
#1D2129 | text-t-primary | var(--text-primary) | 主要文字 |
#86909C | text-t-secondary/bg-6 | var(--text-secondary) | 次要文字 |
#165DFF | bg-primary/text-primary | var(--primary) | 主色调 |
说明:
colors.ts中同时维护了一份colorMapping常量(含大小写两种形式,如'#EFF0F6'/'#eff0f6'),可用于编写自动化迁移脚本时的程序化查表。
三、迁移步骤
迁移遵循「搜索 → 查表 → 替换 → 测试」的四步流程:
- 搜索硬编码颜色:在
packages/desktop/src/renderer下搜索bg-#、text-#、color-#、border-#等模式; - 查表:对照上文「常见颜色映射表」找到对应的主题变量;
- 替换:改写为 UnoCSS 语义化原子类(推荐)或 CSS 变量;
- 测试:在明暗主题下分别切换验证,重点检查背景与文字对比度、边框可见性以及自定义主题下的生效情况。
从当前仓库的搜索现状看,迁移仍在推进中:pages/conversation/Messages/components/MessageToolCall.tsx、MessageToolGroupSummary.tsx与pages/conversation/GroupedHistory/ConversationRow.tsx中仍残留少量bg-#/border-#模式的硬编码,新代码应一律使用语义化写法。
四、迁移示例
Before(硬编码):
<div className='bg-#EFF0F6 hover:bg-#E5E7F0'> <span className='text-#1D2129'>文本</span> <div className='border border-#E5E6EB'></div> </div>After(主题变量):
<div className='bg-aou-1 hover:bg-aou-2'> <span className='text-t-primary'>文本</span> <div className='border border-b-base'></div> </div>常见模式对照:
// ❌ 不推荐 <div className="bg-#F7F8FA text-#86909C border-#E5E6EB"> // ✅ 推荐 <div className="bg-1 text-t-secondary border-b-base">五、源码级原理:uno.config.ts 中的语义色板
迁移的目标类名并非约定俗成,而是由 uno.config.ts 中的 UnoCSS 主题配置严格定义。理解这张"类名 → CSS 变量"的映射表,才能写出与主题系统完全一致的代码:
- 语义化文字色(textColors):
t-primary→var(--text-primary)、t-secondary→var(--text-secondary)、t-tertiary→var(--bg-6)、t-disabled→var(--text-disabled); - 语义状态色(semanticColors):
primary/success/warning/danger/info一组,可同时作用于bg-*、text-*、border-*前缀; - 背景色系统(backgroundColors):数字键
1~10(含base、hover、active)同时支持bg-*和border-*两种前缀,例如bg-1与border-1都指向var(--bg-1); - 边框色(borderColors):
border-b-base、border-b-light、border-b-1~border-b-3; - 品牌色(brandColors):
brand、brand-light、brand-hover; - AOU 品牌色系(aouColors):
aou-1~aou-10十个色阶,是 AionUi 的品牌紫灰色调色板; - 组件专用色(componentColors):
message-user、message-tips、workspace-btn,分别指向消息气泡、提示、工作区按钮背景。
此外,uno.config.ts 还通过自定义rules桥接了 Arco Design 官方色板,可混用text-1~text-4(Arco 文字色)、bg-fill-1~bg-fill-4(填充色)、border-arco-1~border-arco-4(Arco 边框色)、bg-primary-light-1~-light-4(浅色系)、bg-primary-1~-9(官方色阶)以及bg-popup、bg-color-white/bg-color-black等。
六、明暗两套变量从哪来:default-color-scheme.css
所有var(--xxx)变量的实际取值定义在 themes/default-color-scheme.css 中,同一套变量名在亮色与暗色下拥有不同值:
- 亮色基线(
:root, [data-color-scheme='default']):AOU 色板--aou-1: #eff0f6→--aou-10: #0d101c;背景--bg-base: #ffffff、--bg-1: #f9fafb、--bg-2: #f2f3f5、--bg-3: #e5e6eb;文字--text-primary: #000000、--text-secondary: #454d5f、--text-disabled: #c9cdd4;语义色--primary: #165dff、--success: #00b42a、--warning: #ff7d00、--danger: #f53f3f; - 暗色基线(
[data-color-scheme='default'][data-theme='dark']):AOU 色板整体反转(--aou-1: #2a2a2a→--aou-10: #eff0f6);背景--bg-base: #0e0e0e、--bg-1: #1a1a1a、--bg-2: #262626、--bg-3: #333333;文字--text-primary: #ffffff、--text-secondary: #ced3da;语义色替换为适合暗背景的亮色变体(如--primary: #4d9fff、--danger: #f76560)。
这正是迁移后颜色能自动适配明暗主题的根本原因:组件只写语义类名/变量名,具体取哪个十六进制值由主题系统在运行时决定。
七、主题覆盖与 token 契约:自定义主题为何能生效
迁移的意义最终要落到"可被用户主题覆盖"上。AionUi 的主题模型(见 common/theme/types.ts)由appearance加两层覆盖通道组成:结构化tokens与原始css。其中结构化 tokens 受 common/theme/tokenContract.ts 约束——这是"哪些 CSS 变量可被覆盖"的唯一事实来源,包含--bg-base、--text-primary、--border-base、--primary、--brand、--message-user-bg等契约内变量,按appearance-scoped(随明暗变化)与appearance-invariant(明暗一致)两种作用域声明。
底层落盘逻辑在 renderer/utils/theme/tokensToCss.ts:tokensToCss会静默丢弃不在契约中的 key,因此拼写错误的变量名不会污染 DOM;同时它刻意使用:root[data-theme='light'|'dark'](特异性 0,2,0)选择器,才能压过基线暗色块[data-color-scheme='default'][data-theme='dark'](同为 0,2,0),保证暗色模式下 token 覆盖不失效。
主题的实际应用由 renderer/utils/theme/applyTheme.ts 完成:一次调用同时写入<html>上的data-theme属性与<body>上的arco-theme属性,并把 tokens 样式与装饰性 css 以#theme-tokens、#theme-decoration两个<style>追加到<head>末尾。这意味着:只要组件使用契约内的语义变量,任何自定义主题都能立即作用于全应用;而硬编码颜色则会被永久隔离在主题体系之外。
八、快速参考
迁移时可直接对照这份速查清单:
- 背景:
bg-base,bg-1,bg-2,bg-3 - 文字:
text-t-primary,text-t-secondary,text-t-disabled - 边框:
border-b-base,border-b-light - 品牌:
bg-brand,bg-brand-light,bg-brand-hover - 状态:
bg-primary,bg-success,bg-warning,bg-danger - AOU色板:
bg-aou-1~bg-aou-10
结语
AionUi 的主题色迁移本质上是把"固定值"替换为"语义引用":通过 uno.config.ts 定义的原子类与 themes/default-color-scheme.css 定义的 CSS 变量,组件颜色自动获得明暗自适应与用户主题可覆盖两项能力。遵循本文的映射表、迁移步骤与源码级原理解析,即可在新增页面和存量代码中写出真正主题化的界面,相关主题系统的完整架构说明可进一步参考 themes/README.md。
【免费下载链接】AionUiOpen-source 24/7 Cowork app for OpenClaw, Hermes, Claude Code, Codex, OpenCode and 20+ more CLI Agent | Customize your assistants | Team them up|Star if you like it!项目地址: https://gitcode.com/GitHub_Trending/ai/AionUi
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考