59 lines
1.6 KiB
JavaScript
59 lines
1.6 KiB
JavaScript
import React, { useState, useEffect } from 'react';
|
|
|
|
/**
|
|
* RuneScape-style tooltip component
|
|
* Follows mouse cursor and displays formatted text
|
|
*/
|
|
export default function Tooltip({ content, visible, mousePosition }) {
|
|
const [position, setPosition] = useState({ x: 0, y: 0 });
|
|
const [tooltipHeight, setTooltipHeight] = useState(0);
|
|
|
|
useEffect(() => {
|
|
if (visible && mousePosition) {
|
|
const { x, y } = mousePosition;
|
|
|
|
// Position above cursor
|
|
const top = Math.max(0, y - tooltipHeight);
|
|
|
|
// Position to right of cursor, but flip to left if past halfway point
|
|
let left = x + 2;
|
|
if (left >= window.innerWidth / 2) {
|
|
left = x - 2; // Will be adjusted by transform for actual width
|
|
}
|
|
|
|
setPosition({ x: left, y: top });
|
|
}
|
|
}, [mousePosition, visible, tooltipHeight]);
|
|
|
|
useEffect(() => {
|
|
// Measure tooltip height after render
|
|
const tooltip = document.getElementById('rs-tooltip');
|
|
if (tooltip) {
|
|
setTooltipHeight(tooltip.offsetHeight);
|
|
}
|
|
}, [content, visible]);
|
|
|
|
if (!visible || !content) {
|
|
return null;
|
|
}
|
|
|
|
const style = {
|
|
position: 'fixed',
|
|
top: `${position.y}px`,
|
|
left: `${position.x}px`,
|
|
backgroundColor: 'rgba(0, 0, 0, 0.8)',
|
|
border: '1px solid rgba(255, 255, 255, 0.2)',
|
|
padding: '4px',
|
|
pointerEvents: 'none',
|
|
zIndex: 10000,
|
|
color: 'white',
|
|
fontSize: '12px',
|
|
whiteSpace: 'nowrap',
|
|
transform: position.x >= window.innerWidth / 2 ? 'translateX(-100%)' : 'translateX(0)',
|
|
};
|
|
|
|
return (
|
|
<div id="rs-tooltip" style={style} dangerouslySetInnerHTML={{ __html: content }} />
|
|
);
|
|
}
|