From 65f760a2540ede4964903682d8b0cbf2f48df722 Mon Sep 17 00:00:00 2001 From: Falkan Date: Thu, 19 Mar 2026 00:05:09 -0400 Subject: [PATCH] =?UTF-8?q?fix:=20tooltip=20positioning=20=E2=80=94=20meas?= =?UTF-8?q?ure=20after=20rAF,=20shift=20up=20minimally=20to=20fit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data/units.json | 6 ++++-- src/lib/actions/tooltip.ts | 37 +++++++++++++++++-------------------- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/data/units.json b/data/units.json index bca6695..faf7d98 100644 --- a/data/units.json +++ b/data/units.json @@ -253,7 +253,9 @@ "labelPlural": "fathoms", "symbol": "ftm", "group": "lengths-and-distance", - "toBase": 1828.8 + "toBase": 1828.8, + "description": "The conversion of dickloads to fathoms is based on a 1' x 1' x 1ftm column of pure water at 4 degrees celsius. Obviously.", + "hidden": false } ], "groups": [ @@ -270,7 +272,7 @@ "id": "lengths-and-distance", "label": "Lengths and Distance", "baseUnitId": "mm", - "toUniversal": 1, + "toUniversal": 14.2332177486, "alwaysShowLabel": false, "hidden": false } diff --git a/src/lib/actions/tooltip.ts b/src/lib/actions/tooltip.ts index 8197e23..93c148f 100644 --- a/src/lib/actions/tooltip.ts +++ b/src/lib/actions/tooltip.ts @@ -29,19 +29,27 @@ export function tooltip(node: HTMLElement, text: string) { if (!currentText) return; const el = getTooltipEl(); el.textContent = currentText; + + // Position off-screen first so we can measure dimensions after render + el.style.left = '-9999px'; + el.style.top = '-9999px'; el.classList.add('hu-tooltip--visible'); - // Position near cursor, clamped to viewport with 8px margin + // Use rAF to let the browser lay out the element before measuring + requestAnimationFrame(() => { + position(el, e.clientX, e.clientY); + }); + } + + function position(el: HTMLDivElement, cx: number, cy: number) { const margin = 8; 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 + const x = Math.min(cx + 12, window.innerWidth - w - margin); + // Place below cursor; shift up only as much as needed to fit + let y = cy + 20; + const overflow = y + h + margin - window.innerHeight; + if (overflow > 0) y -= overflow; y = Math.max(margin, y); el.style.left = `${x}px`; el.style.top = `${y}px`; @@ -55,18 +63,7 @@ export function tooltip(node: HTMLElement, text: string) { function move(e: MouseEvent) { // Keep tooltip near cursor while hovering if (!tooltipEl?.classList.contains('hu-tooltip--visible')) return; - const el = getTooltipEl(); - const margin = 8; - 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.top = `${y}px`; + position(getTooltipEl(), e.clientX, e.clientY); } function leave() {