FloatingOverlay — это компонент библиотеки Floating UI, предназначенный для управления модальными слоями поверх основного контента. Он обеспечивает корректное позиционирование всплывающих элементов, поддерживает управление фокусом, блокировку прокрутки и взаимодействие с клавиатурой, что делает его ключевым инструментом при реализации всплывающих окон, меню, тултипов и диалогов.
isOpen Определяет состояние видимости
оверлея. При значении true элемент отображается, при
false — скрывается. Это свойство связывается с состоянием
компонента, чтобы динамически управлять появлением слоя.
onDismiss Функция обратного вызова,
вызываемая при попытке закрыть оверлей (например, при клике вне области
оверлея или нажатии клавиши Escape). Часто используется для
синхронизации состояния видимости с родительским компонентом:
<FloatingOverlay
isOpen={isOpen}
onDism iss={() => setIsOpen(false)}
/>
lockScroll Если значение установлено в
true, прокрутка страницы блокируется при открытом оверлее.
Это предотвращает сдвиг контента под слоем, что особенно важно для
мобильных устройств.
preventOutsideScroll Блокирует
прокрутку только за пределами оверлея, позволяя скроллить содержимое
самого оверлея.
FloatingOverlay интегрируется с другими инструментами Floating UI для точного позиционирования:
FloatingPortal — используется для
рендеринга оверлея вне обычной иерархии DOM, что предотвращает
перекрытие родительскими элементами с
overflow: hidden.useFloating — хук, который вычисляет
координаты для оверлея относительно целевого элемента или курсора,
поддерживая автоматическое обновление при изменении размеров окна.Пример интеграции:
import { useFloating, offset, flip } from '@floating-ui/react';
import { FloatingOverlay, FloatingPortal } from '@floating-ui/react';
const { x, y, reference, floating } = useFloating({
placement: 'bottom',
middleware: [offset(8), flip()]
});
return (
<>
<button ref={reference} onCl ick={() => setIsOpen(true)}>Открыть оверлей</button>
{isOpen && (
<FloatingPortal>
<FloatingOverlay lockScroll onDism iss={() => setIsOpen(false)}>
<div ref={floating} style={{ position: 'absolute', top: y ?? 0, left: x ?? 0 }}>
Содержимое оверлея
</div>
</FloatingOverlay>
</FloatingPortal>
)}
</>
);
FloatingOverlay автоматически обеспечивает фокус-траппинг: фокус остается внутри оверлея до его закрытия. Это критически важно для доступности:
Escape закрывает оверлей.Tab циклично перемещает фокус по интерактивным
элементам внутри оверлея.aria-атрибутами.<FloatingOverlay
isOpen={isOpen}
onDism iss={() => setIsOpen(false)}
lockScroll
initialFocus={floatingRef}
/>
initialFocus указывает элемент, на который фокус
устанавливается при открытии оверлея. Если не задан, фокус автоматически
устанавливается на первый интерактивный элемент.
FloatingOverlay не ограничивает способ анимации. Обычно используется комбинация CSS-переходов и хука состояния:
.overlay-enter {
opacity: 0;
transform: scale(0.95);
}
.overlay-enter-active {
opacity: 1;
transform: scale(1);
transition: opacity 200ms, transform 200ms;
}
.overlay-exit {
opacity: 1;
transform: scale(1);
}
.overlay-exit-active {
opacity: 0;
transform: scale(0.95);
transition: opacity 200ms, transform 200ms;
}
preventOutsideScroll предотвращает нежелательную
прокрутку фона на устройствах с маленьким экраном.env(safe-area-inset-*).onDismiss, чтобы синхронизировать
состояние видимости с приложением.id или контекст, чтобы управлять приоритетами
закрытия.lockScroll) рекомендована для
модальных диалогов, но может быть отключена для небольших тултипов.FloatingOverlay предоставляет готовую инфраструктуру для реализации модальных слоев, сохраняя контроль над позиционированием, фокусом и прокруткой. Его гибкость позволяет интегрировать любые анимации, управлять поведением на мобильных устройствах и поддерживать доступность, делая интерфейсы безопасными и отзывчивыми.