> ## Documentation Index
> Fetch the complete documentation index at: https://ui8kit.buildy.tw/llms.txt
> Use this file to discover all available pages before exploring further.

# Темная тема

> Реализация темной темы UI8Kit Core - провайдер тем, управление состоянием, сохранение и интеграция с Tailwind CSS

# Темная тема

Этот документ объясняет реализацию темной темы в `@ui8kit/core`, включая механизм провайдера тем, управление состоянием, стратегии сохранения и интеграцию с Tailwind CSS. Для общих вопросов тематизации и стилизации вариантов см. [Система вариантов](#3.2). Для паттернов стилизации конкретных компонентов см. [Лучшие практики](#5.3).

## Назначение и область применения

Система темной темы обеспечивает автоматическое переключение тем с сохранением пользовательских предпочтений и определением темной темы на уровне системы. Реализация построена на паттерне провайдера React Context, который управляет состоянием темы, применяет CSS-классы к корню документа и синхронизирует предпочтения с localStorage.

**Источники**: [src/themes/providers/ThemeProvider.tsx1-93](https://github.com/ui8kit/core/blob/2afe2195/src/themes/providers/ThemeProvider.tsx#L1-L93)

***

## Архитектура ThemeProvider

Компонент `ThemeProvider` оборачивает приложение и управляет всем состоянием, связанным с темой, через React Context. Он принимает объект `theme`, соответствующий типу `ThemeBase`, и предоставляет значения темы и функции управления через контекст.

```
API браузера

Управление состоянием

Компонент ThemeProvider

Уровень приложения

читает из

читает из

читает из

записывает в

обновляет

Корень приложения

Дочерние компоненты

ThemeProvider

ThemeContext

Хуки useState

Хуки useEffect

isDarkMode: boolean

prefersReducedMotion: boolean

theme: ThemeBase

localStorage
ключ ui:dark

matchMedia
prefers-color-scheme

matchMedia
prefers-reduced-motion

document.documentElement
classList.toggle('dark')
```

**Диаграмма: Поток данных ThemeProvider и интеграция с API браузера**

Провайдер инициализирует состояние из трех источников в порядке приоритета:

1. Значение из localStorage по ключу `"ui:dark"` (если присутствует)
2. Системное предпочтение через `window.matchMedia('(prefers-color-scheme: dark)')`
3. Значение по умолчанию `false`

**Источники**: [src/themes/providers/ThemeProvider.tsx25-44](https://github.com/ui8kit/core/blob/2afe2195/src/themes/providers/ThemeProvider.tsx#L25-L44) [src/themes/providers/ThemeProvider.tsx70-83](https://github.com/ui8kit/core/blob/2afe2195/src/themes/providers/ThemeProvider.tsx#L70-L83)

***

## Инициализация и сохранение состояния темной темы

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

```
Поток обновления

Поток инициализации

Да

Нет

Да

Нет

Монтирование ThemeProvider

Проверка localStorage
window.localStorage.getItem('ui:dark')

stored !== null?

Парсинг сохраненного значения
stored === '1' → true
stored === '0' → false

Проверка системного предпочтения
window.matchMedia('(prefers-color-scheme: dark)')

matchMedia
поддерживается?

Получить значение .matches

По умолчанию false

setIsDarkMode(value)

Изменение состояния isDarkMode

document.documentElement.classList.toggle('dark', isDarkMode)

document.documentElement.style.colorScheme = isDarkMode ? 'dark' : 'light'

localStorage.setItem('ui:dark', isDarkMode ? '1' : '0')
```

**Диаграмма: Поток инициализации и синхронизации состояния темной темы**

Логика инициализации использует ленивую функцию-инициализатор состояния для вычисления начального значения один раз при монтировании. Механизм сохранения сохраняет значения как строки `"1"` (темная) или `"0"` (светлая) в localStorage по ключу `"ui:dark"`.

**Источники**: [src/themes/providers/ThemeProvider.tsx28-35](https://github.com/ui8kit/core/blob/2afe2195/src/themes/providers/ThemeProvider.tsx#L28-L35) [src/themes/providers/ThemeProvider.tsx37-44](https://github.com/ui8kit/core/blob/2afe2195/src/themes/providers/ThemeProvider.tsx#L37-L44)

***

## Интерфейс ThemeContextValue

`ThemeContext` предоставляет типизированный интерфейс для доступа к состоянию темы и функциям управления. Компоненты получают доступ к этому контексту через хук `useTheme`.

| Свойство | Тип | Описание |
| - | - | - |
| `theme` | `T extends ThemeBase` | Объект конфигурации темы |
| `rounded` | `T['rounded']` | Варианты скругления углов из темы |
| `buttonSize` | `T['buttonSize']` | Варианты размеров кнопок из темы |
| `isDarkMode` | `boolean` | Текущее состояние темной темы |
| `isNavFixed` | `boolean \| undefined` | Опциональное состояние фиксированной навигации |
| `prefersReducedMotion` | `boolean` | Предпочтение пользователя по уменьшению движения |
| `toggleDarkMode` | `() => void` | Функция для переключения темной темы |
| `setDarkMode` | `(value: boolean) => void` | Функция для явной установки темной темы |

Тип `ThemeBase` определяет минимальную структуру, необходимую для объектов тем:

```
export type ThemeBase = {
  name: string;
  rounded: Record<string, any> & { default: any };
  buttonSize: Record<string, any> & { default: any };
  isNavFixed?: boolean;
};
```

**Источники**: [src/themes/providers/ThemeProvider.tsx4-10](https://github.com/ui8kit/core/blob/2afe2195/src/themes/providers/ThemeProvider.tsx#L4-L10) [src/themes/providers/ThemeProvider.tsx12-21](https://github.com/ui8kit/core/blob/2afe2195/src/themes/providers/ThemeProvider.tsx#L12-L21)

***

## Использование хука useTheme

Компоненты получают доступ к контексту темы через хук `useTheme`, который обеспечивает использование внутри `ThemeProvider` и возвращает типизированное значение контекста.

**Паттерн использования хука:**

```
import { useTheme } from '@ui8kit/core';

function ThemeToggle() {
  const { isDarkMode, toggleDarkMode } = useTheme();
  
  return (
    <button onClick={toggleDarkMode}>
      {isDarkMode ? '☀️' : '🌙'}
    </button>
  );
}
```

Реализация хука выбрасывает ошибку при использовании вне контекста провайдера, обеспечивая правильную настройку на уровне корня приложения.

**Источники**: [src/themes/providers/ThemeProvider.tsx87-93](https://github.com/ui8kit/core/blob/2afe2195/src/themes/providers/ThemeProvider.tsx#L87-L93) [README.md235-249](https://github.com/ui8kit/core/blob/2afe2195/README.md#L235-L249)

***

## Реализация переключения темной темы

Библиотека предоставляет два метода для управления состоянием темной темы:

### Функция toggleDarkMode

Инвертирует текущее состояние темной темы:

```
const { toggleDarkMode } = useTheme();
// Вызов toggleDarkMode() переключает между светлой и темной темой
```

### Функция setDarkMode

Устанавливает темную тему в конкретное значение:

```
const { setDarkMode } = useTheme();
// setDarkMode(true)  → Принудительно включить темную тему
// setDarkMode(false) → Принудительно включить светлую тему
```

Обе функции запускают поток сохранения, который синхронно обновляет DOM и localStorage.

**Источники**: [src/themes/providers/ThemeProvider.tsx78-79](https://github.com/ui8kit/core/blob/2afe2195/src/themes/providers/ThemeProvider.tsx#L78-L79) [README.md240-248](https://github.com/ui8kit/core/blob/2afe2195/README.md#L240-L248)

***

## Доступность: поддержка уменьшения движения

`ThemeProvider` определяет и отслеживает системное предпочтение пользователя `prefers-reduced-motion` через тот же паттерн медиа-запроса, который используется для определения темной темы.

```
Мониторинг во время выполнения

Инициализация

Очистка

Размонтирование компонента

removeEventListener

Монтирование компонента

window.matchMedia('prefers-reduced-motion: reduce')

setPrefersReducedMotion(matches)

Обработчик событий MediaQueryList

Обработчик события изменения

setPrefersReducedMotion(e.matches)
```

**Диаграмма: Определение и мониторинг предпочтения уменьшения движения**

Реализация включает fallback для старых браузеров, использующих `addListener`/`removeListener` вместо `addEventListener`/`removeEventListener`. Компоненты могут получить доступ к этому значению через контекст для условного отключения анимаций.

**Источники**: [src/themes/providers/ThemeProvider.tsx46-68](https://github.com/ui8kit/core/blob/2afe2195/src/themes/providers/ThemeProvider.tsx#L46-L68)

***

## Интеграция с Tailwind CSS

Система темной темы интегрируется с Tailwind CSS через класс `.dark`, применяемый к `document.documentElement`. Это требует конфигурации Tailwind с `darkMode: 'class'`:

```
// tailwind.config.js
module.exports = {
  darkMode: 'class',
  // ... другая конфигурация
}
```

Когда `isDarkMode` имеет значение `true`, провайдер добавляет класс `dark` к корневому элементу, активируя модификаторы варианта `dark:` в Tailwind:

```
<div className="bg-white dark:bg-slate-900 text-black dark:text-white">
  Контент адаптируется к темной теме
</div>
```

Провайдер также устанавливает `document.documentElement.style.colorScheme` в `"dark"` или `"light"`, что сигнализирует браузеру о предпочтениях пользователя для нативных элементов форм и полос прокрутки.

**Источники**: [src/themes/providers/ThemeProvider.tsx37-44](https://github.com/ui8kit/core/blob/2afe2195/src/themes/providers/ThemeProvider.tsx#L37-L44) [README.md219-233](https://github.com/ui8kit/core/blob/2afe2195/README.md#L219-L233)

***

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

Приложения должны обернуть свой корневой компонент в `ThemeProvider` и передать объект темы. Библиотека экспортирует три предварительно настроенные темы:

| Экспорт темы | Модуль | Название темы |
| - | - | - |
| `modernUITheme` | `@ui8kit/core` | "modernUI" |
| `skyOSTheme` | `@ui8kit/core` | "skyOS" |
| `lesseUITheme` | `@ui8kit/core` | "lesseUI" |

**Паттерн настройки:**

```
import { ThemeProvider, modernUITheme } from '@ui8kit/core';

export function App() {
  return (
    <ThemeProvider theme={modernUITheme}>
      <YourApp />
    </ThemeProvider>
  );
}
```

Каждый объект темы должен удовлетворять ограничению типа `ThemeBase` со свойствами `name`, `rounded` и `buttonSize`. Пользовательские темы могут быть созданы путем реализации этого интерфейса.

**Источники**: [src/themes/index.ts1-9](https://github.com/ui8kit/core/blob/2afe2195/src/themes/index.ts#L1-L9) [README.md223-233](https://github.com/ui8kit/core/blob/2afe2195/README.md#L223-L233)

***

## Соображения по рендерингу на стороне сервера

Реализация включает безопасные для SSR проверки с использованием защитных условий `typeof window !== 'undefined'` и `typeof document === 'undefined'` для предотвращения ошибок во время выполнения при серверном рендеринге. Вычисление начального состояния избегает доступа к API браузера до фазы клиентской гидратации.

Паттерн ленивого инициализатора состояния обеспечивает:

1. Логика инициализации состояния выполняется только один раз при монтировании
2. Доступ к API браузера безопасно защищен
3. Окружения SSR получают разумные значения по умолчанию (`false` для темной темы)

Обработка ошибок оборачивает операции с localStorage в блоки try-catch, чтобы предотвратить блокировку приложения в окружениях с ограниченным доступом к хранилищу.

**Источники**: [src/themes/providers/ThemeProvider.tsx28-35](https://github.com/ui8kit/core/blob/2afe2195/src/themes/providers/ThemeProvider.tsx#L28-L35) [src/themes/providers/ThemeProvider.tsx37-44](https://github.com/ui8kit/core/blob/2afe2195/src/themes/providers/ThemeProvider.tsx#L37-L44) [src/themes/providers/ThemeProvider.tsx46-49](https://github.com/ui8kit/core/blob/2afe2195/src/themes/providers/ThemeProvider.tsx#L46-L49)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.