Skip to content

主题定制

@luxeanor/ui 的主题 = 配色家族 × 明暗档 两个维度,由 <html> 上的属性契约驱动:

html
<html data-theme="amethyst | obsidian | ink | emerald" data-mode="light | dark">
  • data-theme 决定主色调(--lx-primary 及其衍生渐变、发光、容器色)
  • data-mode 决定中性色阶(背景阶梯、文字阶梯、边框、投影)

4 家族 × 2 档

家族light(主色 / 背景)dark(主色 / 背景)
amethyst 紫(默认)#6200EE#FEF7FF#9D8CFF#0B0A10
obsidian 金#8A6820#FDFAF3#D2B37B#0B0C0F
ink 蓝#1E5AE0#F7F9FD#7CA4F8#070C15
emerald 绿#1E7A55#F6FAF7#46C08A#08110E

本文档站导航栏右侧就挂着 LxThemeSwitcher——切一下,整站(含所有 demo)即时换肤。

运行时切换:useTheme

ts
import { useTheme } from '@luxeanor/ui'

const { family, mode, resolvedMode, setFamily, setMode } = useTheme()

setFamily('ink')     // 'amethyst' | 'obsidian' | 'ink' | 'emerald'
setMode('auto')      // 'light' | 'dark' | 'auto'(auto 跟随系统)
resolvedMode.value   // 'light' | 'dark'(auto 解析后的实际档位)
  • 模块级单例:任意组件调用拿到同一份状态,首个调用完成初始化
  • 状态持久化到 localStorage(键 lx-theme),刷新保持
  • auto 档监听系统 prefers-color-scheme 实时跟随
  • SSR 下返回默认值、不触碰 DOM

现成 UI:ThemeSwitcher 主题切换器 组件封装了整套交互。

首屏防闪烁:themeBootScript

CSS 解析前必须把属性打到 <html> 上,否则首屏会闪一帧默认主题。把库导出的 themeBootScript 内联进 index.html<head>(在任何样式表之前):

html
<head>
  <script>/* themeBootScript 字符串内容 */</script>
  <!-- 之后才是样式表 -->
</head>

Vite 项目可在构建时注入;VitePress/Nuxt 可通过 head 配置注入(本站即此做法)。

从 0.1.x 迁移(BREAKING)

v0.2.0 起 data-theme 语义变更:从 dark | light 改为家族名,明暗档移到新增的 data-mode 属性。

0.1.x0.2.0+
切暗色data-theme="dark"data-theme="<家族名>" + data-mode="dark"
默认暗色黑金amethyst 浅色

0.1.x 写过 data-theme="light|dark" 的消费端升级后必须改为新契约,否则会落回默认家族 amethyst