Функция styled для создания кастомных компонентов

styled — это утилита в MUI, предназначенная для создания компонентов с кастомными стилями на основе существующих компонентов или HTML-элементов. Она обеспечивает интеграцию CSS-in-JS подхода с компонентами React, позволяя писать стили в виде JavaScript и использовать преимущества темы MUI.


Основы использования styled

Базовый синтаксис функции выглядит следующим образом:

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

const CustomButton = styled(Button)({
  backgroundColor: 'blue',
  color: 'white',
  padding: '8px 16px',
  '&:hover': {
    backgroundColor: 'darkblue',
  },
});

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

  • styled(Component)(styles) создаёт новый компонент на основе Component.
  • styles может быть объектом, функцией или массивом.
  • Поддерживаются псевдоклассы (&:hover, &:focus) и вложенные селекторы.

Использование темы MUI в styled

Для интеграции с темой MUI, styled может принимать функцию, которая получает объект theme:

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

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

  • theme.palette предоставляет доступ к цветовой палитре.
  • theme.spacing(n) позволяет использовать стандартные интервалы от темы.
  • Любой элемент темы (например, typography, breakpoints) может применяться к стилям.

Кастомизация HTML-элементов

styled можно использовать не только с MUI-компонентами, но и с обычными HTML-элементами:

const StyledDiv = styled('div')({
  display: 'flex',
  flexDirection: 'column',
  gap: '16px',
  padding: '20px',
  backgroundColor: '#f5f5f5',
});

Преимущества такого подхода:

  • Возможность единообразно оформлять элементы без создания отдельных CSS-файлов.
  • Автоматическая поддержка темы через функции.

Передача пропсов в styled

Функция styled позволяет использовать пропсы компонента для динамической стилизации:

const DynamicButton = styled(Button)(({ theme, variant }) => ({
  backgroundColor: variant === 'danger' ? theme.palette.error.main : theme.palette.success.main,
  color: theme.palette.common.white,
  '&:hover': {
    backgroundColor: variant === 'danger' ? theme.palette.error.dark : theme.palette.success.dark,
  },
}));
  • variant используется для условного применения стилей.
  • Любой пользовательский пропс можно использовать для изменения внешнего вида компонента.

Медиазапросы и адаптивная стилизация

styled интегрирован с системой breakpoints MUI:

const ResponsiveBox = styled('div')(({ theme }) => ({
  width: '100%',
  [theme.breakpoints.up('sm')]: {
    width: '50%',
  },
  [theme.breakpoints.up('md')]: {
    width: '33%',
  },
}));
  • theme.breakpoints.up('sm') позволяет задавать стили для экранов шире sm.
  • Поддерживаются up, down, between, only.
  • Такой подход упрощает создание адаптивных интерфейсов без медиа-запросов в CSS.

Сочетание с системой sx

Компоненты, созданные через styled, полностью совместимы с пропсом sx:

<CustomButton sx={{ fontSize: '18px', marginTop: 2 }}>
  Нажми меня
</CustomButton>
  • Проп sx может переопределять стили, заданные через styled.
  • Поддерживается вся функциональность sx, включая темы и медиазапросы.

Вложенные компоненты и композиция

styled позволяет создавать композиции компонентов:

const CardContainer = styled('div')({
  padding: '20px',
  borderRadius: '8px',
  backgroundColor: '#fff',
  boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
});

const CardHeader = styled('h2')({
  fontSize: '1.5rem',
  marginBottom: '12px',
});
  • Компоненты можно комбинировать, создавая единый дизайн-контейнер.
  • Поддерживаются вложенные селекторы для уточнения стилей дочерних элементов:
const ListContainer = styled('ul')({
  listStyle: 'none',
  padding: 0,
  '& li': {
    padding: '8px 0',
    borderBottom: '1px solid #ccc',
  },
});

Дополнительные возможности

  • Анимации: можно использовать CSS-анимации и transitions.
  • Темизация: все стили могут быть связаны с темой, что обеспечивает единый визуальный стиль приложения.
  • Перезапись классов: MUI позволяет использовать проп classes вместе с styled для точного контроля.

Функция styled объединяет мощь CSS-in-JS, адаптивность темы MUI и гибкость React-компонентов, что делает её центральным инструментом для создания современных, стилизованных интерфейсов.