☰
AionUi 主题色迁移指南:从硬编码 Hex 到 UnoCSS 语义化原子类与 CSS 变量
2026/10/1 14:15:02 网站建设 项目流程

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属性切换。如果组件里直接写死十六进制颜色,就会出现两类问题:

  1. 明暗主题无法自适应:硬编码的浅色背景在暗色模式下仍然保持原色,造成刺眼或不可读。
  2. 用户自定义主题失效: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 变量说明
#FFFFFFbg-basevar(--bg-base)主背景
#F7F8FAbg-1var(--bg-1)次级背景/填充色
#F2F3F5bg-2var(--bg-2)三级背景
#E5E6EBbg-3或border-b-basevar(--border-base)边框/分隔线
#7583B2bg-brand/text-brandvar(--brand)品牌色
#EFF0F6bg-aou-1/bg-brand-lightvar(--aou-1)品牌浅色背景
#E5E7F0bg-aou-2var(--aou-2)AOU 色板 2
#1D2129text-t-primaryvar(--text-primary)主要文字
#86909Ctext-t-secondary/bg-6var(--text-secondary)次要文字
#165DFFbg-primary/text-primaryvar(--primary)主色调

说明:colors.ts中同时维护了一份colorMapping常量(含大小写两种形式,如'#EFF0F6'/'#eff0f6'),可用于编写自动化迁移脚本时的程序化查表。

三、迁移步骤

迁移遵循「搜索 → 查表 → 替换 → 测试」的四步流程:

  1. 搜索硬编码颜色:在packages/desktop/src/renderer下搜索bg-#、text-#、color-#、border-#等模式;
  2. 查表:对照上文「常见颜色映射表」找到对应的主题变量;
  3. 替换:改写为 UnoCSS 语义化原子类(推荐)或 CSS 变量;
  4. 测试:在明暗主题下分别切换验证,重点检查背景与文字对比度、边框可见性以及自定义主题下的生效情况。

从当前仓库的搜索现状看,迁移仍在推进中: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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询