mirror of
https://github.com/netbirdio/netbird.git
synced 2026-07-18 04:29:54 +00:00
43 lines
1.3 KiB
TypeScript
43 lines
1.3 KiB
TypeScript
import { useLayoutEffect, useRef, useState, type ReactNode } from "react";
|
|
import { Tooltip } from "@/components/Tooltip";
|
|
|
|
type Props = {
|
|
text: string;
|
|
className?: string;
|
|
tooltipContent?: ReactNode;
|
|
delayDuration?: number;
|
|
};
|
|
|
|
// Renders text with `truncate`; measures scrollWidth vs clientWidth after
|
|
// layout and wraps in a Tooltip only when the text actually overflows. Avoids
|
|
// the "tooltip on hover even though everything fits" annoyance. The caller
|
|
// supplies the wrapper styling (font, max-width, etc.) via className — this
|
|
// component only owns the truncate + measure + tooltip behavior.
|
|
export const TruncatedText = ({
|
|
text,
|
|
className,
|
|
tooltipContent,
|
|
delayDuration = 600,
|
|
}: Props) => {
|
|
const ref = useRef<HTMLSpanElement>(null);
|
|
const [overflowing, setOverflowing] = useState(false);
|
|
|
|
useLayoutEffect(() => {
|
|
const el = ref.current;
|
|
if (!el) return;
|
|
setOverflowing(el.scrollWidth > el.clientWidth);
|
|
}, [text]);
|
|
|
|
const span = (
|
|
<span ref={ref} className={className}>
|
|
{text}
|
|
</span>
|
|
);
|
|
if (!overflowing) return span;
|
|
return (
|
|
<Tooltip content={tooltipContent ?? text} delayDuration={delayDuration}>
|
|
{span}
|
|
</Tooltip>
|
|
);
|
|
};
|