mirror of
https://github.com/fleetdm/fleet
synced 2026-05-24 09:28:54 +00:00
## For #27667 - Have `TooltipTruncatedText` component use `useCheckTruncatedElement` to track its current state of truncation. - Update `useCheckTruncatedElement` to re-evaluate truncation state based on changes to the width of the element itself as opposed to changes to viewport width. This facilitates truncation when the width of the element is updated due to user interaction / change in UI state other than window resize, e.g. checking a policy in the policy software automations modal (see issue description for details reproduction instructions there). **Truncation with tooltip successful for UI state changes:**  Truncation with tooltip successful for viewport resizing:   - [x] Changes file added for user-visible changes in `changes/⁄ - [x] Manual QA for all new/changed functionality --------- Co-authored-by: Jacob Shandling <jacob@fleetdm.com>
65 lines
2.1 KiB
TypeScript
65 lines
2.1 KiB
TypeScript
import React, { useRef } from "react";
|
|
import { uniqueId } from "lodash";
|
|
import classnames from "classnames";
|
|
|
|
import ReactTooltip from "react-tooltip";
|
|
import { COLORS } from "styles/var/colors";
|
|
import { useCheckTruncatedElement } from "hooks/useCheckTruncatedElement";
|
|
|
|
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;
|
|
}
|
|
|
|
const baseClass = "tooltip-truncated-text";
|
|
|
|
const TooltipTruncatedText = ({
|
|
value,
|
|
tooltip,
|
|
tooltipBreakOnWord = false,
|
|
className,
|
|
}: 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<HTMLInputElement>(null);
|
|
const isTruncated = useCheckTruncatedElement(ref);
|
|
|
|
const tooltipId = uniqueId();
|
|
return (
|
|
<div className={classNames}>
|
|
<div className="tooltip-truncated" data-tip data-for={tooltipId}>
|
|
<div ref={ref} className={isTruncated ? "truncated" : undefined}>
|
|
{value}
|
|
</div>
|
|
</div>
|
|
<ReactTooltip
|
|
place="top"
|
|
effect="solid"
|
|
backgroundColor={COLORS["tooltip-bg"]}
|
|
id={tooltipId}
|
|
data-html
|
|
className="truncated-tooltip" // responsive widths
|
|
clickable
|
|
delayHide={200} // need delay set to hover using clickable
|
|
disable={!isTruncated}
|
|
>
|
|
<>
|
|
{tooltip ?? value}
|
|
<div className="safari-hack"> </div>
|
|
{/* Fixes triple click selecting next element in Safari */}
|
|
</>
|
|
</ReactTooltip>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default TooltipTruncatedText;
|