From ea55a8fdf478a29a26d6e16ee712d8091d99b00f Mon Sep 17 00:00:00 2001 From: Pabloader Date: Sat, 11 Apr 2026 14:36:32 +0000 Subject: [PATCH] Format number function --- src/common/utils.ts | 8 +++++++- test/common/utils.test.ts | 27 ++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/common/utils.ts b/src/common/utils.ts index f1a4d3a..5f0f907 100644 --- a/src/common/utils.ts +++ b/src/common/utils.ts @@ -112,11 +112,17 @@ export const callUpdater = (f: StateUpdater, prev: T) => typeof f === 'function' ? (f as Function)(prev) : f; export const formatNumber = (n: number): string => { + if (n === 0) return '0'; + if (n < 0) return `-${formatNumber(-n)}`; if (n >= 1_000_000_000_000) return `${(n / 1_000_000_000_000).toFixed(2)}T`; if (n >= 1_000_000_000) return `${(n / 1_000_000_000).toFixed(2)}B`; if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(2)}M`; if (n >= 1_000) return `${(n / 1_000).toFixed(2)}k`; - return String(n); + if (Math.trunc(n) === n) return n.toString(); + if (n >= 1) return n.toFixed(2); + const result = n.toPrecision(2); + if (parseFloat(result) >= 1) return parseFloat(result).toFixed(2); + return result; }; export const formatTime = (seconds: number): string => { diff --git a/test/common/utils.test.ts b/test/common/utils.test.ts index b34c351..ec3ffdd 100644 --- a/test/common/utils.test.ts +++ b/test/common/utils.test.ts @@ -310,12 +310,27 @@ describe('utils', () => { }); describe('formatNumber', () => { - it('should return small numbers as-is', () => { + it('should return small integer as-is', () => { expect(formatNumber(0)).toBe('0'); expect(formatNumber(42)).toBe('42'); expect(formatNumber(999)).toBe('999'); }); + it('should return small decimals rounded to at most 2 significant digits', () => { + expect(formatNumber(0.1)).toBe('0.10'); + expect(formatNumber(0.123)).toBe('0.12'); + expect(formatNumber(0.5)).toBe('0.50'); + expect(formatNumber(0.999)).toBe('1.00'); + expect(formatNumber(0.001)).toBe('0.0010'); + expect(formatNumber(0.0001234)).toBe('0.00012'); + }); + + it('should return decimals between 100 and 1000 with 2 decimal places', () => { + expect(formatNumber(100.5)).toBe('100.50'); + expect(formatNumber(500.75)).toBe('500.75'); + expect(formatNumber(999.9)).toBe('999.90'); + }); + it('should format thousands with k suffix', () => { expect(formatNumber(1_000)).toBe('1.00k'); expect(formatNumber(5_500)).toBe('5.50k'); @@ -338,6 +353,16 @@ describe('utils', () => { expect(formatNumber(1_000_000_000_000)).toBe('1.00T'); expect(formatNumber(5_250_000_000_000)).toBe('5.25T'); }); + + it('should format negative numbers with a leading minus sign', () => { + expect(formatNumber(-42)).toBe('-42'); + expect(formatNumber(-0.123)).toBe('-0.12'); + expect(formatNumber(-0.999)).toBe('-1.00'); + expect(formatNumber(-1_000)).toBe('-1.00k'); + expect(formatNumber(-1_000_000)).toBe('-1.00M'); + expect(formatNumber(-1_000_000_000)).toBe('-1.00B'); + expect(formatNumber(-1_000_000_000_000)).toBe('-1.00T'); + }); }); describe('formatTime', () => {