import PropTypes from 'prop-types'; import { useCallback, useEffect, useRef, useState } from 'react'; import ReactTooltip from 'react-tooltip'; import styles from './OverflowText.module.css'; const OverflowText = ({ children, tooltipId }) => { const measureEl = useRef(); const [isOverflown, setIsOverflown] = useState(false); const measure = useCallback( el => { if (!el) return; setIsOverflown(el.scrollWidth > el.clientWidth); }, [setIsOverflown], ); // Do one measure on mount useEffect(() => { measure(measureEl.current); }, [measure]); // Set up resize listener for subsequent measures useEffect(() => { if (!measureEl.current) return; // Destructure ref in case it changes out from under us const el = measureEl.current; if ('ResizeObserver' in global) { // Ideally, we have access to ResizeObservers const observer = new ResizeObserver(() => { measure(el); }); observer.observe(el); return () => observer.unobserve(el); } else { // Otherwise, fall back to measuring on window resizes const handler = () => measure(el); window.addEventListener('resize', handler, { passive: true }); return () => window.removeEventListener('resize', handler, { passive: true }); } }); return ( {children} {isOverflown && {children}} ); }; OverflowText.propTypes = { children: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, tooltipId: PropTypes.string.isRequired, }; export default OverflowText;