chore: updating numberFormat for other currencies and languages (#7239)
* adding currency settings option * moving menu item to shared component * adding supported currencies * currency menu items * currency url params * currency selector e2e tests * fixing tests * currency icons * removing eslint * removing another eslint disable * renaming to local currency * more name changes * design updates * adding currencies * changing formatter rules to formatter options * renaming file * fixing lint * custom currency symbol in number formatting * refactoring input to number formatter * locale selection * updating all format numbers with currency and locale * updating portfolio * better formatting symbols * removing adding locale and currency * upgrading constants to be translatable * refactoring * adding tests * updating comment * removing 0 from hardcoded input and comment
This commit is contained in:
parent
cd520a9e2c
commit
60acc689ee
@ -279,16 +279,20 @@ export default function AuthenticatedHeader({ account, openSettings }: { account
|
|||||||
{totalBalance !== undefined ? (
|
{totalBalance !== undefined ? (
|
||||||
<FadeInColumn gap="xs">
|
<FadeInColumn gap="xs">
|
||||||
<ThemedText.HeadlineLarge fontWeight={535} data-testid="portfolio-total-balance">
|
<ThemedText.HeadlineLarge fontWeight={535} data-testid="portfolio-total-balance">
|
||||||
{formatNumber(totalBalance, NumberType.PortfolioBalance)}
|
{formatNumber({
|
||||||
|
input: totalBalance,
|
||||||
|
type: NumberType.PortfolioBalance,
|
||||||
|
})}
|
||||||
</ThemedText.HeadlineLarge>
|
</ThemedText.HeadlineLarge>
|
||||||
<AutoRow marginBottom="20px">
|
<AutoRow marginBottom="20px">
|
||||||
{absoluteChange !== 0 && percentChange && (
|
{absoluteChange !== 0 && percentChange && (
|
||||||
<>
|
<>
|
||||||
<PortfolioArrow change={absoluteChange as number} />
|
<PortfolioArrow change={absoluteChange as number} />
|
||||||
<ThemedText.BodySecondary>
|
<ThemedText.BodySecondary>
|
||||||
{`${formatNumber(Math.abs(absoluteChange as number), NumberType.PortfolioBalance)} (${formatDelta(
|
{`${formatNumber({
|
||||||
percentChange
|
input: Math.abs(absoluteChange as number),
|
||||||
)})`}
|
type: NumberType.PortfolioBalance,
|
||||||
|
})} (${formatDelta(percentChange)})`}
|
||||||
</ThemedText.BodySecondary>
|
</ThemedText.BodySecondary>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
@ -167,18 +167,21 @@ function PositionListItem({ positionInfo }: { positionInfo: PositionInfo }) {
|
|||||||
placement="left"
|
placement="left"
|
||||||
text={
|
text={
|
||||||
<div style={{ padding: '4px 0px' }}>
|
<div style={{ padding: '4px 0px' }}>
|
||||||
<ThemedText.BodySmall>{`${formatNumber(
|
<ThemedText.BodySmall>{`${formatNumber({
|
||||||
liquidityValue,
|
input: liquidityValue,
|
||||||
NumberType.PortfolioBalance
|
type: NumberType.PortfolioBalance,
|
||||||
)} (liquidity) + ${formatNumber(
|
})} (liquidity) + ${formatNumber({
|
||||||
feeValue,
|
input: feeValue,
|
||||||
NumberType.PortfolioBalance
|
type: NumberType.PortfolioBalance,
|
||||||
)} (fees)`}</ThemedText.BodySmall>
|
})} (fees)`}</ThemedText.BodySmall>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<ThemedText.SubHeader>
|
<ThemedText.SubHeader>
|
||||||
{formatNumber((liquidityValue ?? 0) + (feeValue ?? 0), NumberType.PortfolioBalance)}
|
{formatNumber({
|
||||||
|
input: (liquidityValue ?? 0) + (feeValue ?? 0),
|
||||||
|
type: NumberType.PortfolioBalance,
|
||||||
|
})}
|
||||||
</ThemedText.SubHeader>
|
</ThemedText.SubHeader>
|
||||||
</MouseoverTooltip>
|
</MouseoverTooltip>
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ function TokenRow({ token, quantity, denominatedValue, tokenProjectMarket }: Tok
|
|||||||
title={<TokenNameText>{token?.name}</TokenNameText>}
|
title={<TokenNameText>{token?.name}</TokenNameText>}
|
||||||
descriptor={
|
descriptor={
|
||||||
<TokenBalanceText>
|
<TokenBalanceText>
|
||||||
{formatNumber(quantity, NumberType.TokenNonTx)} {token?.symbol}
|
{formatNumber({ input: quantity, type: NumberType.TokenNonTx })} {token?.symbol}
|
||||||
</TokenBalanceText>
|
</TokenBalanceText>
|
||||||
}
|
}
|
||||||
onClick={navigateToTokenDetails}
|
onClick={navigateToTokenDetails}
|
||||||
@ -109,7 +109,10 @@ function TokenRow({ token, quantity, denominatedValue, tokenProjectMarket }: Tok
|
|||||||
denominatedValue && (
|
denominatedValue && (
|
||||||
<>
|
<>
|
||||||
<ThemedText.SubHeader>
|
<ThemedText.SubHeader>
|
||||||
{formatNumber(denominatedValue?.value, NumberType.PortfolioBalance)}
|
{formatNumber({
|
||||||
|
input: denominatedValue?.value,
|
||||||
|
type: NumberType.PortfolioBalance,
|
||||||
|
})}
|
||||||
</ThemedText.SubHeader>
|
</ThemedText.SubHeader>
|
||||||
<Row justify="flex-end">
|
<Row justify="flex-end">
|
||||||
<PortfolioArrow change={percentChange} size={20} strokeWidth={1.75} />
|
<PortfolioArrow change={percentChange} size={20} strokeWidth={1.75} />
|
||||||
|
@ -39,7 +39,10 @@ export function FiatValue({
|
|||||||
<Row gap="sm">
|
<Row gap="sm">
|
||||||
<ThemedText.BodySmall color="neutral2">
|
<ThemedText.BodySmall color="neutral2">
|
||||||
{fiatValue.data ? (
|
{fiatValue.data ? (
|
||||||
formatNumber(fiatValue.data, NumberType.FiatTokenPrice)
|
formatNumber({
|
||||||
|
input: fiatValue.data,
|
||||||
|
type: NumberType.FiatTokenPrice,
|
||||||
|
})
|
||||||
) : (
|
) : (
|
||||||
<MouseoverTooltip text={<Trans>Not enough liquidity to show accurate USD value.</Trans>}>-</MouseoverTooltip>
|
<MouseoverTooltip text={<Trans>Not enough liquidity to show accurate USD value.</Trans>}>-</MouseoverTooltip>
|
||||||
)}
|
)}
|
||||||
|
@ -62,7 +62,12 @@ function Stat({
|
|||||||
return (
|
return (
|
||||||
<StatWrapper data-cy={`${dataCy}`}>
|
<StatWrapper data-cy={`${dataCy}`}>
|
||||||
<MouseoverTooltip text={description}>{title}</MouseoverTooltip>
|
<MouseoverTooltip text={description}>{title}</MouseoverTooltip>
|
||||||
<StatPrice>{formatNumber(value, NumberType.FiatTokenStats)}</StatPrice>
|
<StatPrice>
|
||||||
|
{formatNumber({
|
||||||
|
input: value,
|
||||||
|
type: NumberType.FiatTokenStats,
|
||||||
|
})}
|
||||||
|
</StatPrice>
|
||||||
</StatWrapper>
|
</StatWrapper>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -503,11 +503,19 @@ export const LoadedRow = forwardRef((props: LoadedRowProps, ref: ForwardedRef<HT
|
|||||||
}
|
}
|
||||||
tvl={
|
tvl={
|
||||||
<ClickableContent>
|
<ClickableContent>
|
||||||
{formatNumber(token.market?.totalValueLocked?.value, NumberType.FiatTokenStats)}
|
{formatNumber({
|
||||||
|
input: token.market?.totalValueLocked?.value,
|
||||||
|
type: NumberType.FiatTokenStats,
|
||||||
|
})}
|
||||||
</ClickableContent>
|
</ClickableContent>
|
||||||
}
|
}
|
||||||
volume={
|
volume={
|
||||||
<ClickableContent>{formatNumber(token.market?.volume?.value, NumberType.FiatTokenStats)}</ClickableContent>
|
<ClickableContent>
|
||||||
|
{formatNumber({
|
||||||
|
input: token.market?.volume?.value,
|
||||||
|
type: NumberType.FiatTokenStats,
|
||||||
|
})}
|
||||||
|
</ClickableContent>
|
||||||
}
|
}
|
||||||
sparkLine={
|
sparkLine={
|
||||||
<SparkLine>
|
<SparkLine>
|
||||||
|
@ -73,10 +73,10 @@ export function AdvancedSwapDetails({ trade, allowedSlippage, syncing = false }:
|
|||||||
>
|
>
|
||||||
<TextWithLoadingPlaceholder syncing={syncing} width={50}>
|
<TextWithLoadingPlaceholder syncing={syncing} width={50}>
|
||||||
<ThemedText.BodySmall>
|
<ThemedText.BodySmall>
|
||||||
{`${trade.totalGasUseEstimateUSD ? '~' : ''}${formatNumber(
|
{`${trade.totalGasUseEstimateUSD ? '~' : ''}${formatNumber({
|
||||||
trade.totalGasUseEstimateUSD,
|
input: trade.totalGasUseEstimateUSD,
|
||||||
NumberType.FiatGasPrice
|
type: NumberType.FiatGasPrice,
|
||||||
)}`}
|
})}`}
|
||||||
</ThemedText.BodySmall>
|
</ThemedText.BodySmall>
|
||||||
</TextWithLoadingPlaceholder>
|
</TextWithLoadingPlaceholder>
|
||||||
</MouseoverTooltip>
|
</MouseoverTooltip>
|
||||||
|
@ -39,7 +39,11 @@ const GasCostItem = ({
|
|||||||
<Row justify="space-between">
|
<Row justify="space-between">
|
||||||
<ThemedText.SubHeaderSmall>{title}</ThemedText.SubHeaderSmall>
|
<ThemedText.SubHeaderSmall>{title}</ThemedText.SubHeaderSmall>
|
||||||
<ThemedText.SubHeaderSmall color="neutral1">
|
<ThemedText.SubHeaderSmall color="neutral1">
|
||||||
{itemValue ?? formatNumber(amount, NumberType.FiatGasPrice)}
|
{itemValue ??
|
||||||
|
formatNumber({
|
||||||
|
input: amount,
|
||||||
|
type: NumberType.FiatGasPrice,
|
||||||
|
})}
|
||||||
</ThemedText.SubHeaderSmall>
|
</ThemedText.SubHeaderSmall>
|
||||||
</Row>
|
</Row>
|
||||||
)
|
)
|
||||||
|
@ -47,10 +47,20 @@ export default function GasEstimateTooltip({ trade, loading }: { trade?: Interfa
|
|||||||
{isUniswapXTrade(trade) ? <UniswapXRouterIcon testId="gas-estimate-uniswapx-icon" /> : <StyledGasIcon />}
|
{isUniswapXTrade(trade) ? <UniswapXRouterIcon testId="gas-estimate-uniswapx-icon" /> : <StyledGasIcon />}
|
||||||
<ThemedText.BodySmall color="neutral2">
|
<ThemedText.BodySmall color="neutral2">
|
||||||
<Row gap="xs">
|
<Row gap="xs">
|
||||||
<div>{formatNumber(trade.totalGasUseEstimateUSD, NumberType.FiatGasPrice)}</div>
|
<div>
|
||||||
|
{formatNumber({
|
||||||
|
input: trade.totalGasUseEstimateUSD,
|
||||||
|
type: NumberType.FiatGasPrice,
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
{isUniswapXTrade(trade) && (
|
{isUniswapXTrade(trade) && (
|
||||||
<div>
|
<div>
|
||||||
<s>{formatNumber(trade.classicGasUseEstimateUSD, NumberType.FiatGasPrice)}</s>
|
<s>
|
||||||
|
{formatNumber({
|
||||||
|
input: trade.classicGasUseEstimateUSD,
|
||||||
|
type: NumberType.FiatGasPrice,
|
||||||
|
})}
|
||||||
|
</s>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</Row>
|
</Row>
|
||||||
|
@ -109,7 +109,12 @@ export default function SwapModalFooter({
|
|||||||
</Label>
|
</Label>
|
||||||
</MouseoverTooltip>
|
</MouseoverTooltip>
|
||||||
<MouseoverTooltip placement="right" size={TooltipSize.Small} text={<GasBreakdownTooltip trade={trade} />}>
|
<MouseoverTooltip placement="right" size={TooltipSize.Small} text={<GasBreakdownTooltip trade={trade} />}>
|
||||||
<DetailRowValue>{formatNumber(trade.totalGasUseEstimateUSD, NumberType.FiatGasPrice)}</DetailRowValue>
|
<DetailRowValue>
|
||||||
|
{formatNumber({
|
||||||
|
input: trade.totalGasUseEstimateUSD,
|
||||||
|
type: NumberType.FiatGasPrice,
|
||||||
|
})}
|
||||||
|
</DetailRowValue>
|
||||||
</MouseoverTooltip>
|
</MouseoverTooltip>
|
||||||
</Row>
|
</Row>
|
||||||
</ThemedText.BodySmall>
|
</ThemedText.BodySmall>
|
||||||
|
@ -59,7 +59,10 @@ export function SwapModalHeaderAmount({ tooltipText, label, amount, usdAmount, f
|
|||||||
</ResponsiveHeadline>
|
</ResponsiveHeadline>
|
||||||
{usdAmount && (
|
{usdAmount && (
|
||||||
<ThemedText.BodySmall color="neutral2">
|
<ThemedText.BodySmall color="neutral2">
|
||||||
{formatNumber(usdAmount, NumberType.FiatTokenQuantity)}
|
{formatNumber({
|
||||||
|
input: usdAmount,
|
||||||
|
type: NumberType.FiatTokenQuantity,
|
||||||
|
})}
|
||||||
</ThemedText.BodySmall>
|
</ThemedText.BodySmall>
|
||||||
)}
|
)}
|
||||||
</Column>
|
</Column>
|
||||||
|
@ -58,7 +58,14 @@ export default function TradePrice({ price }: TradePriceProps) {
|
|||||||
<ThemedText.BodySmall>{text}</ThemedText.BodySmall>{' '}
|
<ThemedText.BodySmall>{text}</ThemedText.BodySmall>{' '}
|
||||||
{usdPrice && (
|
{usdPrice && (
|
||||||
<ThemedText.BodySmall color="neutral2">
|
<ThemedText.BodySmall color="neutral2">
|
||||||
<Trans>({formatNumber(usdPrice, NumberType.FiatTokenPrice)})</Trans>
|
<Trans>
|
||||||
|
(
|
||||||
|
{formatNumber({
|
||||||
|
input: usdPrice,
|
||||||
|
type: NumberType.FiatTokenPrice,
|
||||||
|
})}
|
||||||
|
)
|
||||||
|
</Trans>
|
||||||
</ThemedText.BodySmall>
|
</ThemedText.BodySmall>
|
||||||
)}
|
)}
|
||||||
</StyledPriceContainer>
|
</StyledPriceContainer>
|
||||||
|
@ -46,6 +46,31 @@ export type SupportedLocalCurrency = (typeof SUPPORTED_LOCAL_CURRENCIES)[number]
|
|||||||
|
|
||||||
export const DEFAULT_LOCAL_CURRENCY: SupportedLocalCurrency = 'USD'
|
export const DEFAULT_LOCAL_CURRENCY: SupportedLocalCurrency = 'USD'
|
||||||
|
|
||||||
|
// some currencies need to be forced to use the narrow symbol and others need to be forced to use symbol
|
||||||
|
// for example: when CAD is set to narrowSymbol it is displayed as $ which offers no differentiation from USD
|
||||||
|
// but when set to symbol it is displayed as CA$ which is correct
|
||||||
|
// On the other hand when TBH is set to symbol it is displayed as THB, but when set to narrowSymbol it is ฿ which is correct
|
||||||
|
export const LOCAL_CURRENCY_SYMBOL_DISPLAY_TYPE: Record<SupportedLocalCurrency, 'narrowSymbol' | 'symbol'> = {
|
||||||
|
USD: 'narrowSymbol',
|
||||||
|
EUR: 'narrowSymbol',
|
||||||
|
RUB: 'narrowSymbol',
|
||||||
|
INR: 'narrowSymbol',
|
||||||
|
GBP: 'narrowSymbol',
|
||||||
|
JPY: 'narrowSymbol',
|
||||||
|
VND: 'narrowSymbol',
|
||||||
|
SGD: 'symbol',
|
||||||
|
BRL: 'symbol',
|
||||||
|
HKD: 'symbol',
|
||||||
|
CAD: 'symbol',
|
||||||
|
IDR: 'narrowSymbol',
|
||||||
|
TRY: 'narrowSymbol',
|
||||||
|
NGN: 'narrowSymbol',
|
||||||
|
UAH: 'narrowSymbol',
|
||||||
|
PKR: 'narrowSymbol',
|
||||||
|
AUD: 'symbol',
|
||||||
|
THB: 'narrowSymbol',
|
||||||
|
}
|
||||||
|
|
||||||
export function getLocalCurrencyIcon(localCurrency: SupportedLocalCurrency, size = 20): ReactNode {
|
export function getLocalCurrencyIcon(localCurrency: SupportedLocalCurrency, size = 20): ReactNode {
|
||||||
switch (localCurrency) {
|
switch (localCurrency) {
|
||||||
case 'USD':
|
case 'USD':
|
||||||
|
@ -14,122 +14,357 @@ import {
|
|||||||
} from './formatNumbers'
|
} from './formatNumbers'
|
||||||
|
|
||||||
it('formats token reference numbers correctly', () => {
|
it('formats token reference numbers correctly', () => {
|
||||||
expect(formatNumber(1234567000000000, NumberType.TokenNonTx)).toBe('>999T')
|
expect(formatNumber({ input: 1234567000000000, type: NumberType.TokenNonTx })).toBe('>999T')
|
||||||
expect(formatNumber(1002345, NumberType.TokenNonTx)).toBe('1.00M')
|
expect(formatNumber({ input: 1234567000000000, type: NumberType.TokenNonTx, locale: 'de-DE' })).toBe('>999\xa0Bio.')
|
||||||
expect(formatNumber(1234, NumberType.TokenNonTx)).toBe('1,234.00')
|
expect(formatNumber({ input: 1002345, type: NumberType.TokenNonTx })).toBe('1.00M')
|
||||||
expect(formatNumber(0.00909, NumberType.TokenNonTx)).toBe('0.009')
|
expect(formatNumber({ input: 1002345, type: NumberType.TokenNonTx, locale: 'de-DE' })).toBe('1,00\xa0Mio.')
|
||||||
expect(formatNumber(0.09001, NumberType.TokenNonTx)).toBe('0.090')
|
expect(formatNumber({ input: 1234, type: NumberType.TokenNonTx })).toBe('1,234.00')
|
||||||
expect(formatNumber(0.00099, NumberType.TokenNonTx)).toBe('<0.001')
|
expect(formatNumber({ input: 1234, type: NumberType.TokenNonTx, locale: 'de-DE' })).toBe('1.234,00')
|
||||||
expect(formatNumber(0, NumberType.TokenNonTx)).toBe('0')
|
expect(formatNumber({ input: 0.00909, type: NumberType.TokenNonTx })).toBe('0.009')
|
||||||
|
expect(formatNumber({ input: 0.00909, type: NumberType.TokenNonTx, locale: 'de-DE' })).toBe('0,009')
|
||||||
|
expect(formatNumber({ input: 0.09001, type: NumberType.TokenNonTx })).toBe('0.090')
|
||||||
|
expect(formatNumber({ input: 0.09001, type: NumberType.TokenNonTx, locale: 'de-DE' })).toBe('0,090')
|
||||||
|
expect(formatNumber({ input: 0.00099, type: NumberType.TokenNonTx })).toBe('<0.001')
|
||||||
|
expect(formatNumber({ input: 0.00099, type: NumberType.TokenNonTx, locale: 'de-DE' })).toBe('<0,001')
|
||||||
|
expect(formatNumber({ input: 0, type: NumberType.TokenNonTx })).toBe('0')
|
||||||
|
expect(formatNumber({ input: 0, type: NumberType.TokenNonTx, locale: 'de-DE' })).toBe('0')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('formats token transaction numbers correctly', () => {
|
it('formats token transaction numbers correctly', () => {
|
||||||
expect(formatNumber(1234567.8901, NumberType.TokenTx)).toBe('1,234,567.89')
|
expect(formatNumber({ input: 1234567.8901, type: NumberType.TokenTx })).toBe('1,234,567.89')
|
||||||
expect(formatNumber(765432.1, NumberType.TokenTx)).toBe('765,432.10')
|
expect(formatNumber({ input: 1234567.8901, type: NumberType.TokenTx, locale: 'ru-RU' })).toBe('1\xa0234\xa0567,89')
|
||||||
|
expect(formatNumber({ input: 765432.1, type: NumberType.TokenTx })).toBe('765,432.10')
|
||||||
|
expect(formatNumber({ input: 765432.1, type: NumberType.TokenTx, locale: 'ru-RU' })).toBe('765\xa0432,10')
|
||||||
|
|
||||||
expect(formatNumber(7654.321, NumberType.TokenTx)).toBe('7,654.32')
|
expect(formatNumber({ input: 7654.321, type: NumberType.TokenTx })).toBe('7,654.32')
|
||||||
expect(formatNumber(765.4321, NumberType.TokenTx)).toBe('765.432')
|
expect(formatNumber({ input: 7654.321, type: NumberType.TokenTx, locale: 'ru-RU' })).toBe('7\xa0654,32')
|
||||||
expect(formatNumber(76.54321, NumberType.TokenTx)).toBe('76.5432')
|
expect(formatNumber({ input: 765.4321, type: NumberType.TokenTx })).toBe('765.432')
|
||||||
expect(formatNumber(7.654321, NumberType.TokenTx)).toBe('7.65432')
|
expect(formatNumber({ input: 765.4321, type: NumberType.TokenTx, locale: 'ru-RU' })).toBe('765,432')
|
||||||
expect(formatNumber(7.60000054321, NumberType.TokenTx)).toBe('7.60')
|
expect(formatNumber({ input: 76.54321, type: NumberType.TokenTx })).toBe('76.5432')
|
||||||
expect(formatNumber(7.6, NumberType.TokenTx)).toBe('7.60')
|
expect(formatNumber({ input: 76.54321, type: NumberType.TokenTx, locale: 'ru-RU' })).toBe('76,5432')
|
||||||
expect(formatNumber(7, NumberType.TokenTx)).toBe('7.00')
|
expect(formatNumber({ input: 7.654321, type: NumberType.TokenTx })).toBe('7.65432')
|
||||||
|
expect(formatNumber({ input: 7.654321, type: NumberType.TokenTx, locale: 'ru-RU' })).toBe('7,65432')
|
||||||
|
expect(formatNumber({ input: 7.60000054321, type: NumberType.TokenTx })).toBe('7.60')
|
||||||
|
expect(formatNumber({ input: 7.60000054321, type: NumberType.TokenTx, locale: 'ru-RU' })).toBe('7,60')
|
||||||
|
expect(formatNumber({ input: 7.6, type: NumberType.TokenTx })).toBe('7.60')
|
||||||
|
expect(formatNumber({ input: 7.6, type: NumberType.TokenTx, locale: 'ru-RU' })).toBe('7,60')
|
||||||
|
expect(formatNumber({ input: 7, type: NumberType.TokenTx })).toBe('7.00')
|
||||||
|
expect(formatNumber({ input: 7, type: NumberType.TokenTx, locale: 'ru-RU' })).toBe('7,00')
|
||||||
|
|
||||||
expect(formatNumber(0.987654321, NumberType.TokenTx)).toBe('0.98765')
|
expect(formatNumber({ input: 0.987654321, type: NumberType.TokenTx })).toBe('0.98765')
|
||||||
expect(formatNumber(0.9, NumberType.TokenTx)).toBe('0.90')
|
expect(formatNumber({ input: 0.987654321, type: NumberType.TokenTx, locale: 'ru-RU' })).toBe('0,98765')
|
||||||
expect(formatNumber(0.901000123, NumberType.TokenTx)).toBe('0.901')
|
expect(formatNumber({ input: 0.9, type: NumberType.TokenTx })).toBe('0.90')
|
||||||
expect(formatNumber(0.000000001, NumberType.TokenTx)).toBe('<0.00001')
|
expect(formatNumber({ input: 0.9, type: NumberType.TokenTx, locale: 'ru-RU' })).toBe('0,90')
|
||||||
expect(formatNumber(0, NumberType.TokenTx)).toBe('0')
|
expect(formatNumber({ input: 0.901000123, type: NumberType.TokenTx })).toBe('0.901')
|
||||||
|
expect(formatNumber({ input: 0.901000123, type: NumberType.TokenTx, locale: 'ru-RU' })).toBe('0,901')
|
||||||
|
expect(formatNumber({ input: 0.000000001, type: NumberType.TokenTx })).toBe('<0.00001')
|
||||||
|
expect(formatNumber({ input: 0.000000001, type: NumberType.TokenTx, locale: 'ru-RU' })).toBe('<0,00001')
|
||||||
|
expect(formatNumber({ input: 0, type: NumberType.TokenTx })).toBe('0')
|
||||||
|
expect(formatNumber({ input: 0, type: NumberType.TokenTx, locale: 'ru-RU' })).toBe('0')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('formats fiat estimates on token details pages correctly', () => {
|
it('formats fiat estimates on token details pages correctly', () => {
|
||||||
expect(formatNumber(1234567.891, NumberType.FiatTokenDetails)).toBe('$1.23M')
|
expect(formatNumber({ input: 1234567.891, type: NumberType.FiatTokenDetails })).toBe('$1.23M')
|
||||||
expect(formatNumber(1234.5678, NumberType.FiatTokenDetails)).toBe('$1,234.57')
|
expect(
|
||||||
expect(formatNumber(1.048942, NumberType.FiatTokenDetails)).toBe('$1.049')
|
formatNumber({ input: 1234567.891, type: NumberType.FiatTokenDetails, locale: 'fr-FR', localCurrency: 'EUR' })
|
||||||
|
).toBe('1,23\xa0M\xa0€')
|
||||||
|
expect(formatNumber({ input: 1234.5678, type: NumberType.FiatTokenDetails })).toBe('$1,234.57')
|
||||||
|
expect(
|
||||||
|
formatNumber({ input: 1234.5678, type: NumberType.FiatTokenDetails, locale: 'fr-FR', localCurrency: 'EUR' })
|
||||||
|
).toBe('1\u202f234,57\xa0€')
|
||||||
|
expect(formatNumber({ input: 1.048942, type: NumberType.FiatTokenDetails })).toBe('$1.049')
|
||||||
|
expect(
|
||||||
|
formatNumber({ input: 1.048942, type: NumberType.FiatTokenDetails, locale: 'fr-FR', localCurrency: 'EUR' })
|
||||||
|
).toBe('1,049\xa0€')
|
||||||
|
|
||||||
expect(formatNumber(0.001231, NumberType.FiatTokenDetails)).toBe('$0.00123')
|
expect(formatNumber({ input: 0.001231, type: NumberType.FiatTokenDetails })).toBe('$0.00123')
|
||||||
expect(formatNumber(0.00001231, NumberType.FiatTokenDetails)).toBe('$0.0000123')
|
expect(
|
||||||
|
formatNumber({ input: 0.001231, type: NumberType.FiatTokenDetails, locale: 'fr-FR', localCurrency: 'EUR' })
|
||||||
|
).toBe('0,00123\xa0€')
|
||||||
|
expect(formatNumber({ input: 0.00001231, type: NumberType.FiatTokenDetails })).toBe('$0.0000123')
|
||||||
|
expect(
|
||||||
|
formatNumber({ input: 0.00001231, type: NumberType.FiatTokenDetails, locale: 'fr-FR', localCurrency: 'EUR' })
|
||||||
|
).toBe('0,0000123\xa0€')
|
||||||
|
|
||||||
expect(formatNumber(0.0000001234, NumberType.FiatTokenDetails)).toBe('$0.000000123')
|
expect(formatNumber({ input: 0.0000001234, type: NumberType.FiatTokenDetails })).toBe('$0.000000123')
|
||||||
expect(formatNumber(0.000000009876, NumberType.FiatTokenDetails)).toBe('<$0.00000001')
|
expect(
|
||||||
|
formatNumber({ input: 0.0000001234, type: NumberType.FiatTokenDetails, locale: 'fr-FR', localCurrency: 'EUR' })
|
||||||
|
).toBe('0,000000123\xa0€')
|
||||||
|
expect(formatNumber({ input: 0.000000009876, type: NumberType.FiatTokenDetails })).toBe('<$0.00000001')
|
||||||
|
expect(
|
||||||
|
formatNumber({ input: 0.000000009876, type: NumberType.FiatTokenDetails, locale: 'fr-FR', localCurrency: 'EUR' })
|
||||||
|
).toBe('<0,00000001\xa0€')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('formats fiat estimates for tokens correctly', () => {
|
it('formats fiat estimates for tokens correctly', () => {
|
||||||
expect(formatNumber(1234567.891, NumberType.FiatTokenPrice)).toBe('$1.23M')
|
expect(formatNumber({ input: 1234567.891, type: NumberType.FiatTokenPrice })).toBe('$1.23M')
|
||||||
expect(formatNumber(1234.5678, NumberType.FiatTokenPrice)).toBe('$1,234.57')
|
expect(
|
||||||
|
formatNumber({ input: 1234567.891, type: NumberType.FiatTokenPrice, locale: 'es-ES', localCurrency: 'JPY' })
|
||||||
|
).toBe('1,23\xa0M¥')
|
||||||
|
expect(formatNumber({ input: 1234.5678, type: NumberType.FiatTokenPrice })).toBe('$1,234.57')
|
||||||
|
expect(
|
||||||
|
formatNumber({ input: 1234.5678, type: NumberType.FiatTokenPrice, locale: 'es-ES', localCurrency: 'JPY' })
|
||||||
|
).toBe('1234,57\xa0¥')
|
||||||
|
expect(
|
||||||
|
formatNumber({ input: 12345.678, type: NumberType.FiatTokenPrice, locale: 'es-ES', localCurrency: 'JPY' })
|
||||||
|
).toBe('12.345,68\xa0¥')
|
||||||
|
|
||||||
expect(formatNumber(0.010235, NumberType.FiatTokenPrice)).toBe('$0.0102')
|
expect(formatNumber({ input: 0.010235, type: NumberType.FiatTokenPrice })).toBe('$0.0102')
|
||||||
expect(formatNumber(0.001231, NumberType.FiatTokenPrice)).toBe('$0.00123')
|
expect(
|
||||||
expect(formatNumber(0.00001231, NumberType.FiatTokenPrice)).toBe('$0.0000123')
|
formatNumber({ input: 0.010235, type: NumberType.FiatTokenPrice, locale: 'es-ES', localCurrency: 'JPY' })
|
||||||
|
).toBe('0,0102\xa0¥')
|
||||||
|
expect(formatNumber({ input: 0.001231, type: NumberType.FiatTokenPrice })).toBe('$0.00123')
|
||||||
|
expect(
|
||||||
|
formatNumber({ input: 0.001231, type: NumberType.FiatTokenPrice, locale: 'es-ES', localCurrency: 'JPY' })
|
||||||
|
).toBe('0,00123\xa0¥')
|
||||||
|
expect(formatNumber({ input: 0.00001231, type: NumberType.FiatTokenPrice })).toBe('$0.0000123')
|
||||||
|
expect(
|
||||||
|
formatNumber({ input: 0.00001231, type: NumberType.FiatTokenPrice, locale: 'es-ES', localCurrency: 'JPY' })
|
||||||
|
).toBe('0,0000123\xa0¥')
|
||||||
|
|
||||||
expect(formatNumber(0.0000001234, NumberType.FiatTokenPrice)).toBe('$0.000000123')
|
expect(formatNumber({ input: 0.0000001234, type: NumberType.FiatTokenPrice })).toBe('$0.000000123')
|
||||||
expect(formatNumber(0.000000009876, NumberType.FiatTokenPrice)).toBe('<$0.00000001')
|
expect(
|
||||||
expect(formatNumber(10000000000000000000000000000000, NumberType.FiatTokenPrice)).toBe('$1.000000E31')
|
formatNumber({ input: 0.0000001234, type: NumberType.FiatTokenPrice, locale: 'es-ES', localCurrency: 'JPY' })
|
||||||
|
).toBe('0,000000123\xa0¥')
|
||||||
|
expect(formatNumber({ input: 0.000000009876, type: NumberType.FiatTokenPrice })).toBe('<$0.00000001')
|
||||||
|
expect(
|
||||||
|
formatNumber({ input: 0.000000009876, type: NumberType.FiatTokenPrice, locale: 'es-ES', localCurrency: 'JPY' })
|
||||||
|
).toBe('<0,00000001\xa0¥')
|
||||||
|
expect(formatNumber({ input: 10000000000000000000000000000000, type: NumberType.FiatTokenPrice })).toBe(
|
||||||
|
'$1.000000E31'
|
||||||
|
)
|
||||||
|
expect(
|
||||||
|
formatNumber({
|
||||||
|
input: 10000000000000000000000000000000,
|
||||||
|
type: NumberType.FiatTokenPrice,
|
||||||
|
locale: 'es-ES',
|
||||||
|
localCurrency: 'JPY',
|
||||||
|
})
|
||||||
|
).toBe('1,000000E31\xa0¥')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('formats fiat estimates for token stats correctly', () => {
|
it('formats fiat estimates for token stats correctly', () => {
|
||||||
expect(formatNumber(1234576, NumberType.FiatTokenStats)).toBe('$1.2M')
|
expect(formatNumber({ input: 1234576, type: NumberType.FiatTokenStats })).toBe('$1.2M')
|
||||||
expect(formatNumber(234567, NumberType.FiatTokenStats)).toBe('$234.6K')
|
expect(formatNumber({ input: 1234576, type: NumberType.FiatTokenStats, locale: 'ja-JP', localCurrency: 'CAD' })).toBe(
|
||||||
expect(formatNumber(123.456, NumberType.FiatTokenStats)).toBe('$123.46')
|
'CA$123.5万'
|
||||||
expect(formatNumber(1.23, NumberType.FiatTokenStats)).toBe('$1.23')
|
)
|
||||||
expect(formatNumber(0.123, NumberType.FiatTokenStats)).toBe('$0.12')
|
expect(formatNumber({ input: 234567, type: NumberType.FiatTokenStats })).toBe('$234.6K')
|
||||||
expect(formatNumber(0.00123, NumberType.FiatTokenStats)).toBe('<$0.01')
|
expect(formatNumber({ input: 234567, type: NumberType.FiatTokenStats, locale: 'ja-JP', localCurrency: 'CAD' })).toBe(
|
||||||
expect(formatNumber(0, NumberType.FiatTokenStats)).toBe('-')
|
'CA$23.5万'
|
||||||
|
)
|
||||||
|
expect(formatNumber({ input: 123.456, type: NumberType.FiatTokenStats })).toBe('$123.46')
|
||||||
|
expect(formatNumber({ input: 123.456, type: NumberType.FiatTokenStats, locale: 'ja-JP', localCurrency: 'CAD' })).toBe(
|
||||||
|
'CA$123.46'
|
||||||
|
)
|
||||||
|
expect(formatNumber({ input: 1.23, type: NumberType.FiatTokenStats })).toBe('$1.23')
|
||||||
|
expect(formatNumber({ input: 1.23, type: NumberType.FiatTokenStats, locale: 'ja-JP', localCurrency: 'CAD' })).toBe(
|
||||||
|
'CA$1.23'
|
||||||
|
)
|
||||||
|
expect(formatNumber({ input: 0.123, type: NumberType.FiatTokenStats })).toBe('$0.12')
|
||||||
|
expect(formatNumber({ input: 0.123, type: NumberType.FiatTokenStats, locale: 'ja-JP', localCurrency: 'CAD' })).toBe(
|
||||||
|
'CA$0.12'
|
||||||
|
)
|
||||||
|
expect(formatNumber({ input: 0.00123, type: NumberType.FiatTokenStats })).toBe('<$0.01')
|
||||||
|
expect(formatNumber({ input: 0.00123, type: NumberType.FiatTokenStats, locale: 'ja-JP', localCurrency: 'CAD' })).toBe(
|
||||||
|
'<CA$0.01'
|
||||||
|
)
|
||||||
|
expect(formatNumber({ input: 0, type: NumberType.FiatTokenStats })).toBe('-')
|
||||||
|
expect(formatNumber({ input: 0, type: NumberType.FiatTokenStats, locale: 'ja-JP', localCurrency: 'CAD' })).toBe('-')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('formats gas USD prices correctly', () => {
|
it('formats gas USD prices correctly', () => {
|
||||||
expect(formatNumber(1234567.891, NumberType.FiatGasPrice)).toBe('$1.23M')
|
expect(formatNumber({ input: 1234567.891, type: NumberType.FiatGasPrice })).toBe('$1.23M')
|
||||||
expect(formatNumber(18.448, NumberType.FiatGasPrice)).toBe('$18.45')
|
expect(
|
||||||
expect(formatNumber(0.0099, NumberType.FiatGasPrice)).toBe('<$0.01')
|
formatNumber({ input: 1234567.891, type: NumberType.FiatGasPrice, locale: 'pt-PR', localCurrency: 'THB' })
|
||||||
expect(formatNumber(0, NumberType.FiatGasPrice)).toBe('$0.00')
|
).toBe('฿\xa01,23\xa0mi')
|
||||||
|
expect(formatNumber({ input: 18.448, type: NumberType.FiatGasPrice })).toBe('$18.45')
|
||||||
|
expect(formatNumber({ input: 18.448, type: NumberType.FiatGasPrice, locale: 'pt-PR', localCurrency: 'THB' })).toBe(
|
||||||
|
'฿\xa018,45'
|
||||||
|
)
|
||||||
|
expect(formatNumber({ input: 0.0099, type: NumberType.FiatGasPrice })).toBe('<$0.01')
|
||||||
|
expect(formatNumber({ input: 0.0099, type: NumberType.FiatGasPrice, locale: 'pt-PR', localCurrency: 'THB' })).toBe(
|
||||||
|
'<฿\xa00,01'
|
||||||
|
)
|
||||||
|
expect(formatNumber({ input: 0, type: NumberType.FiatGasPrice })).toBe('$0.00')
|
||||||
|
expect(formatNumber({ input: 0, type: NumberType.FiatGasPrice, locale: 'pt-PR', localCurrency: 'THB' })).toBe(
|
||||||
|
'฿\xa00,00'
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('formats USD token quantities prices correctly', () => {
|
it('formats USD token quantities prices correctly', () => {
|
||||||
expect(formatNumber(1234567.891, NumberType.FiatTokenQuantity)).toBe('$1.23M')
|
expect(formatNumber({ input: 1234567.891, type: NumberType.FiatTokenQuantity })).toBe('$1.23M')
|
||||||
expect(formatNumber(18.448, NumberType.FiatTokenQuantity)).toBe('$18.45')
|
expect(formatNumber({ input: 1234567.891, type: NumberType.FiatTokenQuantity, localCurrency: 'NGN' })).toBe('₦1.23M')
|
||||||
expect(formatNumber(0.0099, NumberType.FiatTokenQuantity)).toBe('<$0.01')
|
expect(formatNumber({ input: 18.448, type: NumberType.FiatTokenQuantity })).toBe('$18.45')
|
||||||
expect(formatNumber(0, NumberType.FiatTokenQuantity)).toBe('$0.00')
|
expect(formatNumber({ input: 18.448, type: NumberType.FiatTokenQuantity, localCurrency: 'NGN' })).toBe('₦18.45')
|
||||||
|
expect(formatNumber({ input: 0.0099, type: NumberType.FiatTokenQuantity })).toBe('<$0.01')
|
||||||
|
expect(formatNumber({ input: 0.0099, type: NumberType.FiatTokenQuantity, localCurrency: 'NGN' })).toBe('<₦0.01')
|
||||||
|
expect(formatNumber({ input: 0, type: NumberType.FiatTokenQuantity })).toBe('$0.00')
|
||||||
|
expect(formatNumber({ input: 0, type: NumberType.FiatTokenQuantity, localCurrency: 'NGN' })).toBe('₦0.00')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('formats Swap text input/output numbers correctly', () => {
|
it('formats Swap text input/output numbers correctly', () => {
|
||||||
expect(formatNumber(1234567.8901, NumberType.SwapTradeAmount)).toBe('1234570')
|
expect(formatNumber({ input: 1234567.8901, type: NumberType.SwapTradeAmount })).toBe('1234570')
|
||||||
expect(formatNumber(765432.1, NumberType.SwapTradeAmount)).toBe('765432')
|
expect(formatNumber({ input: 1234567.8901, type: NumberType.SwapTradeAmount, locale: 'ko-KR' })).toBe('1234570')
|
||||||
|
expect(formatNumber({ input: 765432.1, type: NumberType.SwapTradeAmount })).toBe('765432')
|
||||||
|
expect(formatNumber({ input: 765432.1, type: NumberType.SwapTradeAmount, locale: 'ko-KR' })).toBe('765432')
|
||||||
|
|
||||||
expect(formatNumber(7654.321, NumberType.SwapTradeAmount)).toBe('7654.32')
|
expect(formatNumber({ input: 7654.321, type: NumberType.SwapTradeAmount })).toBe('7654.32')
|
||||||
expect(formatNumber(765.4321, NumberType.SwapTradeAmount)).toBe('765.432')
|
expect(formatNumber({ input: 7654.321, type: NumberType.SwapTradeAmount, locale: 'ko-KR' })).toBe('7654.32')
|
||||||
expect(formatNumber(76.54321, NumberType.SwapTradeAmount)).toBe('76.5432')
|
expect(formatNumber({ input: 765.4321, type: NumberType.SwapTradeAmount })).toBe('765.432')
|
||||||
expect(formatNumber(7.654321, NumberType.SwapTradeAmount)).toBe('7.65432')
|
expect(formatNumber({ input: 765.4321, type: NumberType.SwapTradeAmount, locale: 'ko-KR' })).toBe('765.432')
|
||||||
expect(formatNumber(7.60000054321, NumberType.SwapTradeAmount)).toBe('7.60')
|
expect(formatNumber({ input: 76.54321, type: NumberType.SwapTradeAmount })).toBe('76.5432')
|
||||||
expect(formatNumber(7.6, NumberType.SwapTradeAmount)).toBe('7.60')
|
expect(formatNumber({ input: 76.54321, type: NumberType.SwapTradeAmount, locale: 'ko-KR' })).toBe('76.5432')
|
||||||
expect(formatNumber(7, NumberType.SwapTradeAmount)).toBe('7.00')
|
expect(formatNumber({ input: 7.654321, type: NumberType.SwapTradeAmount })).toBe('7.65432')
|
||||||
|
expect(formatNumber({ input: 7.654321, type: NumberType.SwapTradeAmount, locale: 'ko-KR' })).toBe('7.65432')
|
||||||
|
expect(formatNumber({ input: 7.60000054321, type: NumberType.SwapTradeAmount })).toBe('7.60')
|
||||||
|
expect(formatNumber({ input: 7.60000054321, type: NumberType.SwapTradeAmount, locale: 'ko-KR' })).toBe('7.60')
|
||||||
|
expect(formatNumber({ input: 7.6, type: NumberType.SwapTradeAmount })).toBe('7.60')
|
||||||
|
expect(formatNumber({ input: 7.6, type: NumberType.SwapTradeAmount, locale: 'ko-KR' })).toBe('7.60')
|
||||||
|
expect(formatNumber({ input: 7, type: NumberType.SwapTradeAmount })).toBe('7.00')
|
||||||
|
expect(formatNumber({ input: 7, type: NumberType.SwapTradeAmount, locale: 'ko-KR' })).toBe('7.00')
|
||||||
|
|
||||||
expect(formatNumber(0.987654321, NumberType.SwapTradeAmount)).toBe('0.98765')
|
expect(formatNumber({ input: 0.987654321, type: NumberType.SwapTradeAmount })).toBe('0.98765')
|
||||||
expect(formatNumber(0.9, NumberType.SwapTradeAmount)).toBe('0.90')
|
expect(formatNumber({ input: 0.987654321, type: NumberType.SwapTradeAmount, locale: 'ko-KR' })).toBe('0.98765')
|
||||||
expect(formatNumber(0.901000123, NumberType.SwapTradeAmount)).toBe('0.901')
|
expect(formatNumber({ input: 0.9, type: NumberType.SwapTradeAmount })).toBe('0.90')
|
||||||
expect(formatNumber(0.000000001, NumberType.SwapTradeAmount)).toBe('0.000000001')
|
expect(formatNumber({ input: 0.9, type: NumberType.SwapTradeAmount, locale: 'ko-KR' })).toBe('0.90')
|
||||||
expect(formatNumber(0, NumberType.SwapTradeAmount)).toBe('0')
|
expect(formatNumber({ input: 0.901000123, type: NumberType.SwapTradeAmount })).toBe('0.901')
|
||||||
|
expect(formatNumber({ input: 0.901000123, type: NumberType.SwapTradeAmount, locale: 'ko-KR' })).toBe('0.901')
|
||||||
|
expect(formatNumber({ input: 0.000000001, type: NumberType.SwapTradeAmount })).toBe('0.000000001')
|
||||||
|
expect(formatNumber({ input: 0.000000001, type: NumberType.SwapTradeAmount, locale: 'ko-KR' })).toBe('0.000000001')
|
||||||
|
expect(formatNumber({ input: 0, type: NumberType.SwapTradeAmount })).toBe('0')
|
||||||
|
expect(formatNumber({ input: 0, type: NumberType.SwapTradeAmount, locale: 'ko-KR' })).toBe('0')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('formats NFT numbers correctly', () => {
|
it('formats NFT numbers correctly', () => {
|
||||||
expect(formatNumber(1234567000000000, NumberType.NFTTokenFloorPrice)).toBe('>999T')
|
expect(formatNumber({ input: 1234567000000000, type: NumberType.NFTTokenFloorPrice })).toBe('>999T')
|
||||||
expect(formatNumber(1002345, NumberType.NFTTokenFloorPrice)).toBe('1M')
|
expect(
|
||||||
expect(formatNumber(1234, NumberType.NFTTokenFloorPrice)).toBe('1.23K')
|
formatNumber({
|
||||||
expect(formatNumber(12.34467, NumberType.NFTTokenFloorPrice)).toBe('12.34')
|
input: 1234567000000000,
|
||||||
expect(formatNumber(12.1, NumberType.NFTTokenFloorPrice)).toBe('12.1')
|
type: NumberType.NFTTokenFloorPrice,
|
||||||
expect(formatNumber(0.00909, NumberType.NFTTokenFloorPrice)).toBe('0.009')
|
locale: 'pt-BR',
|
||||||
expect(formatNumber(0.09001, NumberType.NFTTokenFloorPrice)).toBe('0.09')
|
localCurrency: 'BRL',
|
||||||
expect(formatNumber(0.00099, NumberType.NFTTokenFloorPrice)).toBe('<0.001')
|
})
|
||||||
expect(formatNumber(0, NumberType.NFTTokenFloorPrice)).toBe('0')
|
).toBe('>999\xa0tri')
|
||||||
|
expect(formatNumber({ input: 1002345, type: NumberType.NFTTokenFloorPrice })).toBe('1M')
|
||||||
|
expect(
|
||||||
|
formatNumber({
|
||||||
|
input: 1002345,
|
||||||
|
type: NumberType.NFTTokenFloorPrice,
|
||||||
|
locale: 'pt-BR',
|
||||||
|
localCurrency: 'BRL',
|
||||||
|
})
|
||||||
|
).toBe('1\xa0mi')
|
||||||
|
expect(formatNumber({ input: 1234, type: NumberType.NFTTokenFloorPrice })).toBe('1.23K')
|
||||||
|
expect(
|
||||||
|
formatNumber({
|
||||||
|
input: 1234,
|
||||||
|
type: NumberType.NFTTokenFloorPrice,
|
||||||
|
locale: 'pt-BR',
|
||||||
|
localCurrency: 'BRL',
|
||||||
|
})
|
||||||
|
).toBe('1,23\xa0mil')
|
||||||
|
expect(formatNumber({ input: 12.34467, type: NumberType.NFTTokenFloorPrice })).toBe('12.34')
|
||||||
|
expect(
|
||||||
|
formatNumber({
|
||||||
|
input: 12.34467,
|
||||||
|
type: NumberType.NFTTokenFloorPrice,
|
||||||
|
locale: 'pt-BR',
|
||||||
|
localCurrency: 'BRL',
|
||||||
|
})
|
||||||
|
).toBe('12,34')
|
||||||
|
expect(formatNumber({ input: 12.1, type: NumberType.NFTTokenFloorPrice })).toBe('12.1')
|
||||||
|
expect(
|
||||||
|
formatNumber({
|
||||||
|
input: 12.1,
|
||||||
|
type: NumberType.NFTTokenFloorPrice,
|
||||||
|
locale: 'pt-BR',
|
||||||
|
localCurrency: 'BRL',
|
||||||
|
})
|
||||||
|
).toBe('12,1')
|
||||||
|
expect(formatNumber({ input: 0.00909, type: NumberType.NFTTokenFloorPrice })).toBe('0.009')
|
||||||
|
expect(
|
||||||
|
formatNumber({
|
||||||
|
input: 0.00909,
|
||||||
|
type: NumberType.NFTTokenFloorPrice,
|
||||||
|
locale: 'pt-BR',
|
||||||
|
localCurrency: 'BRL',
|
||||||
|
})
|
||||||
|
).toBe('0,009')
|
||||||
|
expect(formatNumber({ input: 0.09001, type: NumberType.NFTTokenFloorPrice })).toBe('0.09')
|
||||||
|
expect(
|
||||||
|
formatNumber({
|
||||||
|
input: 0.09001,
|
||||||
|
type: NumberType.NFTTokenFloorPrice,
|
||||||
|
locale: 'pt-BR',
|
||||||
|
localCurrency: 'BRL',
|
||||||
|
})
|
||||||
|
).toBe('0,09')
|
||||||
|
expect(formatNumber({ input: 0.00099, type: NumberType.NFTTokenFloorPrice })).toBe('<0.001')
|
||||||
|
expect(
|
||||||
|
formatNumber({
|
||||||
|
input: 0.00099,
|
||||||
|
type: NumberType.NFTTokenFloorPrice,
|
||||||
|
locale: 'pt-BR',
|
||||||
|
localCurrency: 'BRL',
|
||||||
|
})
|
||||||
|
).toBe('<0,001')
|
||||||
|
expect(formatNumber({ input: 0, type: NumberType.NFTTokenFloorPrice })).toBe('0')
|
||||||
|
expect(
|
||||||
|
formatNumber({
|
||||||
|
input: 0,
|
||||||
|
type: NumberType.NFTTokenFloorPrice,
|
||||||
|
locale: 'pt-BR',
|
||||||
|
localCurrency: 'BRL',
|
||||||
|
})
|
||||||
|
).toBe('0')
|
||||||
|
|
||||||
expect(formatNumber(12.1, NumberType.NFTTokenFloorPriceTrailingZeros)).toBe('12.10')
|
expect(formatNumber({ input: 12.1, type: NumberType.NFTTokenFloorPriceTrailingZeros })).toBe('12.10')
|
||||||
expect(formatNumber(0.09001, NumberType.NFTTokenFloorPriceTrailingZeros)).toBe('0.090')
|
expect(
|
||||||
|
formatNumber({
|
||||||
|
input: 12.1,
|
||||||
|
type: NumberType.NFTTokenFloorPriceTrailingZeros,
|
||||||
|
locale: 'pt-BR',
|
||||||
|
localCurrency: 'BRL',
|
||||||
|
})
|
||||||
|
).toBe('12,10')
|
||||||
|
expect(formatNumber({ input: 0.09001, type: NumberType.NFTTokenFloorPriceTrailingZeros })).toBe('0.090')
|
||||||
|
expect(
|
||||||
|
formatNumber({
|
||||||
|
input: 0.09001,
|
||||||
|
type: NumberType.NFTTokenFloorPriceTrailingZeros,
|
||||||
|
locale: 'pt-BR',
|
||||||
|
localCurrency: 'BRL',
|
||||||
|
})
|
||||||
|
).toBe('0,090')
|
||||||
|
|
||||||
expect(formatNumber(0.987654321, NumberType.NFTCollectionStats)).toBe('1')
|
expect(formatNumber({ input: 0.987654321, type: NumberType.NFTCollectionStats })).toBe('1')
|
||||||
expect(formatNumber(0.9, NumberType.NFTCollectionStats)).toBe('1')
|
expect(
|
||||||
expect(formatNumber(76543.21, NumberType.NFTCollectionStats)).toBe('76.5K')
|
formatNumber({ input: 0.987654321, type: NumberType.NFTCollectionStats, locale: 'pt-BR', localCurrency: 'BRL' })
|
||||||
expect(formatNumber(7.60000054321, NumberType.NFTCollectionStats)).toBe('8')
|
).toBe('1')
|
||||||
expect(formatNumber(1234567890, NumberType.NFTCollectionStats)).toBe('1.2B')
|
expect(formatNumber({ input: 0.9, type: NumberType.NFTCollectionStats })).toBe('1')
|
||||||
expect(formatNumber(1234567000000000, NumberType.NFTCollectionStats)).toBe('1234.6T')
|
expect(formatNumber({ input: 0.9, type: NumberType.NFTCollectionStats, locale: 'pt-BR', localCurrency: 'BRL' })).toBe(
|
||||||
|
'1'
|
||||||
|
)
|
||||||
|
expect(formatNumber({ input: 76543.21, type: NumberType.NFTCollectionStats })).toBe('76.5K')
|
||||||
|
expect(
|
||||||
|
formatNumber({ input: 76543.21, type: NumberType.NFTCollectionStats, locale: 'pt-BR', localCurrency: 'BRL' })
|
||||||
|
).toBe('76,5\xa0mil')
|
||||||
|
expect(formatNumber({ input: 7.60000054321, type: NumberType.NFTCollectionStats })).toBe('8')
|
||||||
|
expect(
|
||||||
|
formatNumber({ input: 7.60000054321, type: NumberType.NFTCollectionStats, locale: 'pt-BR', localCurrency: 'BRL' })
|
||||||
|
).toBe('8')
|
||||||
|
expect(formatNumber({ input: 1234567890, type: NumberType.NFTCollectionStats })).toBe('1.2B')
|
||||||
|
expect(
|
||||||
|
formatNumber({ input: 1234567890, type: NumberType.NFTCollectionStats, locale: 'pt-BR', localCurrency: 'BRL' })
|
||||||
|
).toBe('1,2\xa0bi')
|
||||||
|
expect(formatNumber({ input: 1234567000000000, type: NumberType.NFTCollectionStats })).toBe('1234.6T')
|
||||||
|
expect(
|
||||||
|
formatNumber({
|
||||||
|
input: 1234567000000000,
|
||||||
|
type: NumberType.NFTCollectionStats,
|
||||||
|
locale: 'pt-BR',
|
||||||
|
localCurrency: 'BRL',
|
||||||
|
})
|
||||||
|
).toBe('1234,6\xa0tri')
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('formatUSDPrice', () => {
|
describe('formatUSDPrice', () => {
|
||||||
|
@ -1,244 +1,302 @@
|
|||||||
import { Currency, CurrencyAmount, Percent, Price } from '@uniswap/sdk-core'
|
import { Currency, CurrencyAmount, Percent, Price } from '@uniswap/sdk-core'
|
||||||
import { DEFAULT_LOCALE } from 'constants/locales'
|
import {
|
||||||
|
DEFAULT_LOCAL_CURRENCY,
|
||||||
|
LOCAL_CURRENCY_SYMBOL_DISPLAY_TYPE,
|
||||||
|
SupportedLocalCurrency,
|
||||||
|
} from 'constants/localCurrencies'
|
||||||
|
import { DEFAULT_LOCALE, SupportedLocale } from 'constants/locales'
|
||||||
|
|
||||||
type Nullish<T> = T | null | undefined
|
type Nullish<T> = T | null | undefined
|
||||||
|
type NumberFormatOptions = Intl.NumberFormatOptions
|
||||||
|
|
||||||
// Number formatting follows the standards laid out in this spec:
|
// Number formatting follows the standards laid out in this spec:
|
||||||
// https://www.notion.so/uniswaplabs/Number-standards-fbb9f533f10e4e22820722c2f66d23c0
|
// https://www.notion.so/uniswaplabs/Number-standards-fbb9f533f10e4e22820722c2f66d23c0
|
||||||
|
|
||||||
const FIVE_DECIMALS_MAX_TWO_DECIMALS_MIN = new Intl.NumberFormat('en-US', {
|
const FIVE_DECIMALS_MAX_TWO_DECIMALS_MIN: NumberFormatOptions = {
|
||||||
notation: 'standard',
|
notation: 'standard',
|
||||||
maximumFractionDigits: 5,
|
maximumFractionDigits: 5,
|
||||||
minimumFractionDigits: 2,
|
minimumFractionDigits: 2,
|
||||||
})
|
}
|
||||||
|
|
||||||
const FIVE_DECIMALS_MAX_TWO_DECIMALS_MIN_NO_COMMAS = new Intl.NumberFormat('en-US', {
|
const FIVE_DECIMALS_MAX_TWO_DECIMALS_MIN_NO_COMMAS: NumberFormatOptions = {
|
||||||
notation: 'standard',
|
notation: 'standard',
|
||||||
maximumFractionDigits: 5,
|
maximumFractionDigits: 5,
|
||||||
minimumFractionDigits: 2,
|
minimumFractionDigits: 2,
|
||||||
useGrouping: false,
|
useGrouping: false,
|
||||||
})
|
}
|
||||||
|
|
||||||
const NO_DECIMALS = new Intl.NumberFormat('en-US', {
|
const NO_DECIMALS: NumberFormatOptions = {
|
||||||
notation: 'standard',
|
notation: 'standard',
|
||||||
maximumFractionDigits: 0,
|
maximumFractionDigits: 0,
|
||||||
minimumFractionDigits: 0,
|
minimumFractionDigits: 0,
|
||||||
})
|
}
|
||||||
|
|
||||||
const THREE_DECIMALS_NO_TRAILING_ZEROS = new Intl.NumberFormat('en-US', {
|
const THREE_DECIMALS_NO_TRAILING_ZEROS: NumberFormatOptions = {
|
||||||
notation: 'standard',
|
notation: 'standard',
|
||||||
maximumFractionDigits: 3,
|
maximumFractionDigits: 3,
|
||||||
minimumFractionDigits: 0,
|
minimumFractionDigits: 0,
|
||||||
})
|
}
|
||||||
|
|
||||||
const THREE_DECIMALS = new Intl.NumberFormat('en-US', {
|
const THREE_DECIMALS: NumberFormatOptions = {
|
||||||
notation: 'standard',
|
notation: 'standard',
|
||||||
maximumFractionDigits: 3,
|
maximumFractionDigits: 3,
|
||||||
minimumFractionDigits: 3,
|
minimumFractionDigits: 3,
|
||||||
})
|
}
|
||||||
|
|
||||||
const THREE_DECIMALS_USD = new Intl.NumberFormat('en-US', {
|
const THREE_DECIMALS_CURRENCY: NumberFormatOptions = {
|
||||||
notation: 'standard',
|
notation: 'standard',
|
||||||
maximumFractionDigits: 3,
|
maximumFractionDigits: 3,
|
||||||
minimumFractionDigits: 3,
|
minimumFractionDigits: 3,
|
||||||
currency: 'USD',
|
currency: 'USD',
|
||||||
style: 'currency',
|
style: 'currency',
|
||||||
})
|
}
|
||||||
|
|
||||||
const TWO_DECIMALS_NO_TRAILING_ZEROS = new Intl.NumberFormat('en-US', {
|
const TWO_DECIMALS_NO_TRAILING_ZEROS: NumberFormatOptions = {
|
||||||
notation: 'standard',
|
notation: 'standard',
|
||||||
maximumFractionDigits: 2,
|
maximumFractionDigits: 2,
|
||||||
})
|
}
|
||||||
|
|
||||||
const TWO_DECIMALS = new Intl.NumberFormat('en-US', {
|
const TWO_DECIMALS: NumberFormatOptions = {
|
||||||
notation: 'standard',
|
notation: 'standard',
|
||||||
maximumFractionDigits: 2,
|
maximumFractionDigits: 2,
|
||||||
minimumFractionDigits: 2,
|
minimumFractionDigits: 2,
|
||||||
})
|
}
|
||||||
|
|
||||||
const TWO_DECIMALS_USD = new Intl.NumberFormat('en-US', {
|
const TWO_DECIMALS_CURRENCY: NumberFormatOptions = {
|
||||||
notation: 'standard',
|
notation: 'standard',
|
||||||
maximumFractionDigits: 2,
|
maximumFractionDigits: 2,
|
||||||
minimumFractionDigits: 2,
|
minimumFractionDigits: 2,
|
||||||
currency: 'USD',
|
currency: 'USD',
|
||||||
style: 'currency',
|
style: 'currency',
|
||||||
})
|
}
|
||||||
|
|
||||||
const SHORTHAND_TWO_DECIMALS = new Intl.NumberFormat('en-US', {
|
const SHORTHAND_TWO_DECIMALS: NumberFormatOptions = {
|
||||||
notation: 'compact',
|
notation: 'compact',
|
||||||
minimumFractionDigits: 2,
|
minimumFractionDigits: 2,
|
||||||
maximumFractionDigits: 2,
|
maximumFractionDigits: 2,
|
||||||
})
|
}
|
||||||
|
|
||||||
const SHORTHAND_TWO_DECIMALS_NO_TRAILING_ZEROS = new Intl.NumberFormat('en-US', {
|
const SHORTHAND_TWO_DECIMALS_NO_TRAILING_ZEROS: NumberFormatOptions = {
|
||||||
notation: 'compact',
|
notation: 'compact',
|
||||||
maximumFractionDigits: 2,
|
maximumFractionDigits: 2,
|
||||||
})
|
}
|
||||||
|
|
||||||
const SHORTHAND_ONE_DECIMAL = new Intl.NumberFormat('en-US', {
|
const SHORTHAND_ONE_DECIMAL: NumberFormatOptions = {
|
||||||
notation: 'compact',
|
notation: 'compact',
|
||||||
minimumFractionDigits: 1,
|
minimumFractionDigits: 1,
|
||||||
maximumFractionDigits: 1,
|
maximumFractionDigits: 1,
|
||||||
})
|
}
|
||||||
|
|
||||||
const SHORTHAND_USD_TWO_DECIMALS = new Intl.NumberFormat('en-US', {
|
const SHORTHAND_CURRENCY_TWO_DECIMALS: NumberFormatOptions = {
|
||||||
notation: 'compact',
|
notation: 'compact',
|
||||||
minimumFractionDigits: 2,
|
minimumFractionDigits: 2,
|
||||||
maximumFractionDigits: 2,
|
maximumFractionDigits: 2,
|
||||||
currency: 'USD',
|
currency: 'USD',
|
||||||
style: 'currency',
|
style: 'currency',
|
||||||
})
|
}
|
||||||
|
|
||||||
const SHORTHAND_USD_ONE_DECIMAL = new Intl.NumberFormat('en-US', {
|
const SHORTHAND_CURRENCY_ONE_DECIMAL: NumberFormatOptions = {
|
||||||
notation: 'compact',
|
notation: 'compact',
|
||||||
minimumFractionDigits: 1,
|
minimumFractionDigits: 1,
|
||||||
maximumFractionDigits: 1,
|
maximumFractionDigits: 1,
|
||||||
currency: 'USD',
|
currency: 'USD',
|
||||||
style: 'currency',
|
style: 'currency',
|
||||||
})
|
}
|
||||||
|
|
||||||
const SIX_SIG_FIGS_TWO_DECIMALS = new Intl.NumberFormat('en-US', {
|
const SIX_SIG_FIGS_TWO_DECIMALS: NumberFormatOptions = {
|
||||||
notation: 'standard',
|
notation: 'standard',
|
||||||
maximumSignificantDigits: 6,
|
maximumSignificantDigits: 6,
|
||||||
minimumSignificantDigits: 3,
|
minimumSignificantDigits: 3,
|
||||||
maximumFractionDigits: 2,
|
maximumFractionDigits: 2,
|
||||||
minimumFractionDigits: 2,
|
minimumFractionDigits: 2,
|
||||||
})
|
}
|
||||||
|
|
||||||
const SIX_SIG_FIGS_NO_COMMAS = new Intl.NumberFormat('en-US', {
|
const SIX_SIG_FIGS_NO_COMMAS: NumberFormatOptions = {
|
||||||
notation: 'standard',
|
notation: 'standard',
|
||||||
maximumSignificantDigits: 6,
|
maximumSignificantDigits: 6,
|
||||||
useGrouping: false,
|
useGrouping: false,
|
||||||
})
|
}
|
||||||
|
|
||||||
const SIX_SIG_FIGS_TWO_DECIMALS_NO_COMMAS = new Intl.NumberFormat('en-US', {
|
const SIX_SIG_FIGS_TWO_DECIMALS_NO_COMMAS: NumberFormatOptions = {
|
||||||
notation: 'standard',
|
notation: 'standard',
|
||||||
maximumSignificantDigits: 6,
|
maximumSignificantDigits: 6,
|
||||||
minimumSignificantDigits: 3,
|
minimumSignificantDigits: 3,
|
||||||
maximumFractionDigits: 2,
|
maximumFractionDigits: 2,
|
||||||
minimumFractionDigits: 2,
|
minimumFractionDigits: 2,
|
||||||
useGrouping: false,
|
useGrouping: false,
|
||||||
})
|
}
|
||||||
|
|
||||||
const THREE_SIG_FIGS_USD = new Intl.NumberFormat('en-US', {
|
const ONE_SIG_FIG_CURRENCY: NumberFormatOptions = {
|
||||||
|
notation: 'standard',
|
||||||
|
minimumSignificantDigits: 1,
|
||||||
|
maximumSignificantDigits: 1,
|
||||||
|
currency: 'USD',
|
||||||
|
style: 'currency',
|
||||||
|
}
|
||||||
|
|
||||||
|
const THREE_SIG_FIGS_CURRENCY: NumberFormatOptions = {
|
||||||
notation: 'standard',
|
notation: 'standard',
|
||||||
minimumSignificantDigits: 3,
|
minimumSignificantDigits: 3,
|
||||||
maximumSignificantDigits: 3,
|
maximumSignificantDigits: 3,
|
||||||
currency: 'USD',
|
currency: 'USD',
|
||||||
style: 'currency',
|
style: 'currency',
|
||||||
})
|
}
|
||||||
|
|
||||||
const SEVEN_SIG_FIGS__SCI_NOTATION_USD = new Intl.NumberFormat('en-US', {
|
const SEVEN_SIG_FIGS__SCI_NOTATION_CURRENCY: NumberFormatOptions = {
|
||||||
notation: 'scientific',
|
notation: 'scientific',
|
||||||
minimumSignificantDigits: 7,
|
minimumSignificantDigits: 7,
|
||||||
maximumSignificantDigits: 7,
|
maximumSignificantDigits: 7,
|
||||||
currency: 'USD',
|
currency: 'USD',
|
||||||
style: 'currency',
|
style: 'currency',
|
||||||
})
|
}
|
||||||
|
|
||||||
type Format = Intl.NumberFormat | string
|
|
||||||
|
|
||||||
// each rule must contain either an `upperBound` or an `exact` value.
|
// each rule must contain either an `upperBound` or an `exact` value.
|
||||||
// upperBound => number will use that formatter as long as it is < upperBound
|
// upperBound => number will use that formatter as long as it is < upperBound
|
||||||
// exact => number will use that formatter if it is === exact
|
// exact => number will use that formatter if it is === exact
|
||||||
type FormatterRule =
|
// if hardcodedinput is supplied it will override the input value or use the hardcoded output
|
||||||
| { upperBound?: undefined; exact: number; formatter: Format }
|
type HardCodedInputFormat =
|
||||||
| { upperBound: number; exact?: undefined; formatter: Format }
|
| {
|
||||||
|
input: number
|
||||||
|
prefix?: string
|
||||||
|
hardcodedOutput?: undefined
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
input?: undefined
|
||||||
|
prefix?: undefined
|
||||||
|
hardcodedOutput: string
|
||||||
|
}
|
||||||
|
|
||||||
|
type FormatterBaseRule = { formatterOptions: NumberFormatOptions }
|
||||||
|
type FormatterExactRule = { upperBound?: undefined; exact: number } & FormatterBaseRule
|
||||||
|
type FormatterUpperBoundRule = { upperBound: number; exact?: undefined } & FormatterBaseRule
|
||||||
|
|
||||||
|
type FormatterRule = (FormatterExactRule | FormatterUpperBoundRule) & { hardCodedInput?: HardCodedInputFormat }
|
||||||
|
|
||||||
// these formatter objects dictate which formatter rule to use based on the interval that
|
// these formatter objects dictate which formatter rule to use based on the interval that
|
||||||
// the number falls into. for example, based on the rule set below, if your number
|
// the number falls into. for example, based on the rule set below, if your number
|
||||||
// falls between 1 and 1e6, you'd use TWO_DECIMALS as the formatter.
|
// falls between 1 and 1e6, you'd use TWO_DECIMALS as the formatter.
|
||||||
const tokenNonTxFormatter: FormatterRule[] = [
|
const tokenNonTxFormatter: FormatterRule[] = [
|
||||||
{ exact: 0, formatter: '0' },
|
{ exact: 0, formatterOptions: NO_DECIMALS },
|
||||||
{ upperBound: 0.001, formatter: '<0.001' },
|
{ upperBound: 0.001, hardCodedInput: { input: 0.001, prefix: '<' }, formatterOptions: THREE_DECIMALS },
|
||||||
{ upperBound: 1, formatter: THREE_DECIMALS },
|
{ upperBound: 1, formatterOptions: THREE_DECIMALS },
|
||||||
{ upperBound: 1e6, formatter: TWO_DECIMALS },
|
{ upperBound: 1e6, formatterOptions: TWO_DECIMALS },
|
||||||
{ upperBound: 1e15, formatter: SHORTHAND_TWO_DECIMALS },
|
{ upperBound: 1e15, formatterOptions: SHORTHAND_TWO_DECIMALS },
|
||||||
{ upperBound: Infinity, formatter: '>999T' },
|
{
|
||||||
|
upperBound: Infinity,
|
||||||
|
hardCodedInput: { input: 999_000_000_000_000, prefix: '>' },
|
||||||
|
formatterOptions: SHORTHAND_TWO_DECIMALS_NO_TRAILING_ZEROS,
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const tokenTxFormatter: FormatterRule[] = [
|
const tokenTxFormatter: FormatterRule[] = [
|
||||||
{ exact: 0, formatter: '0' },
|
{ exact: 0, formatterOptions: NO_DECIMALS },
|
||||||
{ upperBound: 0.00001, formatter: '<0.00001' },
|
{
|
||||||
{ upperBound: 1, formatter: FIVE_DECIMALS_MAX_TWO_DECIMALS_MIN },
|
upperBound: 0.00001,
|
||||||
{ upperBound: 10000, formatter: SIX_SIG_FIGS_TWO_DECIMALS },
|
hardCodedInput: { input: 0.00001, prefix: '<' },
|
||||||
{ upperBound: Infinity, formatter: TWO_DECIMALS },
|
formatterOptions: FIVE_DECIMALS_MAX_TWO_DECIMALS_MIN,
|
||||||
|
},
|
||||||
|
{ upperBound: 1, formatterOptions: FIVE_DECIMALS_MAX_TWO_DECIMALS_MIN },
|
||||||
|
{ upperBound: 10000, formatterOptions: SIX_SIG_FIGS_TWO_DECIMALS },
|
||||||
|
{ upperBound: Infinity, formatterOptions: TWO_DECIMALS },
|
||||||
]
|
]
|
||||||
|
|
||||||
const swapTradeAmountFormatter: FormatterRule[] = [
|
const swapTradeAmountFormatter: FormatterRule[] = [
|
||||||
{ exact: 0, formatter: '0' },
|
{ exact: 0, formatterOptions: NO_DECIMALS },
|
||||||
{ upperBound: 0.1, formatter: SIX_SIG_FIGS_NO_COMMAS },
|
{ upperBound: 0.1, formatterOptions: SIX_SIG_FIGS_NO_COMMAS },
|
||||||
{ upperBound: 1, formatter: FIVE_DECIMALS_MAX_TWO_DECIMALS_MIN_NO_COMMAS },
|
{ upperBound: 1, formatterOptions: FIVE_DECIMALS_MAX_TWO_DECIMALS_MIN_NO_COMMAS },
|
||||||
{ upperBound: Infinity, formatter: SIX_SIG_FIGS_TWO_DECIMALS_NO_COMMAS },
|
{ upperBound: Infinity, formatterOptions: SIX_SIG_FIGS_TWO_DECIMALS_NO_COMMAS },
|
||||||
]
|
]
|
||||||
|
|
||||||
const swapPriceFormatter: FormatterRule[] = [
|
const swapPriceFormatter: FormatterRule[] = [
|
||||||
{ exact: 0, formatter: '0' },
|
{ exact: 0, formatterOptions: NO_DECIMALS },
|
||||||
{ upperBound: 0.00001, formatter: '<0.00001' },
|
{
|
||||||
|
upperBound: 0.00001,
|
||||||
|
hardCodedInput: { input: 0.00001, prefix: '<' },
|
||||||
|
formatterOptions: FIVE_DECIMALS_MAX_TWO_DECIMALS_MIN,
|
||||||
|
},
|
||||||
...swapTradeAmountFormatter,
|
...swapTradeAmountFormatter,
|
||||||
]
|
]
|
||||||
|
|
||||||
const fiatTokenDetailsFormatter: FormatterRule[] = [
|
const fiatTokenDetailsFormatter: FormatterRule[] = [
|
||||||
{ exact: 0, formatter: '$0.00' },
|
{ exact: 0, formatterOptions: TWO_DECIMALS_CURRENCY },
|
||||||
{ upperBound: 0.00000001, formatter: '<$0.00000001' },
|
{
|
||||||
{ upperBound: 0.1, formatter: THREE_SIG_FIGS_USD },
|
upperBound: 0.00000001,
|
||||||
{ upperBound: 1.05, formatter: THREE_DECIMALS_USD },
|
hardCodedInput: { input: 0.00000001, prefix: '<' },
|
||||||
{ upperBound: 1e6, formatter: TWO_DECIMALS_USD },
|
formatterOptions: ONE_SIG_FIG_CURRENCY,
|
||||||
{ upperBound: Infinity, formatter: SHORTHAND_USD_TWO_DECIMALS },
|
},
|
||||||
|
{ upperBound: 0.1, formatterOptions: THREE_SIG_FIGS_CURRENCY },
|
||||||
|
{ upperBound: 1.05, formatterOptions: THREE_DECIMALS_CURRENCY },
|
||||||
|
{ upperBound: 1e6, formatterOptions: TWO_DECIMALS_CURRENCY },
|
||||||
|
{ upperBound: Infinity, formatterOptions: SHORTHAND_CURRENCY_TWO_DECIMALS },
|
||||||
]
|
]
|
||||||
|
|
||||||
const fiatTokenPricesFormatter: FormatterRule[] = [
|
const fiatTokenPricesFormatter: FormatterRule[] = [
|
||||||
{ exact: 0, formatter: '$0.00' },
|
{ exact: 0, formatterOptions: TWO_DECIMALS_CURRENCY },
|
||||||
{ upperBound: 0.00000001, formatter: '<$0.00000001' },
|
{
|
||||||
{ upperBound: 1, formatter: THREE_SIG_FIGS_USD },
|
upperBound: 0.00000001,
|
||||||
{ upperBound: 1e6, formatter: TWO_DECIMALS_USD },
|
hardCodedInput: { input: 0.00000001, prefix: '<' },
|
||||||
{ upperBound: 1e16, formatter: SHORTHAND_USD_TWO_DECIMALS },
|
formatterOptions: ONE_SIG_FIG_CURRENCY,
|
||||||
{ upperBound: Infinity, formatter: SEVEN_SIG_FIGS__SCI_NOTATION_USD },
|
},
|
||||||
|
{ upperBound: 1, formatterOptions: THREE_SIG_FIGS_CURRENCY },
|
||||||
|
{ upperBound: 1e6, formatterOptions: TWO_DECIMALS_CURRENCY },
|
||||||
|
{ upperBound: 1e16, formatterOptions: SHORTHAND_CURRENCY_TWO_DECIMALS },
|
||||||
|
{ upperBound: Infinity, formatterOptions: SEVEN_SIG_FIGS__SCI_NOTATION_CURRENCY },
|
||||||
]
|
]
|
||||||
|
|
||||||
const fiatTokenStatsFormatter: FormatterRule[] = [
|
const fiatTokenStatsFormatter: FormatterRule[] = [
|
||||||
// if token stat value is 0, we probably don't have the data for it, so show '-' as a placeholder
|
// if token stat value is 0, we probably don't have the data for it, so show '-' as a placeholder
|
||||||
{ exact: 0, formatter: '-' },
|
{ exact: 0, hardCodedInput: { hardcodedOutput: '-' }, formatterOptions: ONE_SIG_FIG_CURRENCY },
|
||||||
{ upperBound: 0.01, formatter: '<$0.01' },
|
{ upperBound: 0.01, hardCodedInput: { input: 0.01, prefix: '<' }, formatterOptions: TWO_DECIMALS_CURRENCY },
|
||||||
{ upperBound: 1000, formatter: TWO_DECIMALS_USD },
|
{ upperBound: 1000, formatterOptions: TWO_DECIMALS_CURRENCY },
|
||||||
{ upperBound: Infinity, formatter: SHORTHAND_USD_ONE_DECIMAL },
|
{ upperBound: Infinity, formatterOptions: SHORTHAND_CURRENCY_ONE_DECIMAL },
|
||||||
]
|
]
|
||||||
|
|
||||||
const fiatGasPriceFormatter: FormatterRule[] = [
|
const fiatGasPriceFormatter: FormatterRule[] = [
|
||||||
{ exact: 0, formatter: '$0.00' },
|
{ exact: 0, formatterOptions: TWO_DECIMALS_CURRENCY },
|
||||||
{ upperBound: 0.01, formatter: '<$0.01' },
|
{ upperBound: 0.01, hardCodedInput: { input: 0.01, prefix: '<' }, formatterOptions: TWO_DECIMALS_CURRENCY },
|
||||||
{ upperBound: 1e6, formatter: TWO_DECIMALS_USD },
|
{ upperBound: 1e6, formatterOptions: TWO_DECIMALS_CURRENCY },
|
||||||
{ upperBound: Infinity, formatter: SHORTHAND_USD_TWO_DECIMALS },
|
{ upperBound: Infinity, formatterOptions: SHORTHAND_CURRENCY_TWO_DECIMALS },
|
||||||
]
|
]
|
||||||
|
|
||||||
const fiatTokenQuantityFormatter = [{ exact: 0, formatter: '$0.00' }, ...fiatGasPriceFormatter]
|
const fiatTokenQuantityFormatter: FormatterRule[] = [
|
||||||
|
{ exact: 0, formatterOptions: TWO_DECIMALS_CURRENCY },
|
||||||
|
...fiatGasPriceFormatter,
|
||||||
|
]
|
||||||
|
|
||||||
const portfolioBalanceFormatter: FormatterRule[] = [
|
const portfolioBalanceFormatter: FormatterRule[] = [
|
||||||
{ exact: 0, formatter: '$0.00' },
|
{ exact: 0, formatterOptions: TWO_DECIMALS_CURRENCY },
|
||||||
{ upperBound: Infinity, formatter: TWO_DECIMALS_USD },
|
{ upperBound: Infinity, formatterOptions: TWO_DECIMALS_CURRENCY },
|
||||||
]
|
]
|
||||||
|
|
||||||
const ntfTokenFloorPriceFormatterTrailingZeros: FormatterRule[] = [
|
const ntfTokenFloorPriceFormatterTrailingZeros: FormatterRule[] = [
|
||||||
{ exact: 0, formatter: '0' },
|
{ exact: 0, formatterOptions: NO_DECIMALS },
|
||||||
{ upperBound: 0.001, formatter: '<0.001' },
|
{ upperBound: 0.001, hardCodedInput: { input: 0.001, prefix: '<' }, formatterOptions: THREE_DECIMALS },
|
||||||
{ upperBound: 1, formatter: THREE_DECIMALS },
|
{ upperBound: 1, formatterOptions: THREE_DECIMALS },
|
||||||
{ upperBound: 1000, formatter: TWO_DECIMALS },
|
{ upperBound: 1000, formatterOptions: TWO_DECIMALS },
|
||||||
{ upperBound: 1e15, formatter: SHORTHAND_TWO_DECIMALS },
|
{ upperBound: 1e15, formatterOptions: SHORTHAND_TWO_DECIMALS },
|
||||||
{ upperBound: Infinity, formatter: '>999T' },
|
{
|
||||||
|
upperBound: Infinity,
|
||||||
|
hardCodedInput: { input: 999_000_000_000_000, prefix: '>' },
|
||||||
|
formatterOptions: SHORTHAND_TWO_DECIMALS_NO_TRAILING_ZEROS,
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const ntfTokenFloorPriceFormatter: FormatterRule[] = [
|
const ntfTokenFloorPriceFormatter: FormatterRule[] = [
|
||||||
{ exact: 0, formatter: '0' },
|
{ exact: 0, formatterOptions: NO_DECIMALS },
|
||||||
{ upperBound: 0.001, formatter: '<0.001' },
|
{ upperBound: 0.001, hardCodedInput: { input: 0.001, prefix: '<' }, formatterOptions: THREE_DECIMALS },
|
||||||
{ upperBound: 1, formatter: THREE_DECIMALS_NO_TRAILING_ZEROS },
|
{ upperBound: 1, formatterOptions: THREE_DECIMALS_NO_TRAILING_ZEROS },
|
||||||
{ upperBound: 1000, formatter: TWO_DECIMALS_NO_TRAILING_ZEROS },
|
{ upperBound: 1000, formatterOptions: TWO_DECIMALS_NO_TRAILING_ZEROS },
|
||||||
{ upperBound: 1e15, formatter: SHORTHAND_TWO_DECIMALS_NO_TRAILING_ZEROS },
|
{ upperBound: 1e15, formatterOptions: SHORTHAND_TWO_DECIMALS_NO_TRAILING_ZEROS },
|
||||||
{ upperBound: Infinity, formatter: '>999T' },
|
{
|
||||||
|
upperBound: Infinity,
|
||||||
|
hardCodedInput: { input: 999_000_000_000_000, prefix: '>' },
|
||||||
|
formatterOptions: SHORTHAND_TWO_DECIMALS_NO_TRAILING_ZEROS,
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const ntfCollectionStatsFormatter: FormatterRule[] = [
|
const ntfCollectionStatsFormatter: FormatterRule[] = [
|
||||||
{ upperBound: 1000, formatter: NO_DECIMALS },
|
{ upperBound: 1000, formatterOptions: NO_DECIMALS },
|
||||||
{ upperBound: Infinity, formatter: SHORTHAND_ONE_DECIMAL },
|
{ upperBound: Infinity, formatterOptions: SHORTHAND_ONE_DECIMAL },
|
||||||
]
|
]
|
||||||
|
|
||||||
export enum NumberType {
|
export enum NumberType {
|
||||||
@ -300,32 +358,57 @@ const TYPE_TO_FORMATTER_RULES = {
|
|||||||
[NumberType.NFTCollectionStats]: ntfCollectionStatsFormatter,
|
[NumberType.NFTCollectionStats]: ntfCollectionStatsFormatter,
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFormatterRule(input: number, type: NumberType): Format {
|
function getFormatterRule(input: number, type: NumberType): FormatterRule {
|
||||||
const rules = TYPE_TO_FORMATTER_RULES[type]
|
const rules = TYPE_TO_FORMATTER_RULES[type]
|
||||||
for (const rule of rules) {
|
for (const rule of rules) {
|
||||||
if (
|
if (
|
||||||
(rule.exact !== undefined && input === rule.exact) ||
|
(rule.exact !== undefined && input === rule.exact) ||
|
||||||
(rule.upperBound !== undefined && input < rule.upperBound)
|
(rule.upperBound !== undefined && input < rule.upperBound)
|
||||||
) {
|
) {
|
||||||
return rule.formatter
|
return rule
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error(`formatter for type ${type} not configured correctly`)
|
throw new Error(`formatter for type ${type} not configured correctly`)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatNumber(
|
interface FormatNumberOptions {
|
||||||
input: Nullish<number>,
|
input: Nullish<number>
|
||||||
type: NumberType = NumberType.TokenNonTx,
|
type?: NumberType
|
||||||
placeholder = '-'
|
placeholder?: string
|
||||||
): string {
|
locale?: SupportedLocale
|
||||||
|
localCurrency?: SupportedLocalCurrency
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatNumber({
|
||||||
|
input,
|
||||||
|
type = NumberType.TokenNonTx,
|
||||||
|
placeholder = '-',
|
||||||
|
locale = DEFAULT_LOCALE,
|
||||||
|
localCurrency = DEFAULT_LOCAL_CURRENCY,
|
||||||
|
}: FormatNumberOptions): string {
|
||||||
if (input === null || input === undefined) {
|
if (input === null || input === undefined) {
|
||||||
return placeholder
|
return placeholder
|
||||||
}
|
}
|
||||||
|
|
||||||
const formatter = getFormatterRule(input, type)
|
const { hardCodedInput, formatterOptions } = getFormatterRule(input, type)
|
||||||
if (typeof formatter === 'string') return formatter
|
|
||||||
return formatter.format(input)
|
if (formatterOptions.currency) {
|
||||||
|
formatterOptions.currency = localCurrency
|
||||||
|
formatterOptions.currencyDisplay = LOCAL_CURRENCY_SYMBOL_DISPLAY_TYPE[localCurrency]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hardCodedInput) {
|
||||||
|
return new Intl.NumberFormat(locale, formatterOptions).format(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hardCodedInput.hardcodedOutput) {
|
||||||
|
return hardCodedInput.hardcodedOutput
|
||||||
|
}
|
||||||
|
|
||||||
|
const { input: hardCodedInputValue, prefix } = hardCodedInput
|
||||||
|
if (hardCodedInputValue === undefined) return placeholder
|
||||||
|
return (prefix ?? '') + new Intl.NumberFormat(locale, formatterOptions).format(hardCodedInputValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatCurrencyAmount(
|
export function formatCurrencyAmount(
|
||||||
@ -333,7 +416,7 @@ export function formatCurrencyAmount(
|
|||||||
type: NumberType = NumberType.TokenNonTx,
|
type: NumberType = NumberType.TokenNonTx,
|
||||||
placeholder?: string
|
placeholder?: string
|
||||||
): string {
|
): string {
|
||||||
return formatNumber(amount ? parseFloat(amount.toSignificant()) : undefined, type, placeholder)
|
return formatNumber({ input: amount ? parseFloat(amount.toSignificant()) : undefined, type, placeholder })
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatPriceImpact(priceImpact: Percent | undefined): string {
|
export function formatPriceImpact(priceImpact: Percent | undefined): string {
|
||||||
@ -356,13 +439,13 @@ export function formatPrice(
|
|||||||
return '-'
|
return '-'
|
||||||
}
|
}
|
||||||
|
|
||||||
return formatNumber(parseFloat(price.toSignificant()), type)
|
return formatNumber({ input: parseFloat(price.toSignificant()), type })
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatNumberOrString(price: Nullish<number | string>, type: NumberType): string {
|
export function formatNumberOrString(price: Nullish<number | string>, type: NumberType): string {
|
||||||
if (price === null || price === undefined) return '-'
|
if (price === null || price === undefined) return '-'
|
||||||
if (typeof price === 'string') return formatNumber(parseFloat(price), type)
|
if (typeof price === 'string') return formatNumber({ input: parseFloat(price), type })
|
||||||
return formatNumber(price, type)
|
return formatNumber({ input: price, type })
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatUSDPrice(price: Nullish<number | string>, type: NumberType = NumberType.FiatTokenPrice): string {
|
export function formatUSDPrice(price: Nullish<number | string>, type: NumberType = NumberType.FiatTokenPrice): string {
|
||||||
|
Loading…
Reference in New Issue
Block a user