Расширение функциональности

React Aria — это набор хуков для создания доступных компонентов пользовательского интерфейса в React. Он не предоставляет готовых визуальных компонентов, а фокусируется на управлении поведением, состоянием и доступностью, что позволяет расширять функциональность стандартных элементов и создавать собственные UI-компоненты с полной поддержкой ARIA.


Управление состоянием и поведением компонентов

В основе React Aria лежит концепция разделения состояния и рендеринга. Это позволяет создавать обёртки вокруг базовых HTML-элементов или сторонних компонентов, добавляя доступные взаимодействия.

Пример: использование хука useButton для кастомной кнопки.

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

function CustomButton(props) {
  const ref = useRef();
  const {buttonProps} = useButton(props, ref);

  return (
    <button {...buttonProps} ref={ref} style={{padding: '10px', fontSize: '16px'}}>
      {props.children}
    </button>
  );
}

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

  • useButton обеспечивает корректную обработку клавиатуры, фокуса и ARIA-атрибутов.
  • Состояние кнопки (pressed, disabled) синхронизируется с DOM без необходимости вручную писать обработчики событий.

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

React Aria предоставляет хуки для сложных UI-компонентов: селектов, чекбоксов, табов, модальных окон, тултипов и т.д. Эти хуки берут на себя:

  • Управление фокусом и клавиатурой.
  • Обновление ARIA-атрибутов в зависимости от состояния.
  • Поддержку локализации и адаптивного поведения.

Пример расширения стандартного селекта через useSelect:

import {useSelect} from '@react-aria/sel ect';
import {useState, useRef} fr om 'react';

function CustomSelect({items}) {
  const [selectedKey, setSelectedKey] = useState(null);
  const ref = useRef();
  const {labelProps, triggerProps, valueProps, menuProps} = useSelect(
    {items, selectedKey, onSelectionChange: setSelectedKey},
    ref
  );

  return (
    <div>
      <label {...labelProps}>Выберите элемент:</label>
      <button {...triggerProps} ref={ref}>
        {selectedKey || 'Ничего не выбрано'}
      </button>
      <ul {...menuProps}>
        {items.map(item => (
          <li key={item.key}>{item.name}</li>
        ))}
      </ul>
    </div>
  );
}

Особенности расширения:

  • Возможность кастомной визуализации списка.
  • Лёгкое добавление анимаций и стилизации без потери доступности.
  • Управление выбранным элементом через внутреннее состояние компонента.

Состояние взаимодействия и доступность

React Aria активно использует хуки useFocus, useHover, usePress для управления интерактивными состояниями:

  • useFocus отслеживает фокус и позволяет динамически менять стили.
  • useHover регистрирует наведение мыши, обеспечивая визуальную обратную связь.
  • usePress объединяет события клика, касания и клавиатуры в единый API.

Пример сочетания хуков для интерактивного элемента:

import {useFocus, useHover, usePress} from '@react-aria/interactions';
import {useRef, useState} from 'react';

function InteractiveBox() {
  const ref = useRef();
  const [isFocused, setFocused] = useState(false);
  const [isHovered, setHovered] = useState(false);
  const {focusProps} = useFocus({onFocusChange: setFocused});
  const {hoverProps} = useHover({onHoverChange: setHovered});
  const {pressProps} = usePress({onPress: () => alert('Нажато!')});

  const style = {
    width: '150px',
    height: '150px',
    backgroundColor: isFocused ? 'blue' : isHovered ? 'lightblue' : 'grey',
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
    cursor: 'pointer',
    userSelect: 'none'
  };

  return <div {...focusProps} {...hoverProps} {...pressProps} ref={ref} style={style}>Нажми меня</div>;
}

Преимущества:

  • Сложное поведение и визуальные состояния управляются декларативно.
  • Поддержка доступности без необходимости прописывать ARIA-атрибуты вручную.
  • Лёгкое объединение нескольких интерактивных хуков для одного компонента.

Кастомные модальные окна и диалоги

Использование useOverlay и useDialog позволяет расширять стандартные модальные окна с поддержкой доступности:

import {useOverlay, useDialog} from '@react-aria/overlays';
import {useRef} from 'react';

function CustomModal({isOpen, onClose, children}) {
  const ref = useRef();
  const {overlayProps} = useOverlay({isOpen, onClose, isDismissable: true}, ref);
  const {dialogProps, titleProps} = useDialog({}, ref);

  if (!isOpen) return null;

  return (
    <div {...overlayProps} style={{position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, background: 'rgba(0,0,0,0.3)'}}>
      <div {...dialogProps} ref={ref} style={{background: 'white', padding: '20px', margin: '50px auto', width: '300px'}}>
        <h2 {...titleProps}>Заголовок модального окна</h2>
        {children}
        <button onCl ick={onClose}>Закрыть</button>
      </div>
    </div>
  );
}

Расширение функциональности модальных окон:

  • Автоматическое управление фокусом при открытии и закрытии.
  • Поддержка закрытия при клике вне окна или на клавишу Escape.
  • Возможность сочетания с анимациями и кастомной стилизацией.

Локализация и адаптивность

React Aria учитывает локализацию и направления текста (LTR/RTL). Например, useDatePicker автоматически подстраивает календарь под региональные настройки. Это позволяет расширять стандартные компоненты без переписывания логики работы с датами и форматами.


Составные компоненты и композиция хуков

Ключевой принцип расширения функциональности — композиция хуков. Один компонент может объединять useButton, useFocus, useHover и useOverlay, создавая уникальный, доступный UI:

  • Компоненты остаются легкими, декларативными и предсказуемыми.
  • Состояние компонентов централизовано через хуки, а не через сложные классы.
  • Расширение стандартных HTML-элементов становится простым и гибким.

Практическая стратегия расширения

  1. Выделение состояния и поведения — все интерактивные состояния выносятся в хуки.
  2. Добавление кастомной визуализации — React Aria управляет логикой, а рендер выполняется через JSX.
  3. Композиция хуков — объединение нескольких хуков для сложных компонентов.
  4. Поддержка доступности — автоматическое добавление ARIA-атрибутов.
  5. Адаптация под локализацию и устройства — хуки учитывают направление текста, сенсорные устройства и клавиатуру.

Эта стратегия позволяет создавать масштабируемые, доступные и полностью настраиваемые компоненты, расширяя стандартные возможности React без потери производительности и UX.