# Компонент ThemeToggle - Полная документация ## Назначение компонента `ThemeToggle` - компонент для переключения между светлой и темной темами в приложении. Сохраняет выбор пользователя в localStorage, синхронизирует состояние между вкладками и обеспечивает плавные переходы между темами. ## Импорт и регистрация ```coffee # В основном файле приложения (app/temp.coffee) components: 'themetoggle': require 'app/shared/ThemeToggle' ``` ## Базовое использование ```pug //- Минимальное использование themetoggle //- С кастомными классами themetoggle(class="ml-4") //- В навигационной панели div(class="flex items-center space-x-4") language-switcher themetoggle ``` ## Полный список props ### `size` (опциональный) - **Тип:** `String` - **По умолчанию:** `'md'` - **Допустимые значения:** `'sm'`, `'md'`, `'lg'` - **Описание:** Размер переключателя - **Пример:** ```pug themetoggle(size="sm") themetoggle(size="lg") ``` ### `variant` (опциональный) - **Тип:** `String` - **По умолчанию:** `'default'` - **Допустимые значения:** `'default'`, `'minimal'`, `'icon-only'` - **Описание:** Вариант отображения переключателя - **Пример:** ```pug themetoggle(variant="minimal") themetoggle(variant="icon-only") ``` ### `showLabels` (опциональный) - **Тип:** `Boolean` - **По умолчанию:** `true` - **Описание:** Показывать текстовые метки - **Пример:** ```pug themetoggle(:showLabels="false") ``` ### `labels` (опциональный) - **Тип:** `Object` - **По умолчанию:** `{ light: 'Светлая', dark: 'Тёмная', system: 'Системная' }` - **Описание:** Кастомные текстовые метки - **Пример:** ```pug themetoggle(:labels="{ light: 'Light', dark: 'Dark', system: 'Auto' }") ``` ### `storageKey` (опциональный) - **Тип:** `String` - **По умолчанию:** `'borbad-theme'` - **Описание:** Ключ для сохранения в localStorage - **Пример:** ```pug themetoggle(storageKey="my-app-theme") ``` ### `class` (опциональный) - **Тип:** `String | Object | Array` - **По умолчанию:** `''` - **Описание:** Дополнительные CSS классы - **Пример:** ```pug themetoggle(class="border border-gray-300 rounded-lg") ``` ## События (Events) ### `@change` - **Описание:** Событие смены темы - **Payload:** `{ theme: String, previousTheme: String }` - **Пример:** ```pug themetoggle(@change="handleThemeChange") ``` ### `@init` - **Описание:** Событие инициализации темы - **Payload:** `{ theme: String }` - **Пример:** ```pug themetoggle(@init="handleThemeInit") ``` ## Слоты (Slots) ### `[light-icon]` - **Описание:** Иконка для светлой темы - **Пример:** ```pug themetoggle template([light-icon]) svig(class="w-4 h-4" ...) ... ``` ### `[dark-icon]` - **Описание:** Иконка для темной темы - **Пример:** ```pug themetoggle template([dark-icon]) svig(class="w-4 h-4" ...) ... ``` ### `[system-icon]` - **Описание:** Иконка для системной темы - **Пример:** ```pug themetoggle template([system-icon]) svig(class="w-4 h-4" ...) ... ``` ## Доступные темы ### `light` - Светлая тема - Принудительно устанавливает светлый режим ### `dark` - Темная тема - Принудительно устанавливает темный режим ### `system` - Системная тема - Следует за настройками операционной системы - Использует `prefers-color-scheme` media query ## Примеры использования ### 1. Базовые варианты ```pug //- Стандартный переключатель themetoggle //- Только иконки themetoggle(variant="icon-only") //- Минималистичный вариант themetoggle(variant="minimal") //- Разные размеры div(class="flex space-x-2") themetoggle(size="sm") themetoggle(size="md") themetoggle(size="lg") ``` ### 2. Кастомные иконки ```pug themetoggle template([light-icon]) div(class="w-4 h-4 bg-yellow-400 rounded-full") template([dark-icon]) div(class="w-4 h-4 bg-purple-600 rounded-full") template([system-icon]) div(class="w-4 h-4 bg-gray-500 rounded-full") ``` ### 3. Кастомные метки ```pug themetoggle( :labels="{ light: '☀️ Светлая', dark: '🌙 Тёмная', system: '💻 Система' }" ) ``` ### 4. Интеграция с навигацией ```pug header(class="bg-white dark:bg-gray-800 shadow-sm") div(class="container mx-auto px-4") div(class="flex justify-between items-center py-4") //- Логотип app-link(to="/" class="text-xl font-bold") Борбад //- Навигация nav(class="flex items-center space-x-6") app-link(to="/events") Мероприятия app-link(to="/blog") Блог //- Переключатель темы themetoggle( variant="icon-only" class="text-gray-600 dark:text-gray-300" ) ``` ### 5. В мобильном меню ```pug div(class="mobile-menu bg-white dark:bg-gray-800 p-4") div(class="space-y-4") app-link(to="/" class="block") Главная app-link(to="/events" class="block") Мероприятия app-link(to="/blog" class="block") Блог //- Переключатель темы в мобильном меню div(class="pt-4 border-t dark:border-gray-700") themetoggle( variant="minimal" :showLabels="true" class="w-full" ) ``` ### 6. С обработкой событий ```pug themetoggle( @change="onThemeChange" @init="onThemeInit" ) //- В methods компонента methods: onThemeChange: ({ theme, previousTheme }) -> debug.log "Тема изменена: "+previousTheme+" -> "+theme # Можно добавить аналитику analytics.track('theme_changed', { new_theme: theme, previous_theme: previousTheme }) onThemeInit: ({ theme }) -> debug.log "Тема инициализирована: "+theme ``` ## Программное взаимодействие ### Получение текущей темы ```coffee # Через глобальный объект currentTheme = _.appState?.currentTheme # Через EventBus EventBus.on 'theme_changed', (theme) -> debug.log "Текущая тема: "+theme ``` ### Установка темы программно ```coffee # Через глобальный объект _.setTheme('dark') # Через EventBus EventBus.emit('set_theme', 'light') ``` ### Подписка на изменения темы ```coffee # В компоненте beforeMount: -> EventBus.on 'theme_changed', @handleThemeChange methods: handleThemeChange: (theme) -> # Обновляем стили компонента @updateComponentStyles(theme) ``` ## Стили и кастомизация ### CSS-переменные Компонент использует стандартные CSS-переменные Tailwind: ```css :root { --color-bg-primary: #ffffff; --color-bg-secondary: #f7fafc; --color-text-primary: #2d3748; } @media (prefers-color-scheme: dark) { :root { --color-bg-primary: #1a202c; --color-bg-secondary: #2d3748; --color-text-primary: #f7fafc; } } ``` ### Кастомные стили ```styl // Переопределение стандартных стилей .theme-toggle--custom @apply bg-gradient-to-r from-blue-500 to-purple-600 text-white .theme-toggle__button @apply hover:from-blue-600 hover:to-purple-700 .theme-toggle__button--active @apply from-blue-700 to-purple-800 ``` ### Анимации переходов ```styl // Плавные переходы .theme-transition transition: all 0.3s ease-in-out // Анимация переключения @keyframes theme-switch 0% opacity: 0 transform: scale(0.8) 100% opacity: 1 transform: scale(1) .theme-toggle--animating animation: theme-switch 0.3s ease-in-out ``` ## Интеграция с Tailwind CSS ### Конфигурация tailwind.config.js ```javascript module.exports = { darkMode: 'class', // или 'media' для системной темы // ... } ``` ### Использование в компонентах ```pug div(class="bg-white dark:bg-gray-800 text-gray-900 dark:text-white") h1(class="text-2xl font-bold") Заголовок p(class="text-gray-600 dark:text-gray-300") Текст ``` ## Особенности работы ### Определение системной темы ```coffee # Использует matchMedia для определения системных предпочтений systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches ``` ### Синхронизация между вкладками ```coffee # Слушает события storage для синхронизации window.addEventListener('storage', (event) -> if event.key == @storageKey @applyTheme(event.newValue) ) ``` ### Плавные переходы ```coffee # Добавляет класс для анимации при переключении document.documentElement.classList.add('theme-transition') setTimeout(() -> document.documentElement.classList.remove('theme-transition') , 300) ``` ## Методы API ### `setTheme(theme)` - **Описание:** Устанавливает указанную тему - **Параметры:** `theme` - 'light', 'dark', или 'system' - **Пример:** ```coffee @$refs.themeToggle.setTheme('dark') ``` ### `getCurrentTheme()` - **Описание:** Возвращает текущую активную тему - **Возвращает:** `String` - **Пример:** ```coffee currentTheme = @$refs.themeToggle.getCurrentTheme() ``` ### `toggle()` - **Описание:** Переключает между светлой и темной темами - **Пример:** ```coffee @$refs.themeToggle.toggle() ``` ## Обработка ошибок ### Валидация темы ```coffee # Проверка допустимых значений if !['light', 'dark', 'system'].includes(theme) throw new Error("Недопустимое значение темы: "+theme) ``` ### Fallback для localStorage ```coffee try localStorage.setItem(@storageKey, theme) catch error # Используем cookie как fallback document.cookie = @storageKey+"="+theme+"; path=/; max-age=31536000" ``` ## Примеры интеграции ### 1. С аналитикой ```coffee methods: handleThemeChange: ({ theme, previousTheme }) -> # Отправка в аналитику gtag('event', 'theme_change', { event_category: 'ui', event_label: theme, value: theme == 'dark' ? 1 : 0 }) ``` ### 2. С синхронизацией с сервером ```coffee methods: handleThemeChange: ({ theme }) -> # Сохранение на сервере (если пользователь авторизован) if @user await @api.saveUserPreferences({ theme: theme }) ``` ### 3. С кастомной логикой ```coffee methods: handleThemeChange: ({ theme }) -> # Изменение meta-тегов const themeColor = theme == 'dark' ? '#1a202c' : '#ffffff' document.querySelector('meta[name="theme-color"]').content = themeColor # Изменение favicon const favicon = theme == 'dark' ? '/favicon-dark.ico' : '/favicon-light.ico' document.querySelector('link[rel="icon"]').href = favicon ``` ## Best Practices ### 1. Всегда предоставляйте все три варианта ```pug //- Правильно themetoggle //- Неправильно (ограниченный выбор) themetoggle(:themes="['light', 'dark']") ``` ### 2. Используйте системную тему по умолчанию ```pug //- Позволяет следовать системным настройкам themetoggle ``` ### 3. Сохраняйте состояние пользователя ```pug //- Автоматически сохраняет в localStorage themetoggle ``` ### 4. Обеспечивайте доступность ```pug //- Правильные ARIA-атрибуты themetoggle(aria-label="Переключение темы") ``` ### 5. Тестируйте все варианты ```coffee # В тестах describe('ThemeToggle', -> it('should switch between themes', -> toggle.setTheme('light') expect(toggle.getCurrentTheme()).toBe('light') toggle.setTheme('dark') expect(toggle.getCurrentTheme()).toBe('dark') ) ) ``` Компонент ThemeToggle предоставляет полнофункциональное решение для управления темами в приложении с поддержкой доступности, сохранения состояния и плавных переходов.