// tooltip.js function createTooltip(button, tooltipText) { const tooltip = document.createElement('div'); const arrow = document.createElement('div'); arrow.id = 'arrow'; arrow.setAttribute('data-popper-arrow', ''); tooltip.id = 'tooltip'; tooltip.textContent = tooltipText; tooltip.appendChild(arrow); document.body.appendChild(tooltip); const popperInstance = Popper.createPopper(button, tooltip, { modifiers: [ { name: 'offset', options: { offset: [0, 8], }, }, ], }); let hideTimeout = null; let isMouseOverButton = false; let isMouseOverTooltip = false; function show() { // Clear any pending hide timeout if (hideTimeout) { clearTimeout(hideTimeout); hideTimeout = null; } tooltip.setAttribute('data-show', ''); popperInstance.setOptions((options) => ({ ...options, modifiers: [ ...options.modifiers, { name: 'eventListeners', enabled: true }, ], })); popperInstance.update(); } function hide() { // Only hide if mouse is not over button or tooltip if (isMouseOverButton || isMouseOverTooltip) { return; } // Use a delay to allow moving from button to tooltip hideTimeout = setTimeout(() => { // Double check before hiding if (!isMouseOverButton && !isMouseOverTooltip) { tooltip.removeAttribute('data-show'); popperInstance.setOptions((options) => ({ ...options, modifiers: [ ...options.modifiers, { name: 'eventListeners', enabled: false }, ], })); } hideTimeout = null; }, 150); // 150ms delay to allow mouse movement to tooltip } function handleButtonEnter() { isMouseOverButton = true; show(); } function handleButtonLeave() { isMouseOverButton = false; hide(); } function handleTooltipEnter() { isMouseOverTooltip = true; // Clear any pending hide if (hideTimeout) { clearTimeout(hideTimeout); hideTimeout = null; } show(); } function handleTooltipLeave() { isMouseOverTooltip = false; hide(); } const showEvents = ['mouseenter', 'focus']; const hideEvents = ['mouseleave', 'blur']; showEvents.forEach((event) => { button.addEventListener(event, handleButtonEnter); }); hideEvents.forEach((event) => { button.addEventListener(event, handleButtonLeave); }); // Keep tooltip visible when hovering over it tooltip.addEventListener('mouseenter', handleTooltipEnter); tooltip.addEventListener('mouseleave', handleTooltipLeave); return { destroy: () => { if (hideTimeout) { clearTimeout(hideTimeout); } tooltip.removeEventListener('mouseenter', handleTooltipEnter); tooltip.removeEventListener('mouseleave', handleTooltipLeave); tooltip.remove(); popperInstance.destroy(); showEvents.forEach((event) => { button.removeEventListener(event, handleButtonEnter); }); hideEvents.forEach((event) => { button.removeEventListener(event, handleButtonLeave); }); }, }; } // Expose the function as a global variable window.createTooltip = createTooltip;