import React, { useState, useRef, useLayoutEffect } from "react"; import { uniqueId } from "lodash"; import classnames from "classnames"; import ReactTooltip from "react-tooltip"; import { DEFAULT_EMPTY_CELL_VALUE } from "utilities/constants"; import { COLORS } from "styles/var/colors"; interface ITooltipTruncatedTextCellProps { value: React.ReactNode; /** Tooltip to display. If this is provided then this will be rendered as the tooltip content. If * not, the value will be displayed as the tooltip content. Default: undefined */ tooltip?: React.ReactNode; /** If set to `true` the text inside the tooltip will break on words instead of any character. * By default the tooltip text breaks on any character. Default: false */ tooltipBreakOnWord?: boolean; className?: string; /** Content does not get truncated */ prefix?: React.ReactNode; /** Content does not get truncated */ suffix?: React.ReactNode; } const baseClass = "tooltip-truncated-cell"; const TooltipTruncatedTextCell = ({ value, tooltip, tooltipBreakOnWord = false, className, prefix, suffix, }: ITooltipTruncatedTextCellProps): JSX.Element => { const classNames = classnames(baseClass, className, { "tooltip-break-on-word": tooltipBreakOnWord, }); // Tooltip visibility logic: Enable only when text is truncated const ref = useRef(null); const [tooltipDisabled, setTooltipDisabled] = useState(true); useLayoutEffect(() => { if (ref?.current !== null) { const scrollWidth = ref.current.scrollWidth; const offsetWidth = ref.current.offsetWidth; setTooltipDisabled(scrollWidth <= offsetWidth); } }, [ref]); // End const tooltipId = uniqueId(); value = value === null || value === undefined || value === "" ? DEFAULT_EMPTY_CELL_VALUE : value; const isDefaultValue = value === DEFAULT_EMPTY_CELL_VALUE; return (
{prefix && {prefix}}
{value}
<> {tooltip ?? value}
 
{/* Fixes triple click selecting next element in Safari */}
{suffix && {suffix}}
); }; export default TooltipTruncatedTextCell;