В Popper.js объект state является центральной структурой, содержащей текущее состояние позиционирования поппера, а также все данные, необходимые для работы модификаторов. Он доступен внутри каждого модификатора через аргумент функции и включает в себя следующие ключевые поля:
reference и
popper, содержащий DOM-элементы привязки и поппера.reference и popper, где хранятся размеры и
координаты.top,
bottom-start, right-end и т.д.).absolute или fixed.Эта структура state позволяет модификаторам как читать текущее положение элементов, так и модифицировать его для достижения нужного поведения.
Для получения информации о текущем положении поппера используются поля rects и placement:
function logPopperPosition({ state }) {
console.log("Placement:", state.placement);
console.log("Reference rect:", state.rects.reference);
console.log("Popper rect:", state.rects.popper);
}
state.rects.reference содержит объект с полями
x, y, width, height
— размеры и координаты референс-элемента.state.rects.popper содержит аналогичные данные для
поппера.state.placement позволяет определить текущее
направление поппера, которое можно использовать для изменения логики
отображения (например, менять стрелку или смещать контент).Поппер.js предоставляет возможность изменять state
через модификаторы. Модификатор — это объект с обязательным полем
fn, функцией, которая принимает объект с ключами
{ state, name, options }.
Пример изменения позиции поппера с помощью модификатора:
const offsetModifier = {
name: 'customOffset',
enabled: true,
phase: 'main',
fn({ state, options }) {
const offsetX = options.offsetX || 0;
const offsetY = options.offsetY || 0;
state.styles.popper.left = `${parseFloat(state.styles.popper.left || 0) + offsetX}px`;
state.styles.popper.top = `${parseFloat(state.styles.popper.top || 0) + offsetY}px`;
},
options: {
offsetX: 10,
offsetY: 20
}
};
state.styles.popper — объект, где хранятся стили,
применяемые к попперу.Модификаторы выполняются в определённой последовательности, называемой фазами:
Каждая фаза позволяет изменять state в соответствии
с контекстом. Основная фаза main используется для
вычислений и обновления координат, write — для применения
изменений к DOM.
Поле modifiersData позволяет хранить промежуточные данные между вызовами модификаторов:
const storeDataModifier = {
name: 'storeData',
enabled: true,
phase: 'main',
fn({ state }) {
state.modifiersData.storeData = {
previousPlacement: state.placement,
popperHeight: state.rects.popper.height
};
}
};
modifiersData предотвращает повторные
расчёты и позволяет динамически адаптировать позиционирование.State позволяет не только читать, но и динамически изменять placement в зависимости от условий:
const flipPlacementModifier = {
name: 'conditionalFlip',
enabled: true,
phase: 'main',
fn({ state }) {
if (state.rects.popper.bottom > window.innerHeight) {
state.placement = 'top';
}
}
};
Изменение state.styles и state.attributes напрямую влияет на внешний вид и поведение поппера:
state.styles.popper.transform = 'translate3d(0, 10px, 0)';
state.attributes.popper = { 'data-show': true };
write.[data-show].Поле strategy определяет способ позиционирования:
absolute или fixed. Оно влияет на то, как
координаты в state.rects преобразуются в реальные
стили. Для fixed координаты привязаны к viewport, для
absolute — к ближайшему offsetParent.
if (state.strategy === 'fixed') {
// координаты относительно окна браузера
} else {
// координаты относительно родительского элемента
}
Использование state позволяет создавать гибкие, динамические модификаторы, обеспечивающие точное позиционирование поппера в любых условиях и сложных интерфейсах.