Основные различия в API

Floating UI — это современная библиотека для управления позиционированием всплывающих элементов в браузере. Она обеспечивает точное и предсказуемое размещение тултипов, дропдаунов, поповер-меню и других плавающих компонентов. Основные различия в API Floating UI проявляются в подходе к конфигурации, модификаторам и стратегиям позиционирования.


Функция computePosition и её особенности

Основным API является функция computePosition, которая заменяет привычные методы вроде getBoundingClientRect и вручную написанные логики для позиционирования.

import { computePosition, offset, flip, shift } from '@floating-ui/dom';

const reference = document.querySelector('#button');
const floating = document.querySelector('#tooltip');

computePosition(reference, floating, {
  placement: 'top',
  middleware: [offset(8), flip(), shift({ padding: 5 })],
}).then(({ x, y }) => {
  Object.assign(floating.style, {
    left: `${x}px`,
    top: `${y}px`,
  });
});

Ключевые моменты:

  • placement определяет начальное направление появления плавающего элемента (top, bottom, left, right) с возможными вариациями (-start, -end).
  • middleware — массив функций, которые могут модифицировать позицию перед финальным рендером.
  • Возвращаемый объект содержит точные координаты x и y, а также информацию о действующем placement.

Middleware: расширение и модификация поведения

Middleware — это механизм, который позволяет добавлять логику обработки позиции, например, смещение, предотвращение выхода за границы экрана и автоматический флип.

  • offset(value) — задаёт смещение плавающего элемента от привязки.
  • flip() — меняет сторону, если исходная позиция выходит за видимую область.
  • shift(options) — корректирует позицию, чтобы элемент полностью помещался в viewport.
  • arrow({ element }) — позиционирует стрелку тултипа относительно плавающего блока.

Middleware можно комбинировать для сложных сценариев:

middleware: [
  offset(10),
  flip({ fallbackPlacements: ['bottom', 'right'] }),
  shift({ padding: 8 }),
]

Стратегии позиционирования: absolute и fixed

Floating UI поддерживает два типа стратегий:

  • absolute — позиционирование относительно ближайшего ancestor с position: relative. Удобно для элементов внутри контейнеров.
  • fixed — позиционирование относительно viewport. Используется, когда нужно избежать смещения при скролле.

Пример:

computePosition(reference, floating, {
  placement: 'bottom-start',
  strategy: 'fixed',
});

Выбор стратегии влияет на поведение middleware: например, shift будет работать по-разному для absolute и fixed.


Реактивность и автоматическое обновление

Floating UI предоставляет метод autoUpdate, который автоматически отслеживает изменения в размерах и позициях reference или floating элементов.

import { autoUpdate } from '@floating-ui/dom';

const cleanup = autoUpdate(reference, floating, () => {
  computePosition(reference, floating, { placement: 'top' })
    .then(({ x, y }) => Object.assign(floating.style, { left: `${x}px`, top: `${y}px` }));
});

// Для остановки наблюдения
cleanup();

Особенности:

  • Позволяет динамически реагировать на скролл, ресайз и изменение размеров контента.
  • Упрощает создание интерактивных тултипов и дропдаунов без ручного пересчёта координат.

Различия между DOM и React API

Floating UI предоставляет DOM API и React API, которые отличаются по способу интеграции:

  • DOM API — низкоуровневое позиционирование, требует ручного управления стилями и lifecycle элементов.
  • React API (@floating-ui/react) — использует хук useFloating, который возвращает координаты, refs и удобные функции для middleware.

Пример использования React API:

import { useFloating, offset, flip, shift } from '@floating-ui/react';

function Tooltip({ children }) {
  const { x, y, reference, floating } = useFloating({
    placement: 'top',
    middleware: [offset(5), flip(), shift()],
  });

  return (
    <>
      <button ref={reference}>{children}</button>
      <div ref={floating} style={{ position: 'absolute', top: y ?? 0, left: x ?? 0 }}>
        Tooltip content
      </div>
    </>
  );
}

Отличия:

  • В React API нет необходимости вручную вызывать computePosition и autoUpdate.
  • Хук интегрирует реактивность с жизненным циклом компонентов.

Поддержка нескольких элементов и динамических вложенных меню

Floating UI позволяет строить цепочки плавающих элементов, например, контекстные меню с подменю. Используются комбинации computePosition и middleware, чтобы каждый уровень меню правильно флипался и не выходил за пределы экрана.

computePosition(parentMenuItem, subMenu, {
  placement: 'right-start',
  middleware: [offset(4), flip(), shift({ padding: 10 })],
});

Особенности:

  • Middleware применяются для каждого уровня отдельно.
  • Можно задавать fallbackPlacements для разных сценариев открывания подменю.
  • Позволяет создавать сложные UI без хардкодинга координат.

Сравнение с устаревшими методами

Ранее для позиционирования часто использовались:

  • getBoundingClientRect() + ручная логика расчёта
  • CSS-свойства transform и top/left с привязкой к scroll

Floating UI решает все эти проблемы через:

  • Унифицированное API для координат и middleware
  • Автоматическую обработку коллизий с viewport
  • Поддержку стрелок и сложных вложенных структур
  • Режимы absolute и fixed, которые учитывают контекст и скролл

Эти различия делают Floating UI гибким инструментом для современных интерфейсов, позволяя сосредоточиться на логике приложения, а не на тонкостях расчёта позиций элементов.