Темизация

Slim.js — это лёгкая и высокопроизводительная библиотека для создания компонентов в JavaScript. Одной из ключевых возможностей является поддержка темизации компонентов, что позволяет легко менять внешний вид приложения без вмешательства в логику компонентов.

Темизация в Slim.js строится на трёх основных принципах:

  1. Изоляция стилей внутри компонента
  2. Динамическая подстановка тем
  3. Наследование тем для вложенных компонентов

Изоляция стилей внутри компонента

Каждый компонент Slim.js может содержать собственные стили, которые изолированы от глобального CSS. Это достигается с помощью встроенной поддержки Shadow DOM или локальных стилей.

Пример объявления стилей в компоненте:

import Slim from 'slim-js';

class ButtonComponent extends Slim {
  get template() {
    return `
      <button class="btn">Нажми меня</button>
      <style>
        .btn {
          background-color: var(--primary-color, #007bff);
          color: var(--text-color, #fff);
          border: none;
          padding: 10px 20px;
          border-radius: 4px;
          cursor: pointer;
        }
        .btn:hover {
          background-color: var(--primary-hover-color, #0056b3);
        }
      </style>
    `;
  }
}

customElements.define('button-component', ButtonComponent);

В этом примере стили кнопки используют CSS-переменные, что является основой для темизации.


Динамическая подстановка тем

Темизация в Slim.js строится вокруг CSS-переменных, которые могут быть определены на уровне документа или в корневом элементе компонента.

document.documentElement.style.setProperty('--primary-color', '#e74c3c');
document.documentElement.style.setProperty('--primary-hover-color', '#c0392b');
document.documentElement.style.setProperty('--text-color', '#ffffff');

Такой подход позволяет изменять тему на лету без пересоздания компонентов. Все компоненты, использующие эти переменные, автоматически подстраиваются под новую цветовую схему.


Создание нескольких тем

Для поддержки разных тем удобно использовать объект с параметрами тем:

const themes = {
  light: {
    '--primary-color': '#3498db',
    '--primary-hover-color': '#2980b9',
    '--text-color': '#ffffff'
  },
  dark: {
    '--primary-color': '#2c3e50',
    '--primary-hover-color': '#34495e',
    '--text-color': '#ecf0f1'
  }
};

function applyTheme(themeName) {
  const theme = themes[themeName];
  Object.keys(theme).forEach(key => {
    document.documentElement.style.setProperty(key, theme[key]);
  });
}

applyTheme('dark');

Такой подход позволяет централизованно управлять внешним видом всего приложения.


Наследование тем для вложенных компонентов

Slim.js автоматически поддерживает наследование CSS-переменных в дочерних компонентах. Это значит, что если родительский компонент определяет переменные темы, все вложенные элементы смогут их использовать:

class CardComponent extends Slim {
  get template() {
    return `
      <div class="card">
        <slot></slot>
      </div>
      <style>
        .card {
          background-color: var(--primary-color, #007bff);
          color: var(--text-color, #fff);
          padding: 20px;
          border-radius: 8px;
        }
      </style>
    `;
  }
}

customElements.define('card-component', CardComponent);

Используя этот принцип, можно строить многоуровневые интерфейсы, где каждый компонент автоматически подстраивается под активную тему.


Адаптация к пользовательским настройкам

Темизация в Slim.js позволяет реагировать на системные предпочтения, например, тёмную или светлую тему в операционной системе:

const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
applyTheme(prefersDark ? 'dark' : 'light');

window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
  applyTheme(e.matches ? 'dark' : 'light');
});

Это обеспечивает динамическое и автоматическое соответствие пользовательским настройкам без ручного вмешательства.


Советы по построению тем

  • Использовать CSS-переменные для всех ключевых цветов и шрифтов, чтобы централизованно управлять стилями.
  • Не хардкодить цвета в компонентах, даже если это небольшие элементы — это снижает гибкость.
  • Создавать объект тем с единым набором переменных для упрощения смены темы.
  • Проверять наследование переменных для вложенных компонентов, чтобы убедиться, что все элементы корректно подстраиваются.
  • Использовать медиазапросы для автоматического переключения между светлой и тёмной темой.

Темизация в Slim.js позволяет строить гибкие и динамические интерфейсы, где внешний вид компонентов может изменяться централизованно и предсказуемо. Правильное использование CSS-переменных и наследование стилей обеспечивают совместимость между компонентами и удобство управления внешним видом.