Объект platform в библиотеке Floating UI — это
абстрактный слой, отвечающий за получение геометрических и средовых
данных. Он изолирует алгоритмы позиционирования от конкретной среды
выполнения: браузера, React Native, Canvas или даже пользовательских
рендереров.
Алгоритмы вычисления позиции (computePosition) не
работают напрямую с DOM. Вместо этого они вызывают методы
platform, которые предоставляют всю необходимую
информацию:
Это делает систему расширяемой и переносимой.
platformОбъект platform представляет собой набор функций:
const platform = {
getElementRects,
getClippingRect,
getDimensions,
getOffsetParent,
getDocumentElement,
getScale,
isElement,
isRTL
};
Каждый метод выполняет строго определённую роль. Алгоритмы позиционирования полагаются на эти методы как на источник истины.
getElementRectsОдин из ключевых методов. Возвращает прямоугольники
(rects) для reference и floating элементов.
const rects = await platform.getElementRects({
reference,
floating,
strategy
});
Структура результата:
{
reference: { x, y, width, height },
floating: { x, y, width, height }
}
Особенности:
reference обычно вычисляются относительно
viewportfloating — относительно offset parentabsolute или
fixed)Этот метод критичен для начального расчёта позиции.
getClippingRectВозвращает область, в пределах которой элемент может быть видим.
const clippingRect = await platform.getClippingRect({
element,
boundary,
rootBoundary,
strategy
});
Назначение:
определяет границы для middleware вроде flip и
shift
учитывает:
Параметры:
boundary — список контейнеров или
clippingAncestorsrootBoundary — обычно viewport или
documentВажно:
Если clipping рассчитан неверно — позиционирование будет ломаться при прокрутке и переполнении.
getDimensionsВозвращает размеры элемента.
const dimensions = await platform.getDimensions(element);
Результат:
{
width: number,
height: number
}
Отличие от getBoundingClientRect:
Используется при вычислении размеров floating-элемента, особенно до его отображения.
getOffsetParentОпределяет offset-контекст для элемента.
const offsetParent = await platform.getOffsetParent(element);
Что возвращает:
window / documentElementЗачем нужен:
absoluteСложности:
position: fixed игнорирует offset parenttransform) создают новые контекстыgetDocumentElementВозвращает корневой элемент документа.
const docEl = platform.getDocumentElement(element);
Обычно это:
document.documentElement
Используется для:
rootBoundary: documentgetScaleОпределяет масштаб элемента.
const scale = await platform.getScale(element);
Результат:
{
x: number,
y: number
}
Причины появления масштаба:
transform: scale(...)Зачем нужен:
Без учёта масштаба координаты будут искажены.
isElementПроверяет, является ли объект элементом.
platform.isElement(value);
Возвращает:
true | false
Используется внутри алгоритмов для ветвления логики:
isRTLОпределяет направление текста.
const rtl = await platform.isRTL(element);
Возвращает:
true // если right-to-left
false // если left-to-right
Влияние:
offset) работает иначеМетоды platform не используются изолированно. Они
образуют цепочку:
getElementRects — базовая геометрияgetOffsetParent — контекст координатgetScale — корректировка размеровgetClippingRect — ограниченияplatformFloating UI позволяет полностью заменить platform.
Пример:
const customPlatform = {
...platform,
getDimensions: async (element) => {
return {
width: element.customWidth,
height: element.customHeight
};
}
};
Использование:
computePosition(reference, floating, {
platform: customPlatform
});
platform позволяет использовать Floating UI:
Пример виртуального элемента:
const virtualElement = {
getBoundingClientRect() {
return {
x: 100,
y: 200,
width: 0,
height: 0
};
}
};
В этом случае platform должен уметь работать без DOM
API.
Все методы могут быть асинхронными:
await platform.getElementRects(...)
Это важно для:
1. Неверный offset parent
Приводит к смещению floating-элемента.
2. Игнорирование scale
Особенно заметно при zoom и transform.
3. Неправильный clipping
Элемент может “вылезать” за границы.
4. Несоответствие coordinate space
Разные системы координат ломают расчёты.
platformconst minimalPlatform = {
getElementRects: async ({reference, floating}) => ({
reference: reference.getBoundingClientRect(),
floating: floating.getBoundingClientRect()
}),
getDimensions: async (el) => ({
width: el.offsetWidth,
height: el.offsetHeight
}),
getOffsetParent: async () => window,
getDocumentElement: () => document.documentElement,
getScale: async () => ({x: 1, y: 1}),
isElement: (value) => value instanceof Element,
isRTL: async () => false,
getClippingRect: async () => ({
x: 0,
y: 0,
width: window.innerWidth,
height: window.innerHeight
})
};
platform в
middlewareMiddleware (flip, shift,
offset, arrow) активно используют
platform:
detectOverflow вызывает
getClippingRectarrow использует getDimensionsshift зависит от координат rectТаким образом, platform — это фундамент всей системы
позиционирования.
Разделение логики и платформы даёт преимущества:
Это один из ключевых архитектурных элементов Floating UI.