Хук useFloating является ядром библиотеки Floating UI
для создания плавающих элементов, таких как тултипы, поповеры, дропдауны
и модальные окна. Его основная задача — динамически рассчитывать позицию
элемента относительно другого, учитывая размеры, ограничения видимой
области и возможности смещения.
import { useFloating } from '@floating-ui/react-dom';
Хук возвращает объект с ключевыми свойствами и методами:
x, y, strategy, refs
и вспомогательные функции для обновления позиции.
x и y — координаты
плавающего элемента относительно контейнера.strategy — стратегия позиционирования:
"absolute" или "fixed".refs — объект, содержащий ссылки на
целевой элемент (reference) и на сам плавающий элемент
(floating).update() — функция для пересчета
позиции при изменении размеров или состояния DOM.const { x, y, reference, floating, strategy, update } = useFloating({
placement: 'bottom-start',
middleware: [],
});
useFloatingplacement — определяет начальную
позицию плавающего элемента относительно целевого: "top",
"bottom", "left", "right" и их
вариации с "-start" и "-end".strategy — выбирается
"absolute" (позиционирование внутри ближайшего родителя с
position: relative) или "fixed"
(позиционирование относительно окна).middleware — массив функций, влияющих
на вычисление позиции, например offset, flip,
shift, arrow.open и onOpenChange —
используются для управления видимостью элемента, интеграция с кастомными
состояниями.Пример с базовыми middleware:
import { offset, flip, shift } from '@floating-ui/react-dom';
const { x, y, reference, floating, strategy } = useFloating({
placement: 'top',
middleware: [offset(10), flip(), shift({ padding: 5 })],
});
offset Добавляет смещение от целевого
элемента. Может принимать число или функцию:
offset(8); // смещение 8px
offset(({ rects }) => rects.reference.height / 2); // динамическое смещение
flip Позволяет менять позицию при
нехватке пространства. Можно настроить через
fallbackPlacements:
flip({
fallbackPlacements: ['bottom', 'right'],
});
shift Корректирует позицию элемента,
чтобы он не выходил за границы контейнера или viewport:
shift({
padding: 10, // минимальный отступ от краев
limiter: undefined, // можно использовать custom limiter
});
arrow Используется для позиционирования
стрелки относительно целевого элемента:
import { arrow } from '@floating-ui/react-dom';
const arrowRef = useRef(null);
arrow({ element: arrowRef.current });
arrow автоматически возвращает координаты для
позиционирования стрелки: x и y.
refs с DOMХук предоставляет объект refs, который содержит два
ключевых свойства:
reference — ссылка на элемент,
относительно которого позиционируется поповер.floating — ссылка на сам плавающий
элемент.Пример использования в компоненте React:
<button ref={reference}>Открыть меню</button>
<div
ref={floating}
style={{
position: strategy,
top: y ?? 0,
left: x ?? 0,
}}
>
Меню
</div>
refs автоматически обрабатывает пересчет позиции при
изменении DOM, если используется autoUpdate.
Функция autoUpdate позволяет динамически реагировать на
изменения размеров или прокрутки:
import { autoUpdate } from '@floating-ui/react-dom';
useEffect(() => {
if (reference.current && floating.current) {
return autoUpdate(reference.current, floating.current, update);
}
}, [reference, floating, update]);
autoUpdate слушает события resize,
scroll и любые изменения размеров элементов.
Часто useFloating используется вместе с контролем
видимости:
const [open, setOpen] = useState(false);
const { x, y, reference, floating, strategy } = useFloating({
placement: 'bottom',
open,
onOpenChange: setOpen,
});
Теперь можно использовать open для условного рендеринга
и onOpenChange для синхронизации с внешним состоянием.
useFloating легко комбинируется с useClick,
useHover и другими событиями:
import { useHover, useInteractions } from '@floating-ui/react-dom-interactions';
const hover = useHover(context);
const interactions = useInteractions([hover]);
<button ref={interactions.getReferenceProps(reference)}>Наведи</button>
<div ref={interactions.getFloatingProps(floating)}>Контент</div>
useInteractions автоматически обрабатывает все
необходимые события и синхронизирует открытие/закрытие.
middleware для гибкого
позиционирования.autoUpdate при динамическом
контенте.ref и middleware
arrow.useInteractions упрощает управление
событиями мыши и клавиатуры."fixed" полезна для модальных окон и
элементов, которые должны оставаться на экране при скролле.Эти возможности делают useFloating мощным инструментом
для построения адаптивных, интерактивных интерфейсов с точным контролем
позиционирования и поведением плавающих элементов.