Приоритеты размещения

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

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


Настройка позиции через placement

Базовая конфигурация начинается с свойства placement:

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

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

computePosition(reference, floating, {
  placement: 'top',
});

Значение placement может быть любым из следующих:

  • top, bottom, left, right — основные стороны.
  • top-start, top-end, bottom-start, bottom-end — вариации с выравниванием.
  • auto — позволяет библиотеке выбрать оптимальное место автоматически.

Когда placement установлен как одиночное значение (top, bottom и т.д.), оно становится первым приоритетом, а библиотека будет пытаться разместить элемент именно там, прежде чем пробовать альтернативы.


Массив приоритетов через middleware

Для более сложного управления используется комбинация middleware с flip и shift.

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

computePosition(reference, floating, {
  placement: 'top',
  middleware: [
    flip({
      fallbackPlacements: ['right', 'bottom', 'left'],
    }),
    shift({ padding: 5 }),
  ],
});

Разбор ключевых моментов:

  1. flip — отвечает за автоматическую смену позиции, если основная недоступна.

    • fallbackPlacements задаёт список альтернативных местоположений в порядке приоритета.
    • В примере, если top не помещается, библиотека попробует right, затем bottom, затем left.
  2. shift — гарантирует, что элемент не выйдет за пределы видимой области, смещая его при необходимости.

    • padding задаёт минимальный отступ от края экрана.

Комбинирование приоритетов для сложных интерфейсов

В интерфейсах с ограниченным пространством часто необходимо учитывать несколько критериев одновременно:

  • Основное место размещения по дизайну (placement).
  • Доступное пространство вокруг элемента (flip).
  • Подгонка внутри контейнера или окна (shift).
  • Ограничения по размеру элемента (size middleware).

Пример конфигурации с контролем размеров:

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

computePosition(reference, floating, {
  placement: 'bottom',
  middleware: [
    flip({ fallbackPlacements: ['top', 'right'] }),
    shift({ padding: 10 }),
    size({
      apply({ rects, availableWidth, availableHeight, elements }) {
        Object.assign(elements.floating.style, {
          maxWidth: `${availableWidth}px`,
          maxHeight: `${availableHeight}px`,
        });
      },
    }),
  ],
});

Здесь size позволяет динамически ограничивать размеры всплывающего элемента, чтобы он не выходил за доступное пространство. При этом flip и shift сохраняют порядок приоритетов размещения.


Практическое использование приоритетов

  1. Простые тултипы: Используется базовое placement с flip. Часто достаточно пары fallback-значений.

  2. Дропдауны и модальные панели: Рекомендуется комбинировать flip, shift и size. Приоритеты важны для корректного отображения в мобильной версии и при изменении размера окна.

  3. Кастомные сложные компоненты: Можно создавать динамические списки приоритетов на основе анализа размера контейнера и положения элемента на странице. Это позволяет библиотеке выбирать оптимальное место из нескольких вариантов, не ломая дизайн.


Важные нюансы приоритетов

  • Последовательность fallbackPlacements имеет значение — библиотека проверяет их строго по порядку.
  • middleware исполняются по цепочке, и порядок влияет на итоговую позицию.
  • shift и size не заменяют flip, а лишь корректируют позицию и размеры, сохраняя приоритеты.
  • Для динамически изменяющихся интерфейсов можно вызывать computePosition повторно при изменении размера окна или положения триггера, чтобы приоритеты оставались актуальными.

Итоговые рекомендации по приоритетам

  • Задавать основной placement как первую попытку.
  • Использовать flip с аккуратно выбранными fallbackPlacements для контролируемого поведения.
  • Добавлять shift и size для соблюдения ограничений пространства.
  • При сложных интерфейсах создавать динамические списки fallback-значений в зависимости от контекста элемента.

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