Truncates text for toast descriptions and provides inline expansion capability. Preserves single newlines while collapsing multiple spaces/tabs to single spaces.

export const truncateToastMessage = (
text: string,
maxLength: number = 200,
): {
isTruncated: boolean;
truncatedText: string;
fullText: string;
component: React.ReactNode;
} => {
// Early return for whitespace-only strings
if (text.trim().length === 0) {
return {
isTruncated: false,
truncatedText: text,
fullText: text,
component: text,
};
}

// Normalize consecutive spaces/tabs to single spaces, but preserve newlines
const normalizedText = text
.replaceAll(/[ \t]+/g, " ") // Collapse spaces and tabs
.replaceAll(/\n\n+/g, "\n"); // Collapse multiple newlines to single newline

if (normalizedText.length <= maxLength) {
return {
isTruncated: false,
truncatedText: normalizedText,
fullText: normalizedText,
component: normalizedText,
};
}

// Find last space before maxLength for word boundary truncation
let truncateIndex = maxLength;
const lastSpaceIndex = normalizedText.lastIndexOf(" ", maxLength);

if (lastSpaceIndex > 0 && lastSpaceIndex > maxLength - 50) {
// Use word boundary if space is close to maxLength
truncateIndex = lastSpaceIndex;
}

const truncatedText = normalizedText.slice(0, truncateIndex).trim() + "...";

return {
isTruncated: true,
truncatedText,
fullText: normalizedText,
component: React.createElement(TruncatedToastContent, {
text: normalizedText,
truncatedText,
}),
};
};
  • Parameters

    • text: string

      The text to potentially truncate.

    • maxLength: number = 200

      Maximum character length before truncation (default: 200).

    Returns {
        isTruncated: boolean;
        truncatedText: string;
        fullText: string;
        component: ReactNode;
    }

    Object containing truncation status, both versions of text, and React component for rendering.