Item компонент

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


Основные свойства Item

Компонент Item не рендерит визуальный элемент сам по себе, он служит контейнером для данных и свойств, которые будут использованы родительским компонентом. Основные свойства:

  • key – уникальный идентификатор элемента, обязательный для корректной работы с виртуальными списками и отслеживания состояния выделения.
  • textValue – строковое представление элемента, которое используется для поиска и фильтрации. Если не указано, React Aria использует children.
  • children – JSX-контент, который будет визуально отображаться пользователю. Это может быть простой текст или сложный компонент.
  • isDisabled – булево значение, запрещающее выбор элемента. Элемент остаётся видимым, но недоступным для взаимодействия.
  • value – значение элемента, передаваемое родительскому компоненту при выборе.

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

import { Item } from '@react-aria/collections';

<Item key="1" textValue="Apple" value={{ id: 1, name: 'Apple' }}>
  Apple
</Item>
<Item key="2" textValue="Banana" value={{ id: 2, name: 'Banana' }} isDisabled>
  Banana
</Item>
<Item key="3" textValue="Cherry" value={{ id: 3, name: 'Cherry' }}>
  Cherry
</Item>

В этом примере создаётся список фруктов, где Banana помечен как недоступный для выбора.


Интеграция с ListBox и Select

Компонент Item работает только в контексте коллекций React Aria, таких как ListBox или Menu. Он автоматически передаёт свои свойства родителю через внутренний контекст, что позволяет управлять:

  • выделением (selection)
  • фокусом (focus)
  • фильтрацией (search)
  • доступностью (aria-* атрибуты)

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

import { ListBox, useListBox, useListBoxSection } from '@react-aria/listbox';
import { useListState } from '@react-stately/list';

const fruits = [
  { id: '1', name: 'Apple' },
  { id: '2', name: 'Banana', isDisabled: true },
  { id: '3', name: 'Cherry' }
];

function FruitListBox() {
  const state = useListState({ items: fruits });
  const ref = React.useRef();
  const { listBoxProps } = useListBox({ autoFocus: true }, state, ref);

  return (
    <ul {...listBoxProps} ref={ref}>
      {state.collection.map(item => (
        <Item key={item.id} textValue={item.name} value={item}>
          {item.name}
        </Item>
      ))}
    </ul>
  );
}

Здесь Item автоматически получает все необходимые aria-* атрибуты и поддержку клавиатурной навигации от ListBox.


Использование textValue для поиска и фильтрации

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

<Item key="4" textValue="Dragon Fruit" value={{ id: 4 }}>
  <strong>Dragon Fruit</strong>
</Item>

Даже если визуальный контент сложный (например, с HTML-разметкой или компонентами), textValue обеспечивает корректное поведение поиска и выделения.


Обработка состояния isDisabled

Свойство isDisabled не просто делает элемент визуально серым, оно интегрируется с системой управления фокусом. Недоступный элемент:

  • не может быть выбран через клавиатуру или мышь
  • не получает фокус
  • получает корректные aria-disabled="true" атрибуты для доступности
<Item key="5" textValue="Elderberry" value={{ id: 5 }} isDisabled>
  Elderberry
</Item>

При этом родительская коллекция корректно пропускает недоступные элементы при навигации стрелками.


Комплексные примеры: группировка и секции

React Aria позволяет комбинировать Item с Section для создания вложенных списков. Это удобно для меню с заголовками или сложных селекторов:

import { Section, Item } from '@react-aria/collections';

<Section key="citrus" title="Citrus Fruits">
  <Item key="1" textValue="Orange" value={{ id: 1 }}>Orange</Item>
  <Item key="2" textValue="Lemon" value={{ id: 2 }}>Lemon</Item>
</Section>

<Section key="berries" title="Berries">
  <Item key="3" textValue="Strawberry" value={{ id: 3 }}>Strawberry</Item>
  <Item key="4" textValue="Blueberry" value={{ id: 4 }}>Blueberry</Item>
</Section>

Каждая секция получает поддержку доступности автоматически, а Item внутри секции наследует поведение фокусировки и выделения.


Особенности работы с динамическими коллекциями

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

  • Изменение порядка элементов не приводит к потере состояния выделения
  • Удаление элемента корректно обновляет фокус и выбранный элемент
  • Добавление нового элемента автоматически интегрируется в навигацию

Итоговое понимание

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

  • корректное взаимодействие с клавиатурой и мышью
  • поддержку aria-* атрибутов для доступности
  • управление состоянием выделения и фокуса
  • интеграцию с секциями и динамическими коллекциями

Правильное использование Item в сочетании с ListBox, Select и Menu позволяет создавать полностью доступные и удобные интерфейсы без необходимости вручную управлять сложной логикой фокусировки и выбора.