-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(explorer-ui): formatAmount
#2956
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,6 +25,8 @@ export const IconAndAmount = ({ | |
amount = formattedValue / (dec / 10 ** 6) | ||
} | ||
|
||
const displayAmount = amount ? formatAmount(amount) : '< 0.001' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. style: Ensure |
||
|
||
return ( | ||
<div className={`flex items-center ${className}`}> | ||
<div className="flex flex-row items-center text-white"> | ||
|
@@ -35,11 +37,11 @@ export const IconAndAmount = ({ | |
className={`${iconSize} min-w-[1rem] min-h-[1rem] inline rounded-full`} | ||
/> | ||
<div | ||
data-tooltip-content={amount} | ||
data-tooltip-content={displayAmount} | ||
data-tooltip-id="amount" | ||
className="flex-1 pl-1 mr-1 text-white" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. check: Ensure that the formatAmount function handles all edge cases, especially with large or small numbers. |
||
> | ||
{formatAmount(amount)} | ||
{displayAmount} | ||
</div> | ||
</div> | ||
<span className="text-white">{tokenSymbol}</span> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,81 @@ | ||
import numeral from 'numeral' | ||
interface FormatOptions { | ||
fullAmount?: boolean | ||
standardDigits?: number | ||
useCompactNotation?: boolean | ||
compactDigits?: number | ||
minimumAmount?: number | ||
roundingMode?: string | ||
} | ||
|
||
Comment on lines
+1
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ensure The interface FormatOptions {
fullAmount?: boolean
standardDigits?: number
useCompactNotation?: boolean
compactDigits?: number
minimumAmount?: number
roundingMode?: 'ceil' | 'floor' | 'round'
} |
||
export const formatAmount = ( | ||
amount: string, | ||
options?: FormatOptions | ||
): string => { | ||
if (amount === '') { | ||
Comment on lines
+10
to
+13
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider validating the The export const formatAmount = (
amount: string,
options?: FormatOptions
): string => {
if (isNaN(parseFloat(amount))) {
throw new TypeError(`"${amount}" is not a valid numeric string`)
} |
||
return '' | ||
} | ||
|
||
Comment on lines
+14
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Return '0.0' for empty string input. Instead of returning an empty string for an empty if (amount === '') {
return '0.0'
} |
||
const floatAmount = parseFloat(amount) | ||
|
||
try { | ||
Comment on lines
+18
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid re-parsing the amount. The const floatAmount = parseFloat(amount)
if (!Number.isFinite(floatAmount)) {
throw new TypeError(`"${amount}" is not a finite number`)
} |
||
if (!Number.isFinite(floatAmount)) { | ||
throw new TypeError(`"${amount}" is not a finite number`) | ||
} | ||
} catch ({ name, message }) { | ||
// console.error(name, message) | ||
return amount | ||
} | ||
|
||
Comment on lines
+24
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove try-catch block for finite check. The try-catch block is unnecessary since the finite check can be done directly. Remove the try-catch block for simplicity. if (!Number.isFinite(floatAmount)) {
throw new TypeError(`"${amount}" is not a finite number`)
} |
||
const fullAmount = options?.fullAmount ?? false | ||
const standardDigits = options?.standardDigits ?? 4 | ||
const useCompactNotation = options?.useCompactNotation ?? true | ||
const compactDigits = options?.compactDigits ?? (useCompactNotation ? 2 : 0) | ||
const minimumAmount = options?.minimumAmount ?? 0.0001 | ||
|
||
const locales = 'en-UK' | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider making locales configurable. The const locales = options?.locales ?? 'en-UK' |
||
if (!floatAmount) { | ||
return '0.0' | ||
} | ||
|
||
if (fullAmount) { | ||
return Intl.NumberFormat(locales).format(floatAmount) | ||
} | ||
|
||
Comment on lines
+41
to
+43
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider adding locale options for full amount. When if (fullAmount) {
return Intl.NumberFormat(locales).format(floatAmount)
} |
||
if (floatAmount < minimumAmount) { | ||
return `< ${minimumAmount}` | ||
} | ||
|
||
export const formatAmount = (value) => { | ||
numeral.nullFormat('--') | ||
const absAmount = Math.abs(floatAmount) | ||
|
||
if (absAmount < 0.0001) { | ||
return Intl.NumberFormat(locales, { | ||
maximumSignificantDigits: 1, | ||
}).format(floatAmount) | ||
} | ||
|
||
Comment on lines
+49
to
+55
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ensure significant digits are configurable. The significant digits for values less than if (absAmount < 0.0001) {
return Intl.NumberFormat(locales, {
maximumSignificantDigits: options?.significantDigits ?? 1,
}).format(floatAmount)
} |
||
if (absAmount < 1) { | ||
return Intl.NumberFormat(locales, { | ||
minimumFractionDigits: standardDigits, | ||
}).format(floatAmount) | ||
} | ||
|
||
// Round up if the value is less than 0.001 | ||
if (value > 0 && value < 0.001) { | ||
value = 0.001 | ||
if (absAmount < 1000) { | ||
return Intl.NumberFormat(locales, { | ||
minimumSignificantDigits: standardDigits, | ||
maximumSignificantDigits: standardDigits, | ||
}).format(floatAmount) | ||
} | ||
|
||
let format | ||
if (value >= 1000) { | ||
format = '0,0' // No decimal places for values 1000 or greater | ||
} else if (value < 0.01) { | ||
format = '0,0.000' // Four decimal places for values less than 0.01 | ||
} else { | ||
format = '0,0.00' // Two decimal places for all other values | ||
if (absAmount < 1000000) { | ||
return Intl.NumberFormat(locales, { | ||
maximumFractionDigits: 0, | ||
}).format(floatAmount) | ||
} | ||
|
||
return numeral(value).format(format) | ||
return Intl.NumberFormat(locales, { | ||
minimumFractionDigits: compactDigits, | ||
maximumFractionDigits: compactDigits, | ||
notation: useCompactNotation ? 'compact' : 'standard', | ||
}).format(floatAmount) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logic: Consider caching the result of
formatAmount
to avoid repeated calculations.