Композаблы — это фундаментальная концепция Floating UI, позволяющая создавать модульные, переиспользуемые и расширяемые взаимодействия с плавающими элементами. Основная идея заключается в том, что поведение всплывающих элементов можно разделить на независимые части, которые затем комбинируются в единую цепочку обработки.
Floating UI строится на механизме модулей, где
каждый модуль отвечает за конкретную задачу: позиционирование, смещение,
предотвращение выхода за границы окна и т. д. Композаблы реализуются
через функцию compose, которая объединяет несколько модулей
в один объект поведения:
import { offset, flip, shift, autoUpdate, compose } from '@floating-ui/dom';
const composedMiddleware = compose([
offset(10),
flip(),
shift({ padding: 5 })
]);
В этом примере создается последовательность обработчиков:
Каждый модуль принимает контекст, содержащий текущее положение,
размеры целевого элемента, размеры контейнера и дополнительные
параметры. Возвращаемое значение модуля обычно модифицирует координаты
x и y.
Floating UI поддерживает кастомные композаблы, что
позволяет расширять функциональность стандартных модулей. Для этого
создается функция, которая принимает объект context и
возвращает результат работы:
function customArrow({ x, y, placement, middlewareData }) {
// Смещение стрелки на половину ширины
const arrowOffset = 8;
return { x: x + arrowOffset, y };
}
const myMiddleware = compose([
offset(10),
flip(),
customArrow
]);
Особенности создания кастомного композабла:
context содержит все координаты и данные
предыдущих модулей.В React Floating UI предоставляет хуки, которые
полностью интегрируются с концепцией композаблов. Основной хук —
useFloating, где композаблы передаются через массив
middleware:
import { useFloating, offset, flip, shift } from '@floating-ui/react-dom';
const { x, y, reference, floating, strategy } = useFloating({
middleware: [offset(10), flip(), shift({ padding: 5 })]
});
Хук возвращает:
absolute или fixed).Комбинируя стандартные и кастомные композаблы, можно создавать сложные интерфейсы: контекстные меню, тултипы, дропдауны и панели с динамическим поведением.
Порядок, в котором композаблы указаны в compose или в
массиве middleware, критически важен:
Floating UI предоставляет множество готовых модулей:
Каждый из этих композаблов можно комбинировать с любым количеством других, создавая гибкую цепочку обработки.
import { offset, flip, shift, size, arrow, compose } from '@floating-ui/dom';
const complexMiddleware = compose([
offset(8),
flip({ fallbackPlacements: ['top', 'left'] }),
shift({ padding: 10 }),
size({
apply({ availableWidth, availableHeight, elements }) {
Object.assign(elements.floating.style, {
maxWidth: `${availableWidth}px`,
maxHeight: `${availableHeight}px`
});
}
}),
arrow({ element: document.querySelector('.arrow') })
]);
В этом примере одновременно решаются несколько задач:
Композаблы в Floating UI превращают позиционирование всплывающих элементов в гибкую и расширяемую систему, где каждый модуль отвечает за конкретную задачу, а комбинации дают практически неограниченные возможности по управлению интерфейсом.