Бандлинг с Vite

Popper.js — это мощная библиотека для позиционирования всплывающих элементов, таких как тултипы, поповеры и dropdown-меню. Для интеграции с Vite важно правильно настроить пакет и сборку.

Установка через npm

npm install @popperjs/core

Vite автоматически обрабатывает модули ES, поэтому дополнительных конфигураций для работы с Popper.js не требуется. После установки библиотеку можно импортировать в проект:

import { createPopper } from '@popperjs/core';

Настройка структуры проекта

Рекомендуется создавать отдельную директорию для компонентов, использующих Popper.js, например components/ui. Структура может выглядеть так:

src/
 ├─ components/
 │   ├─ ui/
 │   │   ├─ Tooltip.js
 │   │   ├─ Popover.js
 ├─ main.js

Это позволит легко масштабировать проект и использовать Popper.js в нескольких местах без дублирования кода.


Основы работы с Popper.js

Инициализация Popper

Popper.js работает через функцию createPopper, которая принимает три аргумента:

  1. reference — элемент, к которому привязывается всплывающее окно.
  2. popper — сам всплывающий элемент.
  3. options — объект с конфигурацией позиционирования.

Пример базовой инициализации:

const button = document.querySelector('#button');
const tooltip = document.querySelector('#tooltip');

createPopper(button, tooltip, {
  placement: 'top',
});

Ключевой параметр placement задает позицию всплывающего окна относительно reference. Доступные значения:

  • top, bottom, left, right
  • top-start, top-end, bottom-start, bottom-end и аналогично для боковых сторон.

Настройка модификаторов

Модификаторы — это способ тонко настроить поведение Popper.js. Основные модификаторы:

  • offset — смещение поппера относительно reference. Пример:
createPopper(button, tooltip, {
  placement: 'top',
  modifiers: [
    {
      name: 'offset',
      options: {
        offset: [0, 8], // [по горизонтали, по вертикали]
      },
    },
  ],
});
  • preventOverflow — предотвращает выход поппера за границы окна.
  • flip — автоматически меняет позицию, если нет места на выбранной стороне.
modifiers: [
  { name: 'flip', options: { fallbackPlacements: ['bottom', 'right'] } },
  { name: 'preventOverflow', options: { padding: 10 } },
]

Интеграция с Vite и современными фреймворками

Использование с Vue 3

<template>
  <button ref="button">Наведи меня</button>
  <div ref="tooltip" class="tooltip">Инструментальная подсказка</div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import { createPopper } from '@popperjs/core';

const button = ref(null);
const tooltip = ref(null);

onMounted(() => {
  createPopper(button.value, tooltip.value, {
    placement: 'right',
    modifiers: [{ name: 'offset', options: { offset: [0, 10] } }],
  });
});
</script>

<style>
.tooltip {
  background: #333;
  color: #fff;
  padding: 6px 12px;
  border-radius: 4px;
  font-size: 14px;
}
</style>

Использование с React

import React, { useRef, useEffect } from 'react';
import { createPopper } from '@popperjs/core';

export default function Tooltip() {
  const buttonRef = useRef(null);
  const tooltipRef = useRef(null);

  useEffect(() => {
    const popperInstance = createPopper(buttonRef.current, tooltipRef.current, {
      placement: 'bottom',
      modifiers: [{ name: 'offset', options: { offset: [0, 12] } }],
    });

    return () => popperInstance.destroy();
  }, []);

  return (
    <>
      <button ref={buttonRef}>Наведите курсор</button>
      <div ref={tooltipRef} className="tooltip">Подсказка</div>
    </>
  );
}

Продвинутая конфигурация Popper.js

Автоматическое обновление позиции

Popper.js может автоматически обновлять позицию при изменении размера окна или содержимого:

createPopper(button, tooltip, {
  placement: 'top',
  modifiers: [{ name: 'eventListeners', enabled: true }],
});

Использование strategy

Свойство strategy позволяет управлять типом позиционирования:

  • absolute — обычное позиционирование.
  • fixed — фиксированное относительно окна.
createPopper(button, tooltip, {
  strategy: 'fixed',
  placement: 'bottom',
});

Пользовательские модификаторы

Можно создавать свои модификаторы для расширенной логики:

const customModifier = {
  name: 'customFade',
  enabled: true,
  phase: 'write',
  fn({ state }) {
    state.elements.popper.style.opacity = '0.8';
  },
};

createPopper(button, tooltip, {
  modifiers: [customModifier],
});

Оптимизация для Vite

  • Использовать ESM импорты, так как Vite не требует CommonJS транспиляции.
  • Минимизировать количество вызовов createPopper, чтобы не создавать лишние экземпляры.
  • Объединять стили тултипов через CSS или Tailwind, чтобы не перегружать JS код.
  • В больших приложениях хранить экземпляры Popper.js в контексте компонентов для управления их жизненным циклом.

Практические рекомендации

  • Выбирать placement с учётом адаптивного дизайна.
  • Использовать offset и preventOverflow, чтобы всплывающие окна не обрезались на мобильных устройствах.
  • Разделять Popper на модульные компоненты для упрощения тестирования и повторного использования.
  • Активно применять пользовательские модификаторы для сложной анимации или интерактивного поведения.

Popper.js в связке с Vite обеспечивает быструю и стабильную работу интерактивных элементов интерфейса, полностью совместимую с современными фреймворками и методологиями разработки.