Skip to content

Темизация

Тему виджета можно полностью перекрасить с хост-страницы без пересборки бандла. Все параметры темы проходят через единый пайплайн конфига (см. Конфигурацию): задавайте их через window.MZBOT_CONFIG, атрибутом data-mz-* или вживую через MZBOT.setTheme({...}).

Цветовая схема

Четыре режима: light · white · dark · auto.

Через атрибут data-mz-theme на <html> (рекомендуется)

Виджет вживую отслеживает data-mz-theme на <html> и реагирует немедленно:

js
document.documentElement.setAttribute('data-mz-theme', 'dark');   // тёмная
document.documentElement.setAttribute('data-mz-theme', 'light');  // светлая
document.documentElement.setAttribute('data-mz-theme', 'white');  // намного светлее light
document.documentElement.setAttribute('data-mz-theme', 'auto');   // следовать за ОС

Можно задать статически в разметке — применится на загрузке:

html
<html data-mz-theme="dark">

Невалидные значения игнорируются; удаление атрибута оставляет текущую тему. Обратной петли нет: виджет пишет собственное состояние на хост <mz-bot>, но никогда обратно в <html>.

Через JS-API

js
MZBOT.setTheme('dark');                  // короткая форма
MZBOT.setTheme({ theme: 'dark' });       // объектная форма
MZBOT.getTheme();                         // → { theme, resolvedTheme, accent, ... }
MZBOT.subscribe((t) => console.log(t));   // подписка на изменения; возвращает unsubscribe

Начальный конфиг (до загрузки бандла)

html
<script src="bundle.min.js" data-mz-theme="dark" data-mz-accent="#0dbb52" defer></script>
<!-- или -->
<script>window.MZBOT_CONFIG = { theme: 'dark' };</script>

Акцент и паттерн

js
MZBOT.setTheme({
  accent: '#0dbb52',     // любой CSS-цвет — красит всё тематическое
  pattern: 'mesh',       // none | whisper | mesh | scales | bloom | cipher | prism
  patternOpacity: 0.08,  // 0..1
  patternScale: 1.5,     // 0.25..4
});

Доступные паттерны: MZBOT.patterns. Анимации: MZBOT.animations. Темы: MZBOT.themes.

Язык оформления (design)

Скин поверх темы, а не вместо неё: theme, accent, pattern, msgAnimation и glow продолжают работать в обоих вариантах.

js
// widget.config.js
theme: {
  design: 'glass',   // 'default' (или не указано) | 'glass'
}
  • default — обычные плотные поверхности. Штатный вид виджета.

  • glass — гласморфизм. Карточка становится полупрозрачным матовым стеклом с оттенком accent и размывает страницу под собой; поле ввода, пузыри сообщений, подсказки и кнопка-лаунчер — слои того же стекла над ней. Основа стекла берётся из темы: в light/white стекло светлое, в dark — тёмное, accent тонирует оба.

    Шапки как панели в этом дизайне нет: её содержимое лежит прямо на стекле — без заливки, без края, без тени, — а текст берёт цвета темы (8–15:1 в светлой, 6–13:1 в тёмной, на любой подложке страницы). Accent из шапки не уходит, но перестаёт быть заливкой и становится объектом: тонкое кольцо присутствия вокруг аватара, с зазором, — светится акцентом, когда оператор на связи, и гаснет в нейтральный, когда нет. Пока онлайн, кольцо медленно «дышит» — это единственная фоновая анимация дизайна; prefers-reduced-motion: reduce её выключает. Кольцо заменяет зелёную точку статуса, а не дополняет её.

    Бюджет цвета. Accent тратится точечно, а не размазывается: еле уловимый тон в самой панели (настолько слабый, что читается как «тёплый серый»), пузыри сообщений посетителя и то, что сигналит — кнопка отправки, кольцо присутствия, ховер и нажатие, ссылки, галочки прочтения, кнопка-лаунчер. Все остальные поверхности нейтральные: бело-серые в светлой теме, серо-графитовые в тёмной. Сила тона панели — токен --mz-glass-tint-a. Панели, висящие над перепиской — меню опций и карточка прикреплённого файла над полем ввода — намеренно непрозрачные: сквозь них не должны читаться сообщения. Стеклом они остаются за счёт размытия, блика и подсвеченной кромки.

Приоритеты — как у остальных ключей темы:

html
<script src="bundle.min.js" data-mz-design="glass" defer></script>
js
MZBOT_CONFIG = { design: 'glass' };
MZBOT.setTheme({ design: 'glass' });   // живьём; список значений — MZBOT.designs

Что glass меняет в остальном конфиге

КлючПоведение в glass
accentтонирует все поверхности, а не только кнопки
bgColors / bgAngleигнорируются — сплошная заливка чата легла бы поверх стекла и закрыла его
pattern, patternImageработают; текстура читается как взвешенная внутри стекла
mode, msgAnimation, glowбез изменений

Деградация

Движки без backdrop-filter (и посетители с включённым «уменьшить прозрачность») получают тот же скин на почти непрозрачных альфах — теряется матовость, но не читаемость. Сам оттенок собран из rgba() поверх триплета --mz-accent-rgb, который theme.js пишет рядом с --mz-accent, так что color-mix() не нужен и всё рисуется на старых Safari/iPadOS и Android WebView.

Акцентное свечение (glow)

Свечение (halo из box-shadow) вокруг открытого виджета, переключаемое по разрешённой теме.

js
// window.MZBOT_CONFIG
theme: {
  glow: {
    dark:      true,   // свечение, когда активна тёмная тема
    light:     false,  // без свечения на светлой
    intensity: 1,      // множитель силы (1 = дефолт; ~0.1..5)
  },
}

Рантайм:

