Стилизация состояний

Radix UI предоставляет набор высококачественных, доступных компонентов для React, при этом ключевой особенностью является разделение логики компонента и визуальной реализации. Это особенно важно при работе с состояниями компонентов: активный, наведённый, выбранный, фокусированный и т.д. В Radix UI управление состояниями реализовано через атрибуты состояния, а не через собственные CSS-классы, что обеспечивает гибкость в стилизации.


Атрибуты состояния компонентов

Каждый компонент Radix UI предоставляет набор data-атрибутов, отражающих текущие состояния. Примеры наиболее часто встречающихся:

  • data-state – отображает внутреннее состояние компонента (open, closed, active, inactive).
  • data-disabled – указывает на отключённый элемент.
  • data-highlighted – выделенный элемент (например, в списке меню или селекта).
  • data-value – текущее значение элемента управления.
  • data-pressed – используется для кнопок, отражает состояние нажатия.
  • data-focus – элемент в фокусе клавиатуры или программно.

Эти атрибуты можно использовать в CSS-селекторах для точного управления стилями в зависимости от состояния, что делает компоненты Radix UI полностью кастомизируемыми.

/* Пример стилизации кнопки */
.button[data-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
}

.button[data-pressed="true"] {
  background-color: #0044cc;
}

.button[data-focus="true"] {
  outline: 2px solid #ff8800;
}

Состояния открытия и закрытия

Для компонентов, таких как DropdownMenu, Dialog, Accordion, состояние открытия/закрытия является ключевым. Radix UI использует data-state="open" и data-state="closed" для этих элементов.

/* Стилизация выпадающего меню */
.dropdown[data-state="open"] {
  opacity: 1;
  transform: translateY(0);
  transition: opacity 0.2s ease, transform 0.2s ease;
}

.dropdown[data-state="closed"] {
  opacity: 0;
  transform: translateY(-10px);
}
  • transition позволяет создавать плавные анимации открытия и закрытия.
  • Важно использовать именно data-state, а не пытаться следить за локальным состоянием через React, чтобы стили оставались консистентными с логикой Radix UI.

Ховер и фокус

Radix UI компоненты поддерживают стандартные псевдоклассы CSS :hover, :focus, но для комплексных взаимодействий предпочтительнее использовать data-атрибуты, которые отражают состояние взаимодействия, например, data-highlighted или data-focus.

/* Стилизация элементов меню */
.menu-item[data-highlighted="true"] {
  background-color: #f0f0f0;
  color: #222;
}

.menu-item[data-disabled="true"] {
  color: #aaa;
  pointer-events: none;
}
  • data-highlighted часто используется для навигации с клавиатуры в списках и меню.
  • data-disabled предотвращает нежелательные клики и визуально сигнализирует о недоступности.

Состояние выбора

Для компонентов типа Checkbox, RadioGroup, Toggle, состояние выбора управляется через data-state="checked" или data-state="unchecked".

/* Стилизация переключателя */
.toggle[data-state="checked"] {
  background-color: #22aa22;
}

.toggle[data-state="unchecked"] {
  background-color: #ccc;
}
  • Использование data-state обеспечивает точное соответствие визуального состояния и внутренней логики компонента.
  • Можно комбинировать с :focus и :hover для создания сложных интерактивных эффектов.

Анимации и переходы

Radix UI полностью поддерживает CSS-анимации и transition, что позволяет легко создавать динамичные интерфейсы.

/* Анимация появления контента аккордеона */
.accordion-content[data-state="open"] {
  max-height: 500px;
  transition: max-height 0.3s ease;
}

.accordion-content[data-state="closed"] {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease;
}
  • Использование max-height для аккордеонов обеспечивает плавное раскрытие и сворачивание.
  • Важно, что Radix UI управляет data-state, а CSS отвечает за визуальный отклик.

Комбинированная стилизация

Для сложных компонентов можно комбинировать несколько атрибутов состояния:

/* Кнопка с состоянием нажатия и фокуса */
.button[data-pressed="true"][data-focus="true"] {
  background-color: #0044cc;
  outline: 3px solid #ff8800;
}
  • Это позволяет создавать уникальные эффекты без изменения внутренней логики компонента.
  • Сочетание нескольких состояний повышает гибкость интерфейса и улучшает UX.

Использование CSS-in-JS

При применении библиотек вроде Stitches, Emotion или Tailwind атрибуты состояния Radix UI могут быть использованы как варианты в styled-компонентах.

import { styled } from '@stitches/react';

const Button = styled('button', {
  variants: {
    pressed: {
      true: { backgroundColor: '#0044cc' },
      false: { backgroundColor: '#0077ff' },
    },
    focus: {
      true: { outline: '2px solid #ff8800' },
    },
  },
});
  • Атрибуты data-pressed и data-focus можно связывать с этими вариантами для автоматической стилизации.
  • Подход позволяет полностью интегрировать Radix UI с современными системами CSS-in-JS, сохраняя контроль над состояниями.

С помощью атрибутов состояния Radix UI, плавных анимаций и гибкой системы CSS можно создавать полностью кастомизируемые, доступные интерфейсы, где визуальное поведение компонентов всегда синхронизировано с их внутренней логикой.