Skip to content

Commit 61f1acb

Browse files
committed
add locales to options to allow number formatting
1 parent ad390cc commit 61f1acb

File tree

5 files changed

+29
-21
lines changed

5 files changed

+29
-21
lines changed

lib/millify.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { defaultOptions, MillifyOptions } from "./options";
2-
import { parseValue, roundTo, getDefaultDecimalSeparator } from "./utils";
2+
import { getFractionDigits, parseValue, roundTo } from "./utils";
33

44
// Most commonly used digit grouping base.
55
const DIGIT_GROUPING_BASE = 1000;
@@ -75,7 +75,9 @@ function millify(value: number, options?: Partial<MillifyOptions>): string {
7575
// a corresponding unit. Returning anything else is ambiguous.
7676
const unitIndexOutOfRange = unitIndex >= opts.units.length;
7777
if (unitIndexOutOfRange) {
78-
return value.toLocaleString();
78+
// At this point we don't know what to do with the input value,
79+
// so we return it as is, without localizing the string.
80+
return value.toString();
7981
}
8082

8183
// Round decimal up to desired precision.
@@ -95,12 +97,11 @@ function millify(value: number, options?: Partial<MillifyOptions>): string {
9597
// Add a space between number and abbreviation.
9698
const space = opts.space ? " " : "";
9799

98-
// Replace decimal mark if desired.
99-
const defaultDecimalSeparator = getDefaultDecimalSeaparator();
100-
let formatted = rounded.toLocaleString();
101-
if (opts.decimalSeparator) {
102-
formatted = formatted.replace(defaultDecimalSeparator, opts.decimalSeparator);
103-
}
100+
// Format the number according to the desired locale.
101+
const formatted = rounded.toLocaleString(opts.locales, {
102+
// toLocaleString needs the explicit fraction digits.
103+
minimumFractionDigits: getFractionDigits(rounded),
104+
});
104105

105106
return `${prefix}${formatted}${space}${suffix}`;
106107
}

lib/options.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ export interface MillifyOptions {
77
*/
88
precision: number;
99
/**
10-
* The type of decimal marker (e.g. period "."") or *null* to use locale default.
10+
* The active browser or server location. A string with a BCP 47 language
11+
* tag, or an array of such strings, e.g. "en-US".
1112
*/
12-
decimalSeparator: string | null;
13+
locales?: string | string[];
1314
/**
1415
* Convert units to lower case.
1516
*/
@@ -28,7 +29,6 @@ export interface MillifyOptions {
2829
* Default options for Millify.
2930
*/
3031
export const defaultOptions: MillifyOptions = {
31-
decimalSeparator: null,
3232
lowercase: false,
3333
precision: 1,
3434
space: false,

lib/utils.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,12 @@ export function roundTo(value: number, precision: number): number {
3030
}
3131

3232
/**
33-
* Calculates the default decimal separator given the current locale
33+
* Returns the number of digits after the decimal.
3434
*/
35-
export function getDefaultDecimalSeparator(): string {
36-
const value = 1.1;
37-
const result = value.toLocaleString().substring(1, 2);
38-
return result;
35+
export function getFractionDigits(num: number): number {
36+
if (Number.isInteger(num)) {
37+
return 0;
38+
}
39+
const decimalPart = num.toString().split(".")[1];
40+
return decimalPart?.length ?? 0;
3941
}

test.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,15 @@ test("precision adjusts according to options", (t) => {
7878
);
7979
});
8080

81-
test("allows a custom decimal separator", (t) => {
82-
const result = millify(55500, { decimalSeparator: "_" });
83-
const expected = "55_5K";
84-
t.is(expected, result);
81+
test("formats to different languages", (t) => {
82+
const tests = new Map([
83+
["en-US", "1.2"],
84+
["de-DE", "1,2"],
85+
["ar-SA", "١٫٢"],
86+
]);
87+
for (const [locales, expected] of tests.entries()) {
88+
t.is(millify(1.2, { locales }), expected);
89+
}
8590
});
8691

8792
test("allows a space between decimal and unit", (t) => {

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"compilerOptions": {
3-
"target": "es6",
3+
"target": "es2018",
44
"module": "commonjs",
55
"declaration": true,
66
"outDir": "./dist",

0 commit comments

Comments
 (0)