Skip to content

Theme Switching (Dark/Light Mode) — Design

Решения

  • Режим по умолчанию: системные настройки (prefers-color-scheme)
  • Переключатель: иконка sun/moon в хедере (двухпозиционный toggle) + полный контроль в /cabinet/settings
  • Хранение: localStorage + cookie (встроенный механизм @nuxtjs/color-mode из Nuxt UI)
  • Анимация: без анимации, мгновенное переключение
  • Палитра: primary: 'blue', neutral: 'slate' (без изменений)

Техническая основа

Nuxt UI v3 включает @nuxtjs/color-mode как встроенную зависимость:

  • useColorMode() доступен из коробки
  • Режимы: 'light', 'dark', 'system'
  • Хранение: cookie nuxt-color-mode + класс на <html> — SSR без мерцания
  • Tailwind 4 настроен на .dark класс — существующие dark: классы работают

Конфиг в nuxt.config.ts:

ts
colorMode: {
  preference: 'system',
  fallback: 'light',
}

Компоненты UI

Переключатель в хедере

  • Иконка sun в тёмном режиме, moon в светлом
  • UButton с variant="ghost", size="sm"
  • Клик: если preference === 'system' — ставит противоположный от текущего value, иначе toggle light/dark
  • Компонент: app/shared/ui/ThemeToggle.vue

Настройки в кабинете

  • Секция "Оформление" в /cabinet/settings
  • URadioGroup с тремя вариантами: Светлая (sun), Тёмная (moon), Системная (monitor)
  • Подпись для системной: "Следует настройкам вашего устройства"
  • Выбор применяется сразу, без кнопки "Сохранить"

Аудит существующих компонентов

Файлы с dark: классами (уже готовы):

  • layouts/default.vue — бордеры хедера/футера
  • layouts/cabinet.vue — бордеры хедера
  • pages/product/[id].vue — галерея, спеки, секция продавца
  • pages/auth/login.vue — разделители
  • entities/product/ui/ProductCard.vue — бордеры, фоны
  • features/product-form/ui/ProductFormPage.vue — стили формы
  • features/image-upload/ui/ImageUploader.vue — зона загрузки

Проверить после подключения:

  • Визуальный проход по всем страницам в обоих режимах
  • Места с хардкод-цветами без dark: варианта (bg-white без dark:bg-gray-900)
  • Nuxt UI компоненты адаптируются автоматически через CSS-переменные

Правило для разработки

Добавлено в CLAUDE.md → Conventions:

При добавлении цветовых классов Tailwind (bg-*, text-*, border-*) всегда добавлять dark: вариант. Предпочитать семантические CSS-переменные Nuxt UI (text-[var(--ui-text)], bg-[var(--ui-bg)]) вместо хардкода цветов.

Файлы и порядок реализации

Изменяемые файлы

  1. nuxt.config.ts — секция colorMode
  2. app.config.ts — комментарии с примерами палитр
  3. app/shared/ui/ThemeToggle.vue — новый компонент
  4. app/layouts/default.vue — добавить SharedThemeToggle в хедер
  5. app/layouts/cabinet.vue — добавить SharedThemeToggle в хедер
  6. app/pages/cabinet/settings.vue — секция "Оформление"
  7. i18n/locales/ru.json — ключи для темы
  8. CLAUDE.md — правило про dark: классы (готово)

Тесты

  • app/shared/ui/ThemeToggle.test.ts — рендер иконки, клик переключает режим

Порядок

  1. Конфиг (nuxt.config.ts, app.config.ts)
  2. i18n ключи
  3. Компонент ThemeToggle + тест
  4. Интеграция в layouts
  5. Секция в настройках кабинета
  6. Визуальный аудит существующих страниц
  7. Обновление Progress в CLAUDE.md