Множественный выбор

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

Использование useMultipleSelection

Для реализации множественного выбора в React Aria применяется хук useMultipleSelection. Он управляет состоянием выбранных элементов и предоставляет методы для добавления, удаления и управления элементами:

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

function MultiSelect({ items }) {
  const [selectedItems, setSelectedItems] = useState([]);
  const { selectedKeys, addSelectedKey, removeSelectedKey } = useMultipleSelection({
    selectedKeys: selectedItems,
    onSelectionChange: setSelectedItems
  });

  return (
    <ul>
      {items.map(item => (
        <li key={item.key}>
          <input
            type="checkbox"
            checked={selectedKeys.has(item.key)}
            onCha nge={(e) =>
              e.target.checked ? addSelectedKey(item.key) : removeSelectedKey(item.key)
            }
          />
          {item.name}
        </li>
      ))}
    </ul>
  );
}

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

  • selectedKeys — множество выбранных ключей, синхронизированное со внутренним состоянием.
  • addSelectedKey и removeSelectedKey — функции для управления выбором.
  • Управление через onSelectionChange позволяет интегрировать компонент с внешним состоянием.

Связь с useListState

Для более сложных компонентов, таких как комбинированные списки с множественным выбором, рекомендуется использовать useListState, который обеспечивает управление состоянием элементов, фильтрацией и сортировкой:

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

const state = useListState({ items });

Комбинируя useListState с useMultipleSelection, можно получить полностью управляемый список с поддержкой выделения нескольких элементов и навигации с клавиатуры.

Доступность и клавиатурные взаимодействия

React Aria обеспечивает соблюдение стандартов ARIA. При реализации множественного выбора следует учитывать:

  • aria-multiselectable="true" для контейнера списка.

  • aria-selected для каждого элемента, отражающее текущее состояние выбора.

  • Полная поддержка клавиатурных событий:

    • ArrowUp / ArrowDown — перемещение между элементами.
    • Space — переключение выбора текущего элемента.
    • Shift + Arrow — выделение диапазона элементов.

Пример:

<ul role="listbox" aria-multiselectable="true">
  {items.map(item => (
    <li
      role="option"
      aria-selected={selectedKeys.has(item.key)}
      key={item.key}
      onKeyD own={(e) => {
        if (e.key === ' ') {
          selectedKeys.has(item.key) ? removeSelectedKey(item.key) : addSelectedKey(item.key);
          e.preventDefault();
        }
      }}
      tabIndex={0}
    >
      {item.name}
    </li>
  ))}
</ul>

Интеграция с компонентами UI

Для визуального представления множественного выбора часто используют чекбоксы или теги выбранных элементов. React Aria предоставляет абстракции, которые позволяют отделить логику состояния от визуального компонента, что облегчает переиспользование и тестирование.

Пример отображения выбранных элементов:

<div>
  {Array.from(selectedKeys).map(key => (
    <span key={key} className="selected-item">
      {items.find(item => item.key === key).name}
    </span>
  ))}
</div>

Работа с динамическими списками

Множественный выбор должен корректно работать с динамическими изменениями списка:

  • Добавление или удаление элементов не должно сбрасывать выбор других элементов.
  • Использование уникальных ключей (key) критично для корректного управления состоянием.
  • useMultipleSelection автоматически обновляет внутреннее состояние при изменении ключей.

Полезные советы

  • Всегда синхронизировать selectedKeys с внешним состоянием, если компонент интегрируется в большую систему.
  • Для больших списков использовать виртуализацию (например, react-virtualized) совместно с React Aria.
  • При необходимости реализации «Выделить все» или «Снять выделение» использовать методы selectAll и clearSelection из useMultipleSelectionState.

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