封装当内容超过一定宽度之后以省略号的形式显示,且鼠标进入元素可以查看完整内容的组件ToolTip
import { Tooltip, TooltipProps } from 'antd';
import { useState, useRef, useCallback } from 'react';
interface LazyEllipsisTooltipProps {
content: string;
maxWidth?: number | string;
className?: string;
}
const LazyEllipsisTooltip = ({
content,
maxWidth = '100%',
className,
...tooltipProps
}: LazyEllipsisTooltipProps & Omit<TooltipProps, 'title' | 'open' | 'onOpenChange'>) => {
const textRef = useRef<HTMLDivElement>(null);
const [tooltipOpen, setTooltipOpen] = useState(false);
const handleMouseEnter = useCallback(() => {
const el = textRef.current;
if (el) {
const isOverflowed = el.scrollWidth > el.clientWidth;
if (isOverflowed) {
setTooltipOpen(true);
}
}
}, [content]);
const handleMouseLeave = useCallback(() => {
setTooltipOpen(false);
}, []);
return (
<Tooltip
title={content}
open={tooltipOpen}
onOpenChange={open => {
// 防止外部意外打开
if (open && textRef.current) {
const isOverflowed = textRef.current.scrollWidth > textRef.current.clientWidth;
if (!isOverflowed) return;
}
setTooltipOpen(open);
}}
mouseEnterDelay={0.3}
mouseLeaveDelay={0.1}
{...tooltipProps}
>
<div
ref={textRef}
className={className}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
style={{
maxWidth,
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
cursor: 'default',
boxSizing: 'border-box', // 确保 padding 不影响宽度计算
}}
>
{content}
</div>
</Tooltip>
);
};
export { LazyEllipsisTooltip };
使用
<LazyEllipsisTooltip content={text} placement="topLeft" maxWidth={180} />