openreplay/frontend/app/components/ui/TextEllipsis/TextEllipsis.js
Андрей Бабушкин b822b1c067 applied eslint
2025-02-26 20:31:01 +01:00

115 lines
2.6 KiB
JavaScript

import React, {
useState, useRef, useEffect, forwardRef,
} from 'react';
import cn from 'classnames';
import { Tooltip } from 'antd';
import styles from './textEllipsis.module.css';
/** calculates text width in pixels
* by creating a hidden element with
* text and counting its width
* @param text String - text string
* @param fontProp String - font properties
* @returns width number
*/
function findTextWidth(text, fontProp) {
const tag = document.createElement('div');
tag.style.position = 'absolute';
tag.style.left = '-99in';
tag.style.whiteSpace = 'nowrap';
tag.style.font = fontProp;
tag.innerHTML = text;
document.body.appendChild(tag);
const result = tag.clientWidth;
document.body.removeChild(tag);
return result;
}
const Trigger = forwardRef(({
textOrChildren, maxWidth, style, className, ...rest
}, ref) => (
<div
className={cn(styles.textEllipsis, className)}
style={{ maxWidth, ...style }}
ref={ref}
{...rest}
>
{textOrChildren}
</div>
));
function TextEllipsis({
text,
hintText = text,
children = null,
maxWidth = 'auto',
style = {},
className = '',
noHint = false,
popupProps = {},
hintProps = {},
...props
}) {
const [showPopup, setShowPopup] = useState(false);
const [computed, setComputed] = useState(false);
const textRef = useRef(null);
const textOrChildren = text || children;
const popupId = (Math.random() + 1).toString(36).substring(2);
useEffect(() => {
if (computed) return;
if (textRef.current) {
const element = textRef.current;
const fontSize = window.getComputedStyle(element, null).getPropertyValue('font-size');
const textWidth = findTextWidth(element.innerText, fontSize);
if (textWidth > element.clientWidth) setShowPopup(true);
else setShowPopup(false);
setComputed(true);
}
}, [textRef.current, computed]);
if (noHint || !showPopup) {
return (
<Trigger
className={className}
maxWidth={maxWidth}
style={style}
textOrChildren={textOrChildren}
ref={textRef}
{...props}
/>
);
}
return (
<Tooltip
title={(
<div className="customPopupText" {...hintProps}>
{hintText || textOrChildren}
</div>
)}
{...popupProps}
>
<Trigger
className={className}
maxWidth={maxWidth}
style={style}
textOrChildren={textOrChildren}
id={popupId}
ref={textRef}
{...props}
/>
</Tooltip>
);
}
TextEllipsis.displayName = 'TextEllipsis';
export default TextEllipsis;