Popper.js — это мощная библиотека для управления позиционированием всплывающих элементов относительно других элементов на странице. Ключевым аспектом её использования является понимание основных сущностей и их типов, что обеспечивает корректное взаимодействие и предотвращает ошибки во время разработки.
Popper Instance — это объект, создаваемый функцией
createPopper, который управляет положением всплывающего
элемента относительно целевого элемента (reference element). Типичная
структура объекта выглядит следующим образом:
const popperInstance = createPopper(reference, popper, options);
Тип объекта popperInstance включает методы:
update() — пересчитывает и обновляет положение
Popper.destroy() — уничтожает Popper и очищает слушатели
событий.setOptions(options) — позволяет динамически изменять
конфигурацию.interface PopperInstance {
update: () => Promise<void>;
destroy: () => void;
setOptions: (options: Partial<Options>) => Promise<void>;
}
Reference element и Popper element всегда являются DOM-элементами:
type ElementLike = HTMLElement | SVGElement | null;
reference — элемент, на основе которого вычисляется
позиция.popper — элемент, который отображается относительно
reference.Важно учитывать, что Popper.js корректно работает только с реальными
элементами DOM. Передача null допустима только при
динамическом рендеринге и требует проверки на существование элемента
перед созданием Popper.
Объект options определяет конфигурацию Popper и имеет
следующие ключевые поля:
interface Options {
placement?: Placement;
modifiers?: Array<Modifier<any, any>>;
strategy?: 'absolute' | 'fixed';
}
'auto' | 'top' | 'bottom' | 'left' | 'right' |
'top-start' | 'top-end' | 'bottom-start' | 'bottom-end' |
'right-start' | 'right-end' | 'left-start' | 'left-end'
name,
enabled, phase, fn,
options.interface Modifier<Name = string, Options = any> {
name: Name;
enabled?: boolean;
phase?: 'beforeRead' | 'read' | 'afterRead' |
'beforeMain' | 'main' | 'afterMain' |
'beforeWrite' | 'write' | 'afterWrite';
fn?: ModifierFn<any>;
options?: Options;
}
absolute или fixed.Placement — это комбинация основной позиции
(top, bottom, left,
right) и вариации (start,
end).
start или end) задаёт смещение
по оси поперёк основной позиции.type Placement =
| 'auto'
| 'top'
| 'bottom'
| 'right'
| 'left'
| 'top-start'
| 'top-end'
| 'bottom-start'
| 'bottom-end'
| 'right-start'
| 'right-end'
| 'left-start'
| 'left-end';
Модификаторы — это ключевой инструмент настройки Popper.js. Каждый модификатор имеет:
Пример модификатора offset:
const offsetModifier: Modifier<'offset', { offset: [number, number] }> = {
name: 'offset',
options: { offset: [0, 8] },
enabled: true,
phase: 'main',
fn: ({ state, options }) => {
state.styles.popper.top += options.offset[1];
state.styles.popper.left += options.offset[0];
}
};
Состояние Popper хранится в объекте state и содержит
актуальные данные о позиции и размерах:
interface State {
elements: { reference: ElementLike; popper: ElementLike };
styles: { [key: string]: Partial<CSSStyleDeclaration> };
attributes: { [key: string]: Record<string, string> };
placement: Placement;
modifiersData: { [key: string]: any };
}
data-popper-placement).Strategy определяет тип позиционирования Popper:
absolute — относительно ближайшего позиционированного
предка.fixed — относительно окна браузера.Выбор стратегии влияет на вычисления размеров и смещений, особенно при использовании скролла и динамических контейнеров.
Для точного позиционирования Popper.js использует геометрические объекты:
interface Rect {
x: number;
y: number;
width: number;
height: number;
}
type ReferenceRect = Rect;
type PopperRect = Rect;
x, y — координаты относительно
viewport.width, height — размеры элемента.Эти объекты формируются автоматически и используются в расчетах модификаторов.
Popper.js строго разделяет:
reference,
popper)options,
modifiers)state,
styles, attributes)Это позволяет обеспечивать предсказуемое и безопасное позиционирование, минимизируя ошибки при работе с динамическими интерфейсами и адаптивными компонентами.
Хотите, могу продолжить и сделать раздел с подробной типизацией модификаторов с примером TypeScript? Это сильно углубит понимание структуры Popper.js.