В Floating UI middleware представляют собой функции, которые управляют позиционированием всплывающих элементов. Middleware можно комбинировать для решения типичных задач, таких как смещение, ограничение области отображения, автоматическое перемещение и адаптивное позиционирование. Каждый middleware выполняется последовательно, передавая результат следующему, что позволяет строить сложное поведение из простых функций.
Важно понимать, что порядок middleware критически влияет на итоговое положение элемента. Middleware, отвечающие за корректировку положения относительно окна или контейнера, обычно размещаются после middleware, задающих базовое смещение.
offset – один из базовых middleware,
позволяющий добавлять фиксированное смещение относительно якоря. Он
принимает объект с параметрами mainAxis и
crossAxis:
import { offset } from '@floating-ui/dom';
const middleware = [
offset({ mainAxis: 10, crossAxis: 5 })
];
mainAxis – смещение вдоль основной оси (обычно
вертикальной при placement: 'bottom').crossAxis – смещение вдоль поперечной оси.Комбинируется с другими middleware для точного позиционирования:
import { flip, shift } from '@floating-ui/dom';
const middleware = [
offset({ mainAxis: 8 }),
flip(),
shift({ padding: 5 })
];
Такой набор позволяет:
Middleware shift отвечает за
предотвращение выхода элемента за границы контейнера или viewport.
Основные опции:
padding – внутренний отступ от границ.boundary – контейнер, в пределах которого нужно
удерживать элемент.crossAxis – применять ли корректировку по поперечной
оси.Пример использования с offset и flip:
import { shift, flip } from '@floating-ui/dom';
const middleware = [
offset({ mainAxis: 12 }),
flip(),
shift({ padding: 10, crossAxis: true })
];
В этой комбинации middleware обеспечивают:
Middleware flip динамически меняет
направление всплывающего элемента, если он не помещается в исходной
позиции. Он поддерживает настройку возможных альтернативных позиций
через опцию fallbackPlacements:
flip({
fallbackPlacements: ['top', 'right', 'left']
})
Пример полной комбинации для выпадающего меню:
import { offset, flip, shift, arrow } from '@floating-ui/dom';
const middleware = [
offset({ mainAxis: 6 }),
flip({ fallbackPlacements: ['top', 'left'] }),
shift({ padding: 8 }),
arrow({ element: arrowElement, padding: 5 })
];
Здесь происходят несколько операций:
Middleware arrow позволяет точно
позиционировать стрелку относительно якоря. Важно учитывать следующие
моменты:
padding задаёт минимальное расстояние от краев
всплывающего элемента.shift и
flip) для корректного позиционирования:arrow({ element: arrowEl, padding: 5 })
Использование после shift и flip
гарантирует, что стрелка корректно сместится при отражении элемента или
его подгонке к границам.
Для подсказки, которая должна смещаться, не выходить за границы и иметь стрелку:
import { offset, flip, shift, arrow } from '@floating-ui/dom';
const middleware = [
offset({ mainAxis: 10 }),
flip(),
shift({ padding: 5 }),
arrow({ element: tooltipArrow, padding: 4 })
];
Последовательность действий middleware:
offset – добавляет базовое смещение.flip – меняет направление, если нет места.shift – корректирует положение по границам.arrow – устанавливает стрелку относительно текущей
позиции.Floating UI позволяет создавать свои middleware, расширяя стандартный набор. Например, middleware для затемнения фона при открытии всплывающего окна:
function dimBackground() {
return {
name: 'dimBackground',
fn({ elements }) {
elements.floating.style.backgroundColor = 'rgba(0,0,0,0.1)';
return {};
}
};
}
const middleware = [
offset({ mainAxis: 8 }),
flip(),
dimBackground()
];
Комбинации кастомных и встроенных middleware позволяют решать уникальные задачи, сохраняя логичную последовательность выполнения.
offset → flip → shift).arrow) лучше размещать последними.{ x, y } или пустой объект, чтобы не ломать цепочку.Комбинирование middleware в Floating UI позволяет управлять поведением всплывающих элементов гибко и надежно, обеспечивая точное позиционирование, адаптивность и совместимость с различными контейнерами и размерами экрана.