Цветовые схемы Mantine – light, dark и auto
На предыдущем занятии мы создали кастомную тему с цветами, шрифтами и отступами. Теперь пришло время разобраться с одной из самых крутых фишек Mantine — встроенной поддержкой светлой и темной цветовых схем. Вам не нужно писать отдельные стили для каждого режима — Mantine делает это автоматически. В этом уроке мы научимся управлять переключением между темами и добавим в приложение удобный переключатель.
Как Mantine работает с цветовыми схемами
Mantine из коробки поддерживает три значения цветовой схемы: 'light', 'dark' и 'auto' . Все компоненты библиотеки автоматически адаптируются под текущую схему — меняются фоны, цвета текста, обводки, тени и даже состояния при наведении.
Схема хранится в localStorage (по умолчанию), поэтому выбор пользователя сохраняется между сессиями. Система добавляет атрибут data-mantine-color-scheme на корневой элемент HTML, и все стили компонентов используют его для определения, какие цвета применять.
Настройка defaultColorScheme в провайдере
Прежде всего, в MantineProvider можно задать схему по умолчанию. Она используется, когда в localStorage нет сохраненного значения (например, при первом посещении).
// src/App.tsx
import { MantineProvider } from '@mantine/core';
import { theme } from './theme';
function App() {
return (
<MantineProvider theme={theme} defaultColorScheme="auto">
{/* Остальное приложение */}
</MantineProvider>
);
}
Значение 'auto' означает, что Mantine будет автоматически определять предпочтения пользователя на уровне операционной системы (через медиа-запрос prefers-color-scheme). Это самый дружелюбный вариант для пользователей.
Хуки для работы с цветовой схемой
Mantine предоставляет два основных хука для работы с цветовой схемой — они вам понадобятся в 99% случаев.
useMantineColorScheme() — управление схемой
Этот хук возвращает объект с методами для управления цветовой схемой:
import { useMantineColorScheme, Button, Group } from '@mantine/core';
function ColorSchemeControl() {
const { colorScheme, setColorScheme, toggleColorScheme, clearColorScheme } = useMantineColorScheme();
return (
<Group>
<Button onClick={() => setColorScheme('light')}>Светлая</Button>
<Button onClick={() => setColorScheme('dark')}>Темная</Button>
<Button onClick={() => setColorScheme('auto')}>Как в системе</Button>
<Button onClick={clearColorScheme}>Сбросить</Button>
</Group>
);
}
Что возвращает хук:
| Свойство | Тип | Описание |
|---|---|---|
colorScheme |
'light' | 'dark' | 'auto' |
Текущее значение схемы |
setColorScheme |
(scheme) => void |
Устанавливает схему вручную |
toggleColorScheme |
() => void |
Переключает на противоположную схему |
clearColorScheme |
() => void |
Очищает сохраненное значение и возвращается к defaultColorScheme |
Обратите внимание: при использовании SSR (Next.js, React Router) нельзя полагаться на colorScheme в клиентском коде для условного рендеринга — это вызовет ошибки гидратации. Используйте CSS-миксины из postcss-preset-mantine или пропсы lightHidden/darkHidden.
useComputedColorScheme() — фактическое значение
Если вам нужно узнать, какая схема фактически отображается на экране (с учетом 'auto'), используйте useComputedColorScheme():
import { useComputedColorScheme } from '@mantine/core';
function Component() {
// Всегда возвращает только 'light' или 'dark' (без 'auto')
const computedScheme = useComputedColorScheme();
return <div>Сейчас используется: {computedScheme}</div>;
}
Этот хук разрешает 'auto' в 'light' или 'dark' на основе системных настроек пользователя.
Создаем переключатель тем (Toggle)
Теперь соберем все вместе и создадим красивый переключатель тем — компонент, который вы будете использовать в каждом проекте.
// src/components/ThemeToggle.tsx
import { ActionIcon, useMantineColorScheme, useComputedColorScheme } from '@mantine/core';
import { IconSun, IconMoon } from '@tabler/icons-react';
import cx from 'clsx';
import classes from './ThemeToggle.module.css'; // Стили опционально
export function ThemeToggle() {
const { setColorScheme } = useMantineColorScheme();
const computedColorScheme = useComputedColorScheme();
const toggleTheme = () => {
setColorScheme(computedColorScheme === 'light' ? 'dark' : 'light');
};
return (
<ActionIcon
onClick={toggleTheme}
variant="default"
size="lg"
aria-label="Переключить тему"
>
{computedColorScheme === 'light' ? (
<IconMoon size={20} stroke={1.5} />
) : (
<IconSun size={20} stroke={1.5} />
)}
</ActionIcon>
);
}
Теперь добавьте этот компонент в любое место приложения, например, в шапку:
// src/App.tsx
import { MantineProvider, AppShell, Group, Title } from '@mantine/core';
import { theme } from './theme';
import { ThemeToggle } from './components/ThemeToggle';
function App() {
return (
<MantineProvider theme={theme} defaultColorScheme="auto">
<AppShell header={{ height: 60 }} padding="md">
<AppShell.Header>
<Group justify="space-between" p="md">
<Title order={3}>Мое приложение</Title>
<ThemeToggle />
</Group>
</AppShell.Header>
<AppShell.Main>Контент страницы</AppShell.Main>
</AppShell>
</MantineProvider>
);
}
Собери свой код. Запусти сайт!
От наброска на салфетке до первого работающего лендинга. Наш онлайн-курс «Веб-верстка с нуля и до профессионала» — это интенсивный трек, где ты не будешь зубрить теорию, а с первого дня начнешь превращать идеи в чистый HTML и CSS.
Собери свой первый проект под руководством практикующих разработчиков.
Кастомизация цветов для разных схем
Иногда нужно, чтобы определенные цвета выглядели по-разному в светлой и темной теме. Для этого в Mantine есть концепция виртуальных цветов.
import { createTheme, virtualColor } from '@mantine/core';
const theme = createTheme({
colors: {
// Обычные цвета
brand: [
'#f0f0ff', '#e0e0ff', '#c2c2ff', '#a3a3ff',
'#8585ff', '#6666ff', '#4747ff', '#3636cc',
'#262699', '#171766'
],
// Виртуальный цвет — разные оттенки в зависимости от схемы
primary: virtualColor({
name: 'primary',
light: 'brand', // в светлой теме используем brand
dark: 'blue', // в темной теме используем синий
}),
},
});
Теперь компоненты, использующие цвет 'primary', будут автоматически менять свой оттенок при переключении темы.
Советы по работе с цветовыми схемами
Для клиентских приложений (Vite, CRA) вы можете смело использовать colorScheme из хука для условного рендеринга — ошибок гидратации не будет.
Для SSR-приложений используйте CSS-миксины dark и light из postcss-preset-mantine для скрытия/показа элементов.
Анимации при переключении темы отключены по умолчанию, чтобы избежать дергающихся переходов. Чтобы включить их, передайте опцию в хук:
const { toggleColorScheme } = useMantineColorScheme({ keepTransitions: true });
Если нужно переименовать ключ в localStorage, используйте colorSchemeManager:
import { MantineProvider, localStorageColorSchemeManager } from '@mantine/core';
const colorSchemeManager = localStorageColorSchemeManager({
key: 'my-app-theme', // По умолчанию 'mantine-color-scheme'
});
<MantineProvider colorSchemeManager={colorSchemeManager}>
{/* ... */}
</MantineProvider>
Итоги и что дальше
Сегодня вы научились:
- Настраивать цветовую схему по умолчанию через
defaultColorScheme - Использовать
useMantineColorScheme()для управления светлой/темной темой - Получать фактическую схему через
useComputedColorScheme() - Создавать компонент-переключатель тем с иконками
- Применять виртуальные цвета для тонкой настройки в разных схемах
Что должно быть в вашем проекте после этого урока:
- В
MantineProviderзаданdefaultColorScheme="auto" - В приложении есть переключатель тем (
ThemeToggle) - Переключатель правильно показывает иконку в зависимости от текущей схемы
- Переключение тем работает и сохраняется в
localStorage
В следующем уроке мы перейдем к самой вкусной части — стилизации компонентов. Узнаем, как применять стили тремя способами: через пропсы, CSS-модули и глобальные переменные. Выберите свой любимый подход!