Хотите заказать веб-сайт? Связаться с нами

Цветовые схемы Mantine – light, dark и auto

На предыдущем занятии мы создали кастомную тему с цветами, шрифтами и отступами. Теперь пришло время разобраться с одной из самых крутых фишек Mantine — встроенной поддержкой светлой и темной цветовых схем. Вам не нужно писать отдельные стили для каждого режима — Mantine делает это автоматически. В этом уроке мы научимся управлять переключением между темами и добавим в приложение удобный переключатель.

Цветовые схемы Mantine – light, dark и auto

Как 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>

Итоги и что дальше

Сегодня вы научились:

  1. Настраивать цветовую схему по умолчанию через defaultColorScheme
  2. Использовать useMantineColorScheme() для управления светлой/темной темой
  3. Получать фактическую схему через useComputedColorScheme()
  4. Создавать компонент-переключатель тем с иконками
  5. Применять виртуальные цвета для тонкой настройки в разных схемах

Что должно быть в вашем проекте после этого урока:

  1. В MantineProvider задан defaultColorScheme="auto"
  2. В приложении есть переключатель тем (ThemeToggle)
  3. Переключатель правильно показывает иконку в зависимости от текущей схемы
  4. Переключение тем работает и сохраняется в localStorage

В следующем уроке мы перейдем к самой вкусной части — стилизации компонентов. Узнаем, как применять стили тремя способами: через пропсы, CSS-модули и глобальные переменные. Выберите свой любимый подход!

Теги: