Skip to content

Commit 8388e69

Browse files
nmoinvazsindresorhus
andauthoredFeb 21, 2021
Add ability to control number of fractional digits (#62)
Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
1 parent 1be9db1 commit 8388e69

File tree

4 files changed

+119
-7
lines changed

4 files changed

+119
-7
lines changed
 

‎index.d.ts

+41
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,47 @@ declare namespace prettyBytes {
5151
```
5252
*/
5353
readonly binary?: boolean;
54+
55+
/**
56+
The minimum number of fraction digits to display.
57+
58+
If neither `minimumFractionDigits` or `maximumFractionDigits` are set, the default behavior is to round to 3 significant digits.
59+
60+
@default undefined
61+
62+
```
63+
import prettyBytes = require('pretty-bytes');
64+
65+
// Show the number with at least 3 fractional digits
66+
prettyBytes(1900, {minimumFractionDigits: 3});
67+
//=> '1.900 kB'
68+
69+
prettyBytes(1900);
70+
//=> '1.9 kB'
71+
```
72+
*/
73+
readonly minimumFractionDigits?: number;
74+
75+
76+
/**
77+
The maximum number of fraction digits to display.
78+
79+
If neither `minimumFractionDigits` or `maximumFractionDigits` are set, the default behavior is to round to 3 significant digits.
80+
81+
@default undefined
82+
83+
```
84+
import prettyBytes = require('pretty-bytes');
85+
86+
// Show the number with at most 1 fractional digit
87+
prettyBytes(1920, {maximumFractionDigits: 1});
88+
//=> '1.9 kB'
89+
90+
prettyBytes(1920);
91+
//=> '1.92 kB'
92+
```
93+
*/
94+
readonly maximumFractionDigits?: number;
5495
}
5596
}
5697

‎index.js

+22-7
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,12 @@ Formats the given number using `Number#toLocaleString`.
5454
- If locale is true, the system default locale is used for translation.
5555
- If no value for locale is specified, the number is returned unmodified.
5656
*/
57-
const toLocaleString = (number, locale) => {
57+
const toLocaleString = (number, locale, options) => {
5858
let result = number;
5959
if (typeof locale === 'string' || Array.isArray(locale)) {
60-
result = number.toLocaleString(locale);
61-
} else if (locale === true) {
62-
result = number.toLocaleString();
60+
result = number.toLocaleString(locale, options);
61+
} else if (locale === true || options !== undefined) {
62+
result = number.toLocaleString(undefined, options);
6363
}
6464

6565
return result;
@@ -87,15 +87,30 @@ module.exports = (number, options) => {
8787
number = -number;
8888
}
8989

90+
let localeOptions;
91+
92+
if (options.minimumFractionDigits !== undefined) {
93+
localeOptions = {minimumFractionDigits: options.minimumFractionDigits};
94+
}
95+
96+
if (options.maximumFractionDigits !== undefined) {
97+
localeOptions = Object.assign({maximumFractionDigits: options.maximumFractionDigits}, localeOptions);
98+
}
99+
90100
if (number < 1) {
91-
const numberString = toLocaleString(number, options.locale);
101+
const numberString = toLocaleString(number, options.locale, localeOptions);
92102
return prefix + numberString + ' ' + UNITS[0];
93103
}
94104

95105
const exponent = Math.min(Math.floor(options.binary ? Math.log(number) / Math.log(1024) : Math.log10(number) / 3), UNITS.length - 1);
96106
// eslint-disable-next-line unicorn/prefer-exponentiation-operator
97-
number = Number((number / Math.pow(options.binary ? 1024 : 1000, exponent)).toPrecision(3));
98-
const numberString = toLocaleString(number, options.locale);
107+
number /= Math.pow(options.binary ? 1024 : 1000, exponent);
108+
109+
if (!localeOptions) {
110+
number = number.toPrecision(3);
111+
}
112+
113+
const numberString = toLocaleString(Number(number), options.locale, localeOptions);
99114

100115
const unit = UNITS[exponent];
101116

‎readme.md

+40
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,46 @@ Default: `false` *(No localization)*
8585

8686
**Note:** Localization should generally work in browsers. Node.js needs to be [built](https://github.com/nodejs/node/wiki/Intl) with `full-icu` or `system-icu`. Alternatively, the [`full-icu`](https://github.com/unicode-org/full-icu-npm) module can be used to provide support at runtime. [Node.js 13](https://nodejs.org/en/blog/release/v13.0.0/) and later ships with ICU by default.
8787

88+
##### minimumFractionDigits
89+
90+
Type: `number`\
91+
Default: `undefined`
92+
93+
The minimum number of fraction digits to display.
94+
95+
If neither `minimumFractionDigits` or `maximumFractionDigits` are set, the default behavior is to round to 3 significant digits.
96+
97+
```js
98+
const prettyBytes = require('pretty-bytes');
99+
100+
// Show the number with at least 3 fractional digits
101+
prettyBytes(1900, {minimumFractionDigits: 3});
102+
//=> '1.900 kB'
103+
104+
prettyBytes(1900);
105+
//=> '1.9 kB'
106+
```
107+
108+
##### maximumFractionDigits
109+
110+
Type: `number`\
111+
Default: `undefined`
112+
113+
The maximum number of fraction digits to display.
114+
115+
If neither `minimumFractionDigits` or `maximumFractionDigits` are set, the default behavior is to round to 3 significant digits.
116+
117+
```js
118+
const prettyBytes = require('pretty-bytes');
119+
120+
// Show the number with at most 1 fractional digit
121+
prettyBytes(1920, {maximumFractionDigits: 1});
122+
//=> '1.9 kB'
123+
124+
prettyBytes(1920);
125+
//=> '1.92 kB'
126+
```
127+
88128
## Related
89129

90130
- [pretty-bytes-cli](https://github.com/sindresorhus/pretty-bytes-cli) - CLI for this module

‎test.js

+16
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,19 @@ test('bits and binary option', t => {
113113
t.is(prettyBytes(1025, {bits: true, binary: true}), '1 kibit');
114114
t.is(prettyBytes(1e6, {bits: true, binary: true}), '977 kibit');
115115
});
116+
117+
test('fractional digits options', t => {
118+
t.is(prettyBytes(1900, {maximumFractionDigits: 1}), '1.9 kB');
119+
t.is(prettyBytes(1900, {minimumFractionDigits: 3}), '1.900 kB');
120+
t.is(prettyBytes(1911, {maximumFractionDigits: 1}), '1.9 kB');
121+
t.is(prettyBytes(1111, {maximumFractionDigits: 2}), '1.11 kB');
122+
t.is(prettyBytes(1019, {maximumFractionDigits: 3}), '1.019 kB');
123+
t.is(prettyBytes(1001, {maximumFractionDigits: 3}), '1.001 kB');
124+
t.is(prettyBytes(1000, {minimumFractionDigits: 1, maximumFractionDigits: 3}), '1.0 kB');
125+
t.is(prettyBytes(3942, {minimumFractionDigits: 1, maximumFractionDigits: 2}), '3.94 kB');
126+
t.is(prettyBytes(4001, {maximumFractionDigits: 3, binary: true}), '3.907 kiB');
127+
t.is(prettyBytes(18717, {maximumFractionDigits: 2, binary: true}), '18.28 kiB');
128+
t.is(prettyBytes(18717, {maximumFractionDigits: 4, binary: true}), '18.2783 kiB');
129+
t.is(prettyBytes(32768, {minimumFractionDigits: 2, maximumFractionDigits: 3, binary: true}), '32.00 kiB');
130+
t.is(prettyBytes(65536, {minimumFractionDigits: 1, maximumFractionDigits: 3, binary: true}), '64.0 kiB');
131+
});

0 commit comments

Comments
 (0)
Please sign in to comment.