js
MZBOT.setGlow({ dark: true, light: true, intensity: 2 });
MZBOT_CONFIG = { glow: { dark: true, intensity: 1.5 } };

intensity масштабирует размытие halo и прозрачность акцента (clamp ~0.1–5). Свечение следует за активной темой автоматически (включая auto и живые переключения data-mz-theme): theme.js ставит data-mz-glow на хост, что переключает --mz-widget-shadow. Видно только при открытом виджете.

Фон чата

Две независимых ручки кастомизируют область сообщений.

Градиент / заливка (bgColors / bgAngle)

Перекрывает дефолтную поверхность темы своим цветом или градиентом:

js
MZBOT.setTheme({ bgColors: ['#1b2735', '#283e51', '#0a1622'], bgAngle: 160 }); // 3-цветный градиент
MZBOT.setTheme({ bgColors: ['#0d4f2b'] });                                      // один цвет = заливка
MZBOT.setTheme({ bgColors: 'radial-gradient(circle at 30% 0%, #2a5298, #0a1622)' }); // сырой CSS
MZBOT.setTheme({ bgColors: 'none' });                                           // вернуть поверхность темы
  • bgColorsмассив из 1..n CSS-цветов (1 = заливка; 2+ = linear-gradient), строка через запятую (удобно для data-mz-bg-colors), или полная CSS-background-строка (любой *-gradient(...)) — используется как есть. 'none' очищает.
  • bgAngle — направление градиента в градусах (дефолт 160). Игнорируется для одного цвета и сырой строки.

Одиночное значение заменяет поверхность во всех темах (это явный оверрайд) — либо задайте два фона, по одному на тему (ниже).

Два фона: светлая и тёмная тема

Любой ключ фона — bgColors, bgAngle, pattern, patternOpacity, patternScale, patternImage, patternImageOpacity, patternImageSize — принимает либо одно значение (общее для обеих тем), либо карту { light, dark }:

js
theme: {
  mode: 'auto',
  bgColors: {
    light: ['#e9eeea', '#dfe8e0', '#d6e0d4'],   // пока активна светлая тема
    dark:  ['#1b2735', '#283e51', '#0a1622'],   // …а это под тёмную
  },
  bgAngle: 160,                                  // одно значение = обе темы
  pattern: { light: 'whisper', dark: 'scales' },
}
  • Ветка выбирается по активной теме и переприменяется при каждом переключении: MZBOT.setTheme('dark'), mode: 'auto' (следит за системной темой), <html data-mz-theme>. Пересборка и перезагрузка не нужны.
  • white берёт ветку light, если своей нет.
  • Тема, для которой ветки нет, остаётся на своей штатной поверхности — то есть bgColors: { dark: [...] } кастомизирует только тёмную, светлая идёт как из коробки.
  • Работает из любого источника: widget.config.js, window.MZBOT_CONFIG, MZBOT.setTheme({...}) и атрибутов скрипта (data-mz-bg-colors-light / data-mz-bg-colors-dark).

Подписи на фоне подстраиваются сами

Время сообщения пользователя и разделитель дат («сегодня») рисуются прямо на фоне, поэтому их цвет не фиксирован, а подбирается под фон: виджет берёт все стопы bgColors (или поверхность темы), выбирает направление — чёрный или белый, смотря что лучше держится на худшем стопе — и отходит от этого края обратно к фону настолько, насколько позволяет целевой контраст ~4:1 (учитывая opacity: .85, с которой эти подписи рисуются). Получается самый тихий цвет, который ещё уверенно читается: подпись видно на любом фоне, но она не спорит с текстом сообщений.

Ничего настраивать не нужно — пересчёт идёт при каждой смене темы и фона. Если фон в принципе не покрывается одним цветом (градиент от почти белого к почти чёрному), подписи дополнительно получают мягкий ореол (text-shadow) в противоположном цвете.

Бесшовное изображение-оверлей (patternImage)

Тайлит прозрачное изображение-паттерн поверх фона. Либо/либо со встроенными pattern: когда задан patternImage, он заменяет SVG-паттерн (изображение побеждает); patternImage: 'none' возвращает SVG.

js
MZBOT.setTheme({
  patternImage:        'https://cdn.morze.tech/patterns/topography.png',
  patternImageOpacity: 0.5,    // 0..1 (своя альфа PNG тоже применяется)
  patternImageSize:    280,    // px-тайл или любой CSS background-size
});

MZBOT.setTheme({ patternImage: 'none' });   // убрать оверлей
  • patternImage — URL. Принимаются http(s)://, протокол-относительные (//), корневые/относительные (/…, ./…) и data:image/…; остальное (или URL с небезопасными символами) отклоняется. 'none'/'' — выкл.
  • patternImageSize — число (px-ширина тайла, высота авто) или любой CSS background-size.

Через атрибуты загружающего скрипта

html
<script src="bundle.min.js"
        data-mz-bg-colors="#1b2735,#283e51,#0a1622"
        data-mz-bg-angle="160"
        data-mz-pattern-image="https://cdn.morze.tech/patterns/topography.png"
        data-mz-pattern-image-opacity="0.5"
        data-mz-pattern-image-size="280"
        defer></script>

Свой фон на каждую тему — суффиксы -light / -dark у любого из этих атрибутов (базовый атрибут без суффикса остаётся значением для темы, которую не задали явно):

html
<script src="bundle.min.js"
        data-mz-theme="auto"
        data-mz-bg-colors-light="#e9eeea,#dfe8e0,#d6e0d4"
        data-mz-bg-colors-dark="#1b2735,#283e51,#0a1622"
        data-mz-bg-angle="160"
        defer></script>

Анимация сообщений

js
MZBOT.setTheme({ msgAnimation: 'unfurl' });  // bubble | unfurl | cascade | pop | breathe

Все методы темы — на странице JavaScript API.