Пресеты тем
Пять встроенных пресетов — это предлагаемое по умолчанию эстетическое решение lh-ui: каждый берёт основной цвет из традиционной китайской палитры и дополняет его полным набором светлой и тёмной цветовых схем.
Обзор пресетов
Заголовок раздела «Обзор пресетов»| Пресет | name |
Идентификатор | labelEn | Описание | Светлый основной цвет |
|---|---|---|---|---|---|
| 青花瓷 (сине-белый фарфор) | 'cerblue' |
LhCerblue |
Ceramic Blue | Подглазурная роспись сине-белого фарфора, изящная и спокойная | Нет |
| 松花绿 (зелёный сосны) | 'songhua' |
LhSonghua |
Pine Green | Бамбуковая роща, полная жизни | Да |
| 朱砂 (киноварь) | 'zhusha' |
LhZhusha |
Vermilion | Красный киноварный цвет традиционных печатей, торжественный | Нет |
| 水墨 (тушь) | 'shuimo' |
LhShuimo |
Ink Wash | Тушевая живопись, сдержанная и минималистичная | Нет |
| 藤黄 (gamboge) | 'golden' |
LhGolden |
Golden Autumn | Жёлтый цвет клёнов поздней осени, тёплый и золотистый | Да |
cerblue · Ceramic Blue青花瓷釉下彩,清雅素净
--lh-primary-color#2B4C7C--lh-primary-color-hover#3D649E--lh-primary-color-active#1F3A5F--lh-primary-color-bg#E8EDF3--lh-primary-color-border#D4DCE8
songhua · Pine Green竹林修竹,生机勃勃
--lh-primary-color#5B8C5A--lh-primary-color-hover#7BB079--lh-primary-color-active#4F8F4C--lh-primary-color-bg#E8F5E8--lh-primary-color-border#D0E8CF--lh-color-on-primary#101410--lh-selected-color#456F44
zhusha · Vermilion传统印章朱砂红,喜庆庄重
--lh-primary-color#B23A3A--lh-primary-color-hover#C45050--lh-primary-color-active#9A3030--lh-primary-color-bg#FDF0F0--lh-primary-color-border#F0D8D8
shuimo · Ink Wash水墨丹青,素雅极简
--lh-primary-color#2C2C2C--lh-primary-color-hover#5A5A5A--lh-primary-color-active#1A1A1A--lh-primary-color-bg#F5F5F5--lh-primary-color-border#E0E0E0
golden · Golden Autumn深秋枫黄,温暖金黄
--lh-primary-color#B8860B--lh-primary-color-hover#D4A843--lh-primary-color-active#A87F0A--lh-primary-color-bg#FBF6EA--lh-primary-color-border#F0E8D0--lh-color-on-primary#1E1A16--lh-selected-color#82600A
vars каждого пресета
Заголовок раздела «vars каждого пресета»Пять базовых ключей (есть у всех пресетов)
Заголовок раздела «Пять базовых ключей (есть у всех пресетов)»{ '--lh-primary-color': '...', '--lh-primary-color-hover': '...', '--lh-primary-color-active': '...', '--lh-primary-color-bg': '...', '--lh-primary-color-border': '...',}Два дополнительных ключа у пресетов со светлым основным цветом
Заголовок раздела «Два дополнительных ключа у пресетов со светлым основным цветом»songhua (松花绿 (зелёный сосны)) и golden (藤黄 (gamboge)) — светлоосновные; контрастность белого текста на них не дотягивает до AA, поэтому для них обязательно добавить ещё два ключа:
| Ключ | Назначение |
|---|---|
--lh-color-on-primary |
Цвет текста на кнопке основного цвета (для светлого основного цвета используется чёрный) |
--lh-selected-color |
Цвет текста выделенного пункта (контрастность активного цвета в качестве текста на фоне при наведении недостаточна — цвет отдельно затемняется) |
Почему это необходимо: светлоосновная кнопка с белым текстом даёт контрастность всего 3.x:1, что не достигает AA 4.5:1. Гейт verify:theme это пресечёт.
Пример с 松花绿 (зелёный сосны): в комментариях к исходному коду зафиксированы причины исправлений:
--lh-color-on-primary: 松花绿 (зелёный сосны) — светлый основной цвет, контрастность белого текста всего 3.93:1; чёрный текст даёт 4.73:1--lh-selected-color: активный цвет в качестве текста на фоне при наведении даёт всего 3.48:1, для выделенного пункта цвет затемняется отдельно (на цвет фона активной кнопки это не влияет)--lh-primary-color-active: исходный#4B7A4Aдавал 3.70:1 →#4F8F4Cдаёт 4.75:1
Для 藤黄 (gamboge) аналогично: белый текст 3.25:1 → чёрный текст 5.31:1; текст выделения 3.41:1 → затемнён до #82600A; active #9A7208 3.94:1 → #A87F0A 4.70:1.
Жёсткое требование при добавлении нового пресета со светлым основным цветом: обязательно задаются --lh-color-on-primary и --lh-selected-color, иначе гейт AA 4.5:1 в verify:theme завершится неудачей.
Использование пресетов
Заголовок раздела «Использование пресетов»Получение пресета
Заголовок раздела «Получение пресета»import { LH_THEME_PRESETS, getThemePreset, getThemeVars } from '@lh-ui/share/theme'
LH_THEME_PRESETS // Все пятьgetThemePreset('cerblue') // Объект LhCerbluegetThemePreset('not-exists') // undefinedgetThemeVars('cerblue')?.['--lh-primary-color']Инъекция пресета (слой UI)
Заголовок раздела «Инъекция пресета (слой UI)»import { buildPresetStyleText, LH_PRESET_THEME_STYLE_ID } from '@lh-ui/share/theme'
function applyPreset(name: LhThemePresetName) { const vars = getThemeVars(name) if (!vars) return
const text = buildPresetStyleText(vars) let style = document.getElementById(LH_PRESET_THEME_STYLE_ID) if (!style) { style = document.createElement('style') style.id = LH_PRESET_THEME_STYLE_ID document.head.appendChild(style) } style.textContent = text // Заменяет, а не дописывает: при переключении темы старые пользовательские стили не остаются}Ключевые моменты (см. ограничение инъекции в обзоре системы тем): создавать можно только элементы <style>, а не встроенный style на documentElement — иначе цветовая палитра тёмной темы исказится.
ConfigProvider в UI-библиотеках
Заголовок раздела «ConfigProvider в UI-библиотеках»<!-- lh-ui-plus / lh-ui-vue2 --><lh-config-provider theme="cerblue"> <App /></lh-config-provider>Prop theme принимает LhThemePresetName, а внутри компонента выполняется описанная выше логика инъекции. Страница настройки темы и ThemeStudio на сайте docs проходят по LH_THEME_PRESETS и автоматически выводят все пресеты — после добавления нового пресета страницы документации в библиотеках править вручную не нужно.
Пользовательские пресеты
Заголовок раздела «Пользовательские пресеты»import { registerTheme, getThemePreset } from '@lh-ui/share/theme'
registerTheme({ name: 'my-brand', label: 'Брендовый цвет', labelEn: 'Brand', description: 'Основной брендовый цвет компании', vars: { '--lh-primary-color': '#722ED1', '--lh-primary-color-hover': '#9254DE', '--lh-primary-color-active': '#531DAB', '--lh-primary-color-bg': '#F9F0FF', '--lh-primary-color-border': '#D3ADF7', // Для светлоосновного пресета нужно добавить ещё два: // '--lh-color-on-primary': '#101410', // '--lh-selected-color': '#...', },})
getThemePreset('my-brand') // Зарегистрировали — можно использоватьСемантика registerTheme:
- Одноимённое переопределение:
registerTheme({ name: 'cerblue', ... })перекроет встроенный пресет 青花瓷 (сине-белый фарфор) — это сделано осознанно, чтобы сторона бизнеса могла настроить тему по умолчанию, не трогая компоненты. - Новые имена добавляются в конец массива: порядок
LH_THEME_PRESETS— «пять встроенных + зарегистрированные». - Реестр — состояние уровня модуля: импортировали — им пользуются; на всё приложение один экземпляр.
Процесс добавления нового встроенного пресета
Заголовок раздела «Процесс добавления нового встроенного пресета»- Добавить объект
LhThemePresetвsrc/theme/themes/index.ts(как минимум пять--lh-primary-*; для пресета со светлым основным цветом обязательно добавить--lh-color-on-primaryи--lh-selected-color). - Добавить в массив
LH_THEME_PRESETSи дополнить имя в реэкспортеsrc/theme/index.ts. - Запустить
pnpm test(вtheme.specесть регрессия согласованности пресетов) +pnpm verify:theme(гейт AA 4.5:1). - Приложить changeset; страница настройки темы в документации библиотеки автоматически выведет новый пресет.
Важно: vars служат только для потребления в runtime на JS; основной цвет, используемый в компонентных SCSS, по-прежнему находится в styles/theme/common/variables.scss — при переопределении основного цвета встроенной темы менять нужно в двух местах (в theme.spec есть регрессия).
Соглашения об именовании
Заголовок раздела «Соглашения об именовании»Строковые значения пресетов (name: 'cerblue') — это конфигурационные значения, которые пользователи пишут в theme ConfigProvider; их изменение сломает все downstream-конфигурации — это один из пунктов реестра исключений из правил именования. Соответствующие TS-идентификаторы тем не менее несут префикс (LhCerblue).
Примечания
Заголовок раздела «Примечания»- Незарегистрированное имя возвращает
undefined:getThemePreset/getThemeVarsне выбрасывают исключений — слою UI нужно не забывать проверять на пустоту. --lh-primary-color-activeи--lh-selected-color— разные вещи: первый — это цвет фона нажатой кнопки, второй — цвет текста в списках / выделенных пунктах. В пресетах со светлым основным цветом контрастность активного цвета в качестве текста выделения недостаточна — именно поэтому нужен отдельный--lh-selected-color.- Тёмная тема пресетов с тёмным основным цветом осветляется автоматически:
buildPresetDarkVarsопределяет, что контрастность основного цвета относительно тёмного фона страницы#1A1A2Eниже 3, и осветляет его (см. Обзор системы тем).
Связанные документы
Заголовок раздела «Связанные документы»Copyright © 2024-2026 FengMo WenXue