Options в state

Объект state в Popper.js является центральной структурой данных, которая хранит текущее состояние поппера, его позиции, размеры, а также параметры, переданные при инициализации. Важнейшей частью state является поле options, содержащее конфигурацию, определяющую поведение и внешний вид поппера. Понимание структуры и назначения state.options позволяет гибко управлять позиционированием и поведением всплывающих элементов.


Структура state.options

Поле options имеет тип объекта и включает следующие ключевые элементы:

state.options = {
  placement: 'bottom',      // базовое расположение поппера относительно reference
  modifiers: [],            // массив модификаторов для изменения поведения поппера
  strategy: 'absolute',     // стратегия позиционирования ('absolute' или 'fixed')
  onFirstUpdate: () => {},  // callback, вызываемый при первом обновлении
};

placement

  • Определяет начальное расположение поппера относительно элемента-опоры (reference).
  • Возможные значения: 'top', 'bottom', 'left', 'right', с вариациями -start и -end (например, 'bottom-start').
  • placement используется движком Popper.js для вычисления координат на основе размеров элементов и окна.

modifiers

  • Массив объектов, описывающих модификаторы.

  • Модификатор — это объект с ключами:

    {
      name: 'offset',
      options: { offset: [0, 10] },
      enabled: true,
      phase: 'main', // этап, на котором применяется модификатор
      fn: ({ state, options, name }) => { /* логика модификатора */ }
    }
  • В state.options.modifiers хранится список всех модификаторов, активных для текущего поппера.

  • Модификаторы могут менять положение, размеры, стрелки, ограничивать выход за границы окна и многое другое.

strategy

  • Определяет CSS-стратегию позиционирования элемента:

    • 'absolute' — поппер позиционируется относительно ближайшего предка с позиционированием;
    • 'fixed' — поппер фиксирован относительно окна.
  • В state.options.strategy хранится выбранная стратегия, которая используется движком при вычислении координат и генерации стилей.

onFirstUpdate

  • Callback, который выполняется один раз после первого расчета позиции.
  • Может использоваться для кастомной логики, например, динамического изменения placement или модификаторов при первой отрисовке.

Взаимодействие state.options с state.modifiersData

Каждый модификатор, указанный в state.options.modifiers, при выполнении функции fn получает доступ к state. В частности, state.modifiersData содержит промежуточные результаты работы других модификаторов:

state.modifiersData[name] = {...};

Пример: модификатор offset записывает рассчитанное смещение в state.modifiersData.offset. Это позволяет другим модификаторам учитывать уже примененные изменения при расчете финального положения.


Динамическое обновление state.options

Popper.js позволяет менять параметры конфигурации на лету, обновляя state.options через методы экземпляра popperInstance.setOptions():

popperInstance.setOptions({
  placement: 'top-end',
  modifiers: [
    { name: 'offset', options: { offset: [0, 20] } }
  ]
});
  • При этом происходит пересчет координат и повторное применение модификаторов.
  • Новые параметры перезаписывают старые, что обеспечивает гибкое управление поведением поппера.

Важные особенности и нюансы

  1. Приоритет модификаторов — порядок элементов в массиве modifiers определяет последовательность их применения. Модификаторы с более высоким приоритетом должны стоять раньше.
  2. Immutable Options — Popper.js не мутирует исходный объект конфигурации при инициализации. Все изменения происходят через state.options или методы экземпляра.
  3. Фаза применения — каждый модификатор имеет фазу (beforeRead, read, main, write), которая влияет на момент изменения данных в state.options и state.modifiersData.
  4. Совместимость с реактивными фреймворками — при изменении state.options внутри реактивной среды важно использовать методы Popper.js, а не прямую мутацию объекта, чтобы избежать рассинхронизации расчетов.

Пример комплексной конфигурации state.options

const popperOptions = {
  placement: 'bottom-start',
  strategy: 'fixed',
  modifiers: [
    { name: 'offset', options: { offset: [0, 12] }, enabled: true },
    { name: 'flip', options: { fallbackPlacements: ['top', 'right'] }, enabled: true },
    { name: 'preventOverflow', options: { padding: 8 }, enabled: true }
  ],
  onFirstUpdate: ({ state }) => {
    console.log('Поппер инициализирован с координатами', state.rects.popper);
  }
};
  • Этот пример демонстрирует использование нескольких модификаторов, фиксированного позиционирования и кастомного обработчика при первом обновлении.
  • Используя state.options, можно полностью контролировать поведение поппера в любых условиях.