Настройка темного режима

Библиотека MUI (Material-UI) предоставляет мощные возможности для управления темами, включая легкую реализацию темного режима. В основе лежит система ThemeProvider и функция createTheme, которая позволяет задавать глобальные параметры интерфейса, включая цвета, типографику и компоненты.


Создание темы

Темная тема создается с помощью функции createTheme, где ключевым параметром является объект palette:

import { createTheme } from '@mui/material/styles';

const darkTheme = createTheme({
  palette: {
    mode: 'dark',
    primary: {
      main: '#90caf9', // основной цвет
    },
    secondary: {
      main: '#f48fb1', // дополнительный цвет
    },
    background: {
      default: '#121212', // основной фон
      paper: '#1e1e1e',   // цвет карточек и панелей
    },
    text: {
      primary: '#ffffff',
      secondary: '#b0bec5',
    },
  },
});

Ключевые моменты:

  • mode: 'dark' — переключает всю палитру на темный режим.
  • background.default — задает фон приложения.
  • background.paper — фон элементов типа Paper, Card, Dialog.
  • Цвета primary и secondary используются во всех компонентах для акцентов.

Подключение темы к приложению

Используется ThemeProvider для оборачивания корневого компонента:

import { ThemeProvider } from '@mui/material/styles';
import CssBaseline from '@mui/material/CssBaseline';
import App from './App';

function Root() {
  return (
    <ThemeProvider theme={darkTheme}>
      <CssBaseline />
      <App />
    </ThemeProvider>
  );
}

export default Root;

CssBaseline — важный компонент, который нормализует стили и применяет цвета фона и текста в соответствии с темой.


Динамическое переключение светлой и темной темы

MUI позволяет легко переключать темы в приложении:

import React, { useState, useMemo } from 'react';
import { ThemeProvider, createTheme, CssBaseline, Button } from '@mui/material';

function App() {
  const [darkMode, setDarkMode] = useState(false);

  const theme = useMemo(
    () =>
      createTheme({
        palette: {
          mode: darkMode ? 'dark' : 'light',
        },
      }),
    [darkMode]
  );

  return (
    <ThemeProvider theme={theme}>
      <CssBaseline />
      <Button onCl ick={() => setDarkMode(prev => !prev)}>
        Переключить тему
      </Button>
    </ThemeProvider>
  );
}

export default App;

Особенности реализации:

  • Использование useMemo позволяет пересоздавать тему только при изменении darkMode, что улучшает производительность.
  • Переключение mode между 'light' и 'dark' автоматически меняет все базовые цвета компонентов MUI.

Настройка цветов для темной темы

В темной теме особенно важно контролировать контрастность текста и фона. Можно расширить стандартную палитру:

const darkTheme = createTheme({
  palette: {
    mode: 'dark',
    primary: {
      main: '#bb86fc',
      contrastText: '#000000', // цвет текста на кнопках
    },
    secondary: {
      main: '#03dac6',
      contrastText: '#000000',
    },
    error: {
      main: '#cf6679',
    },
    background: {
      default: '#121212',
      paper: '#1f1f1f',
    },
    text: {
      primary: '#ffffff',
      secondary: '#b3b3b3',
      disabled: '#666666',
    },
  },
});

Рекомендации по дизайну темного режима:

  • Использовать более мягкие оттенки для фона (#121212, #1e1e1e), чтобы снизить нагрузку на глаза.
  • Контрастный текст должен быть белым или светло-серым для удобочитаемости.
  • Акцентные цвета (primary, secondary) могут быть ярче для визуальной ясности.

Настройка компонентов под темный режим

Для некоторых компонентов можно задавать стили, зависящие от темы:

import { styled } from '@mui/material/styles';
import Button from '@mui/material/Button';

const ThemedButton = styled(Button)(({ theme }) => ({
  backgroundColor: theme.palette.primary.main,
  color: theme.palette.primary.contrastText,
  '&:hover': {
    backgroundColor: theme.palette.primary.dark,
  },
}));

export default ThemedButton;

Особенности:

  • theme.palette автоматически предоставляет доступ к текущей теме, будь она светлой или темной.
  • Стили могут адаптироваться в зависимости от theme.palette.mode.

Пользовательский переключатель темы с localStorage

Для сохранения предпочтений пользователя между сессиями:

const [darkMode, setDarkMode] = useState(() => {
  const saved = localStorage.getItem('darkMode');
  return saved ? JSON.parse(saved) : false;
});

const toggleTheme = () => {
  setDarkMode(prev => {
    localStorage.setItem('darkMode', JSON.stringify(!prev));
    return !prev;
  });
};

Преимущества:

  • Пользовательская тема сохраняется после перезагрузки страницы.
  • Простая интеграция с существующим переключателем темы.

Расширенные возможности

  1. Комбинирование с адаптивными стилями MUI поддерживает адаптивные настройки через breakpoints в theme, что позволяет менять цвета или размеры под разные устройства.

  2. Поддержка кастомных цветов Можно добавлять новые цвета в палитру, например tertiary, и использовать их в компонентах:

const theme = createTheme({
  palette: {
    tertiary: {
      main: '#ffb74d',
      contrastText: '#000000',
    },
  },
});
  1. Темы для отдельных компонентов Можно локально переопределять тему только для определенной области приложения, оборачивая компонент в отдельный ThemeProvider.

Темный режим в MUI строится вокруг глобальной палитры и ThemeProvider, с гибкой настройкой цветов, фона и компонентов. Правильное использование контрастных цветов и сохранение пользовательских предпочтений обеспечивает удобство интерфейса и визуальную консистентность.