关于 univer-customize-theme
面向 Univer 应用开发者的主题定制 Skill,指导通过公开 Facade 和主题服务构建、应用完整主题,并核对版本、样式及明暗模式。
主要功能
- 01基于内置主题构建完整调色板
- 02通过 createUniver 设置初始主题
- 03使用 Facade 执行运行时主题切换
- 04借助 ThemeService 获取实时颜色
- 05检查产品主题、暗色模式与样式
适用场景
- 01为 Univer 应用配置品牌主题
- 02为插件渲染代码读取主题颜色
- 03验证明暗模式下的界面与画布
- 04排查版本或 Facade API 不匹配
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ dream-num/ skills --skill univer-customize-theme安装后在 Claude Code 中输入/univer-customize-theme确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/openai.yamlreferences/products-and-pro.mdtheme-api.md详细介绍
Univer 自定义主题
在不绕过公共 Facade 或运行时主题服务的情况下,构建并应用完整的 Univer 主题。
源码基线:当前 Univer OSS 和 Pro 源码,其清单中标识的版本为
1.0.0-beta.0。请先检查目标应用已安装的声明;版本标签相同的 npm 发行版可能落后于当前源码 API。
工作流
- 判断请求涉及应用配色、暗色模式、插件样式,还是 Pro Chart 主题。这些属于不同的契约。
- 检查确切的已安装版本和集成模式。预设会组合插件和 Facade 扩展;插件模式需要显式导入插件和
/facade。 - 从内置主题派生完整的
Theme。不要手写或强制转换不完整的对象。 - 将初始主题传递给
createUniver。仅当目标声明中存在当前的FUniver主题方法时,才使用这些方法。 - 在插件和渲染代码中通过
ThemeService读取实时颜色,在浏览器 CSS 中通过--univer-*变量读取。 - 在每个启用的产品宿主中验证浅色和暗色外观。
构建完整的品牌配色
从所属软件包导入,并确保它与目标应用使用的 Univer 版本完全一致:
import type { Theme } from '@univerjs/themes';
import { defaultTheme } from '@univerjs/themes';
export const brandTheme: Theme = {
...defaultTheme,
primary: {
...defaultTheme.primary,
50: '#F5F3FF',
100: '#EDE9FE',
200: '#DDD6FE',
300: '#C4B5FD',
400: '#A78BFA',
500: '#8B5CF6',
600: '#7C3AED',
700: '#6D28D9',
800: '#5B21B6',
900: '#4C1D95',
},
};
当前源码架构还包含 gray、语义色阶、loop-color 和 highlight.background。除非设计有意替换,否则请保留所有分支。有关架构、内置主题和发行版检查要求,请参阅主题 API 和迁移。
应用主题
将初始主题添加到现有的 createUniver 配置中。保持该集成的语言环境、预设、容器和显式样式表导入不变:
const { univer, univerAPI } = createUniver({
locale: LocaleType.EN_US,
locales,
presets,
theme: brandTheme,
darkMode: false,
});
当前源码支持通过基础 Facade 在运行时更改主题:
univerAPI.setTheme(brandTheme);
univerAPI.toggleDarkMode(true);
const currentTheme = univerAPI.getCurrentTheme();
const darkMode = univerAPI.isDarkMode();
主题选择和暗色模式相互独立。setTheme() 不会切换暗色模式,toggleDarkMode() 也不会替换配色。
预设模式会构建基础 Facade。在手动插件模式下,注册插件后,请从公共核心入口构建它:
import { FUniver } from '@univerjs/core/facade';
const univerAPI = FUniver.newAPI(univer);
不存在 @univerjs/themes/facade 软件包。如果已安装的 FUniver 声明中没有 setTheme()、getCurrentTheme() 或 isDarkMode(),请在初始化期间配置完整主题或升级;不要通过 univer.__getInjector() 访问内部实现。
让自定义代码适配主题
对于自定义 DOM,请使用 UI 工作台注入的变量:
.brand-action {
color: var(--univer-gray-0);
background: var(--univer-primary-600);
border-color: var(--univer-primary-700);
}
对于插件服务、画布渲染和模型代码,请注入 ThemeService 并解析实时标记,而不是将内置配色作为运行时状态导入:
import { Inject, ThemeService } from '@univerjs/core';
export class SelectionColorProvider {
constructor(
@Inject(ThemeService) private readonly _themeService: ThemeService
) {}
getColor(): string {
return this._themeService.getColorFromTheme('primary.600');
}
}
缓存派生颜色时,请监听 currentTheme$ 或 darkMode$,并在所属对象的生命周期结束时释放订阅。无头运行时具有 ThemeService,但不会注入浏览器 CSS 变量。
六种产品和 Pro Charts
一个 Univer 运行时会在 Sheets、Docs、Slides、Bases、Boards 和 PDFs 之间共享其核心 ThemeService。主题设置不会注册产品插件、加载语言环境或加载 CSS。请保留聚合预设 CSS,或保留插件模式下所选的每个样式表。
Slides、Boards、PDF 表格、Sheet 区域和 Pro Charts 也有内容级的主题/样式系统。它们使用的契约与应用配色不同。更改内容或图表颜色之前,请阅读产品和 Pro 主题。
浏览器全局边界
当前 UI 工作台会将扁平化变量写入一个 :root 样式元素,并在 document.documentElement 上切换 univer-dark。因此,同一文档中的多个浏览器 UI 实例无法隔离 CSS 配色或暗色模式类;最后一次文档级更新会生效。当前的销毁操作也不会恢复之前的文档级样式或根类。请使用统一的外观,或将编辑器隔离在 iframe 等独立文档中;不要承诺 univer.dispose() 会恢复宿主页面的外观。
验证
- 确认所有 Univer 包都使用与目标应用完全一致的发行版本。
- 对完整的
Theme进行类型检查;不要强制转换不完整的对象。 - 验证必需的预设样式和插件样式仍会加载。
- 在工作台挂载后,测试初始主题设置以及支持的运行时切换。
- 检查浅色和深色模式下的 DOM UI 和画布内容。
- 分别测试每个已启用的产品宿主和 Pro Charts。
- 检查文本、焦点、选中、错误和禁用状态的对比度。
避免
- 不要修改内置主题对象;应使用嵌套展开进行复制。
- 不要修改
document.head,也不要自行实例化ThemeSwitcherService。 - 不要将生成的
--univer-*值作为事实来源进行覆盖;下一次主题发出时会替换这些值。 - 不要在插件中从
defaultTheme读取实时运行时颜色。 - 不要假定更改应用主题会重写已持久化的产品内容颜色。
- 不要只更改版本字符串来迁移
0.25.0代码;架构、内置项和 Facade 接口均已更改。
参考资料
- 主题 API 和迁移 — 精确的架构、内置项、Facade/ThemeService API、CSS 展平、深色模式、发行版本门槛以及
0.25.0的差异 - 产品和 Pro 主题 — 六种产品的行为、CSS 所有权、产品内容主题,以及独立的 Pro Chart 主题 API