feat: tooltip viewport clamping — shifts minimally to keep bounding box in view
This commit is contained in:
@@ -12,6 +12,26 @@ function getTooltipEl(): HTMLDivElement {
|
||||
return tooltipEl;
|
||||
}
|
||||
|
||||
function clamp(val: number, min: number, max: number) {
|
||||
return Math.min(Math.max(val, min), max);
|
||||
}
|
||||
|
||||
function positionTooltip(el: HTMLDivElement, cx: number, cy: number) {
|
||||
const margin = 6;
|
||||
// Start with ideal position: just right of and below cursor
|
||||
let x = cx + 12;
|
||||
let y = cy + 16;
|
||||
// Measure after content is set (element is in DOM, opacity-hidden is fine)
|
||||
const w = el.offsetWidth;
|
||||
const h = el.offsetHeight;
|
||||
// Shift left/right only as much as needed
|
||||
x = clamp(x, margin, window.innerWidth - w - margin);
|
||||
// Shift up/down only as much as needed
|
||||
y = clamp(y, margin, window.innerHeight - h - margin);
|
||||
el.style.left = `${x}px`;
|
||||
el.style.top = `${y}px`;
|
||||
}
|
||||
|
||||
export function tooltip(node: HTMLElement, text: string) {
|
||||
let timer: ReturnType<typeof setTimeout> | null = null;
|
||||
let currentText = text;
|
||||
@@ -22,8 +42,8 @@ export function tooltip(node: HTMLElement, text: string) {
|
||||
if (!currentText) return;
|
||||
const el = getTooltipEl();
|
||||
el.textContent = currentText;
|
||||
el.style.left = `${mouseX + 12}px`;
|
||||
el.style.top = `${mouseY + 16}px`;
|
||||
// Position before making visible — offsetWidth/Height valid since el is in DOM
|
||||
positionTooltip(el, mouseX, mouseY);
|
||||
el.classList.add(TOOLTIP_VISIBLE_CLASS);
|
||||
}
|
||||
|
||||
@@ -38,8 +58,7 @@ export function tooltip(node: HTMLElement, text: string) {
|
||||
mouseX = e.clientX;
|
||||
mouseY = e.clientY;
|
||||
if (!tooltipEl?.classList.contains(TOOLTIP_VISIBLE_CLASS)) return;
|
||||
tooltipEl.style.left = `${mouseX + 12}px`;
|
||||
tooltipEl.style.top = `${mouseY + 16}px`;
|
||||
positionTooltip(tooltipEl, mouseX, mouseY);
|
||||
}
|
||||
|
||||
function leave() {
|
||||
@@ -56,6 +75,7 @@ export function tooltip(node: HTMLElement, text: string) {
|
||||
currentText = newText;
|
||||
if (tooltipEl?.classList.contains(TOOLTIP_VISIBLE_CLASS)) {
|
||||
tooltipEl.textContent = newText;
|
||||
positionTooltip(tooltipEl, mouseX, mouseY);
|
||||
}
|
||||
},
|
||||
destroy() {
|
||||
|
||||
Reference in New Issue
Block a user