Commit 932c4482 authored by cartcrom's avatar cartcrom Committed by GitHub

feat: updated rate/routing tooltips (#7412)

* feat: updated routing tooltips

* refactor: gas price formatting

* fit: boolean rendering
parent 2d8dac5c
......@@ -14,7 +14,7 @@ import { Z_INDEX } from 'theme/zIndex'
import { RoutingDiagramEntry } from 'utils/getRoutingDiagramEntries'
import { ReactComponent as DotLine } from '../../assets/svg/dot_line.svg'
import { MouseoverTooltip } from '../Tooltip'
import { MouseoverTooltip, TooltipSize } from '../Tooltip'
const Wrapper = styled(Box)`
align-items: center;
......@@ -142,6 +142,7 @@ function Pool({ currency0, currency1, feeAmount }: { currency0: Currency; curren
return (
<MouseoverTooltip
text={<Trans>{tokenInfo0?.symbol + '/' + tokenInfo1?.symbol + ' ' + feeAmount / 10000}% pool</Trans>}
size={TooltipSize.ExtraSmall}
>
<PoolBadge>
<Box margin="0 4px 0 12px">
......
......@@ -20,7 +20,8 @@ import { getPriceImpactColor } from 'utils/prices'
import { GasBreakdownTooltip, UniswapXDescription } from './GasBreakdownTooltip'
import { MaxSlippageTooltip } from './MaxSlippageTooltip'
import SwapRoute from './SwapRoute'
import { RoutingTooltip, SwapRoute } from './SwapRoute'
import TradePrice from './TradePrice'
export enum SwapLineItemType {
EXCHANGE_RATE,
......@@ -76,15 +77,6 @@ function Loading({ width = 50 }: { width?: number }) {
return <LoadingRow data-testid="loading-row" height={15} width={width} />
}
function ExchangeRateRow({ trade }: { trade: InterfaceTrade }) {
const { formatNumber } = useFormatter()
const rate = `1 ${trade.executionPrice.quoteCurrency.symbol} = ${formatNumber({
input: parseFloat(trade.executionPrice.toFixed(9)),
type: NumberType.TokenTx,
})} ${trade.executionPrice.baseCurrency.symbol}`
return <>{rate}</>
}
function ColoredPercentRow({ percent }: { percent: Percent }) {
const { formatSlippage } = useFormatter()
return <ColorWrapper textColor={getPriceImpactColor(percent)}>{formatSlippage(percent)}</ColorWrapper>
......@@ -122,8 +114,10 @@ function useLineItem(props: SwapLineItemProps): LineItemData | undefined {
switch (type) {
case SwapLineItemType.EXCHANGE_RATE:
return {
Label: () => <Trans>Exchange rate</Trans>,
Value: () => <ExchangeRateRow trade={trade} />,
Label: () => <Trans>Rate</Trans>,
Value: () => <TradePrice price={trade.executionPrice} />,
TooltipBody: !isPreview ? () => <RoutingTooltip trade={trade} /> : undefined,
tooltipSize: isUniswapX ? TooltipSize.Small : TooltipSize.Large,
}
case SwapLineItemType.NETWORK_COST:
if (!SUPPORTED_GAS_ESTIMATE_CHAIN_IDS.includes(chainId)) return
......@@ -185,12 +179,12 @@ function useLineItem(props: SwapLineItemProps): LineItemData | undefined {
loaderWidth: 70,
}
case SwapLineItemType.ROUTING_INFO:
if (isPreview) return { Label: () => <Trans>Order routing</Trans>, Value: () => <Loading /> }
if (isPreview || syncing) return { Label: () => <Trans>Order routing</Trans>, Value: () => <Loading /> }
return {
Label: () => <Trans>Order routing</Trans>,
TooltipBody: () => {
if (isUniswapX) return <UniswapXDescription />
return <SwapRoute data-testid="swap-route-info" trade={trade} syncing={syncing} />
return <SwapRoute data-testid="swap-route-info" trade={trade} />
},
tooltipSize: isUniswapX ? TooltipSize.Small : TooltipSize.Large,
Value: () => <RouterLabel trade={trade} />,
......
import { Trans } from '@lingui/macro'
import { useWeb3React } from '@web3-react/core'
import Column from 'components/Column'
import { LoadingRows } from 'components/Loader/styled'
import RoutingDiagram from 'components/RoutingDiagram/RoutingDiagram'
import { RowBetween } from 'components/Row'
import { SUPPORTED_GAS_ESTIMATE_CHAIN_IDS } from 'constants/chains'
import useAutoRouterSupported from 'hooks/useAutoRouterSupported'
import { ClassicTrade } from 'state/routing/types'
import { ClassicTrade, SubmittableTrade } from 'state/routing/types'
import { isClassicTrade } from 'state/routing/utils'
import { Separator, ThemedText } from 'theme/components'
import { NumberType, useFormatter } from 'utils/formatNumbers'
import getRoutingDiagramEntries from 'utils/getRoutingDiagramEntries'
import RouterLabel from '../RouterLabel'
import { UniswapXDescription } from './GasBreakdownTooltip'
export default function SwapRoute({ trade, syncing }: { trade: ClassicTrade; syncing: boolean }) {
const { chainId } = useWeb3React()
const autoRouterSupported = useAutoRouterSupported()
// TODO(WEB-2022)
// Can `trade.gasUseEstimateUSD` be defined when `chainId` is not in `SUPPORTED_GAS_ESTIMATE_CHAIN_IDS`?
function useGasPrice({ gasUseEstimateUSD, inputAmount }: ClassicTrade) {
const { formatNumber } = useFormatter()
if (!gasUseEstimateUSD || !SUPPORTED_GAS_ESTIMATE_CHAIN_IDS.includes(inputAmount.currency.chainId)) return undefined
const routes = getRoutingDiagramEntries(trade)
return gasUseEstimateUSD === 0 ? '<$0.01' : formatNumber({ input: gasUseEstimateUSD, type: NumberType.FiatGasPrice })
}
const gasPrice =
// TODO(WEB-2022)
// Can `trade.gasUseEstimateUSD` be defined when `chainId` is not in `SUPPORTED_GAS_ESTIMATE_CHAIN_IDS`?
trade.gasUseEstimateUSD && chainId && SUPPORTED_GAS_ESTIMATE_CHAIN_IDS.includes(chainId)
? trade.gasUseEstimateUSD === 0
? '<$0.01'
: '$' + trade.gasUseEstimateUSD.toFixed(2)
: undefined
function RouteLabel({ trade }: { trade: SubmittableTrade }) {
return (
<RowBetween>
<ThemedText.BodySmall color="neutral2">Order Routing</ThemedText.BodySmall>
<RouterLabel trade={trade} color="neutral1" />
</RowBetween>
)
}
function PriceImpactRow({ trade }: { trade: ClassicTrade }) {
const { formatPriceImpact } = useFormatter()
return (
<ThemedText.BodySmall color="neutral2">
<RowBetween>
<Trans>Price Impact</Trans>
<div>{formatPriceImpact(trade.priceImpact)}</div>
</RowBetween>
</ThemedText.BodySmall>
)
}
export function RoutingTooltip({ trade }: { trade: SubmittableTrade }) {
return isClassicTrade(trade) ? (
<Column gap="md">
<RouterLabel trade={trade} color="neutral2" />
<PriceImpactRow trade={trade} />
<Separator />
{syncing ? (
<LoadingRows>
<div style={{ width: '100%', height: '30px' }} />
</LoadingRows>
<RouteLabel trade={trade} />
<SwapRoute trade={trade} />
</Column>
) : (
<RoutingDiagram
currencyIn={trade.inputAmount.currency}
currencyOut={trade.outputAmount.currency}
routes={routes}
/>
)}
{autoRouterSupported && (
<>
<Column gap="md">
<RouteLabel trade={trade} />
<Separator />
{syncing ? (
<LoadingRows>
<div style={{ width: '100%', height: '15px' }} />
</LoadingRows>
) : (
<UniswapXDescription />
</Column>
)
}
export function SwapRoute({ trade }: { trade: ClassicTrade }) {
const { inputAmount, outputAmount } = trade
const routes = getRoutingDiagramEntries(trade)
const gasPrice = useGasPrice(trade)
return useAutoRouterSupported() ? (
<Column gap="md">
<RoutingDiagram routes={routes} currencyIn={inputAmount.currency} currencyOut={outputAmount.currency} />
<ThemedText.Caption color="neutral2">
{gasPrice ? <Trans>Best price route costs ~{gasPrice} in gas.</Trans> : null}{' '}
{Boolean(gasPrice) && <Trans>Best price route costs ~{gasPrice} in gas. </Trans>}
{Boolean(gasPrice) && ' '}
<Trans>
This route optimizes your total output by considering split routes, multiple hops, and the gas cost of
each step.
This route optimizes your total output by considering split routes, multiple hops, and the gas cost of each
step.
</Trans>
</ThemedText.Caption>
)}
</>
)}
</Column>
) : (
<RoutingDiagram routes={routes} currencyIn={inputAmount.currency} currencyOut={outputAmount.currency} />
)
}
......@@ -146,28 +146,6 @@ exports[`SwapDetailsDropdown.tsx renders a trade 1`] = `
fill: #7D7D7D;
}
.c20 {
text-align: right;
overflow-wrap: break-word;
}
.c19 {
cursor: help;
color: #7D7D7D;
}
.c22 {
background: #22222212;
border-radius: 8px;
color: #7D7D7D;
height: 20px;
padding: 0 6px;
}
.c22::after {
content: 'Auto';
}
.c8 {
background-color: transparent;
border: none;
......@@ -200,6 +178,28 @@ exports[`SwapDetailsDropdown.tsx renders a trade 1`] = `
user-select: text;
}
.c20 {
text-align: right;
overflow-wrap: break-word;
}
.c19 {
cursor: help;
color: #7D7D7D;
}
.c22 {
background: #22222212;
border-radius: 8px;
color: #7D7D7D;
height: 20px;
padding: 0 6px;
}
.c22::after {
content: 'Auto';
}
.c5 {
padding: 0;
-webkit-align-items: center;
......
......@@ -91,22 +91,49 @@ exports[`SwapModalFooter.tsx matches base snapshot, test trade exact input 1`] =
gap: 12px;
}
.c9 {
.c7 {
display: inline-block;
height: inherit;
}
.c7 {
.c9 {
background-color: transparent;
border: none;
cursor: pointer;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
padding: 0;
grid-template-columns: 1fr auto;
grid-gap: 0.25rem;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
text-align: left;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
-webkit-user-select: text;
-moz-user-select: text;
-ms-user-select: text;
user-select: text;
}
.c8 {
text-align: right;
overflow-wrap: break-word;
}
.c6 {
cursor: auto;
color: #7D7D7D;
}
.c8 {
cursor: help;
color: #7D7D7D;
}
......@@ -137,29 +164,45 @@ exports[`SwapModalFooter.tsx matches base snapshot, test trade exact input 1`] =
class="c5 c6 css-142zc9n"
data-testid="swap-li-label"
>
Exchange rate
Rate
</div>
<div
class="c5 c7 css-142zc9n"
class="c7"
>
<div>
<div
class="c5 c8 css-142zc9n"
>
<button
class="c9"
title="1 DEF = 1.00 ABC "
>
<div
class="c5 css-142zc9n"
>
1 DEF = 1.00 ABC
</div>
</button>
</div>
</div>
</div>
</div>
<div
class="c2 c3 c4"
>
<div
class="c5 c8 css-142zc9n"
class="c5 c6 css-142zc9n"
data-testid="swap-li-label"
>
Price impact
</div>
<div
class="c9"
class="c7"
>
<div>
<div
class="c5 c7 css-142zc9n"
class="c5 c8 css-142zc9n"
>
<span
class=""
......@@ -174,17 +217,17 @@ exports[`SwapModalFooter.tsx matches base snapshot, test trade exact input 1`] =
class="c2 c3 c4"
>
<div
class="c5 c8 css-142zc9n"
class="c5 c6 css-142zc9n"
data-testid="swap-li-label"
>
Max. slippage
</div>
<div
class="c9"
class="c7"
>
<div>
<div
class="c5 c7 css-142zc9n"
class="c5 c8 css-142zc9n"
>
<div
class="c2 c10"
......@@ -202,17 +245,17 @@ exports[`SwapModalFooter.tsx matches base snapshot, test trade exact input 1`] =
class="c2 c3 c4"
>
<div
class="c5 c8 css-142zc9n"
class="c5 c6 css-142zc9n"
data-testid="swap-li-label"
>
Receive at least
</div>
<div
class="c9"
class="c7"
>
<div>
<div
class="c5 c7 css-142zc9n"
class="c5 c8 css-142zc9n"
>
0.00000000000000098 DEF
</div>
......@@ -223,17 +266,17 @@ exports[`SwapModalFooter.tsx matches base snapshot, test trade exact input 1`] =
class="c2 c3 c4"
>
<div
class="c5 c8 css-142zc9n"
class="c5 c6 css-142zc9n"
data-testid="swap-li-label"
>
Network cost
</div>
<div
class="c9"
class="c7"
>
<div>
<div
class="c5 c7 css-142zc9n"
class="c5 c8 css-142zc9n"
>
<div
class="c2 c13"
......@@ -447,7 +490,7 @@ exports[`SwapModalFooter.tsx renders a preview trade while disabling submission
justify-content: flex-start;
}
.c11 {
.c12 {
width: 100%;
display: -webkit-box;
display: -webkit-flex;
......@@ -476,7 +519,7 @@ exports[`SwapModalFooter.tsx renders a preview trade while disabling submission
color: #222222;
}
.c12 {
.c13 {
color: #7D7D7D;
}
......@@ -495,7 +538,7 @@ exports[`SwapModalFooter.tsx renders a preview trade while disabling submission
gap: 12px;
}
.c10 {
.c11 {
-webkit-animation: fAQEyV 1.5s infinite;
animation: fAQEyV 1.5s infinite;
-webkit-animation-fill-mode: both;
......@@ -508,11 +551,43 @@ exports[`SwapModalFooter.tsx renders a preview trade while disabling submission
width: 50px;
}
.c9 {
.c10 {
display: inline-block;
height: inherit;
}
.c8 {
background-color: transparent;
border: none;
cursor: pointer;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
padding: 0;
grid-template-columns: 1fr auto;
grid-gap: 0.25rem;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
text-align: left;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
-webkit-user-select: text;
-moz-user-select: text;
-ms-user-select: text;
user-select: text;
}
.c7 {
text-align: right;
overflow-wrap: break-word;
......@@ -523,12 +598,12 @@ exports[`SwapModalFooter.tsx renders a preview trade while disabling submission
color: #7D7D7D;
}
.c8 {
.c9 {
cursor: help;
color: #7D7D7D;
}
.c13 {
.c14 {
background: #22222212;
border-radius: 8px;
color: #7D7D7D;
......@@ -536,7 +611,7 @@ exports[`SwapModalFooter.tsx renders a preview trade while disabling submission
padding: 0 6px;
}
.c13::after {
.c14::after {
content: 'Auto';
}
......@@ -558,32 +633,42 @@ exports[`SwapModalFooter.tsx renders a preview trade while disabling submission
class="c5 c6 css-142zc9n"
data-testid="swap-li-label"
>
Exchange rate
Rate
</div>
<div
class="c5 c7 css-142zc9n"
>
<button
class="c8"
title="1 DEF = 1.00 ABC "
>
<div
class="c5 css-142zc9n"
>
1 DEF = 1.00 ABC
</div>
</button>
</div>
</div>
<div
class="c2 c3 c4"
>
<div
class="c5 c8 css-142zc9n"
class="c5 c9 css-142zc9n"
data-testid="swap-li-label"
>
Price impact
</div>
<div
class="c9"
class="c10"
>
<div>
<div
class="c5 c7 css-142zc9n"
>
<div
class="c10"
class="c11"
data-testid="loading-row"
height="15"
width="50"
......@@ -596,23 +681,23 @@ exports[`SwapModalFooter.tsx renders a preview trade while disabling submission
class="c2 c3 c4"
>
<div
class="c5 c8 css-142zc9n"
class="c5 c9 css-142zc9n"
data-testid="swap-li-label"
>
Max. slippage
</div>
<div
class="c9"
class="c10"
>
<div>
<div
class="c5 c7 css-142zc9n"
>
<div
class="c2 c11"
class="c2 c12"
>
<div
class="c12 c13 css-1lgneq0"
class="c13 c14 css-1lgneq0"
/>
2%
</div>
......@@ -624,13 +709,13 @@ exports[`SwapModalFooter.tsx renders a preview trade while disabling submission
class="c2 c3 c4"
>
<div
class="c5 c8 css-142zc9n"
class="c5 c9 css-142zc9n"
data-testid="swap-li-label"
>
Receive at least
</div>
<div
class="c9"
class="c10"
>
<div>
<div
......@@ -645,20 +730,20 @@ exports[`SwapModalFooter.tsx renders a preview trade while disabling submission
class="c2 c3 c4"
>
<div
class="c5 c8 css-142zc9n"
class="c5 c9 css-142zc9n"
data-testid="swap-li-label"
>
Network cost
</div>
<div
class="c9"
class="c10"
>
<div>
<div
class="c5 c7 css-142zc9n"
>
<div
class="c10"
class="c11"
data-testid="loading-row"
height="15"
width="50"
......
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