Множественное выделение (multi-selection) — ключевой элемент взаимодействия с компонентами списка, таблицы и меню, где пользователю необходимо выбрать несколько элементов одновременно. В React Aria это реализуется через хуки, обеспечивающие корректную работу с доступностью (accessibility) и управление состоянием без ручного написания сложной логики.
useMultipleSelectionStateДля управления состоянием множественного выбора применяется хук
useMultipleSelectionState. Он позволяет хранить текущие
выделенные элементы и управлять добавлением или удалением элементов из
выделенной группы.
Пример инициализации состояния:
import {useMultipleSelectionState} from '@react-stately/selection';
const state = useMultipleSelectionState({
selectedKeys: new Set(),
onSelectionChange: keys => console.log(keys),
disallowEmptySelection: false
});
Параметры:
selectedKeys — множество ключей выбранных
элементов.onSelectionChange — callback, который вызывается при
изменении выделения.disallowEmptySelection — если true, нельзя
снять выделение со всех элементов.Хук возвращает объект state с методами:
isSelected(key) — проверяет, выделен ли элемент.toggleKey(key) — переключает состояние выделения для
указанного ключа.selectAll() — выделяет все элементы.clearSelection() — снимает выделение со всех
элементов.React Aria предлагает использовать useListBox вместе с
useMultipleSelectionState для реализации списков с
множественным выделением.
Пример базового списка:
import {useListBox, useListBoxSection} from '@react-aria/listbox';
import {useMultipleSelectionState} from '@react-stately/selection';
const items = [
{id: '1', name: 'Элемент 1'},
{id: '2', name: 'Элемент 2'},
{id: '3', name: 'Элемент 3'}
];
function MultiSelectList() {
const state = useMultipleSelectionState({selectedKeys: new Set()});
return (
<ul role="listbox" aria-multiselectable="true">
{items.map(item => (
<li
key={item.id}
role="option"
aria-selected={state.isSelected(item.id)}
onCl ick={() => state.toggleKey(item.id)}
>
{item.name}
</li>
))}
</ul>
);
}
Ключевые моменты:
aria-multiselectable="true" обязателен для
корректной доступности.role="option" у каждого элемента списка.aria-selected отражает текущее состояние
выделения.Выделение диапазона с Shift: Для поддержки
выделения диапазона необходимо использовать
useSelectableCollectionState и обработчики клавиатуры.
React Aria предоставляет утилиты, позволяющие отслеживать последнюю
выбранную позицию и добавлять элементы между текущей и предыдущей
выделенной позицией при зажатом Shift.
Комбинация Ctrl/Cmd + Click:
toggleKey автоматически корректно добавляет или убирает
элемент из множества выбранных при использовании клавиши
модификатора.
Select All / Deselect All: Методы
selectAll() и clearSelection() позволяют
реализовать кнопки или хоткеи для быстрого управления
выделением.
<button onCl ick={() => state.selectAll()}>Выделить все</button>
<button onCl ick={() => state.clearSelection()}>Снять выделение</button>
React Aria обеспечивает полную поддержку клавиатурного взаимодействия.
selectAll()).Set вместо
массива для повышения производительности при проверках
isSelected.aria-selected="true" можно стилизовать через
CSS, например, добавлять фон или рамку.li[aria-selected="true"] {
background-color: #e0f7fa;
}
Множественное выделение можно комбинировать с:
useFocusRing — для визуального отображения фокуса.useKeyboard — для расширенной обработки
клавиатуры.useOverlay — для списков в выпадающих меню или
модальных окнах.Такое сочетание позволяет строить полностью интерактивные, доступные и гибкие компоненты списка и меню, которые корректно работают как с мышью, так и с клавиатурой.