Themability и система тем

Lit предоставляет гибкую систему работы с темами и стилями, которая позволяет создавать компоненты с адаптивным визуальным оформлением без необходимости дублировать CSS для разных состояний или контекстов. Основной принцип заключается в разделении структуры компонента и его визуальной темы, что обеспечивает легкость кастомизации и повторного использования.

CSS Custom Properties и Lit

Одним из ключевых инструментов для реализации 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.

Контекст тем через CSS-переменные

Для систематической поддержки тем удобно использовать контекст тем. В 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 на корневом элементе автоматически изменяется визуальное оформление всех компонентов, использующих эти переменные.

Themable mixins в Lit

Для более сложных систем тем можно использовать 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-переменные, определённые для текущей темы.

Scoped и глобальные темы

Lit позволяет комбинировать глобальные и scoped темы. Глобальные темы задаются на уровне :root или <body>, тогда как scoped темы определяются на уровне контейнера с помощью data-theme или кастомных свойств. Такой подход позволяет одновременное использование нескольких тем на странице без конфликтов.

Перспективы расширения themability

Lit поддерживает интеграцию с CSS-in-JS и библиотеками генерации тем, что позволяет создавать более сложные системы:

  • Автоматическая генерация светлых и темных оттенков.
  • Использование переменных для анимаций и переходов между темами.
  • Создание адаптивных тем для разных устройств.

Система тем в Lit сочетает декларативность CSS и мощь реактивных компонентов, позволяя строить визуально гибкие интерфейсы с минимальными усилиями. Она обеспечивает как легкую настройку через CSS-переменные, так и динамическую смену стилей на лету, что делает её оптимальной для современных веб-приложений.