Создание дизайн-системы на базе MUI

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

Конфигурация темы

Создание темы начинается с использования функции createTheme:

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

const theme = createTheme({
  palette: {
    primary: {
      main: '#1976d2',
    },
    secondary: {
      main: '#dc004e',
    },
    background: {
      default: '#f5f5f5',
    },
  },
  typography: {
    fontFamily: 'Roboto, Arial, sans-serif',
    h1: {
      fontSize: '2rem',
      fontWeight: 500,
    },
    body1: {
      fontSize: '1rem',
    },
  },
  spacing: 8, // базовая единица для отступов
});

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

  • palette задаёт основные цвета интерфейса. Использование primary, secondary, error, warning, info, success позволяет унифицировать все элементы.
  • typography определяет системные шрифты и стили заголовков и текста.
  • spacing обеспечивает единый подход к отступам и размерам компонентов.

Применение темы через ThemeProvider

Для того чтобы вся библиотека компонентов MUI использовала единый стиль, необходимо обернуть приложение в ThemeProvider:

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

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

CssBaseline применяется для нормализации стилей браузера и интеграции базовых стилей темы.

Кастомизация компонентов

MUI позволяет настраивать стили отдельных компонентов глобально с помощью свойства components в теме:

const theme = createTheme({
  components: {
    MuiButton: {
      styleOverrides: {
        root: {
          borderRadius: 12,
          textTransform: 'none',
        },
        containedPrimary: {
          backgroundColor: '#0d47a1',
        },
      },
    },
    MuiCard: {
      styleOverrides: {
        root: {
          boxShadow: '0 4px 20px rgba(0,0,0,0.1)',
        },
      },
    },
  },
});

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

  • styleOverrides изменяет существующие стили компонента.
  • Можно создавать единый визуальный язык для всех кнопок, карточек, полей ввода и других элементов.

Создание системных компонентов

Для повышения консистентности интерфейса рекомендуется создавать обёртки над стандартными компонентами:

import Button from '@mui/material/Button';

export const PrimaryButton = (props) => (
  <Button {...props} color="primary" variant="contained" />
);

Такие обёртки позволяют использовать унифицированные стили без дублирования кода и сохранять гибкость настройки.

Использование design tokens

Design tokens — это атомарные элементы дизайн-системы: цвета, размеры, отступы, тени, типографика. В MUI их удобно интегрировать через тему:

const theme = createTheme({
  palette: {
    primary: { main: '#1976d2', contrastText: '#fff' },
  },
  shadows: ['none', '0px 2px 4px rgba(0,0,0,0.1)'],
  spacing: 4,
});

Tokens позволяют централизованно управлять визуальным стилем и легко масштабировать систему на несколько приложений.

Темизация на основе режимов

MUI поддерживает темизацию под светлый и тёмный режим:

const lightTheme = createTheme({
  palette: { mode: 'light' },
});

const darkTheme = createTheme({
  palette: { mode: 'dark' },
});

Комбинация ThemeProvider с useMediaQuery позволяет автоматически переключать темы в зависимости от предпочтений пользователя.

Стилизация через sx и styled

MUI предлагает два способа локальной кастомизации:

  1. sx — проп для быстрого инлайнового стайлинга:
<Box sx={{ p: 2, bgcolor: 'primary.main', borderRadius: 2 }}>
  Контент
</Box>
  1. styled — для создания переиспользуемых компонентов с CSS-in-JS:
import { styled } from '@mui/material/styles';
import Button from '@mui/material/Button';

const RoundedButton = styled(Button)(({ theme }) => ({
  borderRadius: theme.shape.borderRadius * 2,
  padding: theme.spacing(1, 4),
}));

Использование theme внутри styled обеспечивает соответствие глобальной дизайн-системе.

Организация структуры дизайн-системы

Эффективная система требует:

  • theme.js — централизованная тема с цветами, типографикой, отступами.
  • components/ — переиспользуемые обёртки компонентов с единым стилем.
  • tokens/ — атомарные элементы (цвета, шрифты, тени) для кросс-проектного использования.
  • layouts/ — системные шаблоны страниц и блоков интерфейса.

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

Интеграция с Storybook

Для проверки визуального соответствия и создания библиотеки UI-компонентов полезно подключать Storybook. Компоненты с системными стилями можно демонстрировать в изолированной среде, что облегчает работу дизайнеров и разработчиков.


Эта структура позволяет создать полноценную дизайн-систему на базе MUI, объединяя глобальные темы, кастомизированные компоненты и атомарные токены, сохраняя единый визуальный язык на всех уровнях приложения.