add format numeric value component

This commit is contained in:
saml33 2023-01-24 12:26:14 +11:00
parent 0f99619e2c
commit aec60a1288
6 changed files with 179 additions and 80 deletions

View File

@ -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 = () => {
<Td className="text-right">
{tokenBalance ? (
<AmountWithValue
amount={formatDecimal(tokenBalance, bank.mintDecimals)}
value={formatFixedDecimals(
tokenBalance * oraclePrice,
true,
true
)}
amount={tokenBalance}
amountDecimals={bank.mintDecimals}
value={tokenBalance * oraclePrice}
stacked
/>
) : (
<AmountWithValue amount="0" value="$0.00" stacked />
<AmountWithValue
amount="0"
amountDecimals={0}
value={0}
stacked
/>
)}
</Td>
<Td className="text-right">
{inOrders ? (
<AmountWithValue
amount={formatDecimal(inOrders, bank.mintDecimals)}
value={formatFixedDecimals(
inOrders * oraclePrice,
true,
true
)}
amount={inOrders}
amountDecimals={bank.mintDecimals}
value={inOrders * oraclePrice}
stacked
/>
) : (
<AmountWithValue amount="0" value="$0.00" stacked />
<AmountWithValue
amount="0"
amountDecimals={0}
value={0}
stacked
/>
)}
</Td>
<Td className="text-right">
{unsettled ? (
<AmountWithValue
amount={formatDecimal(unsettled, bank.mintDecimals)}
value={formatFixedDecimals(
unsettled * oraclePrice,
true,
true
)}
amount={unsettled}
amountDecimals={bank.mintDecimals}
value={unsettled * oraclePrice}
stacked
/>
) : (
<AmountWithValue amount="0" value="$0.00" stacked />
<AmountWithValue
amount="0"
amountDecimals={0}
value={0}
stacked
/>
)}
</Td>
<Td>
<div className="flex flex-col text-right">
<AmountWithValue
amount={
interestAmount
? formatDecimal(interestAmount, bank.mintDecimals)
: '0'
}
value={formatFixedDecimals(interestValue, true, true)}
amount={interestAmount}
amountDecimals={bank.mintDecimals}
value={interestValue}
stacked
/>
</div>
@ -247,16 +251,18 @@ const TokenList = () => {
<Td>
<div className="flex justify-end space-x-1.5">
<p className="text-th-up">
{formatDecimal(bank.getDepositRateUi(), 2, {
fixed: true,
})}
<FormatNumericValue
value={bank.getDepositRateUi()}
decimals={2}
/>
%
</p>
<span className="text-th-fgd-4">|</span>
<p className="text-th-down">
{formatDecimal(bank.getBorrowRateUi(), 2, {
fixed: true,
})}
<FormatNumericValue
value={bank.getBorrowRateUi()}
decimals={2}
/>
%
</p>
</div>

View File

@ -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)}
/>
) : (
<FlipNumbers
@ -264,14 +265,15 @@ const AccountPage = () => {
/>
)
) : (
<span>{formatFixedDecimals(accountValue, true, true)}</span>
<FormatNumericValue
value={accountValue}
isUsd={true}
decimals={2}
/>
)}
</div>
<div className="flex items-center space-x-1.5">
<Change
change={Number(formatDecimal(accountValueChange, 2))}
prefix="$"
/>
<Change change={accountValueChange} prefix="$" />
<p className="text-th-fgd-4">{t('today')}</p>
</div>
</div>
@ -388,15 +390,17 @@ const AccountPage = () => {
</p>
</Tooltip>
<p className="mt-1 mb-0.5 text-2xl font-bold text-th-fgd-1 lg:text-xl xl:text-2xl">
{group && mangoAccount
? formatFixedDecimals(
toUiDecimalsForQuote(
mangoAccount.getCollateralValue(group).toNumber()
),
false,
true
)
: `$${(0).toFixed(2)}`}
<FormatNumericValue
value={
group && mangoAccount
? toUiDecimalsForQuote(
mangoAccount.getCollateralValue(group)
)
: 0
}
decimals={2}
isUsd={true}
/>
</p>
<span className="text-xs font-normal text-th-fgd-4">
<Tooltip
@ -407,17 +411,17 @@ const AccountPage = () => {
>
<span className="tooltip-underline">{t('total')}</span>:
<span className="ml-1 font-mono text-th-fgd-2">
{group && mangoAccount
? formatFixedDecimals(
toUiDecimalsForQuote(
mangoAccount
.getAssetsValue(group, HealthType.init)
.toNumber()
),
false,
true
)
: `$${(0).toFixed(2)}`}
<FormatNumericValue
value={
group && mangoAccount
? toUiDecimalsForQuote(
mangoAccount.getAssetsValue(group, HealthType.init)
)
: 0
}
decimals={2}
isUsd={true}
/>
</span>
</Tooltip>
</span>
@ -436,7 +440,7 @@ const AccountPage = () => {
</p>
</Tooltip>
<p className="mt-1 text-2xl font-bold text-th-fgd-1 lg:text-xl xl:text-2xl">
{leverage.toFixed(2)}x
<FormatNumericValue value={leverage} decimals={2} />x
</p>
</div>
</div>
@ -478,14 +482,14 @@ const AccountPage = () => {
) : null}
</div>
<p className="mt-1 mb-0.5 text-left text-2xl font-bold text-th-fgd-1 lg:text-xl xl:text-2xl">
{formatFixedDecimals(accountPnl, true, true)}
<FormatNumericValue
value={accountPnl}
decimals={2}
isUsd={true}
/>
</p>
<div className="flex space-x-1">
<Change
change={Number(formatDecimal(oneDayPnlChange, 2))}
prefix="$"
size="small"
/>
<Change change={oneDayPnlChange} prefix="$" size="small" />
<p className="text-xs text-th-fgd-4">{t('today')}</p>
</div>
</div>
@ -518,14 +522,14 @@ const AccountPage = () => {
) : null}
</div>
<p className="mt-1 mb-0.5 text-2xl font-bold text-th-fgd-1 lg:text-xl xl:text-2xl">
{formatFixedDecimals(interestTotalValue, true, true)}
<FormatNumericValue
value={interestTotalValue}
decimals={2}
isUsd={true}
/>
</p>
<div className="flex space-x-1">
<Change
change={Number(formatDecimal(oneDayInterestChange, 2))}
prefix="$"
size="small"
/>
<Change change={oneDayInterestChange} prefix="$" size="small" />
<p className="text-xs text-th-fgd-4">{t('today')}</p>
</div>
</div>

View File

@ -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 (
<p className={`font-mono text-th-fgd-2 ${stacked ? 'text-right' : ''}`}>
<>
{amount}{' '}
<FormatNumericValue value={amount} decimals={amountDecimals} />{' '}
<span className={`text-th-fgd-4 ${stacked ? 'block' : ''}`}>
{value}
<FormatNumericValue value={value} decimals={2} isUsd={true} />
</span>
</>
</p>

View File

@ -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)}
<FormatNumericValue
value={isNaN(change) ? '0.00' : Math.abs(change)}
decimals={2}
/>
{suffix ? suffix : ''}
</p>
</div>

View File

@ -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 <span>{formatNumericValue(value, decimals, isUsd, roundUp)}</span>
}
export default FormatNumericValue

View File

@ -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'