From ea0c92a267ec946d5d67c80afbde352c6581cb05 Mon Sep 17 00:00:00 2001 From: Aritra Dey <155592377+AritraDey-Dev@users.noreply.github.com> Date: Sun, 15 Feb 2026 15:21:53 +0530 Subject: [PATCH] fix: use maxLength parameter in truncateOnWord instead of hardcoded value (#27961) Signed-off-by: Aritra Dey Co-authored-by: Romit <85230081+romitg2@users.noreply.github.com> --- packages/lib/text.test.ts | 82 ++++++++++++++++++++++++++++++++++++++- packages/lib/text.ts | 7 +++- 2 files changed, 86 insertions(+), 3 deletions(-) diff --git a/packages/lib/text.test.ts b/packages/lib/text.test.ts index 4d60a46f14..08c2cec961 100644 --- a/packages/lib/text.test.ts +++ b/packages/lib/text.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from "vitest"; -import { truncate } from "./text"; +import { truncate, truncateOnWord } from "./text"; describe("Text util tests", () => { describe("fn: truncate", () => { @@ -69,4 +69,84 @@ describe("Text util tests", () => { } }); }); + describe("fn: truncateOnWord", () => { + it("should return the original text when it is shorter than the max length", () => { + const cases = [ + { + input: "Hello world", + maxLength: 100, + expected: "Hello world", + }, + { + input: "Hello world", + maxLength: 11, + expected: "Hello world", + }, + ]; + + for (const { input, maxLength, expected } of cases) { + const result = truncateOnWord(input, maxLength); + + expect(result).toEqual(expected); + } + }); + + it("should return the truncated text on the last word when it is longer than the max length", () => { + const cases = [ + { + input: "The quick brown fox jumps over the lazy dog", + maxLength: 12, + expected: "The quick...", + }, + { + input: "Cal.com is the scheduling infrastructure for everyone", + maxLength: 14, + expected: "Cal.com is...", + }, + ]; + + for (const { input, maxLength, expected } of cases) { + const result = truncateOnWord(input, maxLength); + + expect(result).toEqual(expected); + } + }); + + it("should return the truncated text without ellipsis when it is longer than the max length and ellipsis is false", () => { + const cases = [ + { + input: "The quick brown fox jumps over the lazy dog", + maxLength: 12, + ellipsis: false, + expected: "The quick", + }, + ]; + + for (const { input, maxLength, ellipsis, expected } of cases) { + const result = truncateOnWord(input, maxLength, ellipsis); + + expect(result).toEqual(expected); + } + }); + + it("should fallback to character truncation when no spaces are present in the truncated segment", () => { + const cases = [ + { + input: "supercalifragilisticexpialidocious", + maxLength: 10, + expected: "supercalif...", + }, + { + input: "https://cal.com/pro/30min/extremely-long-url-without-any-spaces", + maxLength: 20, + expected: "https://cal.com/pro/...", + }, + ]; + + for (const { input, maxLength, expected } of cases) { + const result = truncateOnWord(input, maxLength); + expect(result).toEqual(expected); + } + }); + }); }); diff --git a/packages/lib/text.ts b/packages/lib/text.ts index d9d28ea83d..12f00548a9 100644 --- a/packages/lib/text.ts +++ b/packages/lib/text.ts @@ -8,11 +8,14 @@ export const truncateOnWord = (text: string, maxLength: number, ellipsis = true) if (text.length <= maxLength) return text; // First split on maxLength chars - let truncatedText = text.substring(0, 148); + let truncatedText = text.substring(0, maxLength); // Then split on the last space, this way we split on the last word, // which looks just a bit nicer. - truncatedText = truncatedText.substring(0, Math.min(truncatedText.length, truncatedText.lastIndexOf(" "))); + const lastSpaceIndex = truncatedText.lastIndexOf(" "); + if (lastSpaceIndex !== -1) { + truncatedText = truncatedText.substring(0, lastSpaceIndex); + } if (ellipsis) truncatedText += "...";