Lit предоставляет гибкую систему работы с темами и стилями, которая позволяет создавать компоненты с адаптивным визуальным оформлением без необходимости дублировать CSS для разных состояний или контекстов. Основной принцип заключается в разделении структуры компонента и его визуальной темы, что обеспечивает легкость кастомизации и повторного использования.
Одним из ключевых инструментов для реализации themability в Lit являются CSS-переменные (custom properties). Они позволяют задавать значения, которые могут быть переопределены на уровне компонента, родителя или глобально.
Пример использования CSS-переменной в Lit-компоненте:
import { LitElement, html, css } from 'lit';
class MyButton extends LitElement {
static styles = css`
button {
background-color: var(--button-bg, #007bff);
color: var(--button-color, white);
border: none;
padding: 0.5rem 1rem;
border-radius: 0.25rem;
cursor: pointer;
font-size: 1rem;
}
button:hover {
background-color: var(--button-bg-hover, #0056b3);
}
`;
render() {
return html`<button><slot></slot></button>`;
}
}
customElements.define('my-button', MyButton);
В этом примере используются переменные --button-bg,
--button-color и --button-bg-hover, которые
могут быть переопределены в любом родительском элементе или глобально
через :root.
Для систематической поддержки тем удобно использовать контекст тем. В Lit это реализуется через вложенные CSS-переменные и наследование стилей. Например, можно определить глобальные переменные для светлой и темной темы:
:root {
--primary-color: #007bff;
--secondary-color: #6c757d;
--background-color: #ffffff;
--text-color: #000000;
}
[data-theme="dark"] {
--primary-color: #0d6efd;
--secondary-color: #adb5bd;
--background-color: #121212;
--text-color: #f8f9fa;
}
Компоненты используют эти переменные для задания цветов и других
свойств. При переключении атрибута data-theme на корневом
элементе автоматически изменяется визуальное оформление всех
компонентов, использующих эти переменные.
Для более сложных систем тем можно использовать CSS
mixins или функции генерации стилей. В Lit это делается через
css-шаблоны и наследование стилей.
import { css } from 'lit';
export const buttonTheme = (theme) => css`
button {
background-color: ${theme.primary};
color: ${theme.text};
border-radius: ${theme.radius}px;
}
`;
В компоненте можно подключить такие темы динамически:
import { LitElement, html, css } from 'lit';
import { buttonTheme } from './themes.js';
class ThemedButton extends LitElement {
static styles = css`
${buttonTheme({
primary: 'var(--primary-color)',
text: 'var(--text-color)',
radius: 4
})}
`;
render() {
return html`<button><slot></slot></button>`;
}
}
customElements.define('themed-button', ThemedButton);
Lit поддерживает динамическое обновление темы через реактивные свойства и пересборку стилей. Например, можно реализовать компонент-контейнер, который управляет текущей темой:
import { LitElement, html, css } from 'lit';
class ThemeProvider extends LitElement {
static properties = {
theme: { type: String, reflect: true }
};
updated(changedProperties) {
if (changedProperties.has('theme')) {
this.setAttribute('data-theme', this.theme);
}
}
render() {
return html`<slot></slot>`;
}
}
customElements.define('theme-provider', ThemeProvider);
Использование:
<theme-provider theme="dark">
<themed-button>Кнопка</themed-button>
</theme-provider>
При смене атрибута theme автоматически изменяются все
дочерние компоненты, использующие CSS-переменные, определённые для
текущей темы.
Lit позволяет комбинировать глобальные и
scoped темы. Глобальные темы задаются на уровне
:root или <body>, тогда как scoped темы
определяются на уровне контейнера с помощью data-theme или
кастомных свойств. Такой подход позволяет одновременное использование
нескольких тем на странице без конфликтов.
Lit поддерживает интеграцию с CSS-in-JS и библиотеками генерации тем, что позволяет создавать более сложные системы:
Система тем в Lit сочетает декларативность CSS и мощь реактивных компонентов, позволяя строить визуально гибкие интерфейсы с минимальными усилиями. Она обеспечивает как легкую настройку через CSS-переменные, так и динамическую смену стилей на лету, что делает её оптимальной для современных веб-приложений.