feat: add tooltip utility for hover labels
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
// Tooltip positioning options
|
||||
type TooltipPosition = 'left' | 'right' | 'above';
|
||||
|
||||
const TOOLTIP_STYLE = `
|
||||
position: absolute;
|
||||
background: #1a1a2e;
|
||||
border: 2px solid #7878d8;
|
||||
color: #e0d0b0;
|
||||
font-family: 'Press Start 2P', monospace;
|
||||
font-size: 10px;
|
||||
padding: 4px 8px;
|
||||
white-space: nowrap;
|
||||
pointer-events: none;
|
||||
z-index: 10000;
|
||||
`;
|
||||
|
||||
/**
|
||||
* Attach a hover tooltip to an element.
|
||||
* Returns a cleanup function to remove the listeners.
|
||||
*/
|
||||
export function attachTooltip(
|
||||
element: HTMLElement,
|
||||
text: string,
|
||||
position: TooltipPosition = 'right',
|
||||
): () => void {
|
||||
let tooltip: HTMLDivElement | null = null;
|
||||
|
||||
const show = () => {
|
||||
tooltip = document.createElement('div');
|
||||
tooltip.style.cssText = TOOLTIP_STYLE;
|
||||
tooltip.textContent = text;
|
||||
document.body.appendChild(tooltip);
|
||||
|
||||
const rect = element.getBoundingClientRect();
|
||||
const tipRect = tooltip.getBoundingClientRect();
|
||||
|
||||
switch (position) {
|
||||
case 'right':
|
||||
tooltip.style.left = `${rect.right + 6}px`;
|
||||
tooltip.style.top = `${rect.top + (rect.height - tipRect.height) / 2}px`;
|
||||
break;
|
||||
case 'left':
|
||||
tooltip.style.left = `${rect.left - tipRect.width - 6}px`;
|
||||
tooltip.style.top = `${rect.top + (rect.height - tipRect.height) / 2}px`;
|
||||
break;
|
||||
case 'above':
|
||||
tooltip.style.left = `${rect.left + (rect.width - tipRect.width) / 2}px`;
|
||||
tooltip.style.top = `${rect.top - tipRect.height - 6}px`;
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const hide = () => {
|
||||
if (tooltip) {
|
||||
tooltip.remove();
|
||||
tooltip = null;
|
||||
}
|
||||
};
|
||||
|
||||
element.addEventListener('mouseenter', show);
|
||||
element.addEventListener('mouseleave', hide);
|
||||
|
||||
return () => {
|
||||
element.removeEventListener('mouseenter', show);
|
||||
element.removeEventListener('mouseleave', hide);
|
||||
hide();
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user