Popper.js — это мощная библиотека для создания динамических всплывающих элементов, таких как тултипы, всплывающие меню и подсказки, которые позиционируются относительно других элементов на странице. В основе работы Popper.js лежит концепция поппера (popper — всплывающий элемент) и референс-элемента (reference element), относительно которого этот поппер размещается.
Поппер создаётся через конструктор Popper или через
функцию createPopper. Основная структура:
import { createPopper } from '@popperjs/core';
const referenceElement = document.querySelector('#button');
const popperElement = document.querySelector('#tooltip');
const popperInstance = createPopper(referenceElement, popperElement, {
placement: 'top', // место размещения: top, bottom, left, right
modifiers: [],
});
referenceElement — элемент, к которому будет привязан
поппер.popperElement — сам всплывающий элемент.placement — позиция относительно
референс-элемента.modifiers — массив объектов, которые изменяют поведение
поппера.Модификаторы позволяют контролировать динамическое поведение поппера:
modifiers: [
{
name: 'offset',
options: {
offset: [0, 8], // по оси X и Y
},
},
]
modifiers: [
{
name: 'flip',
options: {
fallbackPlacements: ['bottom', 'right'],
},
},
]
modifiers: [
{
name: 'preventOverflow',
options: {
boundary: 'viewport',
},
},
]
Popper.js использует TypeScript Generic типы для
строгой типизации конфигураций, что обеспечивает безопасность и
автокомплитацию. Основной generic тип — это
<Modifiers>, который позволяет указать набор
модификаторов, используемых для конкретного поппера.
import type { Modifier, Placement } from '@popperjs/core';
interface MyModifiers extends Array<Modifier<any, any>> {}
const popperInstance = createPopper<HTMLButtonElement, HTMLDivElement, MyModifiers>(
referenceElement,
popperElement,
{
placement: 'top',
modifiers: [
{ name: 'offset', options: { offset: [0, 10] } },
],
}
);
<HTMLButtonElement, HTMLDivElement, MyModifiers>
— типы для референса, поппера и модификаторов.Создание собственного модификатора требует указания типа:
const customModifier: Modifier<'myModifier', { factor: number }> = {
name: 'myModifier',
enabled: true,
phase: 'write',
fn({ state, options }) {
const factor = options.factor;
state.styles.popper.top = `${parseFloat(state.styles.popper.top) * factor}px`;
},
options: {
factor: 1.5,
},
};
Modifier<'myModifier', { factor: number }> —
generic тип, где первый параметр имя модификатора, второй — структура
опций.options и
предотвратить ошибки.Generic типы обеспечивают возможность расширять стандартные модификаторы:
type ExtendedModifiers = Modifier<'offset', { offset: [number, number] }> | Modifier<'flip', { fallbackPlacements: Placement[] }>;
const popperInstance = createPopper<HTMLDivElement, HTMLDivElement, ExtendedModifiers>(
referenceElement,
popperElement,
{
placement: 'right',
modifiers: [
{ name: 'offset', options: { offset: [0, 15] } },
{ name: 'flip', options: { fallbackPlacements: ['bottom'] } },
],
}
);
Generic типы применяются также к колбэкам модификаторов:
type ModifierFn<Options = any> = (args: {
state: any;
instance: any;
options: Options;
}) => void;
const logModifier: ModifierFn<{ prefix: string }> = ({ state, options }) => {
console.log(options.prefix, state);
};
options.Generic типы в Popper.js делают библиотеку безопасной, масштабируемой и удобной для интеграции в проекты на TypeScript. Они позволяют описывать сложное поведение попперов без потери контроля над типами и предотвращают распространённые ошибки на этапе компиляции.