Переопределение компонентов темы

Chakra UI предоставляет мощный механизм для переопределения стандартных компонентов темы, что позволяет создавать единообразный стиль приложения и минимизировать повторение кода. Основной инструмент для этого — объект extendTheme, который позволяет настраивать цвета, типографику, размеры компонентов и их поведение.


Структура темы

Тема в Chakra UI состоит из нескольких ключевых разделов:

  • colors — палитра цветов для всех компонентов.
  • fonts — шрифты для заголовков, текста и моноширинных блоков.
  • fontSizes — набор стандартных размеров шрифта.
  • space — единицы отступов (margin, padding).
  • components — конфигурация отдельных компонентов.

Раздел components позволяет глобально переопределять стили для всех экземпляров компонента. Формат объекта компонента обычно включает следующие поля:

const theme = extendTheme({
  components: {
    Button: {
      baseStyle: {}, // базовые стили
      sizes: {},     // варианты размеров
      variants: {},  // визуальные варианты
      defaultProps: {} // значения по умолчанию
    }
  }
});

Переопределение базового стиля

baseStyle определяет фундаментальный вид компонента, который применяется ко всем экземплярам. Пример для кнопки:

const theme = extendTheme({
  components: {
    Button: {
      baseStyle: {
        fontWeight: "bold",
        borderRadius: "md",
        _hover: {
          bg: "blue.600"
        }
      }
    }
  }
});
  • fontWeight: "bold" — делает текст кнопки жирным.
  • borderRadius: "md" — задаёт стандартное скругление углов.
  • _hover — псевдокласс, определяющий поведение при наведении.

baseStyle может использовать токены темы, например colors.blue.500, space.4, что обеспечивает консистентность дизайна.


Создание пользовательских вариантов (variants)

В Chakra UI каждый компонент может иметь несколько вариантов оформления, которые можно переключать с помощью пропа variant. Пример для кнопки:

const theme = extendTheme({
  components: {
    Button: {
      variants: {
        solid: {
          bg: "green.400",
          color: "white",
          _hover: { bg: "green.500" }
        },
        outline: {
          border: "2px solid",
          borderColor: "green.400",
          color: "green.400",
          _hover: { bg: "green.50" }
        }
      }
    }
  }
});
  • solid и outline — настраиваемые варианты, которые можно использовать в компоненте как <Button variant="solid">.
  • _hover и другие псевдоклассы можно комбинировать с focus, active, disabled.

Переопределение размеров компонентов

Поле sizes позволяет создавать кастомные размеры компонента:

const theme = extendTheme({
  components: {
    Button: {
      sizes: {
        xl: {
          h: "56px",
          fontSize: "lg",
          px: "32px"
        },
        sm: {
          h: "32px",
          fontSize: "sm",
          px: "16px"
        }
      }
    }
  }
});
  • h — высота компонента.
  • px — горизонтальные отступы (padding).
  • fontSize — размер текста.

Применяется через проп size: <Button size="xl">.


Установка значений по умолчанию

defaultProps позволяет задать значения по умолчанию для всех экземпляров компонента:

const theme = extendTheme({
  components: {
    Button: {
      defaultProps: {
        size: "md",
        variant: "solid",
        colorScheme: "blue"
      }
    }
  }
});
  • size — стандартный размер кнопки.
  • variant — стандартный вариант отображения.
  • colorScheme — базовая цветовая схема, связанная с палитрой темы.

Переопределение пользовательских компонентов

Chakra UI позволяет создавать собственные компоненты с полной интеграцией в тему. Для этого используется функция createMultiStyleConfigHelpers для составных компонентов:

import { createMultiStyleConfigHelpers } from "@chakra-ui/react";

const { definePartsStyle, defineMultiStyleConfig } = createMultiStyleConfigHelpers(["container", "label"]);

const customBadgeStyle = definePartsStyle({
  container: { bg: "purple.400", color: "white", px: 4 },
  label: { fontWeight: "bold" }
});

const Badge = defineMultiStyleConfig({ baseStyle: customBadgeStyle });
  • definePartsStyle — задаёт стили для отдельных частей компонента.
  • defineMultiStyleConfig — объединяет их в конфигурацию, которая подключается через components в теме.

Динамическое использование токенов темы

В extendTheme можно использовать функции с доступом к токенам темы:

const theme = extendTheme({
  components: {
    Button: {
      variants: {
        dynamic: (props) => ({
          bg: props.colorMode === "dark" ? "orange.300" : "orange.500",
          color: props.colorMode === "dark" ? "gray.800" : "white"
        })
      }
    }
  }
});
  • props.colorMode позволяет адаптировать стили под светлую и тёмную темы.
  • Можно использовать другие свойства темы: theme.colors, theme.space, theme.fontSizes.

Интеграция переопределённых компонентов в приложение

После настройки темы её нужно передать через ChakraProvider:

import { ChakraProvider } from "@chakra-ui/react";

function App() {
  return (
    <ChakraProvider theme={theme}>
      <Button variant="solid">Кнопка</Button>
      <Button variant="outline" size="sm">Маленькая кнопка</Button>
    </ChakraProvider>
  );
}

Все переопределения автоматически применяются ко всем компонентам в приложении, что обеспечивает единообразный дизайн без дублирования CSS.


Рекомендации по структурированию темы

  1. Разделять components и foundations — базовые цвета, размеры и шрифты лучше держать отдельно.
  2. Использовать токены вместо хардкодаcolors.blue.500 вместо #3182CE.
  3. Создавать переиспользуемые варианты — если компонент повторяется во многих местах.
  4. Обеспечивать поддержку цветовой схемы (light/dark) — через функции в variants и baseStyle.

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