Section для группировки

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


Импорт и базовое применение

Для начала необходимо импортировать хук useListBoxSection или useListSection из React Aria, в зависимости от контекста:

import { useListBoxSection } from "@react-aria/listbox";

Section обычно используется внутри компонента, который рендерит коллекцию элементов. Основная цель — корректное отображение групп в структуре ARIA, например, в ListBox или Menu.

function MyList({ sections }) {
  return (
    <ul>
      {sections.map(section => (
        <ListSection key={section.key} section={section} />
      ))}
    </ul>
  );
}

function ListSection({ section }) {
  const { itemProps, headingProps, groupProps } = useListBoxSection({ section });
  
  return (
    <li {...groupProps}>
      {section.rendered && <div {...headingProps}>{section.rendered}</div>}
      <ul>
        {section.items.map(item => (
          <li key={item.key}>{item.rendered}</li>
        ))}
      </ul>
    </li>
  );
}

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

  • section.rendered — заголовок группы, который может быть строкой или React-элементом.
  • groupProps — атрибуты для контейнера элементов группы, обеспечивающие правильную навигацию.
  • headingProps — атрибуты для заголовка группы, включающие ARIA-метки.

Сочетание с Collection и ListBox

В React Aria коллекции строятся через Collection API, который позволяет описывать элементы и их группы декларативно. Section используется для создания вложенной структуры:

const sections = [
  {
    key: "fruits",
    rendered: "Фрукты",
    items: [
      { key: "apple", rendered: "Яблоко" },
      { key: "banana", rendered: "Банан" }
    ]
  },
  {
    key: "vegetables",
    rendered: "Овощи",
    items: [
      { key: "carrot", rendered: "Морковь" },
      { key: "pepper", rendered: "Перец" }
    ]
  }
];

Каждый объект section содержит:

  • key — уникальный идентификатор группы.
  • rendered — заголовок.
  • items — массив элементов внутри группы, каждый элемент также должен иметь уникальный key и rendered.

При рендеринге через ListBox или Menu Section автоматически генерирует соответствующие ARIA-атрибуты, включая aria-labelledby для связи заголовка с группой элементов.


Доступность и ARIA

Использование Section обеспечивает:

  • Правильную поддержку навигации с клавиатуры в списках с разделами.
  • Возможность экранным читалкам озвучивать заголовок группы перед элементами.
  • Семантическую структуру через role="group" и aria-labelledby.
<li role="group" aria-labelledby="fruits-label">
  <div id="fruits-label">Фрукты</div>
  <ul>
    <li>Яблоко</li>
    <li>Банан</li>
  </ul>
</li>

Таким образом, React Aria автоматически связывает заголовок и элементы группы, что делает интерфейс доступным без ручного управления ARIA-атрибутами.


Работа с вложенными группами

Section поддерживает вложенные группы, что особенно полезно для сложных меню и иерархических списков:

const nestedSections = [
  {
    key: "citrus",
    rendered: "Цитрусовые",
    items: [
      { key: "orange", rendered: "Апельсин" },
      { key: "lemon", rendered: "Лимон" }
    ]
  },
  {
    key: "berries",
    rendered: "Ягоды",
    items: [
      { key: "strawberry", rendered: "Клубника" },
      { key: "blueberry", rendered: "Черника" }
    ]
  }
];

Вложенные Section могут быть рекурсивно отрендерены через тот же компонент ListSection, что обеспечивает единый API для любых уровней вложенности.


Кастомизация визуального отображения

Хотя React Aria отвечает за доступность, визуальное оформление полностью контролируется через CSS или styled-components. Часто используются стили для заголовков групп:

.group-heading {
  font-weight: bold;
  padding: 8px 12px;
  background-color: #f4f4f4;
}
.group-items li {
  padding: 6px 12px;
}

Компонент рендерит семантику, а стилизация создаёт удобный интерфейс для пользователей.


Итоговая структура

Использование Section позволяет создавать:

  • Списки с группами элементов (ListBox, Menu, Select).
  • Доступные интерфейсы с правильными ARIA-атрибутами.
  • Рекурсивные вложенные структуры для сложных коллекций.
  • Чёткую семантическую связь между заголовком группы и её элементами.

Эта структура упрощает поддержку, улучшает доступность и делает код более декларативным и предсказуемым.