Skip to content

Commit 5df2e63

Browse files
refactor: move formatting related code into separate file (anuraghazra#4568)
Co-authored-by: Alexandr <qwerty541zxc@gmail.com>
1 parent c4a59b5 commit 5df2e63

8 files changed

Lines changed: 58 additions & 63 deletions

File tree

src/cards/gist.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ import {
44
parseEmojis,
55
wrapTextMultiline,
66
encodeHTML,
7-
kFormatter,
87
measureText,
98
flexLayout,
109
iconWithLabel,
1110
createLanguageNode,
1211
} from "../common/utils.js";
1312
import Card from "../common/Card.js";
1413
import { getCardColors } from "../common/color.js";
14+
import { kFormatter } from "../common/fmt.js";
1515
import { icons } from "../common/icons.js";
1616

1717
/** Import language colors.

src/cards/repo.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
import { Card } from "../common/Card.js";
44
import { getCardColors } from "../common/color.js";
5+
import { kFormatter } from "../common/fmt.js";
56
import { I18n } from "../common/I18n.js";
67
import { icons } from "../common/icons.js";
78
import {
89
encodeHTML,
910
flexLayout,
10-
kFormatter,
1111
measureText,
1212
parseEmojis,
1313
wrapTextMultiline,

src/cards/stats.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,10 @@
33
import { Card } from "../common/Card.js";
44
import { getCardColors } from "../common/color.js";
55
import { CustomError } from "../common/error.js";
6+
import { kFormatter } from "../common/fmt.js";
67
import { I18n } from "../common/I18n.js";
78
import { icons, rankIcon } from "../common/icons.js";
8-
import {
9-
clampValue,
10-
flexLayout,
11-
kFormatter,
12-
measureText,
13-
} from "../common/utils.js";
9+
import { clampValue, flexLayout, measureText } from "../common/utils.js";
1410
import { statCardLocales, wakatimeCardLocales } from "../translations.js";
1511

1612
const CARD_MIN_WIDTH = 287;

src/cards/top-languages.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
import { Card } from "../common/Card.js";
44
import { getCardColors } from "../common/color.js";
55
import { createProgressNode } from "../common/createProgressNode.js";
6+
import { formatBytes } from "../common/fmt.js";
67
import { I18n } from "../common/I18n.js";
78
import {
89
chunkArray,
910
clampValue,
1011
flexLayout,
1112
lowercaseTrim,
1213
measureText,
13-
formatBytes,
1414
} from "../common/utils.js";
1515
import { langCardLocales } from "../translations.js";
1616

src/common/fmt.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/**
2+
* Retrieves num with suffix k(thousands) precise to given decimal places.
3+
*
4+
* @param {number} num The number to format.
5+
* @param {number=} precision The number of decimal places to include.
6+
* @returns {string|number} The formatted number.
7+
*/
8+
const kFormatter = (num, precision) => {
9+
const abs = Math.abs(num);
10+
const sign = Math.sign(num);
11+
12+
if (typeof precision === "number" && !isNaN(precision)) {
13+
return (sign * (abs / 1000)).toFixed(precision) + "k";
14+
}
15+
16+
if (abs < 1000) {
17+
return sign * abs;
18+
}
19+
20+
return sign * parseFloat((abs / 1000).toFixed(1)) + "k";
21+
};
22+
23+
/**
24+
* Convert bytes to a human-readable string representation.
25+
*
26+
* @param {number} bytes The number of bytes to convert.
27+
* @returns {string} The human-readable representation of bytes.
28+
* @throws {Error} If bytes is negative or too large.
29+
*/
30+
const formatBytes = (bytes) => {
31+
if (bytes < 0) {
32+
throw new Error("Bytes must be a non-negative number");
33+
}
34+
35+
if (bytes === 0) {
36+
return "0 B";
37+
}
38+
39+
const sizes = ["B", "KB", "MB", "GB", "TB", "PB", "EB"];
40+
const base = 1024;
41+
const i = Math.floor(Math.log(bytes) / Math.log(base));
42+
43+
if (i >= sizes.length) {
44+
throw new Error("Bytes is too large to convert to a human-readable string");
45+
}
46+
47+
return `${(bytes / Math.pow(base, i)).toFixed(1)} ${sizes[i]}`;
48+
};
49+
50+
export { kFormatter, formatBytes };

src/common/index.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ export {
1010
ERROR_CARD_LENGTH,
1111
renderError,
1212
encodeHTML,
13-
kFormatter,
1413
parseBoolean,
1514
parseArray,
1615
clampValue,

src/common/utils.js

Lines changed: 0 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -76,28 +76,6 @@ const iconWithLabel = (icon, label, testid, iconSize) => {
7676
return flexLayout({ items: [iconSvg, text], gap: 20 }).join("");
7777
};
7878

79-
/**
80-
* Retrieves num with suffix k(thousands) precise to given decimal places.
81-
*
82-
* @param {number} num The number to format.
83-
* @param {number=} precision The number of decimal places to include.
84-
* @returns {string|number} The formatted number.
85-
*/
86-
const kFormatter = (num, precision) => {
87-
const abs = Math.abs(num);
88-
const sign = Math.sign(num);
89-
90-
if (typeof precision === "number" && !isNaN(precision)) {
91-
return (sign * (abs / 1000)).toFixed(precision) + "k";
92-
}
93-
94-
if (abs < 1000) {
95-
return sign * abs;
96-
}
97-
98-
return sign * parseFloat((abs / 1000).toFixed(1)) + "k";
99-
};
100-
10179
/**
10280
* Returns boolean if value is either "true" or "false" else the value as it is.
10381
*
@@ -399,40 +377,12 @@ const dateDiff = (d1, d2) => {
399377
return Math.round(diff / (1000 * 60));
400378
};
401379

402-
/**
403-
* Convert bytes to a human-readable string representation.
404-
*
405-
* @param {number} bytes The number of bytes to convert.
406-
* @returns {string} The human-readable representation of bytes.
407-
* @throws {Error} If bytes is negative or too large.
408-
*/
409-
const formatBytes = (bytes) => {
410-
if (bytes < 0) {
411-
throw new Error("Bytes must be a non-negative number");
412-
}
413-
414-
if (bytes === 0) {
415-
return "0 B";
416-
}
417-
418-
const sizes = ["B", "KB", "MB", "GB", "TB", "PB", "EB"];
419-
const base = 1024;
420-
const i = Math.floor(Math.log(bytes) / Math.log(base));
421-
422-
if (i >= sizes.length) {
423-
throw new Error("Bytes is too large to convert to a human-readable string");
424-
}
425-
426-
return `${(bytes / Math.pow(base, i)).toFixed(1)} ${sizes[i]}`;
427-
};
428-
429380
export {
430381
ERROR_CARD_LENGTH,
431382
renderError,
432383
createLanguageNode,
433384
iconWithLabel,
434385
encodeHTML,
435-
kFormatter,
436386
parseBoolean,
437387
parseArray,
438388
clampValue,
@@ -445,5 +395,4 @@ export {
445395
chunkArray,
446396
parseEmojis,
447397
dateDiff,
448-
formatBytes,
449398
};

tests/utils.test.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1+
// @ts-check
2+
13
import { describe, expect, it } from "@jest/globals";
24
import { queryByTestId } from "@testing-library/dom";
35
import "@testing-library/jest-dom";
46
import {
57
encodeHTML,
6-
formatBytes,
7-
kFormatter,
88
parseBoolean,
99
renderError,
1010
wrapTextMultiline,
1111
} from "../src/common/utils.js";
12+
import { formatBytes, kFormatter } from "../src/common/fmt.js";
1213

1314
describe("Test utils.js", () => {
1415
it("should test kFormatter default behavior", () => {

0 commit comments

Comments
 (0)