stash/ui/v2.5/src/components/Shared/TruncatedText.tsx
DingDongSoLong4 50c4ac98af
Thumbnail scrubber improvements (#4081)
* Remove deps from useDebounce hook
* Add useThrottle hook
* Throttle preview scrubber
* Scrubber improvements
2023-09-08 11:33:16 +10:00

68 lines
1.7 KiB
TypeScript

import React, { useRef, useState } from "react";
import { Overlay, Tooltip } from "react-bootstrap";
import { Placement } from "react-bootstrap/Overlay";
import cx from "classnames";
import { useDebounce } from "src/hooks/debounce";
const CLASSNAME = "TruncatedText";
const CLASSNAME_TOOLTIP = `${CLASSNAME}-tooltip`;
interface ITruncatedTextProps {
text?: JSX.Element | string | null;
lineCount?: number;
placement?: Placement;
delay?: number;
className?: string;
}
export const TruncatedText: React.FC<ITruncatedTextProps> = ({
text,
className,
lineCount = 1,
placement = "bottom",
delay = 1000,
}) => {
const [showTooltip, setShowTooltip] = useState(false);
const target = useRef(null);
const startShowingTooltip = useDebounce(() => setShowTooltip(true), delay);
if (!text) return <></>;
const handleFocus = (element: HTMLElement) => {
// Check if visible size is smaller than the content size
if (
element.offsetWidth < element.scrollWidth ||
element.offsetHeight + 10 < element.scrollHeight
)
startShowingTooltip();
};
const handleBlur = () => {
startShowingTooltip.cancel();
setShowTooltip(false);
};
const overlay = (
<Overlay target={target.current} show={showTooltip} placement={placement}>
<Tooltip id={CLASSNAME} className={CLASSNAME_TOOLTIP}>
{text}
</Tooltip>
</Overlay>
);
return (
<div
className={cx(CLASSNAME, className)}
style={{ WebkitLineClamp: lineCount }}
ref={target}
onMouseEnter={(e) => handleFocus(e.currentTarget)}
onFocus={(e) => handleFocus(e.currentTarget)}
onMouseLeave={handleBlur}
onBlur={handleBlur}
>
{text}
{overlay}
</div>
);
};