69 lines
1.9 KiB
TypeScript
69 lines
1.9 KiB
TypeScript
import React, { useState } from 'react';
|
|
import { ActionIcon, Group, Modal, Text, Tooltip } from '@mantine/core';
|
|
import InformationOutlineIcon from 'mdi-react/InformationOutlineIcon';
|
|
import { iconMStyle } from '~/styles.ts';
|
|
|
|
interface TruncatedTextProps {
|
|
text: string;
|
|
maxLength?: number;
|
|
maxTooltipLength?: number;
|
|
title?: string;
|
|
}
|
|
|
|
export function TruncatedText({
|
|
text,
|
|
maxLength = 20,
|
|
maxTooltipLength = 200,
|
|
title = 'Details'
|
|
}: TruncatedTextProps) {
|
|
const [opened, setOpened] = useState(false);
|
|
|
|
if (!text) return <Text>-</Text>;
|
|
|
|
if (text.length <= maxLength) {
|
|
return <Text>{text}</Text>;
|
|
}
|
|
|
|
const truncatedText = `${text.substring(0, maxLength)}...`;
|
|
|
|
const tooltipText = text.length > maxTooltipLength
|
|
? `${text.substring(0, maxTooltipLength)}...`
|
|
: text
|
|
|
|
return (
|
|
<>
|
|
<Tooltip
|
|
label={tooltipText}
|
|
multiline
|
|
maw={300}
|
|
position="top"
|
|
withArrow
|
|
transitionProps={{ duration: 200 }}
|
|
>
|
|
<Group gap="xs" wrap="nowrap">
|
|
<Text>{truncatedText}</Text>
|
|
<ActionIcon
|
|
size="sm"
|
|
variant="subtle"
|
|
onClick={() => setOpened(true)}
|
|
title="Show full content"
|
|
>
|
|
<InformationOutlineIcon style={iconMStyle} />
|
|
</ActionIcon>
|
|
</Group>
|
|
</Tooltip>
|
|
|
|
<Modal
|
|
opened={opened}
|
|
onClose={() => setOpened(false)}
|
|
title={title}
|
|
size="md"
|
|
centered
|
|
>
|
|
<Text style={{ whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}>
|
|
{text}
|
|
</Text>
|
|
</Modal>
|
|
</>
|
|
);
|
|
}
|