FloatingArrow

FloatingArrow — это модуль в библиотеке Floating UI, предназначенный для управления визуальным указателем (стрелкой), который соединяет всплывающий элемент (popper, tooltip, dropdown) с целевым элементом на странице. Он решает ключевую задачу: обеспечить точное позиционирование стрелки независимо от размеров и положения окна, сохраняя плавность адаптации при динамических изменениях интерфейса.


Импорт и базовое использование

Для работы со стрелкой необходимо импортировать модуль arrow из @floating-ui/dom (для веб-приложений) или @floating-ui/react-dom (для React):

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

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

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

  const { x: arrowX, y: arrowY } = middlewareData.arrow;
  Object.assign(arrowElement.style, {
    left: arrowX != null ? `${arrowX}px` : '',
    top: arrowY != null ? `${arrowY}px` : '',
  });
});

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

  • element — ссылка на DOM-элемент стрелки.
  • padding — минимальное расстояние между стрелкой и границами всплывающего элемента, предотвращающее её смещение за пределы контейнера.
  • middlewareData.arrow содержит координаты x и y для точного позиционирования стрелки.

Параметры и их влияние

  1. element Обязательный параметр. Без него стрелка не будет позиционироваться. Обычно это <div> или <span> внутри всплывающего контейнера.

  2. padding Позволяет задать отступ стрелки от краев всплывающего элемента. Удобно при округлых границах или при необходимости оставить визуальный зазор.

  3. axis Можно ограничить движение стрелки по одной оси:

    arrow({ element: arrowElement, axis: 'x' });

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

  4. crossAxis Управляет смещением стрелки перпендикулярно основной оси всплывающего элемента. Позволяет избежать столкновений со скругленными краями или границами контейнера.


Использование с другими middleware

FloatingArrow тесно интегрируется с другими middleware Floating UI:

  • offset — задаёт расстояние между reference и floating элементом.
  • flip — обеспечивает автоматический переворот всплывающего элемента при нехватке места. Стрелка при этом корректно адаптируется.
  • shift — предотвращает выход всплывающего элемента за границы видимой области. Стрелка смещается вместе с элементом.

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


Динамическое обновление позиции стрелки

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

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

autoUpdate(reference, floating, () => {
  computePosition(reference, floating, {
    middleware: [offset(10), flip(), shift({ padding: 5 }), arrow({ element: arrowElement })],
  }).then(({ x, y, middlewareData }) => {
    Object.assign(floating.style, { left: `${x}px`, top: `${y}px` });
    const { x: arrowX, y: arrowY } = middlewareData.arrow;
    Object.assign(arrowElement.style, { left: arrowX != null ? `${arrowX}px` : '', top: arrowY != null ? `${arrowY}px` : '' });
  });
});

Такое решение позволяет стрелке оставаться идеально выровненной даже при прокрутке страницы или изменении размеров окна.


Создание адаптивных стрелок

  • Процентное смещение: Стрелку можно позиционировать в процентах относительно ширины или высоты всплывающего элемента. Это удобно для динамических контентных блоков.

  • CSS-перетекания: Можно использовать transform: translate(-50%, -50%) для плавного центрирования, особенно если стрелка имеет сложную форму или декоративные эффекты.

  • Интерактивные элементы: В tooltip или dropdown стрелка может быть кликабельной или анимированной. FloatingArrow не ограничивает стилизацию — координаты остаются точными.


Практические советы

  1. Всегда задавать фиксированные размеры стрелки через CSS (width, height) для корректного расчета.
  2. Учитывать padding middleware arrow, если есть скругленные края или декоративные рамки.
  3. Для сложных интерфейсов использовать axis и crossAxis для предотвращения некорректного смещения.
  4. Проверять работу стрелки при всех вариантах flip() — особенно при ограниченной ширине окна.

FloatingArrow превращает обычный tooltip или popper в профессионально выверенный интерфейсный компонент, обеспечивая согласованность позиционирования и плавность адаптации к любым изменениям DOM.