@spaced-out/ui-design-system
Version:
Sense UI components library
105 lines (92 loc) • 2.63 kB
Flow
// @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>
);
};