From aec60a12880cfa8f2437dc59f02bd78bbb1f8ce4 Mon Sep 17 00:00:00 2001 From: saml33 Date: Tue, 24 Jan 2023 12:26:14 +1100 Subject: [PATCH] add format numeric value component --- components/TokenList.tsx | 72 ++++++++++---------- components/account/AccountPage.tsx | 84 +++++++++++++----------- components/shared/AmountWithValue.tsx | 9 ++- components/shared/Change.tsx | 7 +- components/shared/FormatNumericValue.tsx | 18 +++++ utils/numbers.ts | 69 ++++++++++++++++++- 6 files changed, 179 insertions(+), 80 deletions(-) create mode 100644 components/shared/FormatNumericValue.tsx diff --git a/components/TokenList.tsx b/components/TokenList.tsx index 7fc7fb45..fc65b90c 100644 --- a/components/TokenList.tsx +++ b/components/TokenList.tsx @@ -36,6 +36,7 @@ import { USDC_MINT } from 'utils/constants' import { PublicKey } from '@solana/web3.js' import ActionsLinkButton from './account/ActionsLinkButton' import AmountWithValue from './shared/AmountWithValue' +import FormatNumericValue from './shared/FormatNumericValue' const TokenList = () => { const { t } = useTranslation(['common', 'token', 'trade']) @@ -189,57 +190,60 @@ const TokenList = () => { {tokenBalance ? ( ) : ( - + )} {inOrders ? ( ) : ( - + )} {unsettled ? ( ) : ( - + )}
@@ -247,16 +251,18 @@ const TokenList = () => {

- {formatDecimal(bank.getDepositRateUi(), 2, { - fixed: true, - })} + %

|

- {formatDecimal(bank.getBorrowRateUi(), 2, { - fixed: true, - })} + %

diff --git a/components/account/AccountPage.tsx b/components/account/AccountPage.tsx index be701fb5..fc064b09 100644 --- a/components/account/AccountPage.tsx +++ b/components/account/AccountPage.tsx @@ -6,7 +6,7 @@ import { useTranslation } from 'next-i18next' import { useEffect, useMemo, useState } from 'react' import AccountActions from './AccountActions' import mangoStore, { PerformanceDataItem } from '@store/mangoStore' -import { formatDecimal, formatFixedDecimals } from '../../utils/numbers' +import { formatNumericValue } from '../../utils/numbers' import FlipNumbers from 'react-flip-numbers' import dynamic from 'next/dynamic' const SimpleAreaChart = dynamic( @@ -41,6 +41,7 @@ import { useViewport } from 'hooks/useViewport' import { breakpoints } from 'utils/theme' import useMangoGroup from 'hooks/useMangoGroup' import PnlHistoryModal from '@components/modals/PnlHistoryModal' +import FormatNumericValue from '@components/shared/FormatNumericValue' const AccountPage = () => { const { t } = useTranslation(['common', 'account']) @@ -251,7 +252,7 @@ const AccountPage = () => { play delay={0.05} duration={1} - numbers={formatFixedDecimals(accountValue, true, true)} + numbers={formatNumericValue(accountValue, 2, true)} /> ) : ( { /> ) ) : ( - {formatFixedDecimals(accountValue, true, true)} + )}
- +

{t('today')}

@@ -388,15 +390,17 @@ const AccountPage = () => {

- {group && mangoAccount - ? formatFixedDecimals( - toUiDecimalsForQuote( - mangoAccount.getCollateralValue(group).toNumber() - ), - false, - true - ) - : `$${(0).toFixed(2)}`} +

{ > {t('total')}: - {group && mangoAccount - ? formatFixedDecimals( - toUiDecimalsForQuote( - mangoAccount - .getAssetsValue(group, HealthType.init) - .toNumber() - ), - false, - true - ) - : `$${(0).toFixed(2)}`} + @@ -436,7 +440,7 @@ const AccountPage = () => {

- {leverage.toFixed(2)}x + x

@@ -478,14 +482,14 @@ const AccountPage = () => { ) : null}

- {formatFixedDecimals(accountPnl, true, true)} +

- +

{t('today')}

@@ -518,14 +522,14 @@ const AccountPage = () => { ) : null}

- {formatFixedDecimals(interestTotalValue, true, true)} +

- +

{t('today')}

diff --git a/components/shared/AmountWithValue.tsx b/components/shared/AmountWithValue.tsx index ee472db6..7471e4cb 100644 --- a/components/shared/AmountWithValue.tsx +++ b/components/shared/AmountWithValue.tsx @@ -1,20 +1,23 @@ import Decimal from 'decimal.js' +import FormatNumericValue from './FormatNumericValue' const AmountWithValue = ({ amount, + amountDecimals, value, stacked, }: { amount: Decimal | number | string - value: string + amountDecimals?: number + value: number | string stacked?: boolean }) => { return (

<> - {amount}{' '} + {' '} - {value} +

diff --git a/components/shared/Change.tsx b/components/shared/Change.tsx index 6ff99afc..e877a9bb 100644 --- a/components/shared/Change.tsx +++ b/components/shared/Change.tsx @@ -1,6 +1,6 @@ import { MinusSmallIcon } from '@heroicons/react/20/solid' -import { formatDecimal } from 'utils/numbers' import { DownTriangle, UpTriangle } from './DirectionTriangles' +import FormatNumericValue from './FormatNumericValue' const Change = ({ change, @@ -42,7 +42,10 @@ const Change = ({ }`} > {prefix ? prefix : ''} - {isNaN(change) ? '0.00' : formatDecimal(Math.abs(change), 2)} + {suffix ? suffix : ''}

diff --git a/components/shared/FormatNumericValue.tsx b/components/shared/FormatNumericValue.tsx new file mode 100644 index 00000000..5a3edb57 --- /dev/null +++ b/components/shared/FormatNumericValue.tsx @@ -0,0 +1,18 @@ +import Decimal from 'decimal.js' +import { formatNumericValue } from 'utils/numbers' + +const FormatNumericValue = ({ + value, + decimals, + isUsd, + roundUp, +}: { + value: Decimal | number | string + decimals?: number + isUsd?: boolean + roundUp?: boolean +}) => { + return {formatNumericValue(value, decimals, isUsd, roundUp)} +} + +export default FormatNumericValue diff --git a/utils/numbers.ts b/utils/numbers.ts index a50d6fa6..91898e76 100644 --- a/utils/numbers.ts +++ b/utils/numbers.ts @@ -1,5 +1,68 @@ import Decimal from 'decimal.js' +export const formatNumericValue = ( + value: number | string | Decimal, + decimals?: number, + isUSD?: boolean, + roundUp?: boolean +): string => { + const numberValue = Number(value) + let formattedValue + if (numberValue > -0.0000000001 && numberValue < 0.000000001) { + formattedValue = isUSD ? '$0.00' : '0' + } else if (decimals) { + formattedValue = isUSD + ? Intl.NumberFormat('en', { + minimumFractionDigits: decimals, + maximumFractionDigits: decimals, + style: 'currency', + currency: 'USD', + }).format(numberValue) + : roundUp + ? roundValueUp(numberValue, decimals) + : roundValueDown(numberValue, decimals) + } else if (Math.abs(numberValue) >= 1000) { + formattedValue = isUSD + ? usdFormatter0.format(numberValue) + : roundUp + ? roundValueUp(numberValue, 0) + : roundValueDown(numberValue, 0) + } else if (Math.abs(numberValue) >= 0.1) { + formattedValue = isUSD + ? usdFormatter2.format(numberValue) + : roundUp + ? roundValueUp(numberValue, 3) + : roundValueDown(numberValue, 3) + } else { + formattedValue = isUSD + ? usdFormatter3Sig.format(numberValue) + : roundUp + ? roundValueUp(numberValue, 9) + : roundValueDown(numberValue, 9) + } + + if (formattedValue === '-$0.00') return '$0.00' + return formattedValue +} + +export const roundValueDown = ( + value: number | string | Decimal, + decimals: number +): string => { + const decimal = value instanceof Decimal ? value : new Decimal(value) + + return decimal.toDecimalPlaces(decimals, Decimal.ROUND_DOWN).toFixed(decimals) +} + +export const roundValueUp = ( + value: number | string | Decimal, + decimals: number +): string => { + const decimal = value instanceof Decimal ? value : new Decimal(value) + + return decimal.toDecimalPlaces(decimals, Decimal.ROUND_UP).toFixed(decimals) +} + const digits2 = new Intl.NumberFormat('en', { maximumFractionDigits: 2 }) const digits5 = new Intl.NumberFormat('en', { maximumFractionDigits: 5 }) const digits6 = new Intl.NumberFormat('en', { maximumFractionDigits: 6 }) @@ -50,7 +113,7 @@ const usdFormatter2 = Intl.NumberFormat('en', { currency: 'USD', }) -const usdFormatter3 = Intl.NumberFormat('en', { +const usdFormatter3Sig = Intl.NumberFormat('en', { minimumSignificantDigits: 3, maximumSignificantDigits: 3, style: 'currency', @@ -80,7 +143,9 @@ export const formatFixedDecimals = ( maximumFractionDigits: 3, }) } else { - formattedValue = isUSD ? usdFormatter3.format(value) : digits9.format(value) + formattedValue = isUSD + ? usdFormatter3Sig.format(value) + : digits9.format(value) } if (formattedValue === '-$0.00') return '$0.00'