Комбинации middleware для типичных задач

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

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


Смещение и управление отступами

offset – один из базовых middleware, позволяющий добавлять фиксированное смещение относительно якоря. Он принимает объект с параметрами mainAxis и crossAxis:

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

const middleware = [
  offset({ mainAxis: 10, crossAxis: 5 })
];
  • mainAxis – смещение вдоль основной оси (обычно вертикальной при placement: 'bottom').
  • crossAxis – смещение вдоль поперечной оси.

Комбинируется с другими middleware для точного позиционирования:

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

const middleware = [
  offset({ mainAxis: 8 }),
  flip(),
  shift({ padding: 5 })
];

Такой набор позволяет:

  1. Добавлять небольшой отступ.
  2. Менять позицию, если всплывающее окно выходит за пределы видимой области.
  3. Корректировать положение при пересечении границ контейнера.

Ограничение области отображения

Middleware shift отвечает за предотвращение выхода элемента за границы контейнера или viewport. Основные опции:

  • padding – внутренний отступ от границ.
  • boundary – контейнер, в пределах которого нужно удерживать элемент.
  • crossAxis – применять ли корректировку по поперечной оси.

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

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

const middleware = [
  offset({ mainAxis: 12 }),
  flip(),
  shift({ padding: 10, crossAxis: true })
];

В этой комбинации middleware обеспечивают:

  • Смещение от якоря.
  • Автоматическое отражение при нехватке места.
  • Подстраивание под границы окна или контейнера.

Автоматическое перемещение и адаптивная смена позиции

Middleware flip динамически меняет направление всплывающего элемента, если он не помещается в исходной позиции. Он поддерживает настройку возможных альтернативных позиций через опцию fallbackPlacements:

flip({
  fallbackPlacements: ['top', 'right', 'left']
})

Пример полной комбинации для выпадающего меню:

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

const middleware = [
  offset({ mainAxis: 6 }),
  flip({ fallbackPlacements: ['top', 'left'] }),
  shift({ padding: 8 }),
  arrow({ element: arrowElement, padding: 5 })
];

Здесь происходят несколько операций:

  1. Смещение по основной оси.
  2. Автоматическое изменение позиции при нехватке места.
  3. Корректировка позиции относительно границ.
  4. Размещение стрелки (arrow) с учетом отступов.

Работа со стрелками и выравнивание

Middleware arrow позволяет точно позиционировать стрелку относительно якоря. Важно учитывать следующие моменты:

  • Элемент стрелки должен быть отдельным DOM-узлом.
  • padding задаёт минимальное расстояние от краев всплывающего элемента.
  • Используется вместе с другими middleware (shift и flip) для корректного позиционирования:
arrow({ element: arrowEl, padding: 5 })

Использование после shift и flip гарантирует, что стрелка корректно сместится при отражении элемента или его подгонке к границам.


Пример типичной комбинации для tooltip

Для подсказки, которая должна смещаться, не выходить за границы и иметь стрелку:

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

const middleware = [
  offset({ mainAxis: 10 }),
  flip(),
  shift({ padding: 5 }),
  arrow({ element: tooltipArrow, padding: 4 })
];

Последовательность действий middleware:

  1. offset – добавляет базовое смещение.
  2. flip – меняет направление, если нет места.
  3. shift – корректирует положение по границам.
  4. arrow – устанавливает стрелку относительно текущей позиции.

Применение нескольких кастомных middleware

Floating UI позволяет создавать свои middleware, расширяя стандартный набор. Например, middleware для затемнения фона при открытии всплывающего окна:

function dimBackground() {
  return {
    name: 'dimBackground',
    fn({ elements }) {
      elements.floating.style.backgroundColor = 'rgba(0,0,0,0.1)';
      return {};
    }
  };
}

const middleware = [
  offset({ mainAxis: 8 }),
  flip(),
  dimBackground()
];

Комбинации кастомных и встроенных middleware позволяют решать уникальные задачи, сохраняя логичную последовательность выполнения.


Рекомендации по организации middleware

  • Сначала базовые смещения, затем корректировки относительно границ (offset → flip → shift).
  • Middleware с побочными эффектами (например, arrow) лучше размещать последними.
  • Кастомные функции должны возвращать объект { x, y } или пустой объект, чтобы не ломать цепочку.
  • Для сложных UI компонентов полезно создавать конфигурации middleware как отдельные константы для повторного использования.

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