В основе работы библиотеки лежит абстракция платформы — набора методов, через которые происходит взаимодействие с окружением (DOM, браузер, виртуальная среда). Эти методы используются функцией позиционирования для получения геометрии элементов, вычисления границ и обработки прокрутки.
Ключевая идея — отделение алгоритма позиционирования от конкретной среды выполнения. Это позволяет:
Платформа представлена объектом с набором функций, которые можно переопределять.
Базовый набор методов платформы включает:
Каждый из этих методов может быть заменён пользовательской реализацией.
В средах без стандартного DOM (например, Canvas или WebGL)
отсутствуют привычные методы вроде getBoundingClientRect.
Переопределение позволяет подставить собственные вычисления
координат.
Floating UI поддерживает виртуальные reference-элементы — объекты, которые ведут себя как DOM-элементы, но не существуют в дереве документа. Например, курсор мыши или координаты выделения текста.
При работе с трансформациями, масштабированием или вложенными контекстами может потребоваться собственная логика расчёта позиций.
Можно упростить вычисления, если известны ограничения среды — например, убрать поддержку сложных сценариев прокрутки.
Функция computePosition принимает объект
platform, который переопределяет стандартную
реализацию:
import {computePosition} from '@floating-ui/dom';
computePosition(reference, floating, {
platform: {
getElementRects: async ({reference, floating}) => {
return {
reference: {
x: 100,
y: 100,
width: 50,
height: 20,
},
floating: {
x: 0,
y: 0,
width: 80,
height: 40,
},
};
}
}
});
Если метод не указан, используется реализация по умолчанию.
Этот метод — один из ключевых, поскольку определяет исходные данные для позиционирования.
Стандартная версия использует getBoundingClientRect, но
при переопределении можно:
Пример с учётом пользовательского смещения:
const platform = {
async getElementRects({reference, floating}) {
const refRect = reference.getBoundingClientRect();
const floatRect = floating.getBoundingClientRect();
return {
reference: {
...refRect,
x: refRect.x + 10,
y: refRect.y + 20,
},
floating: floatRect,
};
}
};
Метод отвечает за вычисление области, внутри которой должен находиться floating-элемент.
В стандартной реализации учитываются:
Переопределение может потребоваться, если:
Пример фиксированной области:
const platform = {
async getClippingRect() {
return {
width: 800,
height: 600,
x: 0,
y: 0,
};
}
};
Виртуальный элемент — объект с методом
getBoundingClientRect:
const virtualReference = {
getBoundingClientRect() {
return {
x: mouseX,
y: mouseY,
width: 0,
height: 0,
top: mouseY,
left: mouseX,
right: mouseX,
bottom: mouseY,
};
}
};
При необходимости можно полностью заменить платформенный метод
isElement, чтобы библиотека корректно обрабатывала такие
объекты:
const platform = {
isElement: (value) => {
return value && typeof value.getBoundingClientRect === 'function';
}
};
Этот метод влияет на систему координат, в которой происходит позиционирование.
Стандартное поведение:
position,
transform.Кастомизация может понадобиться:
Пример принудительного использования document.body:
const platform = {
getOffsetParent: () => document.body
};
Если элементы масштабируются через CSS
(transform: scale), координаты могут искажаться. Метод
getScale позволяет учитывать это.
Переопределение полезно, если:
const platform = {
getScale: () => ({x: 1.5, y: 1.5})
};
Не требуется реализовывать весь интерфейс — достаточно заменить только нужные методы. Остальные будут взяты из стандартной реализации.
Комбинирование:
import {platform as defaultPlatform} from '@floating-ui/dom';
const customPlatform = {
...defaultPlatform,
getElementRects: async (args) => {
const rects = await defaultPlatform.getElementRects(args);
return {
...rects,
reference: {
...rects.reference,
x: rects.reference.x + 5,
}
};
}
};
Middleware (например, offset, flip,
shift) используют данные платформы. Любое изменение методов
напрямую влияет на:
Ошибки в платформе приводят к:
При переопределении методов необходимо проверять:
Рекомендуется:
Нет DOM — требуется полная реализация платформы:
window,flip
и shiftgetScale искажает позиционирование
при трансформацияхТакой подход позволяет сохранить стабильность и избежать сложных ошибок при полной замене платформенного слоя.