world-simulator / frontend /src /components /TooltipLabel.tsx
DeltaZN
Refactor frontend panels and default to vLLM
0092d86
Raw
History Blame Contribute Delete
1.9 kB
import type { ReactNode } from "react";
import { useLayoutEffect, useRef, useState } from "react";
type TooltipLabelProps = {
value: string;
className?: string;
children?: ReactNode;
};
export function TooltipLabel({ value, className, children }: TooltipLabelProps) {
const classes = ["tooltipAnchor", className].filter(Boolean).join(" ");
const labelRef = useRef<HTMLSpanElement>(null);
const measureRef = useRef<HTMLSpanElement>(null);
const [isCollapsed, setIsCollapsed] = useState(false);
useLayoutEffect(() => {
const labelElement = labelRef.current;
const measureElement = measureRef.current;
if (!labelElement || !measureElement) {
return undefined;
}
const updateCollapsedState = () => {
const styles = window.getComputedStyle(labelElement);
const horizontalPadding =
Number.parseFloat(styles.paddingLeft) + Number.parseFloat(styles.paddingRight);
const availableWidth = labelElement.clientWidth - horizontalPadding;
const fullTextWidth = measureElement.getBoundingClientRect().width;
setIsCollapsed(fullTextWidth > availableWidth + 1);
};
updateCollapsedState();
const resizeObserver = new ResizeObserver(updateCollapsedState);
resizeObserver.observe(labelElement);
resizeObserver.observe(measureElement);
window.addEventListener("resize", updateCollapsedState);
return () => {
resizeObserver.disconnect();
window.removeEventListener("resize", updateCollapsedState);
};
}, [value, children]);
return (
<span
ref={labelRef}
className={classes}
data-tooltip={isCollapsed ? value : undefined}
tabIndex={isCollapsed ? 0 : undefined}
>
<span className="truncateText">{children ?? value}</span>
<span ref={measureRef} className="tooltipMeasure" aria-hidden="true">
{value}
</span>
</span>
);
}