Функциональные значения

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


Принцип работы функциональных значений

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

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

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

computePosition(reference, element, {
  middleware: [
    offset(({ rects, placement }) => {
      if (placement === 'top') return 10;
      return 5;
    })
  ]
});

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


Использование функциональных значений в middleware

Практически все middleware Floating UI поддерживают функциональные значения:

  1. offset — вычисляет смещение от целевого элемента:
offset(({ rects }) => rects.reference.height / 2)
  1. shift — корректирует позицию, чтобы элемент не выходил за пределы видимой области:
shift(({ placement, x, y, rects }) => {
  if (x + rects.floating.width > window.innerWidth) {
    return { x: window.innerWidth - rects.floating.width - 10, y };
  }
  return { x, y };
})
  1. flip — меняет сторону размещения в зависимости от доступного пространства:
flip(({ placement, middlewareData }) => {
  return placement.startsWith('top') ? 'bottom' : 'top';
})

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


Функциональные значения для стилей

Floating UI также позволяет использовать функциональные значения при расчёте стилей для элементов. Например, можно вычислять transform в зависимости от позиции:

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

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

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

Здесь offset использует функциональное значение, которое автоматически корректирует позицию в зависимости от ориентации тултипа.


Аргументы функциональных значений

Функции в middleware получают объект с актуальной информацией о положении элементов:

  • rects — объект с размерами reference и floating элементов.
  • placement — текущее предпочтительное размещение (top, bottom, left, right).
  • strategy — стратегия позиционирования (absolute или fixed).
  • middlewareData — данные, переданные или изменённые другими middleware.

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


Примеры сложных функциональных значений

  1. Динамический отступ на основе размеров контента
offset(({ rects }) => Math.max(10, rects.reference.width * 0.1))
  1. Автоматический выбор цвета или прозрачности
import { computePosition } from '@floating-ui/dom';

const dynamicOpacity = ({ rects, placement }) => {
  return placement.startsWith('bottom') ? 0.9 : 0.7;
};
  1. Комбинирование нескольких middleware с функциональными значениями
computePosition(reference, floating, {
  middleware: [
    offset(({ placement }) => placement === 'top' ? 8 : 12),
    flip(),
    shift(({ x, y, rects }) => {
      return { x: Math.max(0, x), y: Math.max(0, y) };
    })
  ]
});

Такой подход позволяет создать полностью адаптивный и предсказуемый интерфейс, который реагирует на любые изменения размеров, прокрутки и окна браузера.


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