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

Chakra UI предоставляет мощный механизм для настройки внешнего вида компонентов через варианты (variants), позволяя создавать множество визуальных и функциональных стилей для одного и того же базового компонента. В отличие от обычного переопределения стилей через sx или style, использование вариантов делает код более структурированным, повторно используемым и читаемым.

В Chakra UI варианты определяются внутри тематической конфигурации (theme) и позволяют задать разные стили для одного компонента, например, кнопки (Button) или поля ввода (Input).


Настройка темы для вариантов компонентов

Для начала необходимо создать или расширить существующую тему:

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

const theme = extendTheme({
  components: {
    Button: {
      // Базовые стили, применяемые ко всем кнопкам
      baseStyle: {
        fontWeight: "bold",
        borderRadius: "md",
      },
      // Определение вариантов
      variants: {
        solid: {
          bg: "blue.500",
          color: "white",
          _hover: { bg: "blue.600" },
        },
        outline: {
          border: "2px solid",
          borderColor: "blue.500",
          color: "blue.500",
          _hover: { bg: "blue.50" },
        },
        ghost: {
          color: "blue.500",
          _hover: { bg: "blue.50" },
        },
      },
      // Значение варианта по умолчанию
      defaultProps: {
        variant: "solid",
      },
    },
  },
});

export default theme;

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

  • baseStyle задаёт стили, которые будут применяться ко всем вариантам компонента.
  • variants позволяет создать несколько визуальных версий компонента.
  • defaultProps задаёт вариант по умолчанию, если не указан явно через пропс variant.

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

После определения вариантов в теме их можно использовать напрямую в JSX через пропс variant:

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

<Button variant="solid">Солидная кнопка</Button>
<Button variant="outline">Контурная кнопка</Button>
<Button variant="ghost">Прозрачная кнопка</Button>

Если variant не указан, применяется вариант по умолчанию, определённый в defaultProps.


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

Помимо стандартных вариантов, Chakra UI позволяет создавать собственные уникальные стили для конкретных компонентов. Например, добавим danger вариант для кнопки:

const theme = extendTheme({
  components: {
    Button: {
      variants: {
        danger: {
          bg: "red.500",
          color: "white",
          _hover: { bg: "red.600" },
        },
      },
    },
  },
});

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

<Button variant="danger">Удалить</Button>

Варианты с функцией

В Chakra UI можно использовать функции для вариантов, если нужно динамически менять стили на основе пропсов компонента:

const theme = extendTheme({
  components: {
    Button: {
      variants: {
        sizeBased: (props) => ({
          fontSize: props.size === "lg" ? "xl" : "sm",
          padding: props.size === "lg" ? "1.5rem" : "0.5rem",
        }),
      },
    },
  },
});

Применение:

<Button variant="sizeBased" size="lg">Большая кнопка</Button>
<Button variant="sizeBased" size="sm">Маленькая кнопка</Button>

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


Варианты для всех компонентов темы

Механизм вариантов работает не только с кнопками. Любой компонент Chakra UI может иметь свои варианты:

  • Input – текстовые поля
  • Badge – бейджи
  • Alert – уведомления
  • Menu – выпадающие меню

Пример для Input:

const theme = extendTheme({
  components: {
    Input: {
      variants: {
        filled: {
          field: {
            bg: "gray.100",
            _hover: { bg: "gray.200" },
            _focus: { bg: "white", borderColor: "blue.500" },
          },
        },
      },
    },
  },
});

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

<Input variant="filled" placeholder="Введите текст" />

Комбинация с size и colorScheme

В Chakra UI можно одновременно использовать размеры (size) и цветовые схемы (colorScheme) вместе с вариантами:

<Button variant="solid" size="lg" colorScheme="green">
  Подтвердить
</Button>
<Button variant="outline" size="sm" colorScheme="red">
  Отменить
</Button>
  • size управляет размерами (padding, fontSize, height).
  • colorScheme автоматически подбирает оттенки для bg, border и hover.

Наследование и переопределение вариантов

Если требуется переопределить стандартный вариант, можно расширить существующую тему без полной замены:

import { extendTheme, theme as baseTheme } from "@chakra-ui/react";

const theme = extendTheme({
  components: {
    Button: {
      variants: {
        solid: {
          ...baseTheme.components.Button.variants.solid,
          bg: "purple.500",
          _hover: { bg: "purple.600" },
        },
      },
    },
  },
});

Так сохраняется вся логика исходного варианта (solid), при этом меняются только нужные свойства.


Практические советы

  • Для больших проектов все варианты лучше описывать в теме, чтобы централизованно управлять стилями.
  • Использовать функциональные варианты для компонентов с зависимым стилем (props, colorScheme, size).
  • Сочетать варианты с size и colorScheme для максимальной гибкости.
  • Для пользовательских компонентов создавать собственные варианты по аналогии с Chakra, чтобы стили оставались унифицированными.

Варианты компонентов в Chakra UI делают архитектуру интерфейса более предсказуемой, модульной и удобной для масштабирования, позволяя управлять визуальными стилями без хаоса повторяющихся CSS.