/**
* Ultimate Liquid Tooltip System (TXA Tooltip V2)
* High performance, mouse-following, glassmorphism design
* Supports data-txa-tooltip, data-txatooltip, and .txatooltip class
*/
(function () {
'use strict';
if (window.isTxaTooltipInit) return;
window.isTxaTooltipInit = true;
const tooltip = document.getElementById('txa-tooltip') || document.createElement('div');
if (!tooltip.id) {
tooltip.id = 'txa-tooltip';
tooltip.style.cssText = `
position: fixed;
pointer-events: none;
z-index: 2147483647;
padding: 12px 18px;
background: rgba(15, 23, 42, 0.96);
backdrop-filter: blur(20px) saturate(180%);
-webkit-backdrop-filter: blur(20px) saturate(180%);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 16px;
color: #fff;
font-size: 14px;
font-weight: 500;
box-shadow: 0 20px 50px rgba(0,0,0,0.6), 0 0 20px rgba(99, 102, 241, 0.2);
opacity: 0;
transform: scale(0.95) translateY(10px);
transition: opacity 0.3s cubic-bezier(0.16, 1, 0.3, 1), transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);
white-space: normal;
max-width: 320px;
line-height: 1.6;
text-align: left;
word-break: break-word;
font-family: 'Outfit', sans-serif;
`;
}
function initTooltip() {
if (!document.body) {
window.addEventListener('DOMContentLoaded', initTooltip);
return;
}
if (!document.getElementById('txa-tooltip')) {
document.body.appendChild(tooltip);
}
}
window.initTxaTooltips = initTooltip;
initTooltip();
document.addEventListener('astro:page-load', initTooltip);
let currentTarget = null;
let hideTimeout = null;
let isMouseOnTooltip = false;
tooltip.addEventListener('mouseenter', () => {
isMouseOnTooltip = true;
clearTimeout(hideTimeout);
});
tooltip.addEventListener('mouseleave', () => {
isMouseOnTooltip = false;
if (!currentTarget) hideTooltip();
});
function showTooltip(text, target, e = null) {
if (!text) return;
clearTimeout(hideTimeout);
const link = target.getAttribute('data-tooltip-link');
const linkTitle = target.getAttribute('data-tooltip-link-title') || 'Xem chi tiết';
let content = `
${text}
`;
if (link) {
content += `
`;
tooltip.style.pointerEvents = 'auto';
} else {
tooltip.style.pointerEvents = 'none';
}
tooltip.innerHTML = content;
// Dynamic alignment
tooltip.style.textAlign = text.length > 40 ? 'left' : 'center';
tooltip.style.opacity = '1';
tooltip.style.transform = 'scale(1) translateY(0)';
currentTarget = target;
if (e) {
updatePosition(e);
}
}
function hideTooltip() {
if (isMouseOnTooltip) return;
hideTimeout = setTimeout(() => {
if (isMouseOnTooltip) return;
tooltip.style.opacity = '0';
tooltip.style.transform = 'scale(0.95) translateY(10px)';
currentTarget = null;
}, 100);
}
function updatePosition(e) {
if (tooltip.style.opacity === '0' || isMouseOnTooltip) return;
const offset = 20;
const rect = tooltip.getBoundingClientRect();
let x = e.clientX - (rect.width / 2);
let y = e.clientY - rect.height - offset;
const padding = 15;
if (x < padding) x = padding;
if (x + rect.width + padding > window.innerWidth) {
x = window.innerWidth - rect.width - padding;
}
if (y < padding) {
y = e.clientY + offset;
}
tooltip.style.left = x + 'px';
tooltip.style.top = y + 'px';
}
document.addEventListener('mouseover', (e) => {
const target = e.target.closest('[data-txa-tooltip], [data-txatooltip], .txatooltip, .txaxtooltip');
if (target) {
// Logic for sidebar menu items (collapsed state)
if (target.classList.contains('menu-item') || target.classList.contains('sidebar-link')) {
const isSidebarCollapsed = document.body.classList.contains('sidebar-collapsed');
if (!isSidebarCollapsed && window.innerWidth > 992) return;
}
const tooltipText = target.getAttribute('data-txa-tooltip') || target.getAttribute('data-txatooltip') || target.title;
if (tooltipText) {
// Remove title to prevent browser default tooltip
if (target.title) {
target.setAttribute('data-original-title', target.title);
target.title = '';
}
showTooltip(tooltipText, target, e);
}
}
});
document.addEventListener('mouseout', (e) => {
const target = e.target.closest('[data-txa-tooltip], [data-txatooltip], .txatooltip, .txaxtooltip');
if (target) {
// Restore title if needed
const originalTitle = target.getAttribute('data-original-title');
if (originalTitle) {
target.title = originalTitle;
target.removeAttribute('data-original-title');
}
hideTooltip();
}
});
document.addEventListener('mousemove', (e) => {
if (currentTarget) updatePosition(e);
});
document.addEventListener('click', (e) => {
if (!tooltip.contains(e.target)) hideTooltip();
});
// Fullscreen support
function handleFullscreenChange() {
const fsElem = document.fullscreenElement || document.webkitFullscreenElement;
if (fsElem) {
fsElem.appendChild(tooltip);
tooltip.style.zIndex = '2147483647';
} else {
if (document.body && !document.body.contains(tooltip)) {
document.body.appendChild(tooltip);
}
}
}
document.addEventListener('fullscreenchange', handleFullscreenChange);
document.addEventListener('webkitfullscreenchange', handleFullscreenChange);
})();