mirror of
https://github.com/datahub-project/datahub.git
synced 2025-12-07 16:14:40 +00:00
80 lines
2.3 KiB
TypeScript
80 lines
2.3 KiB
TypeScript
import OptionalTooltip from '@app/sharedV2/ant/OptionalTooltip';
|
|
import { TooltipProps } from 'antd';
|
|
import React, { useEffect } from 'react';
|
|
import styled from 'styled-components';
|
|
import Highlight from 'react-highlighter';
|
|
|
|
const Wrapper = styled.div<{ scale: number; computedRatio: boolean }>`
|
|
// Wrap up to two lines, shrinking text as needed
|
|
font-size: ${({ scale }) => `${scale}em`} !important;
|
|
line-height: 1.25;
|
|
max-height: 2.5em; // 2 lines with 1.25 line height
|
|
overflow: hidden;
|
|
white-space: ${({ computedRatio }) => (computedRatio ? 'normal' : 'nowrap')};
|
|
word-break: break-all;
|
|
|
|
// Position at start, vertically, as parent aligns center
|
|
display: flex;
|
|
align-items: start;
|
|
height: 100%;
|
|
|
|
mark {
|
|
padding: 0;
|
|
}
|
|
`;
|
|
|
|
const ExtraWrapper = styled.span`
|
|
margin-left: 0.4em;
|
|
`;
|
|
|
|
const MIN_SCALE = 2 / 3;
|
|
const TOOLTIP_THRESHOLD = 0.8; // Show tooltip if text is smaller than TOOLTIP_THRESHOLD em
|
|
|
|
interface Props {
|
|
title?: string;
|
|
highlightText?: string;
|
|
highlightColor?: string;
|
|
extra?: React.ReactNode;
|
|
className?: string;
|
|
placement?: TooltipProps['placement'];
|
|
}
|
|
|
|
export default function OverflowTitle({
|
|
title,
|
|
highlightText,
|
|
highlightColor,
|
|
extra,
|
|
className,
|
|
placement = 'top',
|
|
}: Props) {
|
|
const [scale, setScale] = React.useState<number>(1);
|
|
const [ratio, setRatio] = React.useState<number | undefined>(undefined);
|
|
|
|
useEffect(() => {
|
|
setScale(1);
|
|
}, [title]);
|
|
|
|
useEffect(() => {
|
|
if (ratio && ratio > 1) {
|
|
setScale(Math.max(MIN_SCALE, Math.min(1, 2 / ratio - 0.03)));
|
|
}
|
|
}, [title, ratio]);
|
|
|
|
const ref = React.useCallback((node: HTMLDivElement) => {
|
|
if (node !== null) {
|
|
setRatio((oldRatio) => oldRatio ?? node.scrollWidth / node.clientWidth);
|
|
}
|
|
}, []);
|
|
|
|
return (
|
|
<OptionalTooltip tooltipProps={{ title, placement }} enabled={scale < TOOLTIP_THRESHOLD}>
|
|
<Wrapper className={className} ref={ref} scale={scale} computedRatio={!!ratio}>
|
|
<Highlight search={highlightText} matchStyle={{ backgroundColor: highlightColor }}>
|
|
{title}
|
|
{!!extra && <ExtraWrapper>{extra}</ExtraWrapper>}
|
|
</Highlight>
|
|
</Wrapper>
|
|
</OptionalTooltip>
|
|
);
|
|
}
|