truncateWithEllipsisPreserveWords method
Truncates the string to cutoff graphemes and appends an ellipsis '…'.
This method will not cut words in half. It will truncate at the last
full word that fits within the cutoff. If the first word is longer than
the cutoff, it falls back to simple truncation at the cutoff point to
ensure some content is always returned.
Uses grapheme clusters for proper Unicode support, including emojis.
Args: cutoff (int?): The maximum grapheme length before truncation. If null, 0, or negative, returns the original string.
Returns:
String: The truncated string with ellipsis, or the original string if it's
shorter than cutoff.
Example:
'Hello World'.truncateWithEllipsisPreserveWords(8); // Returns 'Hello…'
'Hello World'.truncateWithEllipsisPreserveWords(20); // Returns 'Hello World'
'Supercalifragilistic'.truncateWithEllipsisPreserveWords(5); // Returns 'Super…'
Implementation
String truncateWithEllipsisPreserveWords(int? cutoff) {
final int charLength = characters.length;
// Return original string if it's empty, cutoff is invalid, or it's already short enough.
if (isEmpty || cutoff == null || cutoff <= 0 || charLength <= cutoff) {
return this;
}
// Find the last space within the allowed length (checking up to cutoff + 1 to include
// a space right at the cutoff boundary)
final int searchLength = cutoff + 1 > charLength ? charLength : cutoff + 1;
final int lastSpaceIndex = substringSafe(0, searchLength).lastIndexOf(' ');
// If no space is found (e.g., a single long word), fall back to simple truncation
// at the cutoff point. This ensures we always return some meaningful content
// rather than just an ellipsis.
if (lastSpaceIndex == -1 || lastSpaceIndex == 0) {
return '${substringSafe(0, cutoff)}$ellipsis';
}
// Truncate at the last space found and remove any trailing space before adding the ellipsis.
return '${substringSafe(0, lastSpaceIndex).trimRight()}$ellipsis';
}