chore: updating formatCurrencyAmount to handle multiple langs and cur… (#7263)

* chore: updating formatCurrencyAmount to handle multiple langs and currencies

* missed advanced swap details

* missed confirmed swap modal

* removing updating visual effects

* removing it from parseLocale

* chore: displaying local currency and language formatting

* making effects visible

* moving to hook

* useFormatCurrencyAmount

* moving it to useformatter hook

* exporting formatting locales

* missed one parsed remote

* moving hook to bottom of file

* moving to bottom
This commit is contained in:
Jack Short 2023-09-11 13:51:11 -04:00 committed by GitHub
parent e4d103b015
commit 86e4dd5153
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 137 additions and 55 deletions

@ -3,6 +3,7 @@ import { t } from '@lingui/macro'
import { ChainId, Currency, CurrencyAmount, TradeType } from '@uniswap/sdk-core'
import { nativeOnChain } from '@uniswap/smart-order-router'
import UniswapXBolt from 'assets/svg/bolt.svg'
import { SupportedLocale } from 'constants/locales'
import { TransactionStatus } from 'graphql/data/__generated__/types-and-hooks'
import { ChainTokenMap, useAllTokensMultichain } from 'hooks/Tokens'
import { useMemo } from 'react'
@ -23,7 +24,7 @@ import {
TransactionType,
WrapTransactionInfo,
} from 'state/transactions/types'
import { formatCurrencyAmount } from 'utils/formatNumbers'
import { formatCurrencyAmount, useFormatterLocales } from 'utils/formatNumbers'
import { CancelledTransactionTitleTable, getActivityTitle, OrderTextTable } from '../constants'
import { Activity, ActivityMap } from './types'
@ -37,11 +38,16 @@ function buildCurrencyDescriptor(
amtA: string,
currencyB: Currency | undefined,
amtB: string,
delimiter = t`for`
delimiter = t`for`,
locale?: SupportedLocale
) {
const formattedA = currencyA ? formatCurrencyAmount(CurrencyAmount.fromRawAmount(currencyA, amtA)) : t`Unknown`
const formattedA = currencyA
? formatCurrencyAmount({ amount: CurrencyAmount.fromRawAmount(currencyA, amtA), locale })
: t`Unknown`
const symbolA = currencyA?.symbol ?? ''
const formattedB = currencyB ? formatCurrencyAmount(CurrencyAmount.fromRawAmount(currencyB, amtB)) : t`Unknown`
const formattedB = currencyB
? formatCurrencyAmount({ amount: CurrencyAmount.fromRawAmount(currencyB, amtB), locale })
: t`Unknown`
const symbolB = currencyB?.symbol ?? ''
return [formattedA, symbolA, delimiter, formattedB, symbolB].filter(Boolean).join(' ')
}
@ -49,7 +55,8 @@ function buildCurrencyDescriptor(
function parseSwap(
swap: ExactInputSwapTransactionInfo | ExactOutputSwapTransactionInfo,
chainId: ChainId,
tokens: ChainTokenMap
tokens: ChainTokenMap,
locale?: SupportedLocale
): Partial<Activity> {
const tokenIn = getCurrency(swap.inputCurrencyId, chainId, tokens)
const tokenOut = getCurrency(swap.outputCurrencyId, chainId, tokens)
@ -59,7 +66,7 @@ function parseSwap(
: [swap.expectedInputCurrencyAmountRaw, swap.outputCurrencyAmountRaw]
return {
descriptor: buildCurrencyDescriptor(tokenIn, inputRaw, tokenOut, outputRaw),
descriptor: buildCurrencyDescriptor(tokenIn, inputRaw, tokenOut, outputRaw, undefined, locale),
currencies: [tokenIn, tokenOut],
prefixIconSrc: swap.isUniswapXOrder ? UniswapXBolt : undefined,
}
@ -149,7 +156,8 @@ export function getTransactionStatus(details: TransactionDetails): TransactionSt
export function transactionToActivity(
details: TransactionDetails,
chainId: ChainId,
tokens: ChainTokenMap
tokens: ChainTokenMap,
locale?: SupportedLocale
): Activity | undefined {
try {
const status = getTransactionStatus(details)
@ -168,7 +176,7 @@ export function transactionToActivity(
let additionalFields: Partial<Activity> = {}
const info = details.info
if (info.type === TransactionType.SWAP) {
additionalFields = parseSwap(info, chainId, tokens)
additionalFields = parseSwap(info, chainId, tokens, locale)
} else if (info.type === TransactionType.APPROVAL) {
additionalFields = parseApproval(info, chainId, tokens, status)
} else if (info.type === TransactionType.WRAP) {
@ -199,7 +207,11 @@ export function transactionToActivity(
}
}
export function signatureToActivity(signature: SignatureDetails, tokens: ChainTokenMap): Activity | undefined {
export function signatureToActivity(
signature: SignatureDetails,
tokens: ChainTokenMap,
locale?: SupportedLocale
): Activity | undefined {
switch (signature.type) {
case SignatureType.SIGN_UNISWAPX_ORDER: {
// Only returns Activity items for orders that don't have an on-chain counterpart
@ -217,7 +229,7 @@ export function signatureToActivity(signature: SignatureDetails, tokens: ChainTo
from: signature.offerer,
statusMessage,
prefixIconSrc: UniswapXBolt,
...parseSwap(signature.swapInfo, signature.chainId, tokens),
...parseSwap(signature.swapInfo, signature.chainId, tokens, locale),
}
}
default:
@ -229,23 +241,24 @@ export function useLocalActivities(account: string): ActivityMap {
const allTransactions = useMultichainTransactions()
const allSignatures = useAllSignatures()
const tokens = useAllTokensMultichain()
const { formatterLocale } = useFormatterLocales()
return useMemo(() => {
const activityMap: ActivityMap = {}
for (const [transaction, chainId] of allTransactions) {
if (transaction.from !== account) continue
const activity = transactionToActivity(transaction, chainId, tokens)
const activity = transactionToActivity(transaction, chainId, tokens, formatterLocale)
if (activity) activityMap[transaction.hash] = activity
}
for (const signature of Object.values(allSignatures)) {
if (signature.offerer !== account) continue
const activity = signatureToActivity(signature, tokens)
const activity = signatureToActivity(signature, tokens, formatterLocale)
if (activity) activityMap[signature.id] = activity
}
return activityMap
}, [account, allSignatures, allTransactions, tokens])
}, [account, allSignatures, allTransactions, formatterLocale, tokens])
}

@ -16,7 +16,7 @@ import { forwardRef, ReactNode, useCallback, useEffect, useState } from 'react'
import { Lock } from 'react-feather'
import styled, { useTheme } from 'styled-components'
import { flexColumnNoWrap, flexRowNoWrap } from 'theme/styles'
import { formatCurrencyAmount, NumberType } from 'utils/formatNumbers'
import { NumberType, useFormatter } from 'utils/formatNumbers'
import { ReactComponent as DropDown } from '../../assets/images/dropdown.svg'
import { useCurrencyBalance } from '../../state/connection/hooks'
@ -277,6 +277,7 @@ const SwapCurrencyInputPanel = forwardRef<HTMLInputElement, SwapCurrencyInputPan
const { account, chainId } = useWeb3React()
const selectedCurrencyBalance = useCurrencyBalance(account ?? undefined, currency ?? undefined)
const theme = useTheme()
const { formatCurrencyAmount } = useFormatter()
const handleDismissSearch = useCallback(() => {
setModalOpen(false)
@ -396,7 +397,13 @@ const SwapCurrencyInputPanel = forwardRef<HTMLInputElement, SwapCurrencyInputPan
renderBalance ? (
renderBalance(selectedCurrencyBalance)
) : (
<Trans>Balance: {formatCurrencyAmount(selectedCurrencyBalance, NumberType.TokenNonTx)}</Trans>
<Trans>
Balance:{' '}
{formatCurrencyAmount({
amount: selectedCurrencyBalance,
type: NumberType.TokenNonTx,
})}
</Trans>
)
) : null}
</ThemedText.DeprecatedBody>

@ -8,7 +8,7 @@ import { useStablecoinValue } from 'hooks/useStablecoinPrice'
import useCurrencyBalance from 'lib/hooks/useCurrencyBalance'
import styled, { useTheme } from 'styled-components'
import { ThemedText } from 'theme'
import { formatCurrencyAmount, NumberType } from 'utils/formatNumbers'
import { NumberType, useFormatter } from 'utils/formatNumbers'
const BalancesCard = styled.div`
background-color: ${({ theme }) => theme.surface1};
@ -67,8 +67,15 @@ export default function BalanceSummary({ token }: { token: Currency }) {
const theme = useTheme()
const { label, color } = getChainInfo(asSupportedChain(chainId) ?? ChainId.MAINNET)
const balance = useCurrencyBalance(account, token)
const formattedBalance = formatCurrencyAmount(balance, NumberType.TokenNonTx)
const formattedUsdValue = formatCurrencyAmount(useStablecoinValue(balance), NumberType.FiatTokenStats)
const { formatCurrencyAmount } = useFormatter()
const formattedBalance = formatCurrencyAmount({
amount: balance,
type: NumberType.TokenNonTx,
})
const formattedUsdValue = formatCurrencyAmount({
amount: useStablecoinValue(balance),
type: NumberType.FiatTokenStats,
})
if (!account || !balance) {
return null

@ -7,7 +7,7 @@ import { useStablecoinValue } from 'hooks/useStablecoinPrice'
import useCurrencyBalance from 'lib/hooks/useCurrencyBalance'
import styled from 'styled-components'
import { StyledInternalLink } from 'theme'
import { formatCurrencyAmount, NumberType } from 'utils/formatNumbers'
import { NumberType, useFormatter } from 'utils/formatNumbers'
const Wrapper = styled.div`
align-content: center;
@ -84,8 +84,15 @@ const SwapButton = styled(StyledInternalLink)`
export default function MobileBalanceSummaryFooter({ token }: { token: Currency }) {
const { account } = useWeb3React()
const balance = useCurrencyBalance(account, token)
const formattedBalance = formatCurrencyAmount(balance, NumberType.TokenNonTx)
const formattedUsdValue = formatCurrencyAmount(useStablecoinValue(balance), NumberType.FiatTokenStats)
const { formatCurrencyAmount } = useFormatter()
const formattedBalance = formatCurrencyAmount({
amount: balance,
type: NumberType.TokenNonTx,
})
const formattedUsdValue = formatCurrencyAmount({
amount: useStablecoinValue(balance),
type: NumberType.FiatTokenStats,
})
const chain = CHAIN_ID_TO_BACKEND_NAME[token.chainId].toLowerCase()
return (

@ -9,7 +9,7 @@ import { ZERO_PERCENT } from 'constants/misc'
import useNativeCurrency from 'lib/hooks/useNativeCurrency'
import { ClassicTrade, InterfaceTrade } from 'state/routing/types'
import { getTransactionCount, isClassicTrade } from 'state/routing/utils'
import { formatCurrencyAmount, formatPriceImpact, NumberType, useFormatter } from 'utils/formatNumbers'
import { formatPriceImpact, NumberType, useFormatter } from 'utils/formatNumbers'
import { ExternalLink, Separator, ThemedText } from '../../theme'
import Column from '../Column'
@ -47,7 +47,7 @@ export function AdvancedSwapDetails({ trade, allowedSlippage, syncing = false }:
const { chainId } = useWeb3React()
const nativeCurrency = useNativeCurrency(chainId)
const txCount = getTransactionCount(trade)
const { formatNumber } = useFormatter()
const { formatNumber, formatCurrencyAmount } = useFormatter()
const supportsGasEstimate = chainId && SUPPORTED_GAS_ESTIMATE_CHAIN_IDS.includes(chainId)
@ -117,9 +117,10 @@ export function AdvancedSwapDetails({ trade, allowedSlippage, syncing = false }:
<TextWithLoadingPlaceholder syncing={syncing} width={70}>
<ThemedText.BodySmall>
{trade.tradeType === TradeType.EXACT_INPUT
? `${formatCurrencyAmount(trade.minimumAmountOut(allowedSlippage), NumberType.SwapTradeAmount)} ${
trade.outputAmount.currency.symbol
}`
? `${formatCurrencyAmount({
amount: trade.minimumAmountOut(allowedSlippage),
type: NumberType.SwapTradeAmount,
})} ${trade.outputAmount.currency.symbol}`
: `${trade.maximumAmountIn(allowedSlippage).toSignificant(6)} ${trade.inputAmount.currency.symbol}`}
</ThemedText.BodySmall>
</TextWithLoadingPlaceholder>
@ -141,9 +142,10 @@ export function AdvancedSwapDetails({ trade, allowedSlippage, syncing = false }:
</RowFixed>
<TextWithLoadingPlaceholder syncing={syncing} width={65}>
<ThemedText.BodySmall>
{`${formatCurrencyAmount(trade.postTaxOutputAmount, NumberType.SwapTradeAmount)} ${
trade.outputAmount.currency.symbol
}`}
{`${formatCurrencyAmount({
amount: trade.postTaxOutputAmount,
type: NumberType.SwapTradeAmount,
})} ${trade.outputAmount.currency.symbol}`}
</ThemedText.BodySmall>
</TextWithLoadingPlaceholder>
</RowBetween>

@ -29,7 +29,7 @@ import styled from 'styled-components'
import { ThemedText } from 'theme'
import invariant from 'tiny-invariant'
import { isL2ChainId } from 'utils/chains'
import { formatCurrencyAmount, NumberType } from 'utils/formatNumbers'
import { NumberType, useFormatter } from 'utils/formatNumbers'
import { formatSwapPriceUpdatedEventProperties } from 'utils/loggingFormatters'
import { didUserReject } from 'utils/swapErrorToUserReadableMessage'
import { tradeMeaningfullyDiffers } from 'utils/tradeMeaningFullyDiffer'
@ -84,6 +84,7 @@ function useConfirmModalState({
const [confirmModalState, setConfirmModalState] = useState<ConfirmModalState>(ConfirmModalState.REVIEWING)
const [approvalError, setApprovalError] = useState<PendingModalError>()
const [pendingModalSteps, setPendingModalSteps] = useState<PendingConfirmModalState[]>([])
const { formatCurrencyAmount } = useFormatter()
// This is a function instead of a memoized value because we do _not_ want it to update as the allowance changes.
// For example, if the user needs to complete 3 steps initially, we should always show 3 step indicators
@ -123,7 +124,10 @@ function useConfirmModalState({
const { execute: onWrap } = useWrapCallback(
nativeCurrency,
trade.inputAmount.currency,
formatCurrencyAmount(trade.inputAmount, NumberType.SwapTradeAmount)
formatCurrencyAmount({
amount: trade.inputAmount,
type: NumberType.SwapTradeAmount,
})
)
const wrapConfirmed = useIsTransactionConfirmed(wrapTxHash)
const prevWrapConfirmed = usePrevious(wrapConfirmed)

@ -18,12 +18,12 @@ describe('SwapModalHeader.tsx', () => {
expect(asFragment()).toMatchSnapshot()
expect(screen.getByText(/Output is estimated. You will receive at least /i)).toBeInTheDocument()
expect(screen.getByTestId('INPUT-amount')).toHaveTextContent(
`${formatCurrencyAmount(TEST_TRADE_EXACT_INPUT.inputAmount, NumberType.TokenTx)} ${
`${formatCurrencyAmount({ amount: TEST_TRADE_EXACT_INPUT.inputAmount, type: NumberType.TokenTx })} ${
TEST_TRADE_EXACT_INPUT.inputAmount.currency.symbol ?? ''
}`
)
expect(screen.getByTestId('OUTPUT-amount')).toHaveTextContent(
`${formatCurrencyAmount(TEST_TRADE_EXACT_INPUT.outputAmount, NumberType.TokenTx)} ${
`${formatCurrencyAmount({ amount: TEST_TRADE_EXACT_INPUT.outputAmount, type: NumberType.TokenTx })} ${
TEST_TRADE_EXACT_INPUT.outputAmount.currency.symbol ?? ''
}`
)
@ -40,10 +40,12 @@ describe('SwapModalHeader.tsx', () => {
expect(asFragment()).toMatchSnapshot()
expect(screen.getByText(/Output is estimated. You will receive at least /i)).toBeInTheDocument()
expect(screen.getByTestId('INPUT-amount')).toHaveTextContent(
`${formatCurrencyAmount(TEST_DUTCH_TRADE_ETH_INPUT.inputAmount, NumberType.TokenTx)} ${ETH_MAINNET.symbol}`
`${formatCurrencyAmount({ amount: TEST_DUTCH_TRADE_ETH_INPUT.inputAmount, type: NumberType.TokenTx })} ${
ETH_MAINNET.symbol
}`
)
expect(screen.getByTestId('OUTPUT-amount')).toHaveTextContent(
`${formatCurrencyAmount(TEST_DUTCH_TRADE_ETH_INPUT.outputAmount, NumberType.TokenTx)} ${
`${formatCurrencyAmount({ amount: TEST_DUTCH_TRADE_ETH_INPUT.outputAmount, type: NumberType.TokenTx })} ${
TEST_DUTCH_TRADE_ETH_INPUT.outputAmount.currency.symbol ?? ''
}`
)
@ -57,12 +59,12 @@ describe('SwapModalHeader.tsx', () => {
expect(screen.getByText(/Input is estimated. You will sell at most/i)).toBeInTheDocument()
expect(screen.getByTestId('INPUT-amount')).toHaveTextContent(
`${formatCurrencyAmount(TEST_TRADE_EXACT_OUTPUT.inputAmount, NumberType.TokenTx)} ${
`${formatCurrencyAmount({ amount: TEST_TRADE_EXACT_OUTPUT.inputAmount, type: NumberType.TokenTx })} ${
TEST_TRADE_EXACT_OUTPUT.inputAmount.currency.symbol ?? ''
}`
)
expect(screen.getByTestId('OUTPUT-amount')).toHaveTextContent(
`${formatCurrencyAmount(TEST_TRADE_EXACT_OUTPUT.outputAmount, NumberType.TokenTx)} ${
`${formatCurrencyAmount({ amount: TEST_TRADE_EXACT_OUTPUT.outputAmount, type: NumberType.TokenTx })} ${
TEST_TRADE_EXACT_OUTPUT.outputAmount.currency.symbol ?? ''
}`
)

@ -25,7 +25,7 @@ import { ArrowLeft } from 'react-feather'
import styled from 'styled-components'
import { BREAKPOINTS, ThemedText } from 'theme'
import { Z_INDEX } from 'theme/zIndex'
import { formatCurrencyAmount, NumberType } from 'utils/formatNumbers'
import { NumberType, useFormatter } from 'utils/formatNumbers'
import { shallow } from 'zustand/shallow'
import { ListModal } from './Modal/ListModal'
@ -186,6 +186,7 @@ export const ListPage = () => {
const { provider, chainId } = useWeb3React()
const isMobile = useIsMobile()
const trace = useTrace({ modal: InterfaceModalName.NFT_LISTING })
const { formatCurrencyAmount } = useFormatter()
const { setGlobalMarketplaces, sellAssets, issues } = useSellAsset(
({ setGlobalMarketplaces, sellAssets, issues }) => ({
setGlobalMarketplaces,
@ -208,7 +209,10 @@ export const ListPage = () => {
const nativeCurrency = useNativeCurrency(chainId)
const parsedAmount = tryParseCurrencyAmount(totalEthListingValue.toString(), nativeCurrency)
const usdcValue = useStablecoinValue(parsedAmount)
const usdcAmount = formatCurrencyAmount(usdcValue, NumberType.FiatTokenPrice)
const usdcAmount = formatCurrencyAmount({
amount: usdcValue,
type: NumberType.FiatTokenPrice,
})
const [showListModal, toggleShowListModal] = useReducer((s) => !s, false)
const [selectedMarkets, setSelectedMarkets] = useState([ListingMarkets[0]]) // default marketplace: x2y2
const signer = provider?.getSigner()

@ -15,7 +15,7 @@ import { X } from 'react-feather'
import styled from 'styled-components'
import { BREAKPOINTS, ThemedText } from 'theme'
import { Z_INDEX } from 'theme/zIndex'
import { formatCurrencyAmount, NumberType } from 'utils/formatNumbers'
import { NumberType, useFormatter } from 'utils/formatNumbers'
import { shallow } from 'zustand/shallow'
import { TitleRow } from '../shared'
@ -48,6 +48,7 @@ export const ListModal = ({ overlayClick }: { overlayClick: () => void }) => {
const { provider, chainId } = useWeb3React()
const signer = provider?.getSigner()
const trace = useTrace({ modal: InterfaceModalName.NFT_LISTING })
const { formatCurrencyAmount } = useFormatter()
const sellAssets = useSellAsset((state) => state.sellAssets)
const { setListingStatusAndCallback, setLooksRareNonce, getLooksRareNonce, collectionsRequiringApproval, listings } =
useNFTList(
@ -75,7 +76,10 @@ export const ListModal = ({ overlayClick }: { overlayClick: () => void }) => {
const nativeCurrency = useNativeCurrency(chainId)
const parsedAmount = tryParseCurrencyAmount(totalEthListingValue.toString(), nativeCurrency)
const usdcValue = useStablecoinValue(parsedAmount)
const usdcAmount = formatCurrencyAmount(usdcValue, NumberType.FiatTokenPrice)
const usdcAmount = formatCurrencyAmount({
amount: usdcValue,
type: NumberType.FiatTokenPrice,
})
const allCollectionsApproved = useMemo(
() => collectionsRequiringApproval.every((collection) => collection.status === ListingStatus.APPROVED),

@ -13,7 +13,7 @@ import { useMemo } from 'react'
import { Twitter, X } from 'react-feather'
import styled, { css, useTheme } from 'styled-components'
import { BREAKPOINTS, ThemedText } from 'theme'
import { formatCurrencyAmount, NumberType } from 'utils/formatNumbers'
import { NumberType, useFormatter } from 'utils/formatNumbers'
import { TitleRow } from '../shared'
@ -79,6 +79,7 @@ export const SuccessScreen = ({ overlayClick }: { overlayClick: () => void }) =>
const sellAssets = useSellAsset((state) => state.sellAssets)
const { chainId } = useWeb3React()
const nativeCurrency = useNativeCurrency(chainId)
const { formatCurrencyAmount } = useFormatter()
const totalEthListingValue = useMemo(() => getTotalEthValue(sellAssets), [sellAssets])
const parsedAmount = tryParseCurrencyAmount(totalEthListingValue.toString(), nativeCurrency)
@ -110,7 +111,10 @@ export const SuccessScreen = ({ overlayClick }: { overlayClick: () => void }) =>
<ThemedText.SubHeader>{formatEth(totalEthListingValue)} ETH</ThemedText.SubHeader>
{usdcValue && (
<ThemedText.BodySmall lineHeight="20px" color="neutral2">
{formatCurrencyAmount(usdcValue, NumberType.FiatTokenPrice)}
{formatCurrencyAmount({
amount: usdcValue,
type: NumberType.FiatTokenPrice,
})}
</ThemedText.BodySmall>
)}
</ProceedsColumn>

@ -58,7 +58,7 @@ import styled, { useTheme } from 'styled-components'
import { LinkStyledButton, ThemedText } from 'theme'
import { maybeLogFirstSwapAction } from 'tracing/swapFlowLoggers'
import { computeFiatValuePriceImpact } from 'utils/computeFiatValuePriceImpact'
import { formatCurrencyAmount, NumberType } from 'utils/formatNumbers'
import { NumberType, useFormatter } from 'utils/formatNumbers'
import { maxAmountSpend } from 'utils/maxAmountSpend'
import { computeRealizedPriceImpact, warningSeverity } from 'utils/prices'
import { didUserReject } from 'utils/swapErrorToUserReadableMessage'
@ -382,14 +382,19 @@ export function Swap({
swapResult: undefined,
})
const { formatCurrencyAmount } = useFormatter()
const formattedAmounts = useMemo(
() => ({
[independentField]: typedValue,
[dependentField]: showWrap
? parsedAmounts[independentField]?.toExact() ?? ''
: formatCurrencyAmount(parsedAmounts[dependentField], NumberType.SwapTradeAmount, ''),
: formatCurrencyAmount({
amount: parsedAmounts[dependentField],
type: NumberType.SwapTradeAmount,
placeholder: '',
}),
[dependentField, independentField, parsedAmounts, showWrap, typedValue]
}),
[dependentField, formatCurrencyAmount, independentField, parsedAmounts, showWrap, typedValue]
)
const userHasSpecifiedInputOutput = Boolean(

@ -415,12 +415,28 @@ export function formatNumber({
return (prefix ?? '') + new Intl.NumberFormat(locale, formatterOptions).format(hardCodedInputValue)
}
export function formatCurrencyAmount(
amount: Nullish<CurrencyAmount<Currency>>,
type: NumberType = NumberType.TokenNonTx,
interface FormatCurrencyAmountOptions {
amount: Nullish<CurrencyAmount<Currency>>
type?: NumberType
placeholder?: string
): string {
return formatNumber({ input: amount ? parseFloat(amount.toSignificant()) : undefined, type, placeholder })
locale?: SupportedLocale
localCurrency?: SupportedLocalCurrency
}
export function formatCurrencyAmount({
amount,
type = NumberType.TokenNonTx,
placeholder,
locale = DEFAULT_LOCALE,
localCurrency = DEFAULT_LOCAL_CURRENCY,
}: FormatCurrencyAmountOptions): string {
return formatNumber({
input: amount ? parseFloat(amount.toSignificant()) : undefined,
type,
placeholder,
locale,
localCurrency,
})
}
export function formatPriceImpact(priceImpact: Percent | undefined): string {
@ -523,14 +539,14 @@ export const formatTransactionAmount = (num: number | undefined | null, maxDigit
const MAX_AMOUNT_STR_LENGTH = 9
export function formatReviewSwapCurrencyAmount(amount: CurrencyAmount<Currency>): string {
let formattedAmount = formatCurrencyAmount(amount, NumberType.TokenTx)
let formattedAmount = formatCurrencyAmount({ amount, type: NumberType.TokenTx })
if (formattedAmount.length > MAX_AMOUNT_STR_LENGTH) {
formattedAmount = formatCurrencyAmount(amount, NumberType.SwapTradeAmount)
formattedAmount = formatCurrencyAmount({ amount, type: NumberType.SwapTradeAmount })
}
return formattedAmount
}
function useFormatterLocales(): {
export function useFormatterLocales(): {
formatterLocale: SupportedLocale
formatterLocalCurrency: SupportedLocalCurrency
} {
@ -561,10 +577,17 @@ export function useFormatter() {
[formatterLocalCurrency, formatterLocale]
)
const formatCurrencyAmountWithLocales = useCallback(
(options: Omit<FormatCurrencyAmountOptions, 'locale' | 'localCurrency'>) =>
formatCurrencyAmount({ ...options, locale: formatterLocale, localCurrency: formatterLocalCurrency }),
[formatterLocalCurrency, formatterLocale]
)
return useMemo(
() => ({
formatNumber: formatNumberWithLocales,
formatCurrencyAmount: formatCurrencyAmountWithLocales,
}),
[formatNumberWithLocales]
[formatCurrencyAmountWithLocales, formatNumberWithLocales]
)
}