Обработка действий пользователя

Radix UI предоставляет низкоуровневые, но мощные компоненты для построения интерактивных интерфейсов на JavaScript и React. Ключевая особенность библиотеки — управление пользовательскими действиями через строго типизированные пропсы и события, что позволяет создавать сложные компоненты с предсказуемым поведением.

События и управление состоянием

В Radix UI почти каждый компонент управляет состоянием через controlled и uncontrolled подходы.

  • Controlled: состояние компонента управляется извне через пропсы value и события onValueChange.
  • Uncontrolled: компонент управляет своим состоянием самостоятельно, при этом внешние события могут быть перехвачены через колбэки.

Пример использования onValueChange для компонента Toggle:

import * as Toggle from '@radix-ui/react-toggle';
import { useState } from 'react';

function ToggleExample() {
  const [checked, setChecked] = useState(false);

  return (
    <Toggle.Root
      pressed={checked}
      onPressedCha nge={(state) => setChecked(state)}
    >
      {checked ? 'Включено' : 'Выключено'}
    </Toggle.Root>
  );
}

Здесь onPressedChange — основной механизм реагирования на действия пользователя. Любое изменение состояния кнопки проходит через этот обработчик, что обеспечивает синхронизацию с внешним состоянием.

Обработка кликов и взаимодействий мышью

Для компонентов, таких как Button, Checkbox, RadioGroup, Radix UI использует нативные события onClick и специфичные колбэки:

  • onClick — стандартный клик, который срабатывает при активации элемента пользователем.
  • onValueChange — изменение состояния, например, переключение чекбокса или радио-кнопки.

Особое внимание уделяется доступности: все интерактивные компоненты поддерживают управление с клавиатуры и сенсорных устройств, поэтому события onKeyDown, onFocus и onBlur тесно интегрированы с внутренней логикой компонентов.

Контекст и вложенные компоненты

Radix UI активно использует контекст для передачи состояний между корневым компонентом и дочерними элементами. Пример с DropdownMenu:

import * as DropdownMenu from '@radix-ui/react-dropdown-menu';

function MenuExample() {
  return (
    <DropdownMenu.Root>
      <DropdownMenu.Trigger>Меню</DropdownMenu.Trigger>
      <DropdownMenu.Content>
        <DropdownMenu.Item onSel ect={() => console.log('Выбран 1')}>
          Пункт 1
        </DropdownMenu.Item>
        <DropdownMenu.Item onSel ect={() => console.log('Выбран 2')}>
          Пункт 2
        </DropdownMenu.Item>
      </DropdownMenu.Content>
    </DropdownMenu.Root>
  );
}
  • DropdownMenu.Trigger инициирует открытие меню.
  • DropdownMenu.Item реагирует на событие onSelect, что является встроенной обработкой пользовательского действия выбора.
  • Контекст гарантирует синхронизацию состояний между Trigger и Content, включая управление фокусом и закрытие меню при клике вне.

Делегирование событий

Radix UI минимизирует необходимость ручной подписки на нативные DOM-события. Вместо этого используется делегирование через внутренние колбэки, что повышает производительность и предотвращает дублирование логики.

Пример для Tabs:

import * as Tabs from '@radix-ui/react-tabs';
import { useState } from 'react';

function TabsExample() {
  const [tab, setTab] = useState('tab1');

  return (
    <Tabs.Root value={tab} onValueCha nge={setTab}>
      <Tabs.List>
        <Tabs.Trigger value="tab1">Вкладка 1</Tabs.Trigger>
        <Tabs.Trigger value="tab2">Вкладка 2</Tabs.Trigger>
      </Tabs.List>
      <Tabs.Content value="tab1">Контент 1</Tabs.Content>
      <Tabs.Content value="tab2">Контент 2</Tabs.Content>
    </Tabs.Root>
  );
}

onValueChange делегирует обработку смены активной вкладки, включая установку фокуса и скрытие неактивного контента.

Поддержка клавиатурных действий

Все компоненты Radix UI соответствуют стандартам WAI-ARIA, что обеспечивает полное управление через клавиатуру:

  • ArrowUp / ArrowDown для навигации в списках и меню.
  • Enter и Space для активации элементов.
  • Escape для закрытия всплывающих элементов (меню, диалогов, поповеров).

Пример кастомного обработчика в Dialog:

import * as Dialog from '@radix-ui/react-dialog';

function DialogExample() {
  return (
    <Dialog.Root>
      <Dialog.Trigger>Открыть</Dialog.Trigger>
      <Dialog.Content onEscapeKeyD own={() => console.log('Закрытие')}>
        Содержимое диалога
      </Dialog.Content>
    </Dialog.Root>
  );
}

onEscapeKeyDown позволяет перехватывать нажатие клавиши Escape до выполнения стандартного закрытия, предоставляя гибкость в логике реакции на действия пользователя.

События фокуса и управление доступностью

Radix UI тщательно отслеживает фокусировку элементов. Компоненты предоставляют колбэки:

  • onFocus — срабатывает при получении фокуса элементом.
  • onBlur — при потере фокуса.
  • onPointerDown — реагирует на нажатие мышью или сенсорное касание, позволяя реализовать кастомные эффекты до события клика.

Пример с Tooltip:

import * as Tooltip from '@radix-ui/react-tooltip';

function TooltipExample() {
  return (
    <Tooltip.Root>
      <Tooltip.Trigger onFo cus={() => console.log('Фокус')}>
        Наведи или фокус
      </Tooltip.Trigger>
      <Tooltip.Content>Подсказка</Tooltip.Content>
    </Tooltip.Root>
  );
}

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

Итоговые принципы

  1. Все пользовательские действия обрабатываются через колбэки, предоставляемые компонентами.
  2. Состояние может быть контролируемым или неконтролируемым, с гибкой синхронизацией.
  3. Контекст и делегирование событий обеспечивают согласованное поведение сложных интерфейсов.
  4. Полная поддержка клавиатурных и сенсорных действий гарантирует доступность и совместимость с WAI-ARIA.
  5. Управление фокусом и обработка специальных клавиш позволяют тонко настраивать реакцию на действия пользователя.

Обработка действий пользователя в Radix UI строится на принципах предсказуемости, доступности и максимальной гибкости при минимальном вмешательстве в низкоуровневую логику.