Middleware в Floating UI — это мощный инструмент для управления положением всплывающих элементов (popper, tooltip, dropdown) относительно их якорей. Middleware можно рассматривать как цепочку функций, которые модифицируют координаты и поведение floating-элемента после расчёта базового положения.
Middleware вызываются последовательно в момент вычисления позиции floating-элемента. Каждая функция получает текущее состояние и может:
x и y.viewport) или родительских контейнеров.Состояние, передаваемое middleware, обычно содержит:
x и y — текущие координаты
floating-элемента.strategy — стратегия позиционирования
(absolute или fixed).placement — текущая выбранная позиция
(top, bottom, left,
right и их варианты с
-start/-end).middlewareData — объект для хранения данных между
middleware.Каждая middleware-функция возвращает объект с потенциальными изменениями:
{
x: number, // новая координата по оси X
y: number, // новая координата по оси Y
data: any // дополнительные данные
}
Floating UI предоставляет ряд готовых middleware для решения распространённых задач:
Добавляет смещение между якорем и floating-элементом. Используется для создания отступов, чтобы элемент не прилипал к триггеру.
import { offset } from '@floating-ui/dom';
const middleware = [offset(10)]; // смещение 10px
Параметры offset могут быть числами или функциями,
возвращающими массив [mainAxis, crossAxis].
Автоматически меняет сторону появления floating-элемента, если исходная позиция выходит за границы видимой области.
import { flip } from '@floating-ui/dom';
const middleware = [flip({ fallbackPlacements: ['top', 'right'] })];
fallbackPlacements — список альтернативных позиций, к
которым можно «приклеиться».Сдвигает floating-элемент по оси, чтобы он оставался полностью видимым.
import { shift } from '@floating-ui/dom';
const middleware = [shift({ padding: 8 })];
padding задаёт минимальное расстояние до краев видимой
области.top остаётся
top), а лишь корректирует координаты.Позволяет динамически изменять размеры floating-элемента на основе доступного пространства.
import { size } from '@floating-ui/dom';
const middleware = [size({
apply({ availableWidth, availableHeight, elements }) {
Object.assign(elements.floating.style, {
maxWidth: `${availableWidth}px`,
maxHeight: `${availableHeight}px`
});
}
})];
availableWidth и availableHeight
рассчитываются исходя из позиции и ограничений viewport.Middleware можно создавать самостоятельно, если требуется особая логика позиционирования:
function myMiddleware(options) {
return {
name: 'myMiddleware',
fn({ x, y, placement, elements }) {
// Пример: сдвигаем floating элемент на 20px вправо
return { x: x + 20, y };
}
};
}
name обязателен, используется для дебага и
идентификации.fn получает текущее состояние и возвращает
изменения.data для передачи информации
следующей middleware.Порядок подключения middleware критически важен:
offset).flip,
shift).size, кастомные middleware).Нарушение порядка может привести к неправильному позиционированию, например, элемент может «выпасть» за границы экрана или не учесть смещение.
[offset(8), flip(), shift(), size()].middlewareData для
повторного использования.Floating UI с middleware предоставляет гибкую и расширяемую архитектуру для позиционирования элементов. Понимание работы цепочек middleware позволяет создавать сложные, динамичные интерфейсы без необходимости вручную управлять координатами и проверками видимости.