Выделение строк

React Aria предоставляет набор хуков и утилит для управления доступностью интерактивных компонентов. Для работы с выделением строк в списках, таблицах или коллекциях используется комбинация хуков useSelectableCollection, useSelectableItem и useListState. Эти инструменты позволяют управлять состоянием выделения, фокусом и поддержкой клавиатурной навигации.

useListState формирует состояние коллекции элементов, поддерживая операции выделения:

import { useListState } from '@react-stately/list';

const listState = useListState({
  selectionMode: 'multiple', // 'single' или 'multiple'
  initialSelectedKeys: ['1', '3'],
  items: [
    { id: '1', name: 'Элемент 1' },
    { id: '2', name: 'Элемент 2' },
    { id: '3', name: 'Элемент 3' }
  ]
});

Ключевые параметры:

  • selectionMode — режим выделения (single или multiple).
  • initialSelectedKeys — массив ключей, которые будут выделены изначально.
  • items — массив объектов коллекции с уникальными ключами.

Хуки для управления выделением

useSelectableCollection предоставляет контекст для всей коллекции и позволяет интегрировать клавиатурные события и фокусировку:

import { useSelectableCollection } from '@react-aria/selection';

const collectionProps = useSelectableCollection(
  { selectionMode: 'multiple', disabledKeys: new Set(['2']) },
  listState,
  ref
);

Основные возможности:

  • Автоматическая обработка клавиш ArrowUp, ArrowDown, Home, End.
  • Поддержка выделения несколькими элементами через Shift+Click/Shift+Arrow.
  • Игнорирование неактивных или отключённых элементов.

useSelectableItem применяется на уровне каждой строки, чтобы управлять её состоянием выделения и фокусом:

import { useSelectableItem } from '@react-aria/selection';

const { itemProps, isSelected, isDisabled } = useSelectableItem(
  { key: item.id },
  listState,
  ref
);
  • itemProps — набор пропсов для элемента, включая обработчики клика, фокуса и клавиатуры.
  • isSelected — булево значение, указывающее, выделен ли элемент.
  • isDisabled — указывает, доступен ли элемент для выделения.

Пример интеграции с компонентом строки

function Row({ item, state }) {
  const ref = React.useRef();
  const { itemProps, isSelected } = useSelectableItem({ key: item.id }, state, ref);

  return (
    <div
      {...itemProps}
      ref={ref}
      style={{
        backgroundColor: isSelected ? '#D0E1FF' : 'transparent',
        padding: '8px',
        cursor: 'pointer'
      }}
    >
      {item.name}
    </div>
  );
}

Элементы автоматически получают доступность через атрибуты aria-selected и role="option" для списков, что полностью соответствует требованиям WCAG.

Работа с коллекцией

function List({ items }) {
  const ref = React.useRef();
  const state = useListState({ items, selectionMode: 'multiple' });
  const { collectionProps } = useSelectableCollection({ selectionMode: 'multiple' }, state, ref);

  return (
    <div {...collectionProps} ref={ref} role="listbox">
      {items.map(item => <Row key={item.id} item={item} state={state} />)}
    </div>
  );
}

Особенности работы коллекции:

  • Каждая строка автоматически отслеживает выделение через state.selectedKeys.
  • Поддержка множественного выделения с клавиатуры и мыши.
  • Легкая интеграция с виртуализированными списками и динамическим добавлением элементов.

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

React Aria автоматически управляет следующими сценариями:

  • ArrowUp/ArrowDown — перемещение фокуса между строками.
  • Space/Enter — выделение или снятие выделения текущей строки.
  • Shift+Arrow — расширение выделения для множественных элементов.
  • Home/End — перемещение фокуса к первому или последнему элементу.

Каждый элемент получает атрибут aria-selected, что позволяет вспомогательным технологиям корректно интерпретировать состояние выделения.

Настройка кастомного поведения

Можно расширять функциональность:

  • Прописывать собственные стили для выделенных строк.
  • Отключать выделение отдельных элементов через disabledKeys.
  • Управлять фокусом программно с помощью state.setFocusedKey(key).

Использование React Aria для выделения строк обеспечивает:

  • Полную доступность элементов списка.
  • Удобную работу с множественным выделением.
  • Единый подход для всех коллекций, включая таблицы, списки и меню.

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