В Floating UI обработка кликов вне элемента является важной частью взаимодействия с всплывающими элементами, такими как тултипы, дропдауны, модальные окна и меню. Библиотека предоставляет гибкие инструменты для отслеживания кликов вне целевого элемента и корректного закрытия или скрытия всплывающих компонентов.
useClickOutsideОсновной инструмент для обработки кликов вне элемента — функция
useClickOutside. Она позволяет определить, когда
пользователь кликает за пределами заданного DOM-узла, и выполнить
соответствующее действие, например, закрыть меню.
Пример использования:
import { useRef } from 'react';
import { useClickOutside } from '@floating-ui/react';
function Dropdown({ onClose }) {
const ref = useRef(null);
useClickOutside(ref, onClose);
return (
<div ref={ref} className="dropdown">
<p>Содержимое меню</p>
</div>
);
}
Ключевые моменты:
ref указывает на элемент, за пределами которого будут
отслеживаться клики.useClickOutside корректно работает с вложенными
элементами и несколькими всплывающими компонентами.Иногда требуется исключить из обработки клики по определённым
элементам, например, по кнопке, открывающей меню. В Floating UI это
реализуется через параметр ignore:
useClickOutside(ref, onClose, {
ignore: [buttonRef.current]
});
Особенности:
ignore принимает массив DOM-элементов.floating и open состояниемДля компонентов с Floating UI важно синхронизировать обработку кликов вне элемента с состоянием открытия:
import { useFloating } from '@floating-ui/react';
function Tooltip() {
const { refs, open, setOpen } = useFloating({ placement: 'bottom' });
useClickOutside(refs.floating, () => setOpen(false));
return (
<>
<button ref={refs.reference} onCl ick={() => setOpen(!open)}>
Нажми меня
</button>
{open && <div ref={refs.floating} className="tooltip">Подсказка</div>}
</>
);
}
Принципы работы:
open управляет видимостью всплывающего
элемента.refs.floating используется для отслеживания кликов
вне.setOpen(false), что корректно
закрывает всплывающий элемент.Если всплывающее окно рендерится через портал
(ReactDOM.createPortal) или находится на другом уровне DOM,
useClickOutside корректно определяет клики вне:
ref всегда указывает на DOM-узел всплывающего
элемента.Floating UI использует делегирование событий для оптимальной производительности:
document.ref.current.contains(event.target)).Можно также контролировать тип события (mousedown,
mouseup, click) через опции:
useClickOutside(ref, onClose, { event: 'mousedown' });
Преимущества:
Когда существует несколько всплывающих компонентов, например, выпадающее меню с подменю:
useClickOutside.ignore, чтобы клики по
родительскому элементу не закрывали дочернее меню.useClickOutside(submenuRef, () => setSubmenuOpen(false), { ignore: [parentMenuRef.current] });
ref, чтобы обработка
кликов вне оставалась точной.ignore для элементов, которые управляют
открытием/закрытием всплывающих окон.useClickOutside с состоянием
open или аналогичным, чтобы избежать ошибок видимости.Эти подходы позволяют гибко и безопасно обрабатывать клики вне элементов в проектах с Floating UI, обеспечивая предсказуемое поведение всплывающих компонентов, будь то тултипы, дропдауны, модальные окна или сложные многоуровневые меню.