Skip to content
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- `truncate` string utility function

## [1.5.0] - 2025-07-07

### Added
Expand Down
38 changes: 37 additions & 1 deletion src/lib/string.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isNullOrEmpty, isNullOrWhitespace, capitalize, uncapitalize } from "./string";
import { isNullOrEmpty, isNullOrWhitespace, capitalize, uncapitalize, truncate } from "./string";

describe("string tests", () => {
test.each([
Expand Down Expand Up @@ -84,4 +84,40 @@ describe("string tests", () => {
])("uncapitalize", (value, expected) => {
expect(uncapitalize(value)).toBe(expected);
});

test.each([
[null as unknown as string, 10, "", null],
[undefined as unknown as string, 10, "", undefined],
["", 10, "", ""],
["hello", 10, "", "hello"],
["hello", 5, "", "hello"],
["hello world", 5, "", "hello"],
["hello world", 8, "", "hello wo"],
["hello world", 11, "", "hello world"],
["hello world", 0, "", ""],
["hello", 3, ">>", "hel>>"],
["test", 2, "", "te"],
["hello world", 5, "...", "hello..."],
["hello world", 8, "...", "hello wo..."],
["hello world", 0, "...", "..."],
])("truncate", (value, maxLength, suffix, expected) => {
expect(truncate(value, maxLength, suffix)).toBe(expected);
});

test.each([
[null as unknown as string, 10, null],
[undefined as unknown as string, 10, undefined],
["", 10, ""],
["hello", 10, "hello"],
["hello", 5, "hello"],
["hello world", 5, "hello"],
["hello world", 8, "hello wo"],
["hello world", 11, "hello world"],
["hello world", 0, ""],
["test", 2, "te"],
["a very long string", 6, "a very"],
["short", 10, "short"],
])("truncate without suffix parameter", (value, maxLength, expected) => {
expect(truncate(value, maxLength)).toBe(expected);
});
});
19 changes: 19 additions & 0 deletions src/lib/string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,22 @@ export function uncapitalize(value?: string): string | undefined {

return value.charAt(0).toLowerCase() + value.slice(1);
}

/**
* Truncates a string to a maximum length, adding a suffix if truncated
* @param value The string to truncate
* @param maxLength The maximum length of the resulting string
* @param suffix The suffix to append if truncated (default: "")
* @returns The truncated string
*/
export function truncate(value: string | undefined, maxLength: number, suffix = ""): string | undefined {
if (!value || isNullOrWhitespace(value)) {
return value;
}

if (value.length <= maxLength) {
return value;
}

return `${value.slice(0, maxLength)}${suffix}`;
}