86 lines
1.8 KiB
TypeScript

import { useEffect, useRef, useState } from "react";
import { cn } from "@/lib/utils";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
interface Props {
children: React.ReactNode;
className?: string;
contentClassName?: string;
}
export default function LongText({
children,
className = "",
contentClassName = "",
}: Props) {
const ref = useRef<HTMLDivElement>(null);
const [isOverflown, setIsOverflown] = useState(false);
useEffect(() => {
if (checkOverflow(ref.current)) {
setIsOverflown(true);
return;
}
setIsOverflown(false);
}, []);
if (!isOverflown)
return (
<div ref={ref} className={cn("truncate", className)}>
{children}
</div>
);
return (
<>
<div className="hidden sm:block">
<TooltipProvider delayDuration={0}>
<Tooltip>
<TooltipTrigger asChild>
<div ref={ref} className={cn("truncate", className)}>
{children}
</div>
</TooltipTrigger>
<TooltipContent>
<p className={contentClassName}>{children}</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
<div className="sm:hidden">
<Popover>
<PopoverTrigger asChild>
<div ref={ref} className={cn("truncate", className)}>
{children}
</div>
</PopoverTrigger>
<PopoverContent className={cn("w-fit", contentClassName)}>
<p>{children}</p>
</PopoverContent>
</Popover>
</div>
</>
);
}
const checkOverflow = (textContainer: HTMLDivElement | null) => {
if (textContainer) {
return (
textContainer.offsetHeight < textContainer.scrollHeight ||
textContainer.offsetWidth < textContainer.scrollWidth
);
}
return false;
};