Урок 18. Справочник: конструкции внутри компонентов

📁 Раздел: shadcn/ui ⏱️ Время изучения: ~55 мин 🎯 Сложность: Продвинутая

⚡ Кратко

Справочник конструкций, которые встречаются в исходниках реестра: произвольные селекторы, слоты, переменные компонента, состояния примитивов.

Произвольные селекторы и варианты

ЗаписьЗначение
[&_svg]:size-4любой svg внутри элемента
[&>svg]:size-3только прямой потомок svg
[&_svg:not([class*='size-'])]:size-4иконка, у которой не задан свой размер
[.border-b]:pb-4если у элемента есть класс border-b
*:rounded-t-xlвсе прямые дети
**:text-smвсе потомки
in-data-[slot=button-group]:rounded-lgесли элемент находится внутри группы кнопок

Слоты и состояния

ЗаписьЗначение
data-slot="card-header"метка части компонента
has-data-[slot=card-footer]:pb-0у элемента внутри есть часть-футер
group-data-[size=sm]/card:text-smименованная группа плюс атрибут родителя
data-open:animate-inсостояние примитива Base UI: открыт
data-closed:animate-outсостояние: закрывается
data-[state=open]:rotate-180состояние в старом стиле (Radix)
aria-expanded:bg-mutedоформление по ARIA-атрибуту
aria-invalid:border-destructiveошибка формы

Переменные компонента

ЗаписьЗначение
[--card-spacing:--spacing(4)]объявить переменную со значением из шкалы
py-(--card-spacing)использовать переменную как значение утилиты
bg-(--brand)то же для цвета
--spacing(4)функция темы: 4 шага шкалы отступов
Круглые скобки — сокращение для var(): py-(--card-spacing) эквивалентно py-[var(--card-spacing)], только читается легче.

Структура компонента-канона

// 1. импорты: примитив, cva, cn
// 2. описание вариантов через cva
// 3. функция-компонент с data-slot и cn()
// 4. экспорт компонента и (при необходимости) его вариантов
export { Button, buttonVariants }

Полиморфизм

APIПримерГде встречается
render<Button render={<a href="/x" />} />Base UI, актуальные версии
asChild<Button asChild><a href="/x">…</a></Button>Radix, старые версии

Типы

type ButtonProps =
  & ButtonPrimitive.Props                      // всё, что принимает примитив
  & VariantProps<typeof buttonVariants>        // variant и size из cva

Для компонентов без примитива используется React.ComponentProps<"div"> — тип обычного элемента.