Popper.js — это библиотека для управления позиционированием элементов относительно других элементов на странице, часто используется для создания всплывающих подсказок, тултипов, дропдаунов и модальных окон. Основной принцип работы Popper.js заключается в том, чтобы динамически рассчитывать положение элемента (поппера) относительно целевого элемента (reference) с учётом ограничений пространства и видимой области браузера.
Создание экземпляра Popper осуществляется через конструктор
createPopper(reference, popper, options), где:
Пример базовой инициализации:
import { createPopper } from '@popperjs/core';
const button = document.querySelector('#button');
const tooltip = document.querySelector('#tooltip');
const popperInstance = createPopper(button, tooltip, {
placement: 'top',
modifiers: [
{
name: 'offset',
options: {
offset: [0, 8],
},
},
],
});
В данном примере поппер будет располагаться сверху относительно кнопки с отступом 8 пикселей.
Popper.js использует модификаторы для управления поведением поппера. Основные модификаторы:
Пример использования нескольких модификаторов:
createPopper(button, tooltip, {
placement: 'right',
modifiers: [
{ name: 'offset', options: { offset: [10, 20] } },
{ name: 'preventOverflow', options: { padding: 5 } },
{ name: 'flip', options: { fallbackPlacements: ['top', 'bottom'] } },
],
});
Здесь поппер будет смещён на 10px по горизонтали и 20px по вертикали, а при нехватке места автоматически перевернётся на верх или низ.
Popper.js предоставляет метод update(), который
пересчитывает позиции поппера в реальном времени. Он возвращает промис,
что позволяет использовать асинхронные операции:
popperInstance.update().then(() => {
console.log('Позиция поппера обновлена');
});
Если требуется часто пересчитывать позицию, можно использовать метод
forceUpdate(), который выполняет пересчёт синхронно, без
промиса.
Popper.js активно используется вместе с фреймворками. Для React
существует официальный пакет @popperjs/react, который
позволяет управлять позиционированием через хуки и компоненты. Пример
использования хука usePopper:
import { usePopper } from 'react-popper';
const [referenceElement, setReferenceElement] = useState(null);
const [popperElement, setPopperElement] = useState(null);
const { styles, attributes } = usePopper(referenceElement, popperElement, {
placement: 'bottom',
});
return (
<>
<button ref={setReferenceElement}>Кнопка</button>
<div ref={setPopperElement} style={styles.popper} {...attributes.popper}>
Тултип
</div>
</>
);
Для Vue используется директива v-popper или компонентный
подход с привязкой элементов через refs.
При интеграционных тестах Popper.js проверяется не только логика позиционирования, но и визуальная корректность расположения элементов относительно DOM. Основные подходы:
getBoundingClientRect() поппера с ожидаемыми значениями
относительно reference.Пример интеграционного теста на Jest с jsdom:
import { createPopper } from '@popperjs/core';
test('Поппер позиционируется сверху кнопки', () => {
document.body.innerHTML = `
<button id="btn">Кнопка</button>
<div id="popper">Тултип</div>
`;
const button = document.querySelector('#btn');
const tooltip = document.querySelector('#popper');
const popperInstance = createPopper(button, tooltip, { placement: 'top' });
const btnRect = button.getBoundingClientRect();
const popperRect = tooltip.getBoundingClientRect();
expect(popperRect.bottom).toBeLessThanOrEqual(btnRect.top);
});
Тест проверяет, что тултип появляется сверху кнопки. Аналогично можно тестировать flip, offset и другие модификаторы.
cy.get().should('have.css', ...).Popper.js позволяет гибко управлять положением элементов, а интеграционные тесты обеспечивают стабильность интерфейса при сложной логике пользовательских взаимодействий. Использование модификаторов и методов обновления создаёт надёжную и предсказуемую систему позиционирования, пригодную для любых интерфейсных компонентов.