generated from Zoltu/preact-es2020-template
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Updated abbreviate values component (#267)
* updated abbreviate values component * sync with latest from interceptor
- Loading branch information
Showing
4 changed files
with
60 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,21 @@ | ||
export const AbbreviatedValue = ({ floatValue }: { floatValue: number }) => { | ||
const prefixes = [ | ||
{ value: 1e9, symbol: 'G' }, | ||
{ value: 1e6, symbol: 'M' }, | ||
{ value: 1e3, symbol: 'k' }, | ||
]; | ||
import type { ComponentChild } from 'preact' | ||
import { bigintToNumberFormatParts } from '../library/bigint.utils.js' | ||
|
||
for (const prefix of prefixes) { | ||
if (floatValue >= prefix.value) { | ||
return <>{toFixedLengthDigits(floatValue / prefix.value) + prefix.symbol}</> | ||
} | ||
} | ||
export const AbbreviatedValue = ({ amount, decimals = 18n }: { amount: bigint, decimals?: bigint }) => { | ||
const numberParts = bigintToNumberFormatParts(amount, decimals) | ||
const domElement: ComponentChild[] = [] | ||
|
||
// if value is a fraction of 1 | ||
if (floatValue && floatValue % 1 === floatValue) { | ||
const [coefficient, exponent] = floatValue.toExponential().split('e') | ||
const leadingZerosCount = Math.abs(parseInt(exponent)) - 1 | ||
const significantDigits = coefficient.replace('.', '') | ||
return <>0.<small>{'0'.repeat(leadingZerosCount)}</small>{significantDigits}</> | ||
for (const [type, value] of numberParts) { | ||
if (type === 'fraction') { | ||
const significantDigits = `${ Number(value) }` | ||
const zeroPad = value.replace(significantDigits, '') | ||
if (zeroPad.length) { | ||
domElement.push(<><small>{ zeroPad }</small>{ significantDigits }</>) | ||
continue | ||
} | ||
} | ||
domElement.push([value]) | ||
} | ||
|
||
return <>{toFixedLengthDigits(floatValue)}</> | ||
} | ||
|
||
function toFixedLengthDigits(num: number, max: number = 5) { | ||
const formatter = new Intl.NumberFormat('en-US', { maximumSignificantDigits: max, useGrouping: false }) | ||
return formatter.format(num) | ||
return <>{ domElement }</> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { ethers } from "ethers" | ||
|
||
export const bigintToNumberFormatParts = (amount: bigint, decimals = 18n, maximumSignificantDigits = 4) => { | ||
const floatValue = Number(ethers.formatUnits(amount, decimals)) | ||
|
||
let formatterOptions: Intl.NumberFormatOptions = { useGrouping: false, maximumFractionDigits: 3 } | ||
|
||
// maintain accuracy if value is a fraction of 1 ex 0.00001 | ||
if (floatValue % 1 === floatValue) formatterOptions.maximumSignificantDigits = maximumSignificantDigits | ||
|
||
// apply only compacting with prefixes for values >= 10k or values <= -10k | ||
if (Math.abs(floatValue) >= 1e4) { | ||
formatterOptions = { minimumFractionDigits: 0, notation: 'compact' } | ||
} | ||
|
||
const formatter = new Intl.NumberFormat('en-US', formatterOptions) | ||
const parts = formatter.formatToParts(floatValue) | ||
const partsMap = new Map<Intl.NumberFormatPartTypes, string>() | ||
|
||
for (const part of parts) { | ||
if (part.type === 'compact') { | ||
// replace American format with Metric prefixes https://www.ibiblio.org/units/prefixes.html | ||
const prefix = part.value.replace('K', 'k').replace('B', 'G') | ||
partsMap.set(part.type, prefix) | ||
continue | ||
} | ||
partsMap.set(part.type, part.value) | ||
} | ||
|
||
return partsMap | ||
} | ||
|
||
export const bigintToRoundedPrettyDecimalString = (amount: bigint, decimals?: bigint, maximumSignificantDigits = 4) => { | ||
const numberParts = bigintToNumberFormatParts(amount, decimals, maximumSignificantDigits) | ||
let numberString = '' | ||
|
||
for (const [_type, value] of numberParts) numberString += value | ||
|
||
return numberString | ||
} |