Настройка темы Material

Для работы с компонентами в стиле Material Design в SvelteKit чаще всего используют библиотеки, такие как Svelte Material UI (SMUI) или Material Components Web (MDC) с адаптацией под Svelte. Установка SMUI выполняется через npm:

npm install --save-dev @smui/button @smui/textfield @smui/card

Каждый пакет соответствует конкретному компоненту или набору компонентов. Для комплексных интерфейсов рекомендуется подключать только те компоненты, которые реально используются, чтобы минимизировать размер сборки.

После установки необходимо настроить глобальные стили Material. В src/app.css подключаются темы и переменные:

@import '@smui/button/styles.css';
@import '@smui/textfield/styles.css';
@import '@smui/card/styles.css';

/* Можно определить собственные переменные темы */
:root {
  --mdc-theme-primary: #6200ee;
  --mdc-theme-secondary: #03dac6;
  --mdc-theme-background: #ffffff;
  --mdc-theme-surface: #f5f5f5;
  --mdc-theme-error: #b00020;
  --mdc-theme-on-primary: #ffffff;
  --mdc-theme-on-secondary: #000000;
}

Эти переменные управляют основной палитрой приложения: цветами кнопок, текстовых полей, карточек и фоновых элементов.


Конфигурация темы и цветов

Svelte Material UI позволяет динамически переключать темы и настраивать цвета компонентов через объект темы. В файле src/lib/theme.js можно создать централизованное хранилище:

import { writable } from 'svelte/store';

export const theme = writable({
  primary: '#6200ee',
  secondary: '#03dac6',
  background: '#ffffff',
  surface: '#f5f5f5',
  error: '#b00020',
  onPrimary: '#ffffff',
  onSecondary: '#000000'
});

Применение темы к компонентам выполняется с использованием реактивной подписки на store:

<script>
  import { theme } from '$lib/theme';
  import Button from '@smui/button';

  let currentTheme;
  theme.subscribe(value => currentTheme = value);
</script>

<Button style="background-color: {currentTheme.primary}; color: {currentTheme.onPrimary}">
  Кнопка
</Button>

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


Темизация с использованием SvelteKit Layout

Чтобы тема применялась глобально, можно использовать layout-файл src/routes/+layout.svelte:

<script>
  import { theme } from '$lib/theme';
  import { onMount } from 'svelte';
  
  onMount(() => {
    theme.subscribe(value => {
      document.documentElement.style.setProperty('--mdc-theme-primary', value.primary);
      document.documentElement.style.setProperty('--mdc-theme-secondary', value.secondary);
      document.documentElement.style.setProperty('--mdc-theme-background', value.background);
      document.documentElement.style.setProperty('--mdc-theme-surface', value.surface);
      document.documentElement.style.setProperty('--mdc-theme-error', value.error);
    });
  });
</script>

<slot />

Этот метод гарантирует, что все страницы и компоненты SvelteKit будут использовать единый стиль Material без дублирования кода.


Стилизация отдельных компонентов

Каждый компонент SMUI поддерживает псевдоклассы и CSS-переменные:

  • --mdc-theme-primary — основной цвет компонента
  • --mdc-theme-on-primary — цвет текста на основной заливке
  • --mdc-theme-surface — фон карточек и панелей
  • --mdc-theme-background — фон страниц

Пример настройки карточки с пользовательским цветом:

<script>
  import Card from '@smui/card';
</script>

<Card style="--mdc-theme-surface: #e0f7fa; --mdc-theme-on-surface: #006064;">
  <h2>Заголовок карточки</h2>
  <p>Текст внутри карточки с кастомной темой.</p>
</Card>

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


Реализация тёмной и светлой темы

Для переключения между светлой и тёмной схемой создается функция:

export function toggleDarkMode(isDark) {
  theme.update(current => {
    if (isDark) {
      return {
        ...current,
        primary: '#bb86fc',
        background: '#121212',
        surface: '#1e1e1e',
        onPrimary: '#000000',
        onSecondary: '#000000'
      };
    } else {
      return {
        ...current,
        primary: '#6200ee',
        background: '#ffffff',
        surface: '#f5f5f5',
        onPrimary: '#ffffff',
        onSecondary: '#000000'
      };
    }
  });
}

Использование:

<script>
  import { toggleDarkMode } from '$lib/theme';
</script>

<Button on:click={() => toggleDarkMode(true)}>Тёмная тема</Button>
<Button on:click={() => toggleDarkMode(false)}>Светлая тема</Button>

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


Интеграция с Tailwind и другими UI утилитами

SMUI совместим с TailwindCSS и другими CSS-фреймворками. Основные правила:

  1. Использовать @apply с классами Tailwind для быстрой стилизации SMUI-компонентов.
  2. Не переопределять базовые CSS-переменные, если требуется динамическая смена темы.
  3. Комбинировать глобальные переменные Material с локальными Tailwind-классами для гибкой адаптивной верстки.

Пример:

<Button class="rounded-lg shadow-md" style="--mdc-theme-primary: #03a9f4;">
  Кнопка с Tailwind
</Button>

Выводы по организации темы

  • Централизованное хранение цветов через store обеспечивает одинаковый стиль по всему приложению.
  • CSS-переменные Material позволяют динамически менять тему без перезагрузки страниц.
  • Использование layout-файлов SvelteKit гарантирует глобальное применение стилей.
  • Комбинация SMUI с Tailwind или другими утилитами CSS расширяет возможности дизайна и адаптивности.

Этот подход создает гибкую и расширяемую систему Material-темизации, полностью интегрированную с архитектурой SvelteKit.