fix: tooltip flips above cursor when it would clip viewport bottom

This commit is contained in:
Falkan
2026-03-18 23:58:40 -04:00
parent 52fc0b826f
commit c13db8b826

View File

@@ -29,13 +29,22 @@ export function tooltip(node: HTMLElement, text: string) {
if (!currentText) return; if (!currentText) return;
const el = getTooltipEl(); const el = getTooltipEl();
el.textContent = currentText; el.textContent = currentText;
el.classList.add('hu-tooltip--visible');
// Position near cursor, clamped to viewport // Position near cursor, clamped to viewport with 8px margin
const x = Math.min(e.clientX + 12, window.innerWidth - el.offsetWidth - 8); const margin = 8;
const y = e.clientY + 20; const w = el.offsetWidth;
const h = el.offsetHeight;
const x = Math.min(e.clientX + 12, window.innerWidth - w - margin);
// Try below cursor first; if it clips the bottom, flip above
let y = e.clientY + 20;
if (y + h + margin > window.innerHeight) {
y = e.clientY - h - 12;
}
// Final clamp: don't go above top of viewport
y = Math.max(margin, y);
el.style.left = `${x}px`; el.style.left = `${x}px`;
el.style.top = `${y}px`; el.style.top = `${y}px`;
el.classList.add('hu-tooltip--visible');
} }
function enter(e: MouseEvent) { function enter(e: MouseEvent) {
@@ -47,8 +56,15 @@ export function tooltip(node: HTMLElement, text: string) {
// Keep tooltip near cursor while hovering // Keep tooltip near cursor while hovering
if (!tooltipEl?.classList.contains('hu-tooltip--visible')) return; if (!tooltipEl?.classList.contains('hu-tooltip--visible')) return;
const el = getTooltipEl(); const el = getTooltipEl();
const x = Math.min(e.clientX + 12, window.innerWidth - el.offsetWidth - 8); const margin = 8;
const y = e.clientY + 20; const w = el.offsetWidth;
const h = el.offsetHeight;
const x = Math.min(e.clientX + 12, window.innerWidth - w - margin);
let y = e.clientY + 20;
if (y + h + margin > window.innerHeight) {
y = e.clientY - h - 12;
}
y = Math.max(margin, y);
el.style.left = `${x}px`; el.style.left = `${x}px`;
el.style.top = `${y}px`; el.style.top = `${y}px`;
} }