const tooltip = (element: HTMLElement) => { let tooltipDiv: HTMLDivElement | null = null; const offset = 10; const tooltipTransitionTime = 200; const tooltipHideDelay = 10; let hideTimeout: number | undefined = undefined; const createTooltip = () => { if (!tooltipDiv) { tooltipDiv = document.createElement('div'); tooltipDiv.style.position = 'absolute'; tooltipDiv.style.zIndex = '1000'; tooltipDiv.style.opacity = '0'; tooltipDiv.style.transition = `opacity ${tooltipTransitionTime}ms ease-in-out`; tooltipDiv.style.pointerEvents = 'none'; tooltipDiv.style.whiteSpace = 'nowrap'; tooltipDiv.classList.add('card'); tooltipDiv.classList.add('card-small'); document.body.appendChild(tooltipDiv); } }; const updateTooltipPosition = (x: number, y: number) => { if (tooltipDiv) { const tooltipWidth = tooltipDiv.offsetWidth; const tooltipHeight = tooltipDiv.offsetHeight; let top = y - tooltipHeight - offset; let left = x - tooltipWidth / 2; if (left < 0) left = offset; if (left + tooltipWidth > window.innerWidth) left = window.innerWidth - tooltipWidth - offset; if (top < 0) top = y + offset; tooltipDiv.style.left = `${left}px`; tooltipDiv.style.top = `${top}px`; } }; const showTooltip = (content: string, x: number, y: number) => { clearTimeout(hideTimeout); createTooltip(); if (tooltipDiv) { tooltipDiv.innerHTML = content; updateTooltipPosition(x, y); setTimeout(() => { if (tooltipDiv) tooltipDiv.style.opacity = '1'; }, 10); } }; const hideTooltip = () => { hideTimeout = window.setTimeout(() => { if (tooltipDiv) { tooltipDiv.style.opacity = '0'; setTimeout(() => { if (tooltipDiv) { document.body.removeChild(tooltipDiv); tooltipDiv = null; } }, tooltipTransitionTime); } }, tooltipHideDelay); }; element.addEventListener('mouseenter', (event) => { const title = element.getAttribute('title'); if (title) { element.removeAttribute('title'); showTooltip(title, event.pageX, event.pageY); } }); element.addEventListener('mousemove', (event) => { if (tooltipDiv && tooltipDiv.style.opacity === '1') updateTooltipPosition(event.pageX, event.pageY); }); element.addEventListener('mouseleave', () => { element.setAttribute('title', tooltipDiv ? tooltipDiv.textContent || '' : ''); hideTooltip(); }); return { destroy() { element.removeEventListener('mouseenter', showTooltip as unknown as EventListener); element.removeEventListener('mousemove', updateTooltipPosition as unknown as EventListener); element.removeEventListener('mouseleave', hideTooltip as EventListener); if (hideTimeout) clearTimeout(hideTimeout); if (tooltipDiv && document.body.contains(tooltipDiv)) { document.body.removeChild(tooltipDiv); tooltipDiv = null; } } }; }; export default tooltip;