Скин компонентов
Уровень скина компонентов перестилизует встроенные компоненты. Он строится на конкретном стеке стилизации и стабильном контракте хуков.
Стек стилизации
Встроенный UI использует четыре технологии вместе:
- CSS Modules для стилей в области компонента, с хэшированными именами классов, которые явно не являются публичным контрактом.
- CSS Custom Properties для семантических токенов (
--st-*). - Cascade Layers для упорядочивания источников истины.
- Container Queries для макета, адаптирующегося к контейнеру самого
компонента, с размерами в
rem.
Темы нацеливаются на атрибуты хуков, а не на генерируемые имена классов.
Порядок каскадных слоёв
Все стили живут в фиксированном порядке каскадных слоёв:
@layer reset, tokens, base, components, plugin-base, theme, user;
Более поздние слои побеждают более ранние, поэтому приоритет таков:
reset— базовый сброс.tokens— определения токенов.base— значения по умолчанию на уровне элементов.components— стили встроенных компонентов.plugin-base— слой для базовых стилей, предоставляемых плагинами.theme— скин активной темы.user— собственные оверрайды пользователя, которые загружаются последними.
Таблица стилей пользовательских оверрайдов всегда загружается последней,
поэтому сломанная или навязчивая тема никогда не сможет помешать пользователю
переопределить её. В терминах !important: конструкция запрещена в CSS темы,
кроме слоя предпочтений доступности, который относится к пользовательским
режимам a11y.
Контракт хуков
Темы стилизуют компоненты через четыре атрибута, публикуемых хостом и версионируемых как и остальной SDK:
<div
data-component="chat-message"
data-part="container"
data-role="assistant"
data-state="streaming"
></div>
data-component— вид компонента.data-part— структурная часть внутри компонента.data-role— семантическая роль, например роль сообщения.data-state— состояние, напримерopen,closedилиstreaming.
CSS скина темы тогда выглядит так:
@layer theme {
[data-component='button'][data-variant='primary'] > [data-part='icon'] {
color: var(--st-color-accent-text);
}
[data-component='action-bar'] [data-part='group'][data-role='secondary'] {
color: var(--st-color-text-secondary);
}
}
Пакет @neotavern/theme-sdk экспортирует хелпер dataHook для построения этих
объектов атрибутов, чтобы авторы компонентов и авторы тем согласовывали одни
и те же имена.
Что не является контрактом
- Генерируемые имена классов CSS-modules — хэшированные, нестабильные и не входящие в SDK. Тема, нацеленная на них, ломается при следующей сборке.
- Внутренняя иерархия React — темы не должны зависеть от внутренностей компонентов или порядка DOM сверх документированных хуков.
- Числовые значения макета — координаты, схемы grid и контрольные точки
нельзя стилизовать через контракт токенов; контрольные точки области
просмотра живут в реестре, а container queries должны писаться в
rem.
Запрещённый CSS
Таблицы стилей тем сканируются до загрузки. Запрещённые конструкции отклоняются при установке и проверке:
@import- URL
javascript:иexpression(). -moz-bindingиbehavior:.- Удалённые или протокол-относительные URL (
url(http:,url(https:,url(//). data:text/html.!important(кроме слоя предпочтений a11y).
Это держит CSS тем чистым, локальным и безопасным. О токенах, на которые скин должен ссылаться, см. Дизайн-токены; об именованных областях, которые может перестилизовать скин, см. Контракт оболочки.