Commit c4a456a0 authored by Zach Pomerantz's avatar Zach Pomerantz Committed by GitHub

chore: simplify Price in its own component (#3508)

* chore: simplify Price in its own component

* fix: restore reversal

* fix: output usdc naming
parent 4b9098a7
import { useLingui } from '@lingui/react'
import { Trade } from '@uniswap/router-sdk'
import { Currency, CurrencyAmount, Token, TradeType } from '@uniswap/sdk-core'
import Row from 'lib/components/Row'
import { ThemedText } from 'lib/theme'
import formatLocaleNumber from 'lib/utils/formatLocaleNumber'
import { useCallback, useMemo, useState } from 'react'
import { formatCurrencyAmount, formatPrice } from 'utils/formatCurrencyAmount'
import { TextButton } from '../Button'
interface PriceProps {
trade: Trade<Currency, Currency, TradeType>
outputUSDC?: CurrencyAmount<Token>
}
/** Displays the price of a trade. If outputUSDC is included, also displays the unit price. */
export default function Price({ trade, outputUSDC }: PriceProps) {
const { i18n } = useLingui()
const { inputAmount, outputAmount, executionPrice } = trade
const [base, setBase] = useState<'input' | 'output'>('input')
const onClick = useCallback(() => setBase((base) => (base === 'input' ? 'output' : 'input')), [])
// Compute the usdc price from the output price, so that it aligns with the displayed price.
const { price, usdcPrice } = useMemo(() => {
switch (base) {
case 'input':
return {
price: executionPrice,
usdcPrice: outputUSDC?.multiply(inputAmount.decimalScale).divide(inputAmount),
}
case 'output':
return {
price: executionPrice.invert(),
usdcPrice: outputUSDC?.multiply(outputAmount.decimalScale).divide(outputAmount),
}
}
}, [base, executionPrice, inputAmount, outputAmount, outputUSDC])
return (
<TextButton color="primary" onClick={onClick}>
<ThemedText.Caption>
<Row gap={0.25}>
{formatLocaleNumber({ number: 1, sigFigs: 1, locale: i18n.locale })} {price.baseCurrency.symbol} ={' '}
{formatPrice(price, 6, i18n.locale)} {price.quoteCurrency.symbol}
{usdcPrice && (
<ThemedText.Caption color="secondary">(${formatCurrencyAmount(usdcPrice, 6, 'en', 2)})</ThemedText.Caption>
)}
</Row>
</ThemedText.Caption>
</TextButton>
)
}
......@@ -2,23 +2,23 @@ import { Trans } from '@lingui/macro'
import { useLingui } from '@lingui/react'
import { Trade } from '@uniswap/router-sdk'
import { Currency, TradeType } from '@uniswap/sdk-core'
import ActionButton, { Action } from 'lib/components/ActionButton'
import { IconButton } from 'lib/components/Button'
import Column from 'lib/components/Column'
import { Header } from 'lib/components/Dialog'
import Row from 'lib/components/Row'
import Rule from 'lib/components/Rule'
import { useSwapTradeType } from 'lib/hooks/swap'
import useScrollbar from 'lib/hooks/useScrollbar'
import { Slippage } from 'lib/hooks/useSlippage'
import useUSDCPriceImpact from 'lib/hooks/useUSDCPriceImpact'
import { AlertTriangle, BarChart, Expando, Info } from 'lib/icons'
import styled, { Color, ThemedText } from 'lib/theme'
import formatLocaleNumber from 'lib/utils/formatLocaleNumber'
import { useMemo, useState } from 'react'
import { formatCurrencyAmount, formatPrice } from 'utils/formatCurrencyAmount'
import { formatCurrencyAmount } from 'utils/formatCurrencyAmount'
import { tradeMeaningfullyDiffers } from 'utils/tradeMeaningFullyDiffer'
import ActionButton, { Action } from '../../ActionButton'
import Column from '../../Column'
import { Header } from '../../Dialog'
import Row from '../../Row'
import Rule from '../../Rule'
import Price from '../Price'
import Details from './Details'
import Summary from './Summary'
......@@ -105,7 +105,7 @@ interface SummaryDialogProps {
}
export function SummaryDialog({ trade, slippage, onConfirm }: SummaryDialogProps) {
const { inputAmount, outputAmount, executionPrice } = trade
const { inputAmount, outputAmount } = trade
const inputCurrency = inputAmount.currency
const outputCurrency = outputAmount.currency
const usdcPriceImpact = useUSDCPriceImpact(inputAmount, outputAmount)
......@@ -152,12 +152,7 @@ export function SummaryDialog({ trade, slippage, onConfirm }: SummaryDialogProps
<Body flex align="stretch" gap={0.75} padded open={open}>
<SummaryColumn gap={0.75} flex justify="center">
<Summary input={inputAmount} output={outputAmount} usdcPriceImpact={usdcPriceImpact} />
<Row>
<ThemedText.Caption userSelect>
{formatLocaleNumber({ number: 1, sigFigs: 1, locale: i18n.locale })} {inputCurrency.symbol} ={' '}
{formatPrice(executionPrice, 6, i18n.locale)} {outputCurrency.symbol}
</ThemedText.Caption>
</Row>
<Price trade={trade} />
</SummaryColumn>
<Rule />
<Row>
......
......@@ -8,12 +8,10 @@ import { WrapType } from 'lib/hooks/swap/useWrapCallback'
import useUSDCPriceImpact from 'lib/hooks/useUSDCPriceImpact'
import { AlertTriangle, Icon, Info, InlineSpinner } from 'lib/icons'
import styled, { ThemedText } from 'lib/theme'
import { ReactNode, useCallback, useMemo, useState } from 'react'
import { ReactNode, useCallback } from 'react'
import { InterfaceTrade } from 'state/routing/types'
import { formatCurrencyAmount } from 'utils/formatCurrencyAmount'
import { TextButton } from '../../Button'
import Row from '../../Row'
import Price from '../Price'
import RoutingDiagram from '../RoutingDiagram'
const Loading = styled.span`
......@@ -80,33 +78,8 @@ export function WrapCurrency({ loading, wrapType }: { loading: boolean; wrapType
}
export function Trade({ trade }: { trade: InterfaceTrade<Currency, Currency, TradeType> }) {
const [flip, setFlip] = useState(true)
const { inputAmount: input, outputAmount: output, executionPrice } = trade
const { inputUSDC, outputUSDC, priceImpact, warning: priceImpactWarning } = useUSDCPriceImpact(input, output)
const ratio = useMemo(() => {
const [a, b] = flip ? [output, input] : [input, output]
const priceString = (!flip ? executionPrice : executionPrice?.invert())?.toSignificant(6)
const ratio = `1 ${a.currency.symbol} = ${priceString} ${b.currency.symbol}`
const usdc = !flip
? inputUSDC
? ` ($${formatCurrencyAmount(inputUSDC, 6, 'en', 2)})`
: null
: outputUSDC
? ` ($${formatCurrencyAmount(outputUSDC, 6, 'en', 2)})`
: null
return (
<ThemedText.Caption userSelect>
<Row gap={0.25}>
{ratio}
{usdc && <ThemedText.Caption color="secondary">{usdc}</ThemedText.Caption>}
</Row>
</ThemedText.Caption>
)
}, [flip, output, input, executionPrice, inputUSDC, outputUSDC])
const { inputAmount: input, outputAmount: output } = trade
const { outputUSDC, priceImpact, warning: priceImpactWarning } = useUSDCPriceImpact(input, output)
return (
<>
<Tooltip placement="bottom" icon={priceImpactWarning ? AlertTriangle : Info}>
......@@ -122,9 +95,7 @@ export function Trade({ trade }: { trade: InterfaceTrade<Currency, Currency, Tra
<RoutingDiagram trade={trade} />
</Column>
</Tooltip>
<TextButton color="primary" onClick={() => setFlip(!flip)}>
{ratio}
</TextButton>
<Price trade={trade} outputUSDC={outputUSDC} />
</>
)
}
......@@ -22,7 +22,11 @@ export default function formatLocaleNumber({
} else {
localeArg = [locale, DEFAULT_LOCALE]
}
options.maximumSignificantDigits = options.maximumSignificantDigits || sigFigs
options.minimumFractionDigits = options.minimumFractionDigits || fixedDecimals
options.maximumFractionDigits = options.maximumFractionDigits || fixedDecimals
// Fixed decimals should override significant figures.
options.maximumSignificantDigits = options.maximumSignificantDigits || fixedDecimals ? undefined : sigFigs
let numberString: number
if (typeof number === 'number') {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment