Tippy.js — это высоко настраиваемая библиотека для создания всплывающих подсказок и элементов интерфейса поверх HTML-элементов. Контекстные меню представляют собой особый тип всплывающих элементов, которые отображаются по клику правой кнопкой мыши или по определённым событиям пользователя. В Tippy.js такие меню строятся на основе инстансов Tippy, что позволяет гибко управлять их поведением и стилем.
import tippy from 'tippy.js';
import 'tippy.js/dist/tippy.css';
const contextMenu = tippy(document.querySelector('#menuTarget'), {
content: '<ul><li>Пункт 1</li><li>Пункт 2</li><li>Пункт 3</li></ul>',
allowHTML: true,
interactive: true,
trigger: 'manual',
placement: 'right-start',
animation: 'shift-away',
});
В этом примере создаётся всплывающее меню, которое не появляется
автоматически, а управляется вручную через методы .show() и
.hide(). Атрибут interactive: true позволяет
взаимодействовать с содержимым меню, например, нажимать на пункты
списка.
Контекстное меню традиционно открывается по событию
contextmenu (правая кнопка мыши). Tippy.js позволяет
переопределить стандартные триггеры:
const target = document.querySelector('#menuTarget');
target.addEventListener('contextmenu', (event) => {
event.preventDefault();
contextMenu[0].setProps({
getReferenceClientRect: () => ({
width: 0,
height: 0,
top: event.clientY,
bottom: event.clientY,
left: event.clientX,
right: event.clientX,
}),
});
contextMenu[0].show();
});
Использование getReferenceClientRect позволяет точно
позиционировать меню в точке клика, а
event.preventDefault() предотвращает стандартное системное
меню браузера.
Для контекстного меню критично, чтобы оно не исчезало при наведении курсора на элементы внутри. В Tippy.js это достигается через:
interactive: true — разрешает взаимодействие с
содержимым.hideOnClick: true | false | 'toggle' — контролирует
поведение при кликах вне меню.onShow, onHide,
onMount для управления динамическим содержимым.Пример динамического меню с обработкой кликов:
const dynamicMenu = tippy(target, {
content: '',
allowHTML: true,
interactive: true,
trigger: 'manual',
onShow(instance) {
instance.setContent(`
<ul>
<li id="action1">Действие 1</li>
<li id="action2">Действие 2</li>
</ul>
`);
document.getElementById('action1').oncl ick = () => { console.log('Action 1'); instance.hide(); };
document.getElementById('action2').oncl ick = () => { console.log('Action 2'); instance.hide(); };
},
});
Tippy.js использует Popper.js под капотом, что позволяет автоматически корректировать позицию меню при недостатке места на экране. Основные опции позиционирования:
placement — направление относительно целевого элемента
(top, bottom, left,
right, с модификаторами -start,
-end).offset — смещение по горизонтали и вертикали.flip — автоматическое изменение позиции при
переполнении видимой области.boundary — определяет контейнер для проверки выхода за
границы.tippy(target, {
content: 'Меню',
placement: 'bottom-start',
offset: [0, 10],
flip: true,
interactive: true,
});
Tippy.js позволяет использовать собственные CSS-классы для оформления
контекстных меню. Атрибут theme или className
задаёт стиль, который можно определить в CSS:
tippy(target, {
content: '<ul><li>Пункт A</li><li>Пункт B</li></ul>',
allowHTML: true,
interactive: true,
theme: 'custom-menu',
});
CSS пример:
.tippy-box[data-theme~='custom-menu'] {
background-color: #2c3e50;
color: #ecf0f1;
border-radius: 6px;
padding: 8px;
}
.tippy-box[data-theme~='custom-menu'] ul {
margin: 0;
padding: 0;
list-style: none;
}
.tippy-box[data-theme~='custom-menu'] li {
padding: 6px 12px;
cursor: pointer;
}
.tippy-box[data-theme~='custom-menu'] li:hover {
background-color: #34495e;
}
При работе с несколькими элементами важно создавать отдельные инстансы для каждого таргета или использовать делегирование:
tippy.delegate(document.body, {
target: '.has-menu',
content: 'Динамическое меню',
allowHTML: true,
interactive: true,
trigger: 'manual',
});
Метод delegate позволяет привязать одно поведение ко
многим элементам без необходимости создавать отдельный инстанс для
каждого.
fade, scale, shift-away) и
позволяет подключать кастомные.onCreate,
onMount, onShow, onHide,
onDestroy дают полный контроль над поведением меню.Tippy.js сочетает гибкость позиционирования, богатую настройку интерактивности и возможности визуальной кастомизации, делая создание контекстных меню простым и эффективным.