Библиотека React Aria предоставляет удобные хуки для
работы с доступностью и управлением интерактивных компонентов. Один из
ключевых инструментов для работы с модальными окнами, всплывающими
подсказками, тултипами и другими оверлеями — это хук
useOverlayTriggerState. Он позволяет
централизованно управлять состоянием отображения оверлея и его жизненным
циклом.
useOverlayTriggerStateХук предоставляет следующие возможности:
Открытие и закрытие оверлея С помощью методов
open() и close() можно явно управлять
видимостью оверлея. Также поддерживается автоматическое закрытие при
потере фокуса или нажатии клавиши Escape.
Слежение за состоянием оверлея Свойство
isOpen позволяет узнать, открыт ли оверлей в текущий
момент, и использовать это состояние для условного рендеринга
компонентов.
Интеграция с другими хуками React Aria
useOverlayTriggerState хорошо сочетается с хуками
useOverlay, useDialog,
useTooltip, обеспечивая корректное управление фокусом и
доступностью.
Хук импортируется из пакета @react-stately/overlays:
import { useOverlayTriggerState } from '@react-stately/overlays';
Создание состояния оверлея выполняется следующим образом:
const overlayState = useOverlayTriggerState({
isOpen: false, // начальное состояние
defaultOpen: false, // опциональное значение по умолчанию
onOpenChange: (open) => console.log('Overlay is now', open)
});
isOpen — управляемое состояние, если
нужно контролировать оверлей извне.defaultOpen — начальное состояние для
неконтролируемого использования.onOpenChange — колбек, вызываемый при
каждом изменении состояния оверлея.После создания состояния доступны методы:
open() — открывает оверлей.close() — закрывает оверлей.toggle() — переключает состояние
оверлея.Свойство isOpen отражает текущее
состояние видимости.
import React from 'react';
import { useOverlayTriggerState } from '@react-stately/overlays';
import { useOverlay, OverlayContainer } from '@react-aria/overlays';
function Modal({ state }) {
const ref = React.useRef();
const { overlayProps } = useOverlay(
{
isOpen: state.isOpen,
onClose: () => state.close(),
isDismissable: true
},
ref
);
if (!state.isOpen) return null;
return (
<OverlayContainer>
<div {...overlayProps} ref={ref} style={{
position: 'fixed',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
background: 'white',
padding: 20,
boxShadow: '0 4px 16px rgba(0,0,0,0.2)'
}}>
<h2>Модальное окно</h2>
<button onCl ick={() => state.close()}>Закрыть</button>
</div>
</OverlayContainer>
);
}
export default function App() {
const state = useOverlayTriggerState({});
return (
<div>
<button onCl ick={() => state.open()}>Открыть модальное окно</button>
<Modal state={state} />
</div>
);
}
В этом примере:
useOverlayTriggerState управляет
состоянием модального окна.useOverlay обеспечивает правильное
поведение фокуса и закрытие по клику вне модального окна или нажатию
Escape.OverlayContainer гарантирует корректное
отображение оверлея поверх других элементов DOM.Хук подходит не только для модальных окон, но и для:
Принцип одинаковый: состояние оверлея централизовано, и все компоненты, использующие это состояние, синхронизированы.
Хук поддерживает расширенные настройки:
isDismissable — определяет, можно ли
закрывать оверлей кликом вне компонента или клавишей
Escape.shouldCloseOnBlur — автоматически
закрывает оверлей при уходе фокуса.onOpenChange — полезен для интеграции
с внешними системами состояния или аналитикой.isOpen.useOverlay, useDialog,
useTooltip для соблюдения стандартов ARIA.useOverlayTriggerState является фундаментальным
инструментом для любого интерактивного React-компонента, требующего
всплывающего интерфейса. Он обеспечивает простое, безопасное и
доступное управление оверлеями, позволяя сосредоточиться на
содержании компонентов, а не на сложной логике их отображения.