@coingecko/cryptoformat 0.4.4 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -165,6 +165,23 @@ function generateFallbackFormatter(isoCode, locale, numDecimals = 2) {
165
165
  }
166
166
  }
167
167
 
168
+ function generateAbbreviatedFormatter(isoCode, locale) {
169
+ // Show regular numbers if no Intl.NumberFormat support.
170
+ if (!IntlNumberFormatSupported()) {
171
+ return generateFallbackFormatter(isoCode, locale, 0);
172
+ }
173
+
174
+ let numberFormatOptions = { style: "decimal", notation: "compact", minimumFractionDigits: 0, maximumFractionDigits: 2 };
175
+
176
+ // Currency symbol is supported if currency is Fiat/BTC/ETH.
177
+ if (!isCrypto(isoCode) || isBTCETH(isoCode)) {
178
+ numberFormatOptions.style = "currency";
179
+ numberFormatOptions.currency = isoCode;
180
+ }
181
+
182
+ return new Intl.NumberFormat(locale, numberFormatOptions);
183
+ }
184
+
168
185
  function generateFormatter(isoCode, locale, numDecimals, numSigFig) {
169
186
  const isNumberFormatSupported = IntlNumberFormatSupported();
170
187
 
@@ -185,6 +202,9 @@ let currencyFormatterTwoDecimal;
185
202
  let currencyFormatterSmall;
186
203
  let currencyFormatterVerySmall;
187
204
  let currencyFormatterVeryVerySmall;
205
+ let currencyFormatter15DP;
206
+ let currencyFormatter18DP;
207
+ let currencyFormatterAbbreviated;
188
208
 
189
209
  // If a page has to display multiple currencies, formatters would have to be created for each of them
190
210
  // To save some effort, we save formatters for reuse
@@ -219,6 +239,15 @@ function initializeFormatters(isoCode, locale) {
219
239
  currencyFormatterVeryVerySmall = cachedFormatter
220
240
  ? cachedFormatter.currencyFormatterVeryVerySmall
221
241
  : generateFormatter(isoCode, locale, 12);
242
+ currencyFormatter15DP = cachedFormatter
243
+ ? cachedFormatter.currencyFormatter15DP
244
+ : generateFormatter(isoCode, locale, 15);
245
+ currencyFormatter18DP = cachedFormatter
246
+ ? cachedFormatter.currencyFormatter18DP
247
+ : generateFormatter(isoCode, locale, 18);
248
+ currencyFormatterAbbreviated = cachedFormatter
249
+ ? cachedFormatter.currencyFormatterAbbreviated
250
+ : generateAbbreviatedFormatter(isoCode, locale);
222
251
 
223
252
  // Save in cache
224
253
  if (cachedFormatter == null) {
@@ -230,6 +259,9 @@ function initializeFormatters(isoCode, locale) {
230
259
  formattersCache[cacheKey].currencyFormatterSmall = currencyFormatterSmall;
231
260
  formattersCache[cacheKey].currencyFormatterVerySmall = currencyFormatterVerySmall;
232
261
  formattersCache[cacheKey].currencyFormatterVeryVerySmall = currencyFormatterVeryVerySmall;
262
+ formattersCache[cacheKey].currencyFormatter15DP = currencyFormatter15DP;
263
+ formattersCache[cacheKey].currencyFormatter18DP = currencyFormatter18DP;
264
+ formattersCache[cacheKey].currencyFormatterAbbreviated = currencyFormatterAbbreviated;
233
265
  }
234
266
  }
235
267
 
@@ -245,7 +277,8 @@ function formatCurrency(
245
277
  isoCode,
246
278
  locale = "en",
247
279
  raw = false,
248
- noDecimal = false
280
+ noDecimal = false,
281
+ abbreviated = false,
249
282
  ) {
250
283
  isoCode = isoCode.toUpperCase();
251
284
 
@@ -257,6 +290,17 @@ function formatCurrency(
257
290
  initializeFormatters(isoCode, locale);
258
291
  }
259
292
 
293
+ if (abbreviated) {
294
+ let formattedAbbreviatedCurrency = currencyFormatterAbbreviated.format(amount);
295
+
296
+ // Manually add currency code to the back for non-BTC/ETH crypto currencies.
297
+ if (isCrypto(isoCode) && !isBTCETH(isoCode)) {
298
+ formattedAbbreviatedCurrency = `${formattedAbbreviatedCurrency} ${isoCode}`;
299
+ }
300
+
301
+ return formatCurrencyOverride(formattedAbbreviatedCurrency, locale);
302
+ }
303
+
260
304
  if (noDecimal === true && amount > 100.0) {
261
305
  return formatCurrencyOverride(
262
306
  currencyFormatterNoDecimal.format(amount),
@@ -345,19 +389,32 @@ function formatCurrency(
345
389
  currencyFormatterVerySmall.format(amount),
346
390
  locale
347
391
  );
348
- } else {
349
- // Crypto amount < 0.000001, show 12 fraction digits
392
+ } else if (price >= 10**-9 && price < 10**-6) {
350
393
  return formatCurrencyOverride(
351
394
  currencyFormatterVeryVerySmall.format(amount),
352
395
  locale
353
396
  );
397
+ } else if (price >= 10**-12 && price < 10**-9) {
398
+ return formatCurrencyOverride(
399
+ currencyFormatter15DP.format(amount),
400
+ locale
401
+ );
402
+ } else if (price < 10**-12) {
403
+ return formatCurrencyOverride(
404
+ currencyFormatter18DP.format(amount),
405
+ locale
406
+ );
354
407
  }
355
408
  } else {
356
409
  const unsigned_amount = Math.abs(amount);
357
410
  if (raw) {
358
- if (unsigned_amount < 0.00001) {
411
+ if (unsigned_amount < 10**-12) {
412
+ return amount.toFixed(18);
413
+ } else if (unsigned_amount < 10**-9) {
414
+ return amount.toFixed(15);
415
+ } else if (unsigned_amount < 10**-6) {
359
416
  return amount.toFixed(12);
360
- } else if (unsigned_amount < 0.001) {
417
+ } else if (unsigned_amount < 10**-3) {
361
418
  return amount.toFixed(8);
362
419
  } else if (unsigned_amount < 1.0) {
363
420
  return amount.toFixed(6);
@@ -371,7 +428,17 @@ function formatCurrency(
371
428
  currencyFormatterNormal.format(amount),
372
429
  locale
373
430
  );
374
- } else if (unsigned_amount < 0.000001) {
431
+ } else if (unsigned_amount < 10**-12) {
432
+ return formatCurrencyOverride(
433
+ currencyFormatter18DP.format(amount),
434
+ locale
435
+ );
436
+ } else if (unsigned_amount < 10**-9) {
437
+ return formatCurrencyOverride(
438
+ currencyFormatter15DP.format(amount),
439
+ locale
440
+ );
441
+ } else if (unsigned_amount < 10**-6) {
375
442
  return formatCurrencyOverride(
376
443
  currencyFormatterVeryVerySmall.format(amount),
377
444
  locale
@@ -161,6 +161,23 @@ function generateFallbackFormatter(isoCode, locale, numDecimals = 2) {
161
161
  }
162
162
  }
163
163
 
164
+ function generateAbbreviatedFormatter(isoCode, locale) {
165
+ // Show regular numbers if no Intl.NumberFormat support.
166
+ if (!IntlNumberFormatSupported()) {
167
+ return generateFallbackFormatter(isoCode, locale, 0);
168
+ }
169
+
170
+ let numberFormatOptions = { style: "decimal", notation: "compact", minimumFractionDigits: 0, maximumFractionDigits: 2 };
171
+
172
+ // Currency symbol is supported if currency is Fiat/BTC/ETH.
173
+ if (!isCrypto(isoCode) || isBTCETH(isoCode)) {
174
+ numberFormatOptions.style = "currency";
175
+ numberFormatOptions.currency = isoCode;
176
+ }
177
+
178
+ return new Intl.NumberFormat(locale, numberFormatOptions);
179
+ }
180
+
164
181
  function generateFormatter(isoCode, locale, numDecimals, numSigFig) {
165
182
  const isNumberFormatSupported = IntlNumberFormatSupported();
166
183
 
@@ -181,6 +198,9 @@ let currencyFormatterTwoDecimal;
181
198
  let currencyFormatterSmall;
182
199
  let currencyFormatterVerySmall;
183
200
  let currencyFormatterVeryVerySmall;
201
+ let currencyFormatter15DP;
202
+ let currencyFormatter18DP;
203
+ let currencyFormatterAbbreviated;
184
204
 
185
205
  // If a page has to display multiple currencies, formatters would have to be created for each of them
186
206
  // To save some effort, we save formatters for reuse
@@ -215,6 +235,15 @@ function initializeFormatters(isoCode, locale) {
215
235
  currencyFormatterVeryVerySmall = cachedFormatter
216
236
  ? cachedFormatter.currencyFormatterVeryVerySmall
217
237
  : generateFormatter(isoCode, locale, 12);
238
+ currencyFormatter15DP = cachedFormatter
239
+ ? cachedFormatter.currencyFormatter15DP
240
+ : generateFormatter(isoCode, locale, 15);
241
+ currencyFormatter18DP = cachedFormatter
242
+ ? cachedFormatter.currencyFormatter18DP
243
+ : generateFormatter(isoCode, locale, 18);
244
+ currencyFormatterAbbreviated = cachedFormatter
245
+ ? cachedFormatter.currencyFormatterAbbreviated
246
+ : generateAbbreviatedFormatter(isoCode, locale);
218
247
 
219
248
  // Save in cache
220
249
  if (cachedFormatter == null) {
@@ -226,6 +255,9 @@ function initializeFormatters(isoCode, locale) {
226
255
  formattersCache[cacheKey].currencyFormatterSmall = currencyFormatterSmall;
227
256
  formattersCache[cacheKey].currencyFormatterVerySmall = currencyFormatterVerySmall;
228
257
  formattersCache[cacheKey].currencyFormatterVeryVerySmall = currencyFormatterVeryVerySmall;
258
+ formattersCache[cacheKey].currencyFormatter15DP = currencyFormatter15DP;
259
+ formattersCache[cacheKey].currencyFormatter18DP = currencyFormatter18DP;
260
+ formattersCache[cacheKey].currencyFormatterAbbreviated = currencyFormatterAbbreviated;
229
261
  }
230
262
  }
231
263
 
@@ -241,7 +273,8 @@ function formatCurrency(
241
273
  isoCode,
242
274
  locale = "en",
243
275
  raw = false,
244
- noDecimal = false
276
+ noDecimal = false,
277
+ abbreviated = false,
245
278
  ) {
246
279
  isoCode = isoCode.toUpperCase();
247
280
 
@@ -253,6 +286,17 @@ function formatCurrency(
253
286
  initializeFormatters(isoCode, locale);
254
287
  }
255
288
 
289
+ if (abbreviated) {
290
+ let formattedAbbreviatedCurrency = currencyFormatterAbbreviated.format(amount);
291
+
292
+ // Manually add currency code to the back for non-BTC/ETH crypto currencies.
293
+ if (isCrypto(isoCode) && !isBTCETH(isoCode)) {
294
+ formattedAbbreviatedCurrency = `${formattedAbbreviatedCurrency} ${isoCode}`;
295
+ }
296
+
297
+ return formatCurrencyOverride(formattedAbbreviatedCurrency, locale);
298
+ }
299
+
256
300
  if (noDecimal === true && amount > 100.0) {
257
301
  return formatCurrencyOverride(
258
302
  currencyFormatterNoDecimal.format(amount),
@@ -341,19 +385,32 @@ function formatCurrency(
341
385
  currencyFormatterVerySmall.format(amount),
342
386
  locale
343
387
  );
344
- } else {
345
- // Crypto amount < 0.000001, show 12 fraction digits
388
+ } else if (price >= 10**-9 && price < 10**-6) {
346
389
  return formatCurrencyOverride(
347
390
  currencyFormatterVeryVerySmall.format(amount),
348
391
  locale
349
392
  );
393
+ } else if (price >= 10**-12 && price < 10**-9) {
394
+ return formatCurrencyOverride(
395
+ currencyFormatter15DP.format(amount),
396
+ locale
397
+ );
398
+ } else if (price < 10**-12) {
399
+ return formatCurrencyOverride(
400
+ currencyFormatter18DP.format(amount),
401
+ locale
402
+ );
350
403
  }
351
404
  } else {
352
405
  const unsigned_amount = Math.abs(amount);
353
406
  if (raw) {
354
- if (unsigned_amount < 0.00001) {
407
+ if (unsigned_amount < 10**-12) {
408
+ return amount.toFixed(18);
409
+ } else if (unsigned_amount < 10**-9) {
410
+ return amount.toFixed(15);
411
+ } else if (unsigned_amount < 10**-6) {
355
412
  return amount.toFixed(12);
356
- } else if (unsigned_amount < 0.001) {
413
+ } else if (unsigned_amount < 10**-3) {
357
414
  return amount.toFixed(8);
358
415
  } else if (unsigned_amount < 1.0) {
359
416
  return amount.toFixed(6);
@@ -367,7 +424,17 @@ function formatCurrency(
367
424
  currencyFormatterNormal.format(amount),
368
425
  locale
369
426
  );
370
- } else if (unsigned_amount < 0.000001) {
427
+ } else if (unsigned_amount < 10**-12) {
428
+ return formatCurrencyOverride(
429
+ currencyFormatter18DP.format(amount),
430
+ locale
431
+ );
432
+ } else if (unsigned_amount < 10**-9) {
433
+ return formatCurrencyOverride(
434
+ currencyFormatter15DP.format(amount),
435
+ locale
436
+ );
437
+ } else if (unsigned_amount < 10**-6) {
371
438
  return formatCurrencyOverride(
372
439
  currencyFormatterVeryVerySmall.format(amount),
373
440
  locale
@@ -167,6 +167,23 @@
167
167
  }
168
168
  }
169
169
 
170
+ function generateAbbreviatedFormatter(isoCode, locale) {
171
+ // Show regular numbers if no Intl.NumberFormat support.
172
+ if (!IntlNumberFormatSupported()) {
173
+ return generateFallbackFormatter(isoCode, locale, 0);
174
+ }
175
+
176
+ let numberFormatOptions = { style: "decimal", notation: "compact", minimumFractionDigits: 0, maximumFractionDigits: 2 };
177
+
178
+ // Currency symbol is supported if currency is Fiat/BTC/ETH.
179
+ if (!isCrypto(isoCode) || isBTCETH(isoCode)) {
180
+ numberFormatOptions.style = "currency";
181
+ numberFormatOptions.currency = isoCode;
182
+ }
183
+
184
+ return new Intl.NumberFormat(locale, numberFormatOptions);
185
+ }
186
+
170
187
  function generateFormatter(isoCode, locale, numDecimals, numSigFig) {
171
188
  const isNumberFormatSupported = IntlNumberFormatSupported();
172
189
 
@@ -187,6 +204,9 @@
187
204
  let currencyFormatterSmall;
188
205
  let currencyFormatterVerySmall;
189
206
  let currencyFormatterVeryVerySmall;
207
+ let currencyFormatter15DP;
208
+ let currencyFormatter18DP;
209
+ let currencyFormatterAbbreviated;
190
210
 
191
211
  // If a page has to display multiple currencies, formatters would have to be created for each of them
192
212
  // To save some effort, we save formatters for reuse
@@ -221,6 +241,15 @@
221
241
  currencyFormatterVeryVerySmall = cachedFormatter
222
242
  ? cachedFormatter.currencyFormatterVeryVerySmall
223
243
  : generateFormatter(isoCode, locale, 12);
244
+ currencyFormatter15DP = cachedFormatter
245
+ ? cachedFormatter.currencyFormatter15DP
246
+ : generateFormatter(isoCode, locale, 15);
247
+ currencyFormatter18DP = cachedFormatter
248
+ ? cachedFormatter.currencyFormatter18DP
249
+ : generateFormatter(isoCode, locale, 18);
250
+ currencyFormatterAbbreviated = cachedFormatter
251
+ ? cachedFormatter.currencyFormatterAbbreviated
252
+ : generateAbbreviatedFormatter(isoCode, locale);
224
253
 
225
254
  // Save in cache
226
255
  if (cachedFormatter == null) {
@@ -232,6 +261,9 @@
232
261
  formattersCache[cacheKey].currencyFormatterSmall = currencyFormatterSmall;
233
262
  formattersCache[cacheKey].currencyFormatterVerySmall = currencyFormatterVerySmall;
234
263
  formattersCache[cacheKey].currencyFormatterVeryVerySmall = currencyFormatterVeryVerySmall;
264
+ formattersCache[cacheKey].currencyFormatter15DP = currencyFormatter15DP;
265
+ formattersCache[cacheKey].currencyFormatter18DP = currencyFormatter18DP;
266
+ formattersCache[cacheKey].currencyFormatterAbbreviated = currencyFormatterAbbreviated;
235
267
  }
236
268
  }
237
269
 
@@ -247,7 +279,8 @@
247
279
  isoCode,
248
280
  locale = "en",
249
281
  raw = false,
250
- noDecimal = false
282
+ noDecimal = false,
283
+ abbreviated = false,
251
284
  ) {
252
285
  isoCode = isoCode.toUpperCase();
253
286
 
@@ -259,6 +292,17 @@
259
292
  initializeFormatters(isoCode, locale);
260
293
  }
261
294
 
295
+ if (abbreviated) {
296
+ let formattedAbbreviatedCurrency = currencyFormatterAbbreviated.format(amount);
297
+
298
+ // Manually add currency code to the back for non-BTC/ETH crypto currencies.
299
+ if (isCrypto(isoCode) && !isBTCETH(isoCode)) {
300
+ formattedAbbreviatedCurrency = `${formattedAbbreviatedCurrency} ${isoCode}`;
301
+ }
302
+
303
+ return formatCurrencyOverride(formattedAbbreviatedCurrency, locale);
304
+ }
305
+
262
306
  if (noDecimal === true && amount > 100.0) {
263
307
  return formatCurrencyOverride(
264
308
  currencyFormatterNoDecimal.format(amount),
@@ -347,19 +391,32 @@
347
391
  currencyFormatterVerySmall.format(amount),
348
392
  locale
349
393
  );
350
- } else {
351
- // Crypto amount < 0.000001, show 12 fraction digits
394
+ } else if (price >= 10**-9 && price < 10**-6) {
352
395
  return formatCurrencyOverride(
353
396
  currencyFormatterVeryVerySmall.format(amount),
354
397
  locale
355
398
  );
399
+ } else if (price >= 10**-12 && price < 10**-9) {
400
+ return formatCurrencyOverride(
401
+ currencyFormatter15DP.format(amount),
402
+ locale
403
+ );
404
+ } else if (price < 10**-12) {
405
+ return formatCurrencyOverride(
406
+ currencyFormatter18DP.format(amount),
407
+ locale
408
+ );
356
409
  }
357
410
  } else {
358
411
  const unsigned_amount = Math.abs(amount);
359
412
  if (raw) {
360
- if (unsigned_amount < 0.00001) {
413
+ if (unsigned_amount < 10**-12) {
414
+ return amount.toFixed(18);
415
+ } else if (unsigned_amount < 10**-9) {
416
+ return amount.toFixed(15);
417
+ } else if (unsigned_amount < 10**-6) {
361
418
  return amount.toFixed(12);
362
- } else if (unsigned_amount < 0.001) {
419
+ } else if (unsigned_amount < 10**-3) {
363
420
  return amount.toFixed(8);
364
421
  } else if (unsigned_amount < 1.0) {
365
422
  return amount.toFixed(6);
@@ -373,7 +430,17 @@
373
430
  currencyFormatterNormal.format(amount),
374
431
  locale
375
432
  );
376
- } else if (unsigned_amount < 0.000001) {
433
+ } else if (unsigned_amount < 10**-12) {
434
+ return formatCurrencyOverride(
435
+ currencyFormatter18DP.format(amount),
436
+ locale
437
+ );
438
+ } else if (unsigned_amount < 10**-9) {
439
+ return formatCurrencyOverride(
440
+ currencyFormatter15DP.format(amount),
441
+ locale
442
+ );
443
+ } else if (unsigned_amount < 10**-6) {
377
444
  return formatCurrencyOverride(
378
445
  currencyFormatterVeryVerySmall.format(amount),
379
446
  locale
package/lib/index.d.ts CHANGED
@@ -24,8 +24,16 @@ export function formatCurrency(
24
24
  raw: boolean,
25
25
  noDecimal: boolean | decimalConfig
26
26
  ): string;
27
+ export function formatCurrency(
28
+ amount: number,
29
+ isoCode: string,
30
+ locale: string,
31
+ raw: boolean,
32
+ noDecimal: boolean | decimalConfig,
33
+ abbreviated: boolean,
34
+ ): string;
27
35
 
28
36
  interface decimalConfig {
29
37
  decimalPlaces?: number,
30
38
  significantFigures?: number
31
- }
39
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coingecko/cryptoformat",
3
- "version": "0.4.4",
3
+ "version": "0.6.0",
4
4
  "description": "Javascript library to format and display cryptocurrencies and fiat",
5
5
  "main": "lib/cryptoformat.cjs.js",
6
6
  "module": "lib/cryptoformat.esm.js",