MUI (Material-UI) предоставляет мощный механизм
управления темами, который позволяет динамически менять цвета
компонентов приложения без необходимости ручного вмешательства в каждый
элемент. Ключевым инструментом для этого является объект темы
(Theme) и функция createTheme, а также хук
useTheme и компонент ThemeProvider.
В MUI темы создаются с помощью функции createTheme. В
объекте темы можно задать цветовую палитру, тип
палитры (light/dark), а также кастомные
переменные.
import { createTheme, ThemeProvider } from '@mui/material/styles';
const lightTheme = createTheme({
palette: {
mode: 'light',
primary: {
main: '#1976d2',
},
secondary: {
main: '#dc004e',
},
},
});
const darkTheme = createTheme({
palette: {
mode: 'dark',
primary: {
main: '#90caf9',
},
secondary: {
main: '#f48fb1',
},
},
});
Ключевой момент: palette.mode
автоматически задаёт базовые цвета для текста, фона и элементов, упрощая
работу с тёмной и светлой темой.
ThemeProvider оборачивает корневой компонент приложения
и передаёт тему всем дочерним компонентам.
<ThemeProvider theme={lightTheme}>
<App />
</ThemeProvider>
Важно: Компоненты MUI, такие как
Button, AppBar, Typography, будут
автоматически использовать цвета из текущей темы.
Для динамической смены цветов можно использовать состояние React и переключение между темами:
import { useState } from 'react';
function AppWrapper() {
const [isDarkMode, setIsDarkMode] = useState(false);
const theme = isDarkMode ? darkTheme : lightTheme;
return (
<ThemeProvider theme={theme}>
<button onCl ick={() => setIsDarkMode(!isDarkMode)}>
Переключить тему
</button>
<App />
</ThemeProvider>
);
}
Ключевой момент: Использование состояния позволяет изменять тему “на лету”, не перезагружая страницу и не изменяя отдельные компоненты вручную.
MUI поддерживает кастомные цвета через
palette и sx пропсы.
import Button from '@mui/material/Button';
<Button sx={{ backgroundColor: 'primary.main', color: 'secondary.main' }}>
Кнопка с кастомным цветом
</Button>
Можно также использовать функцию theme внутри
sx для доступа к текущей теме:
<Button
sx={(theme) => ({
backgroundColor: theme.palette.primary.main,
color: theme.palette.secondary.contrastText,
})}
>
Динамический цвет
</Button>
Особенность: Даже при смене темы кнопка автоматически обновит свои цвета.
MUI позволяет добавлять собственные цвета или настройки, расширяя стандартную палитру:
const theme = createTheme({
palette: {
mode: 'light',
primary: { main: '#1976d2' },
custom: {
highlight: '#ffeb3b',
warning: '#f44336',
},
},
});
// Использование:
<Button sx={(theme) => ({ backgroundColor: theme.palette.custom.highlight })}>
Подсветка
</Button>
Ключевой момент: Для новых цветов необходимо объявить их типизацию, если используется TypeScript, чтобы избежать ошибок компиляции.
Можно менять отдельные свойства темы в реальном времени, не создавая новую тему полностью:
import { useMemo } from 'react';
const dynamicTheme = useMemo(() =>
createTheme({
palette: {
primary: { main: isDarkMode ? '#90caf9' : '#1976d2' },
secondary: { main: isDarkMode ? '#f48fb1' : '#dc004e' },
},
}),
[isDarkMode]
);
Использование useMemo предотвращает ненужное
пересоздание темы при каждом рендере, повышая производительность.
Можно автоматически подстраивать тему под системные настройки
пользователя с помощью хука useMediaQuery:
import { useMediaQuery } from '@mui/material';
const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)');
const theme = useMemo(() =>
createTheme({
palette: { mode: prefersDarkMode ? 'dark' : 'light' },
}),
[prefersDarkMode]
);
Преимущество: Пользователь видит интерфейс в привычной цветовой схеме без необходимости вручную переключать тему.
MUI интегрируется с функцией styled, позволяя задавать
динамические цвета внутри кастомных компонентов:
import { styled } from '@mui/material/styles';
import Button from '@mui/material/Button';
const CustomButton = styled(Button)(({ theme, active }) => ({
backgroundColor: active ? theme.palette.primary.main : theme.palette.secondary.main,
color: theme.palette.getContrastText(active ? theme.palette.primary.main : theme.palette.secondary.main),
}));
<CustomButton active={true}>Активная кнопка</CustomButton>
Особенность: Цвета реагируют на текущую тему и на дополнительные пропсы компонента.
useMemo, чтобы не пересоздавать её
на каждом рендере.primary,
secondary) для максимальной совместимости с
MUI-компонентами.Dynamically changing colors в MUI строится на основе
тем, хука useTheme,
компонента ThemeProvider, а также
состояния приложения, что обеспечивает гибкость и
масштабируемость интерфейса при смене светлой и тёмной темы, кастомных
цветов и адаптации к системным настройкам.