useMenuTrigger — это хук из библиотеки React Aria,
предназначенный для управления поведением элементов, которые открывают
или закрывают меню. Он обеспечивает полную поддержку доступности (ARIA),
включая правильное управление фокусом, клавиатурные события и атрибуты,
необходимые для пользователей с ограниченными возможностями.
Хук используется в сочетании с компонентами меню и триггерами, чтобы гарантировать, что меню будет корректно анонсироваться экранными читалками и работать с клавиатурой.
import { useMenuTrigger } from "@react-aria/menu";
import { useMenuTriggerState } from "@react-stately/menu";
useMenuTrigger работает вместе с
useMenuTriggerState, который управляет состоянием меню
(открыто/закрыто).
Пример базовой реализации:
function MenuButton() {
const state = useMenuTriggerState({ type: "menu" });
const ref = React.useRef();
const { menuTriggerProps, menuProps } = useMenuTrigger({ type: "menu" }, state, ref);
return (
<>
{state.isOpen && (
- Элемент 1
- Элемент 2
- Элемент 3
)}
>
);
}
В этом примере:
menuTriggerProps добавляются на кнопку, чтобы она
правильно управляла меню и поддерживала ARIA.menuProps применяются к контейнеру меню, обеспечивая
правильные роли и атрибуты.state.isOpen контролирует отображение меню.useMenuTriggertype — тип триггера. Может быть "menu" для
стандартного меню или "listbox" для списков выбора.isDisabled — блокирует возможность открытия меню.onOpenChange — обратный вызов, срабатывающий при
открытии или закрытии меню.Пример использования isDisabled:
const { menuTriggerProps } = useMenuTrigger({ type: "menu", isDisabled: true }, state, ref);
useMenuTrigger автоматически обрабатывает стандартные
клавиатурные сценарии:
Фокус управляется через ref, переданный третьим аргументом в хук. Это гарантирует, что кнопка останется активной и корректно взаимодействует с пользователем после закрытия меню.
useMenuTrigger добавляет на триггер необходимые
ARIA-атрибуты:
aria-haspopup — указывает, что элемент вызывает
всплывающее меню.aria-expanded — показывает текущее состояние меню
(true/false).aria-controls — связывает триггер с идентификатором
меню.На контейнер меню добавляются роли:
role="menu" для менюrole="menuitem" для каждого элементаЭто обеспечивает корректное взаимодействие с экранными читалками и улучшает доступность.
Хук можно использовать не только с , но и
с любыми интерактивными компонентами:
с обработкой клавиатуры
с tabIndex={0}
Пример с кастомным компонентом:
function CustomTrigger({ children }) {
const state = useMenuTriggerState({ type: "menu" });
const ref = React.useRef();
const { menuTriggerProps, menuProps } = useMenuTrigger({}, state, ref);
return (
<>
{children}
{state.isOpen && (
- Пункт A
- Пункт B
)}
>
);
}
Советы по использованию
- Всегда передавать
ref для корректной работы
фокуса.
- Использовать
useMenuTriggerState, чтобы управлять
состоянием меню отдельно от компонента.
- Поддерживать
isDisabled для предотвращения открытия
меню в определённых условиях.
- Проверять, что все элементы меню имеют
role="menuitem"
или соответствующие ARIA-ролии.
- При использовании кастомных компонентов задавать
tabIndex и обрабатывать клавиатурные события.
Взаимодействие с
другими хуками React Aria
useMenuTrigger часто комбинируется с:
useMenu — управление самим меню.
useMenuItem — управление элементами меню.
useOverlay — отображение меню поверх других элементов с
поддержкой закрытия при клике вне.
Пример совместной работы с useMenu:
import { useMenu } from "@react-aria/menu";
function Menu({ state, menuRef }) {
const { menuProps } = useMenu({}, state, menuRef);
return (
{state.items.map(item => (
- {item.name}
))}
);
}
Такое разделение обязанностей делает код более чистым, поддерживаемым
и полностью соответствующим стандартам доступности.