Обработка нажатий разными способами

В библиотеке React Aria работа с событиями нажатий реализуется через хук useButton и связанные с ним низкоуровневые хуки, обеспечивающие доступность и корректную обработку взаимодействий на различных устройствах. Основная цель — унифицировать поведение кнопок, ссылок и интерактивных элементов независимо от платформы и способа ввода (мышь, клавиатура, сенсорный экран).


Хук useButton

useButton предоставляет объект с пропсами, которые можно напрямую передать интерактивному элементу. Он автоматически:

  • Обрабатывает клики мышью и касания;
  • Реагирует на нажатие клавиш Enter и Space;
  • Управляет фокусом и состоянием pressed;
  • Генерирует корректные ARIA-атрибуты для доступности.

Пример использования:

import { useButton } from "@react-aria/button";
import { useRef } from "react";

function MyButton({ onPress, children }) {
  let ref = useRef();
  let { buttonProps, isPressed } = useButton({ onPress }, ref);

  return (
    <button {...buttonProps} ref={ref} data-pressed={isPressed}>
      {children}
    </button>
  );
}

Здесь buttonProps содержит все необходимые обработчики событий (onClick, onKeyDown, onKeyUp) и атрибуты доступности (aria-pressed, role, tabIndex). isPressed позволяет визуально отражать состояние нажатия.


Поддержка разных способов ввода

React Aria различает следующие способы ввода:

  1. Мышь и сенсорные экраны

    • События pointerdown и pointerup обеспечивают одинаковое поведение для мыши и touch.
    • Хук usePress позволяет детектировать нажатие независимо от устройства.
import { usePress } from "@react-aria/interactions";

function Pressable({ onPress, children }) {
  let { pressProps, isPressed } = usePress({ onPress });

  return (
    <div {...pressProps} style={{ background: isPressed ? 'gray' : 'white' }}>
      {children}
    </div>
  );
}
  1. Клавиатура

    • Enter и Space автоматически обрабатываются, если элемент имеет правильную роль (button, link, menuitem).
    • Для элементов без семантической роли можно добавить role="button" и применить useButton для корректной работы.

Управление состоянием pressed и focus

React Aria позволяет точно отслеживать состояние нажатия и фокуса через хуки:

  • isPressedtrue, когда пользователь удерживает кнопку;
  • isFocusedtrue, если элемент в фокусе.

Пример комбинированного управления:

import { useButton } from "@react-aria/button";
import { useFocus } from "@react-aria/interactions";
import { useRef } from "react";

function InteractiveButton({ onPress, children }) {
  let ref = useRef();
  let { buttonProps, isPressed } = useButton({ onPress }, ref);
  let { focusProps, isFocused } = useFocus({});

  return (
    <button
      {...buttonProps}
      {...focusProps}
      ref={ref}
      style={{
        background: isPressed ? 'blue' : isFocused ? 'lightblue' : 'white',
      }}
    >
      {children}
    </button>
  );
}

Составные элементы и нажатия

Для сложных компонентов (например, выпадающих списков, слайдеров, табов) React Aria предоставляет низкоуровневый хук usePress и useSelectableItem для обработки интерактивных действий. Основные принципы:

  • Использовать usePress для любого элемента, который реагирует на нажатие, но не является семантической кнопкой.
  • Передавать в хук onPressStart, onPressEnd, onPressChange для точного контроля.
  • Для мультиэлементных списков использовать useSelectableCollection и useSelectableItem, чтобы отслеживать состояние выбора при нажатиях и удержаниях.

Преимущества подхода React Aria

  1. Кроссплатформенность — одинаковое поведение на десктопе, мобильных устройствах и планшетах.
  2. Доступность — автоматическая генерация ARIA-атрибутов.
  3. Управление состоянием — встроенные переменные isPressed, isFocused, isHovered для визуальной обратной связи.
  4. Гибкость — можно оборачивать любые DOM-элементы и кастомные компоненты.

Рекомендации по использованию

  • Всегда оборачивать интерактивные элементы в useButton или usePress, чтобы избежать ручной обработки всех событий.
  • Для нестандартных элементов явно указывать role и tabIndex.
  • Использовать состояния isPressed и isFocused для стилизации, не полагаясь на CSS-псевдоклассы, так как это гарантирует одинаковую работу на сенсорных устройствах.
  • Для составных компонентов комбинировать usePress с useSelectableItem и useFocus для полноценной поддержки взаимодействий.

Обработка нажатий в React Aria строится на едином принципе: унификация всех способов ввода через хуки, автоматическая поддержка доступности и точное управление состояниями pressed и focused. Такой подход позволяет создавать сложные и интерактивные интерфейсы, которые работают одинаково стабильно на всех устройствах.