跳转到内容

配色主题

ui.themes 声明的是数据,不是 CSS:插件只写要改的颜色和结构枚举,核心补齐、检查后生成样式。不需要能力,也不能通过主题交付脚本、字体、动效或页面布局。

import { definePlugin } from '@nextskin/plugin-sdk'
export default definePlugin({
capabilities: [],
ui: {
themes: [
{
name: 'cobalt',
label: 'themes.cobalt',
colors: {
light: { accent: '#2a52e5' },
dark: { accent: '#86a2ff' },
},
},
],
},
})

label 是插件自己的文案键,在 locales/zh-CN.json 和 locales/en.json 中分别写入名字,例如 { "themes": { "cobalt": "钴蓝" } }。官方插件 color-themes 是完整例子。

主题 id 为 <插件 id>/<name>,例如 color-themes/cobalt。name 匹配 [a-z][a-z0-9]*(-[a-z0-9]+)*,最多 32 个字符,同一插件内不能重复;一个插件最多声明 16 套。

ThemeColor 是以下 22 个 token 名的联合,不带 --color- 前缀。这些名字是公开 API,改名或删除要发大版本。

token 用途
bg 页面背景
surface 卡片、面板背景
surface-raised 浮起的表面
surface-sunken 下沉的表面
border 普通边框
border-strong 强调边框
text 正文
text-muted 次要文字
text-inverse 反色文字
accent 画在表面上的强调色(链接、图标、选中态等)
accent-fg 强调色上的前景
accent-subtle 强调色淡底
accent-fill 主要按钮这类色块
accent-fill-fg 色块上的前景
success 成功色
success-fg 成功色上的前景
warning 警告色
warning-fg 警告色上的前景
danger 危险色
danger-fg 危险色上的前景
focus 焦点框
shadow 阴影

stage(材质展台)、checker-a、checker-b(透明区域的棋盘格)锁住,在任何主题下都取钻石青的默认值,保证深色、浅色材质都看得清。

colors.light、colors.dark 都可以省略,也都可以只写一部分。色值只接受 #rrggbb,不分大小写,manifest 中统一存成小写;三位、八位、颜色函数或带空白的写法都不接受。SDK 的 ThemeColorValue 类型只检查 # 开头,完整格式由构建命令检查。

没有声明的颜色按模式补齐:

  • accent-fill 等于本主题的 accent,accent-fill-fg 等于本主题的 accent-fg;
  • focus 等于本主题的 accent;
  • accent-subtle 是本主题的 accent 按 12%(亮色)或 16%(暗色)在 sRGB 中混入本主题的 surface,各通道四舍五入;
  • 其余取钻石青的默认值。

上例只改 accent,推导出的淡底就是亮色 #e5eafc、暗色 #282f41。需要别的焦点框或淡底时可以显式声明。不要抄一整份默认配色:核心以后微调灰色时,省略的值会跟着更新。

accent 要在页面、卡片等表面上看得清;如果颜色在白底上太浅,只适合当有自己前景色的色块,就单独写 accent-fill 和 accent-fill-fg。例如高对比主题在亮色下用黑色作为 accent,荧光黄绿 #d4ff1e 作为 accent-fill,色块上的字用黑色;暗色下荧光色看得清,accent 用它,色块跟着推导即可。focus 和 accent-subtle 仍从 accent 推导。

structure 和 colors 并列,每项都可以省略,省略的取钻石青。亮暗共用一份结构,切换亮暗时边框粗细等尺寸不会跟着变。

项 取值 默认 效果
radius rounded、square rounded square 时 2px、4px 圆角变直角
borders thin、thick thin thick 时常规边框从 1px 变 2px,选中框从 2px 变 4px;原本固定为 2px 的勾选框等不变
cards flat、raised flat raised 时面板和卡片静止带 4px 硬边阴影,颜色取 shadow,悬停照旧上移 2px

三项互不影响,可以只写一项,例如 structure: { borders: 'thick' };高对比主题写的是:

structure: { radius: 'square', borders: 'thick', cards: 'raised' }

交枚举是为了让每种组合都在核心的设计规范内,样式中也只会出现核心生成的值。不接受 CSS 值,CSS 变量名也不是插件 API;插件作者只依赖这三项枚举。未知键或取值会使构建、安装失败。

检查针对补齐后的完整配色,两种模式分别检查以下三条。

  1. 对比度:正文相关组合至少 4.5:1,边框和焦点框至少 3:1。下表同一行有多个背景时,每个都单独检查,共 26 组。

    前景 背景 最低比值
    text bg、surface、surface-raised、stage、accent-subtle 4.5
    text-muted bg、surface、surface-raised、surface-sunken、stage、accent-subtle 4.5
    text-inverse text 4.5
    accent-fg accent 4.5
    accent-fill-fg accent-fill 4.5
    accent bg、surface 4.5
    success-fg success 4.5
    success surface 4.5
    warning-fg warning 4.5
    warning surface 4.5
    danger-fg danger 4.5
    danger surface 4.5
    border-strong surface、bg 3
    focus bg、surface 3
  2. 明暗方向:亮色模式下 bg、text-inverse 的相对亮度都必须大于 text;暗色模式下都必须小于 text,使浏览器原生控件和二维码的明暗方向一致。

  3. 强调色和危险色分开:accent、accent-fill 各自和 danger 的 OKLab 欧氏距离至少为 0.12。主要按钮和删除按钮不能看着一样。其他状态色之间不检查距离,仍建议肉眼核对。

accent-fill 和表面的对比度不检查:色块靠自己的前景色和阴影辨认。没写两个色块颜色时,新检查与原有强调色检查使用同一组值,以前通过的主题仍然通过。

nextskin-plugin build 会检查形状和这三条规则;不通过就构建失败,逐条列出主题名、亮暗模式、哪一组和实际值。洋红强调色配默认危险色的距离只有约 0.10,需要调整危险色;调整以后也要注意它是否与警告色太接近。

核心不信任构建工具:安装、升级插件时用核心自己的默认值再检查,不通过就拒绝安装。核心升级后每次加载插件也检查;某套主题不再通过时,只禁用这一套,后台主题页列出原因,插件的其他功能照常。

插件新带来的主题默认不启用。超级管理员先在后台的主题页查看小样,再启用需要的主题、设置站点默认主题;安装或启用插件不会自动把它的主题开放给用户。

登录用户在用户中心的主题页选择已启用的主题,也可以跟随站点默认。选择存在账号里,换设备仍然生效;亮暗模式独立按设备保存。访客看站点默认主题。

用户所选主题暂时不可用时,回落到站点默认,再回落到钻石青;插件恢复、主题重新可用后,原来的选择继续生效。

NextSkin v0.7.2插件 SDK v1.0.0-rc.7提交 e6ffcd2本站源码