Хук useAccordion предназначен для управления состоянием
и поведением аккордеонов, обеспечивая доступность (accessibility) и
соответствие стандартам ARIA. Он интегрируется с компонентами React,
позволяя создавать сложные интерактивные интерфейсы без необходимости
вручную управлять фокусом и атрибутами ARIA.
import { useAccordion } from "@react-aria/accordion";
import { useAccordionItem } from "@react-aria/accordion";
import { useAccordionState } from "@react-stately/accordion";
useAccordionState — управляет состоянием аккордеона,
хранит информацию о выбранных элементах, открытых панелях и позволяет
контролировать множественный выбор.useAccordion — создает свойства для контейнера
аккордеона, включая атрибуты ARIA.useAccordionItem — применяется к каждому элементу
аккордеона, задавая правильные роли и связывая кнопку и панель
контента.Состояние аккордеона создается с помощью
useAccordionState:
const state = useAccordionState({
allowsMultiple: true, // разрешает открытие нескольких панелей одновременно
defaultSelectedKeys: ["item1"], // начально открытая панель
});
Ключевые параметры:
allowsMultiple — true позволяет открывать
несколько элементов одновременно, false — только один.selectedKeys — контролируемый список открытых
элементов.defaultSelectedKeys — начальные открытые элементы.onSelectionChange — callback при изменении открытых
элементов.const { accordionProps } = useAccordion({ type: "multiple" }, state);
accordionProps содержит необходимые атрибуты ARIA,
включая role="presentation" и другие, обеспечивающие
корректную работу вспомогательных технологий.type принимает значения "single"
или "multiple", отражающие режим открытия элементов.Пример использования:
<div {...accordionProps}>
{items.map(item => (
<AccordionItem key={item.id} item={item} state={state} />
))}
</div>
Для каждого элемента используется useAccordionItem:
function AccordionItem({ item, state }) {
const ref = React.useRef();
const { buttonProps, regionProps } = useAccordionItem(
{ key: item.id },
state,
ref
);
return (
<div>
<h3>
<button {...buttonProps} ref={ref}>
{item.title}
</button>
</h3>
<div {...regionProps}>
{item.content}
</div>
</div>
);
}
Ключевые моменты:
buttonProps — свойства для кнопки, включающие
aria-expanded, aria-controls и управление
клавиатурой.regionProps — свойства панели контента, включая
role="region" и id, связанный с кнопкой.ref нужен для правильного управления фокусом и
анимациями.React Aria автоматически обрабатывает стандартные клавиши аккордеона:
Это исключает необходимость вручную добавлять обработчики событий клавиатуры.
useAccordionState поддерживает оба режима:
defaultSelectedKeys.selectedKeys и
onSelectionChange.Пример контролируемого:
const [selected, setSelected] = React.useState(["item1"]);
const state = useAccordionState({
selectedKeys: selected,
onSelectionChange: setSelected,
allowsMultiple: false
});
Хук useAccordion гарантирует соответствие WAI-ARIA:
role="button" и aria-expanded для
заголовка.role="region" и aria-labelledby для
панели.Все это делает аккордеон полностью доступным без ручной настройки атрибутов.
function MyAccordion() {
const state = useAccordionState({
allowsMultiple: true,
defaultSelectedKeys: ["item1"]
});
const { accordionProps } = useAccordion({}, state);
const items = [
{ id: "item1", title: "Заголовок 1", content: "Контент 1" },
{ id: "item2", title: "Заголовок 2", content: "Контент 2" },
{ id: "item3", title: "Заголовок 3", content: "Контент 3" }
];
return (
<div {...accordionProps}>
{items.map(item => (
<AccordionItem key={item.id} item={item} state={state} />
))}
</div>
);
}
В этом примере:
useAccordionState.React Aria позволяет расширять стандартный аккордеон:
Хук useAccordion создает основу, на которой строится
надежный, доступный и интерактивный аккордеон.
Эта реализация обеспечивает гибкость, соответствие стандартам и простоту интеграции с React-компонентами.