Программное управление выделением

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


useSelection и управление выделением

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

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

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

function SelectableList({items}) {
  const state = useSelectionState({selectionMode: 'multiple', items});
  const ref = useRef();
  const {collectionProps, selectionManager} = useSelectableCollection({selectionManager: state}, ref);

  return (
    <ul {...collectionProps} ref={ref}>
      {items.map(item => (
        <li key={item.key}>
          <input
            type="checkbox"
            checked={state.isSelected(item.key)}
            onCha nge={() => state.toggleSelection(item.key)}
          />
          {item.name}
        </li>
      ))}
    </ul>
  );
}

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

  • selectionMode определяет тип выбора: 'single', 'multiple', 'none'.
  • useSelectionState управляет внутренним состоянием выделения.
  • toggleSelection(key) программно переключает выделение элемента.
  • isSelected(key) проверяет, выделен ли элемент.

Программное выделение элементов

Выделение может управляться не только через пользовательские действия, но и программно. React Aria предоставляет методы setSelectedKeys, toggleSelection и clearSelection:

// Выделение всех элементов
state.setSelectedKeys(items.map(item => item.key));

// Снятие выделения
state.clearSelection();

// Переключение выделения конкретного элемента
state.toggleSelection('item-3');

Особенности:

  • setSelectedKeys заменяет текущее выделение полностью.
  • toggleSelection изменяет состояние одного элемента без влияния на другие.
  • clearSelection очищает весь выбор.

Выделение с клавиатуры и мышью

React Aria учитывает стандартные паттерны взаимодействия:

  • Клавиши стрелок: навигация по списку.
  • Shift + стрелки: расширение диапазона выделения.
  • Ctrl/Cmd + клик: добавление или снятие выделения отдельных элементов.
  • Мышь с drag: выделение диапазона элементов при клике и протягивании.

Использование useSelectableCollection автоматически подключает эти паттерны, гарантируя доступность для клавиатуры и вспомогательных технологий.


Интеграция с виртуализированными списками

Для больших коллекций важно комбинировать выделение с виртуализацией:

import {FixedSizeList as List} from 'react-window';

<List
  height={400}
  itemCount={items.length}
  itemSize={35}
>
  {({index, style}) => {
    const item = items[index];
    return (
      <div style={style}>
        <input
          type="checkbox"
          checked={state.isSelected(item.key)}
          onCha nge={() => state.toggleSelection(item.key)}
        />
        {item.name}
      </div>
    );
  }}
</List>

Особенности:

  • Состояние выделения хранится отдельно от визуальных компонентов.
  • Можно безопасно выделять элементы, которые временно не отображаются.

Работа с диапазоном выделения

Для расширенного управления доступна логика диапазонного выделения:

state.setSelectionRange(startKey, endKey);
  • Выбираются все элементы между startKey и endKey.
  • Совместимо с multiple режимом.
  • Поддерживается как программное управление, так и через Shift + клик.

События и обратные вызовы

React Aria предоставляет события для отслеживания изменений выделения:

<SelectableList
  onSelectionCha nge={(keys) => console.log('Выделенные элементы:', keys)}
/>
  • onSelectionChange вызывается при любом изменении выделения.
  • Позволяет синхронизировать состояние с внешними компонентами.

Управление фокусом и выделением

Важно различать фокус и выделение:

  • Фокус обозначает текущий активный элемент для взаимодействия.
  • Выделение отражает выбор пользователя в компоненте.

React Aria предоставляет методы:

state.setFocusedKey('item-2');
state.focusNext();
state.focusPrevious();
  • Поддержка клавиатурной навигации без вмешательства в выделение.
  • Обеспечение совместимости с вспомогательными технологиями.

Примеры комплексного программного управления

  1. Выбор всех элементов через кнопку:
<button onCl ick={() => state.setSelectedKeys(items.map(i => i.key))}>
  Выбрать все
</button>
  1. Снятие выделения выделенных элементов:
<button onCl ick={() => state.clearSelection()}>
  Снять выделение
</button>
  1. Выделение диапазона программно:
state.setSelectionRange('item-1', 'item-5');
  1. Синхронизация с внешним состоянием:
useEffect(() => {
  externalState.update(state.selectedKeys);
}, [state.selectedKeys]);

Выводы по программному управлению выделением

Программное управление выделением в React Aria позволяет:

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

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