Темизация приложения
Темы Q.Palette основаны на CSS Custom Properties (opens in a new tab): тема — это обычный CSS-файл,
который переопределяет значения токенов. Благодаря этому тему можно менять на лету, без перезагрузки страницы
и без пересборки приложения. Для токенов Q.Palette зарезервирован префикс --q- — учитывайте это,
создавая собственные переменные.
Темизация состоит из двух независимых осей:
| Ось | Атрибут на <html> | Значения |
|---|---|---|
| Тема | data-color-theme | softui (по умолчанию), minimalism, идентификатор вашей темы |
| Цветовая схема | data-color-scheme | light, dark |
Как приложение применяет тему
Рутовое приложение хранит выбранную тему и схему в localStorage, выставляет соответствующие атрибуты на <html>
и подгружает CSS-файл темы в заранее объявленный тег <link id="theme-file"> в index.html.
Файл темы берётся из ассетов рутового приложения — assets/themes/<id>.css. Чтобы обновить тему на стенде,
нужно обновить ассеты образа.
Посмотреть, как токены работают в живом интерфейсе, можно на странице «Темизация приложения» (opens in a new tab) портала для разработчиков: там значения токенов меняются селектором цвета и сразу применяются к области предпросмотра.
Создание собственной темы
Возьмите за основу готовую тему
Файлы поставляемых тем лежат в пакете @diasoft/qpalette-themes:
node_modules/@diasoft/qpalette-themes/assets/softui.css
node_modules/@diasoft/qpalette-themes/assets/minimalism.cssСкопируйте подходящий файл и переименуйте его, например в my-theme.css.
Файл темы самодостаточен: рутовое приложение подменяет содержимое #theme-file целиком, поэтому тема
должна содержать полный набор токенов. «Частичную» тему из нескольких переменных сделать нельзя —
недостающие токены не подхватятся из другой темы.
Замените идентификатор в селекторах
В скопированном файле укажите идентификатор своей темы:
/* светлая схема */
html[data-color-theme='my-theme']:not(data-color-scheme),
html[data-color-theme='my-theme'][data-color-scheme='light'] {
/* ... */
}
/* тёмная схема */
html[data-color-theme='my-theme'][data-color-scheme='dark'] {
/* ... */
}Задайте нужные значения токенов
--q-page-background: #fffdf5;
--q-page-text: #e18e46;
--q-page-text-secondary: hsl(55, 73%, 42%);Разместите файл темы
Файл кладётся в ассеты рутового приложения — src/assets/themes/my-theme.css.
Зарегистрируйте тему в конфигурации
{
"theme": {
"themes": [
{ "name": "My Theme", "id": "my-theme" }
]
}
}Скелет файла темы
Файл темы состоит из трёх блоков: два по схемам и один общий. Токены, значения которых вы не меняете, оставляйте такими же, как в исходном файле, — удалять их нельзя.
/* 1. Светлая схема: палитра и цветовые токены компонентов */
html[data-color-theme='my-theme']:not(data-color-scheme),
html[data-color-theme='my-theme'][data-color-scheme='light'] {
--q-font-family: 'Inter', -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Arial, sans-serif;
--q-is-dark-scheme: 0;
/* палитра */
--q-base-0: white;
--q-base-500: #69727b;
--q-base-1000: black;
--q-primary-500: #3b82f6;
--q-primary: var(--q-primary-500);
/* …остальные рампы и семантические токены — из исходного файла */
/* токены компонентов */
--q-sidebar-bg: var(--q-content-background);
--q-sidebar-text: var(--q-content-text);
/* … */
}
/* 2. Тёмная схема: те же токены с другими значениями */
html[data-color-theme='my-theme'][data-color-scheme='dark'] {
--q-is-dark-scheme: 1;
--q-base-0: black;
--q-base-500: #969ca3;
--q-base-1000: white;
/* … */
}
/* 3. Общая часть: размеры, радиусы и типографика — от схемы не зависят */
html[data-color-theme='my-theme'] {
--q-border-radius-sm: 0.25rem;
--q-border-radius-md: 0.375rem;
--q-border-radius-lg: 0.5rem;
/* … */
}Настройка через конфигурацию
Раздел theme в config.json управляет и списком доступных тем, и тем,
что именно увидит пользователь.
| Поле | Назначение |
|---|---|
theme.themes | Список тем в панели настроек: name и id каждой темы |
theme.theme | Фиксирует тему: выбор темы в панели настроек скрывается |
theme.scheme | Фиксирует цветовую схему: выбор схемы в панели настроек скрывается |
theme.defaultTheme | Тема при первом посещении, пользователь может её сменить |
theme.defaultScheme | Схема при первом посещении |
{
"theme": {
"defaultScheme": "light",
"defaultTheme": "softui",
"themes": [
{ "name": "SoftUI", "id": "softui" },
{ "name": "Минимализм", "id": "minimalism" },
{ "name": "My Theme", "id": "my-theme" }
]
}
}Что применяется при старте
Сначала приложение собирает список доступных тем, затем выбирает из него тему и цветовую схему. Список берётся из первого непустого источника:
themes— устаревший вариант записи на верхнем уровне конфигурации;theme.themes;- список по умолчанию — SoftUI и Минимализм.
Тема и схема выбираются независимо друг от друга, по одному и тому же правилу — первое заданное значение сверху вниз:
| Приоритет | Тема | Цветовая схема |
|---|---|---|
| 1 | theme.theme — фиксация, выбор в настройках скрыт | theme.scheme — фиксация, выбор в настройках скрыт |
| 2 | выбор пользователя из localStorage, если такая тема есть в списке | выбор пользователя из localStorage |
| 3 | theme.defaultTheme | theme.defaultScheme |
| 4 | первая тема из списка | light |
Список тем формируется всегда, даже когда тема зафиксирована через theme.theme: он остаётся источником
запасного значения и наполняет панель настроек там, где выбор доступен.
Совместимость со старыми конфигурациями: color.scheme читается как тема, color.theme — как схема,
color.defaultScheme и color.defaultTheme — как значения по умолчанию для них же. Эти поля объявлены
устаревшими и будут удалены в 9.0.0 — используйте раздел theme.
Структура файла темы
Файл темы состоит из четырёх частей:
- Палитра светлой схемы — цветовые рампы и семантические токены под
[data-color-scheme='light']. - Палитра тёмной схемы — те же токены под
[data-color-scheme='dark']. - Цветовые токены компонентов —
--q-button-*,--q-input-*,--q-sidebar-*и т. д. - Размерные токены — размеры, отступы, радиусы и типографика. Они не зависят от схемы и задаются один раз.
Токены именуются по шаблону --q-<группа>[-модификатор][-шаг|состояние]. Рампа каждого цвета содержит шаги
от -0 (белый) до -1000 (чёрный), алиас без шага, полупрозрачные варианты -transparent-* и тени -shadow-*:
--q-primary-50: #e8f1f8;
--q-primary-500: #3b82f6;
--q-primary-900: #061725;
--q-primary: var(--q-primary-500);
--q-primary-transparent-100: rgba(29, 113, 184, 0.1);Компонентные токены, как правило, ссылаются на семантический слой, а не на конкретные цвета — так тема остаётся согласованной:
--q-sidebar-bg: var(--q-content-background);
--q-sidebar-text: var(--q-content-text);
--q-sidebar-hover: var(--q-primary-500);
--q-sidebar-active-bg: var(--q-primary-transparent-100);
--q-sidebar-active-text: var(--q-primary-700);
--q-sidebar-border: var(--q-content-border);
--q-sidebar-icon: var(--q-base-500);Между светлой и тёмной схемами должны различаться только цвета. Размеры, отступы и типографику задавайте в общей части файла — иначе интерфейс будет «прыгать» при переключении схемы.
Полный перечень токенов смотрите прямо в файлах поставляемых тем — softui.css и minimalism.css
пакета @diasoft/qpalette-themes. Это точный и всегда актуальный источник: набор токенов меняется
вместе с версией Q.Palette.
Проверка результата
Откройте приложение и переключите тему в панели настроек. Убедитесь, что на элементе <html> выставлены
ожидаемые data-color-theme и data-color-scheme, а в <link id="theme-file"> подставлен адрес вашего файла.
Значения конкретных токенов удобно смотреть в инструментах разработчика, на селекторе html.
Если тема не применилась, проверьте: совпадает ли id в конфигурации с идентификатором в селекторах файла,
доступен ли файл по своему адресу (вкладка Network), и не зафиксирована ли другая тема через theme.theme.