import React from 'react';
import { useState, useRef, useEffect, forwardRef } from 'react';
import cn from 'classnames';
import { Popup } from 'UI';
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) => (
{ textOrChildren }
))
const 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 (
)
return (
{ hintText || textOrChildren } }
{ ...popupProps }
>
);
};
TextEllipsis.displayName ="TextEllipsis";
export default TextEllipsis;