index.tsx
import { Tooltip } from 'antd-v4';
import { useEffect, useMemo, useRef, useState } from 'react';
import classNames from 'classnames';
import styles from './index.module.less';
interface Props {
text: string | string[];
width?: number | string;
style?: React.CSSProperties;
className?: string;
lineClamp?: number;
emptyFill?: string;
jointMark?: string;
}
const EllipsisText = ({
text,
width = '100%',
style,
className,
lineClamp = 1,
emptyFill = '-',
jointMark = '、'
}: Props) => {
const textRef = useRef<any>(null);
const [isOverflow, setIsOverflow] = useState(false);
const isSingleLine = useMemo(() => typeof lineClamp !== 'number' || lineClamp <= 1, [lineClamp]);
useEffect(() => {
const checkOverflow = () => {
const element = textRef.current;
if (isSingleLine) {
setIsOverflow(element.scrollWidth > element.offsetWidth);
} else {
setIsOverflow(element.scrollHeight > element.clientHeight);
}
};
checkOverflow();
window.addEventListener('resize', checkOverflow);
return () => {
window.removeEventListener('resize', checkOverflow);
};
}, [isSingleLine]);
const toolTipTitle = useMemo(() => {
const _text =
Array.isArray(text) && !!text?.length
? text?.map(t => <div className='tool-tip-title-col'>{t}</div>)
: text || '';
return isOverflow && _text ? _text : '';
}, [isOverflow, text]);
return (
<Tooltip title={toolTipTitle}>
<div
ref={textRef}
className={classNames(
isSingleLine && styles.ellipsisTextComp,
!isSingleLine && styles.multilineEllipsisTextComp,
className
)}
style={{ width: width, WebkitLineClamp: lineClamp, ...(style || {}) }}
>
{Array.isArray(text) && !!text?.length ? text?.join(jointMark) : text || emptyFill}
</div>
</Tooltip>
);
};
export default EllipsisText;
index.module.less
.ellipsisTextComp {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.multilineEllipsisTextComp {
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
}