Режимы светлой и темной темы

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

Создание темы с поддержкой светлого и темного режимов

Для начала необходимо создать две темы: для светлого и темного режимов. Основная разница заключается в значении mode:

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

const lightTheme = createTheme({
  palette: {
    mode: 'light',
    primary: {
      main: '#1976d2',
    },
    secondary: {
      main: '#9c27b0',
    },
    background: {
      default: '#fafafa',
      paper: '#fff',
    },
  },
});

const darkTheme = createTheme({
  palette: {
    mode: 'dark',
    primary: {
      main: '#90caf9',
    },
    secondary: {
      main: '#ce93d8',
    },
    background: {
      default: '#121212',
      paper: '#1d1d1d',
    },
  },
});

Здесь ключевое значение — palette.mode. Оно автоматически меняет базовые цвета компонентов, такие как Button, AppBar, Paper, Card, под выбранный режим.

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

Для динамического переключения между светлым и темным режимом удобно использовать состояние и контекст. Пример с использованием React Context:

import React, { createContext, useState, useMemo, useContext } from 'react';
import { ThemeProvider } from '@mui/material/styles';
import CssBaseline from '@mui/material/CssBaseline';

const ThemeModeContext = createContext({ toggleTheme: () => {} });

export const useThemeMode = () => useContext(ThemeModeContext);

export default function App() {
  const [mode, setMode] = useState('light');

  const toggleTheme = () => {
    setMode(prevMode => (prevMode === 'light' ? 'dark' : 'light'));
  };

  const theme = useMemo(() => 
    createTheme({
      palette: {
        mode,
      },
    }), [mode]
  );

  return (
    <ThemeModeContext.Provider value={{ toggleTheme }}>
      <ThemeProvider theme={theme}>
        <CssBaseline />
        {/* Компоненты приложения */}
      </ThemeProvider>
    </ThemeModeContext.Provider>
  );
}

Здесь CssBaseline автоматически применяет базовые стили MUI для текущей темы, включая цвет фона, текст и стандартные элементы интерфейса.

Настройка пользовательских цветов для тем

MUI позволяет расширять палитру для каждой темы. Например, можно задать отдельные цвета для кнопок, ссылок и текста:

const customTheme = createTheme({
  palette: {
    mode: 'dark',
    primary: {
      main: '#ff9800',
    },
    secondary: {
      main: '#4caf50',
    },
    text: {
      primary: '#ffffff',
      secondary: '#bbbbbb',
    },
    info: {
      main: '#2196f3',
    },
  },
});

При этом компоненты автоматически используют эти цвета через пропсы color="primary" или color="secondary". Для текстовых элементов можно управлять оттенками через Typography.

Использование sx и кастомизация под темы

Система sx позволяет настраивать стили компонентов с учётом текущей темы:

import { Box, Typography } from '@mui/material';

<Box sx={{ 
  backgroundColor: theme => theme.palette.background.paper, 
  color: theme => theme.palette.text.primary,
  p: 2,
}}>
  <Typography variant="h6">Текст, адаптирующийся под тему</Typography>
</Box>

Функция theme => theme.palette... позволяет динамически брать значения текущей темы, что особенно полезно при переключении светлого и темного режима.

Темы и пользовательский режим в localStorage

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

const savedMode = localStorage.getItem('themeMode') || 'light';
const [mode, setMode] = useState(savedMode);

const toggleTheme = () => {
  const newMode = mode === 'light' ? 'dark' : 'light';
  setMode(newMode);
  localStorage.setItem('themeMode', newMode);
};

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

Адаптация компонентов к теме

MUI предоставляет встроенные компоненты, полностью готовые к работе с темами:

  • AppBar автоматически меняет цвет фона и текста;
  • Paper подстраивается под palette.background.paper;
  • Button учитывает palette.mode для теней и контраста;
  • Typography автоматически адаптирует оттенки текста при смене режима.

Контраст и доступность

При проектировании тем важно следить за контрастом текста и фона. MUI автоматически применяет контрастные цвета для primary и secondary элементов, но для пользовательских цветов рекомендуется использовать функцию getContrastText:

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

const theme = createTheme({
  palette: {
    primary: {
      main: '#ff5722',
      contrastText: '#fff', // Явное указание контрастного текста
    },
  },
});

Это гарантирует читаемость текста в любом режиме.

Итоговые возможности

  • Динамическое переключение между светлой и темной темой;
  • Автоматическая адаптация компонентов под режим;
  • Возможность создания кастомных цветов и оттенков;
  • Управление темой через контекст и сохранение пользовательских настроек;
  • Поддержка sx для гибкой стилизации компонентов.

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