UNPKG

@spaced-out/ui-design-system

Version:
105 lines (92 loc) 2.63 kB
// @flow strict import * as React from 'react'; import debounce from 'lodash/debounce'; import {useWindowSize} from '../../hooks/useWindowSize'; import classify from '../../utils/classify'; import {ConditionalWrapper} from '../ConditionalWrapper'; import type {BaseTooltipProps} from '../Tooltip'; import {Tooltip} from '../Tooltip'; import css from './TruncatedTextWithTooltip.module.css'; type ClassNames = $ReadOnly<{wrapper?: string}>; export type TruncatedTextWithTooltipProps = { children?: React.Node, tooltip?: BaseTooltipProps, classNames?: ClassNames, line?: number, wordBreak?: string, wrapText?: boolean, ... }; export const TruncatedTextWithTooltip = ({ classNames, children, tooltip, wrapText = false, line = 1, wordBreak = 'break-all', ...props }: TruncatedTextWithTooltipProps): React.Node => { const {width} = useWindowSize(); const [showMouseTip, setShowMouseTip] = React.useState(false); const truncatedRef = React.useRef<?HTMLSpanElement>(); const checkIfTextOverflowing = React.useMemo( () => debounce( () => { if ( !wrapText && truncatedRef && truncatedRef.current && truncatedRef.current.scrollHeight > truncatedRef.current.clientHeight ) { setShowMouseTip(true); } else { setShowMouseTip(false); } }, 200, {leading: true}, ), [], ); React.useEffect(() => { checkIfTextOverflowing(); }, [width, line, children, wrapText]); const styles = { '--line-clamp': wrapText ? 'unset' : line, '--word-break': wordBreak, }; return ( <ConditionalWrapper condition={Boolean(showMouseTip)} wrapper={(children) => { const child = React.Children.only(children); //Vivek: This children in tooltip body is modified to remove line clamp style const modifiedChild = React.cloneElement(child, { style: { '--line-clamp': tooltip?.bodyMaxLines || line, '--word-break': wordBreak, }, }); return ( <Tooltip {...tooltip} body={tooltip?.body || modifiedChild} elevation={tooltip?.elevation ?? 'toast'} > <div className={css.childrenWrapper}>{children}</div> </Tooltip> ); }} > <span className={classify(css.truncateLineClamp, classNames?.wrapper)} style={styles} ref={truncatedRef} > {children} </span> </ConditionalWrapper> ); };