/** * Truncates text to a maximum length with ellipsis * @param text - Text to truncate * @param maxLength - Maximum length including ellipsis * @param ellipsis - String to append when truncated (default: '...') * @returns Truncated text */ export function truncate( text: string, maxLength: number, ellipsis: string = '...' ): string { if (text.length <= maxLength) { return text } const truncatedLength = maxLength - ellipsis.length if (truncatedLength <= 0) { throw new Error('maxLength must be greater than ellipsis length') } return text.slice(0, truncatedLength) + ellipsis } /** * Truncates text at word boundary * @param text - Text to truncate * @param maxLength - Maximum length including ellipsis * @param ellipsis - String to append when truncated (default: '...') * @returns Truncated text at word boundary */ export function truncateWords( text: string, maxLength: number, ellipsis: string = '...' ): string { if (text.length <= maxLength) { return text } const truncatedLength = maxLength - ellipsis.length if (truncatedLength <= 0) { throw new Error('maxLength must be greater than ellipsis length') } // Find last space before truncation point const truncated = text.slice(0, truncatedLength) const lastSpace = truncated.lastIndexOf(' ') if (lastSpace === -1) { // No space found, truncate at character boundary return truncated + ellipsis } return truncated.slice(0, lastSpace).trimEnd() + ellipsis }