diff --git a/src/utils/pad.test.ts b/src/utils/pad.test.ts index 7f426a8..84ae338 100644 --- a/src/utils/pad.test.ts +++ b/src/utils/pad.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from 'vitest'; -import { leftPad, leftPadMin, rightPad, rightPadMin } from './pad'; +import { centerPad, leftPad, leftPadMin, rightPad, rightPadMin } from './pad'; import { stripAsni } from './strip-ansi'; describe('leftPad', () => { @@ -65,3 +65,25 @@ describe('rightPadMin', () => { expect(() => rightPadMin('Hello', 3)).toThrow(); }); }); + +describe('centerPad', () => { + it('Correctly pads', () => { + expect(centerPad('1', 3)).toBe(' 1 '); + }); + + it('Adds excess padding to right when padding is uneven', () => { + expect(centerPad('1', 4)).toBe(' 1 '); + }); + + it('Correctly pads with the padding character `padWith`', () => { + expect(centerPad('1', 3, '.')).toBe('.1.'); + }); + + it('Correctly pads with escape characters', () => { + expect(stripAsni(centerPad('\x1b[1;31m1', 3, '.')).length).toBe(3); + }); + + it('Errors when string length is greater than `length`', () => { + expect(() => centerPad('Hello', 3)).toThrow(); + }); +}); diff --git a/src/utils/pad.ts b/src/utils/pad.ts index ca6f761..d487453 100644 --- a/src/utils/pad.ts +++ b/src/utils/pad.ts @@ -76,4 +76,34 @@ const rightPadMin = (str: string, length: number, padWith = ' ') => { return str + padWith.repeat(length - stripAsni(str).length); }; -export { leftPad, leftPadMin, rightPad, rightPadMin }; +/** Pads the string with the `padWith` so that it appears in the center of a new string with the provided length. + * + * @param str + * @param length + * @param padWith + * @returns + * + * ## Usage + * ```ts + * const str = "Hello, World!"; + * + * const padded = centerPad(str, str.length + 4); + * + * console.log(padded); // ' Hello, World! ' + * ``` + */ +const centerPad = (str: string, length: number, padWith = ' ') => { + if (stripAsni(str).length > length) { + throw new Error('String length is greater than the length provided.'); + } + + const overflow = length - stripAsni(str).length; + + const paddingLeft = Math.floor(overflow / 2); + + const paddingRight = Math.ceil(overflow / 2); + + return padWith.repeat(paddingLeft) + str + padWith.repeat(paddingRight); +}; + +export { leftPad, leftPadMin, rightPad, rightPadMin, centerPad };