89 lines
2.4 KiB
TypeScript
89 lines
2.4 KiB
TypeScript
|
|
/**
|
||
|
|
* ResponsiveText Component
|
||
|
|
* Automatically adjusts text size and truncation based on screen size
|
||
|
|
*/
|
||
|
|
|
||
|
|
import React from 'react';
|
||
|
|
import { TextOverflowPrevention, getScreenSize, overflowClasses } from '../../../utils/textUtils';
|
||
|
|
|
||
|
|
export interface ResponsiveTextProps {
|
||
|
|
text: string;
|
||
|
|
maxLength?: {
|
||
|
|
mobile?: number;
|
||
|
|
tablet?: number;
|
||
|
|
desktop?: number;
|
||
|
|
};
|
||
|
|
className?: string;
|
||
|
|
title?: string;
|
||
|
|
truncationType?: 'statusCard' | 'production' | 'mobile';
|
||
|
|
textType?: 'title' | 'subtitle' | 'label' | 'metadata' | 'action';
|
||
|
|
showTooltip?: boolean;
|
||
|
|
as?: keyof JSX.IntrinsicElements;
|
||
|
|
}
|
||
|
|
|
||
|
|
export const ResponsiveText: React.FC<ResponsiveTextProps> = ({
|
||
|
|
text,
|
||
|
|
maxLength,
|
||
|
|
className = '',
|
||
|
|
title,
|
||
|
|
truncationType = 'statusCard',
|
||
|
|
textType = 'title',
|
||
|
|
showTooltip = true,
|
||
|
|
as: Component = 'span'
|
||
|
|
}) => {
|
||
|
|
const screenSize = React.useMemo(() => getScreenSize(), []);
|
||
|
|
|
||
|
|
// Get truncation engine based on type
|
||
|
|
const getTruncationEngine = () => {
|
||
|
|
switch (truncationType) {
|
||
|
|
case 'mobile':
|
||
|
|
return TextOverflowPrevention.mobile;
|
||
|
|
case 'production':
|
||
|
|
return TextOverflowPrevention.production;
|
||
|
|
default:
|
||
|
|
return TextOverflowPrevention.statusCard;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
const engine = getTruncationEngine();
|
||
|
|
|
||
|
|
// Get truncated text based on text type
|
||
|
|
const getTruncatedText = () => {
|
||
|
|
if (maxLength) {
|
||
|
|
const currentMaxLength = maxLength[screenSize] || maxLength.desktop || text.length;
|
||
|
|
return text.length > currentMaxLength
|
||
|
|
? text.substring(0, currentMaxLength - 3) + '...'
|
||
|
|
: text;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Use predefined truncation methods
|
||
|
|
switch (textType) {
|
||
|
|
case 'title':
|
||
|
|
return engine.title ? engine.title(text) : text;
|
||
|
|
case 'subtitle':
|
||
|
|
return engine.subtitle ? engine.subtitle(text) : text;
|
||
|
|
case 'label':
|
||
|
|
return engine.primaryValueLabel ? engine.primaryValueLabel(text) : text;
|
||
|
|
case 'metadata':
|
||
|
|
return engine.metadataItem ? engine.metadataItem(text) : text;
|
||
|
|
case 'action':
|
||
|
|
return engine.actionLabel ? engine.actionLabel(text) : text;
|
||
|
|
default:
|
||
|
|
return text;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
const truncatedText = getTruncatedText();
|
||
|
|
const shouldShowTooltip = showTooltip && truncatedText !== text;
|
||
|
|
|
||
|
|
return (
|
||
|
|
<Component
|
||
|
|
className={`${overflowClasses.truncate} ${className}`}
|
||
|
|
title={shouldShowTooltip ? (title || text) : title}
|
||
|
|
>
|
||
|
|
{truncatedText}
|
||
|
|
</Component>
|
||
|
|
);
|
||
|
|
};
|
||
|
|
|
||
|
|
export default ResponsiveText;
|