Floating UI предоставляет гибкую систему позиционирования элементов, позволяя точно управлять всплывающими окнами, тултипами, поповерами и модальными элементами. Одной из ключевых возможностей является Mapping конфигурации, которая позволяет преобразовывать и адаптировать параметры позиционирования в зависимости от контекста и условий отображения.
Mapping в Floating UI — это механизм, с помощью которого можно
переназначать или модифицировать параметры передаваемой
конфигурации функции computePosition. В отличие от
статических настроек, Mapping позволяет:
offset) в зависимости от
размеров элемента или экрана.flip и
shift.Mapping работает через функцию обратного вызова, которая получает исходные параметры и возвращает новые значения. Пример базового синтаксиса:
import {computePosition, offset} from '@floating-ui/dom';
const mapping = (config) => ({
...config,
middleware: [
offset({mainAxis: config.offset || 10}),
...config.middleware
]
});
const elementConfig = {placement: 'bottom', offset: 20};
computePosition(referenceElement, floatingElement, mapping(elementConfig))
.then(({x, y}) => {
Object.assign(floatingElement.style, {
left: `${x}px`,
top: `${y}px`
});
});
Здесь функция mapping принимает объект конфигурации и
добавляет динамическое смещение, сохраняя остальные
параметры без изменений.
Floating UI строится на концепции middleware, где каждый модуль отвечает за отдельный аспект позиционирования. Mapping позволяет гибко изменять набор middleware в зависимости от условий:
import {shift, flip, offset} from '@floating-ui/dom';
const dynamicMapping = (config) => {
const middleware = [];
if (window.innerWidth < 768) {
middleware.push(offset({mainAxis: 5}));
} else {
middleware.push(offset({mainAxis: 15}));
}
if (config.enableFlip) {
middleware.push(flip());
}
middleware.push(shift({padding: 8}));
return {...config, middleware};
};
computePosition(referenceElement, floatingElement, dynamicMapping({placement: 'top', enableFlip: true}));
Особенности подхода:
placement,
strategy и другие параметры.В реальных проектах часто требуется, чтобы позиционирование зависело не только от размера окна, но и от состояния элемента или контента. Например, тултип, который меняет свое положение при переполнении:
const adaptiveMapping = (config, element) => {
const {clientHeight} = element;
const mainAxisOffset = clientHeight > 100 ? 20 : 10;
return {
...config,
middleware: [
offset({mainAxis: mainAxisOffset}),
flip(),
shift({padding: 12})
]
};
};
computePosition(referenceElement, floatingElement, adaptiveMapping({placement: 'bottom'}, floatingElement));
Здесь offset подстраивается под высоту элемента, а остальные middleware обеспечивают корректное отображение при изменении контента.
Для упрощения поддержки кода рекомендуется создавать универсальные функции mapping, которые можно применять к любым элементам:
export const defaultMapping = (config) => ({
...config,
middleware: [
offset({mainAxis: 10}),
flip({fallbackPlacements: ['top', 'right', 'left']}),
shift({padding: 8})
]
});
// Применение
computePosition(referenceElement, floatingElement, defaultMapping({placement: 'bottom'}));
Преимущества:
В сложных интерфейсах может потребоваться последовательное применение нескольких функций mapping. Floating UI позволяет это делать через композицию:
const combineMappings = (...mappings) => (config) =>
mappings.reduce((acc, fn) => fn(acc), config);
const combined = combineMappings(
(cfg) => ({...cfg, offset: 10}),
(cfg) => ({...cfg, placement: 'top'}),
(cfg) => ({...cfg, middleware: [...(cfg.middleware || []), flip()]})
);
computePosition(referenceElement, floatingElement, combined({}));
Этот подход позволяет строить многоуровневые стратегии позиционирования, сохраняя код чистым и управляемым.
strategy —
absolute и fixed могут требовать разных
смещений.Mapping конфигурации в Floating UI открывает возможности для гибкой адаптации элементов интерфейса без повторного переписывания логики позиционирования. Правильное использование функций mapping делает UI более отзывчивым, устойчивым к изменениям и легко поддерживаемым в больших проектах.