Commit 5dd80597 authored by Zach Pomerantz's avatar Zach Pomerantz Committed by GitHub

fix: routing tooltip styles (#3459)

parent b50e5511
<svg width="100%" height="35" viewBox="800 0 300 200" xmlns="http://www.w3.org/2000/svg"> <svg width="100%" height="35" viewBox="850 0 300 200" xmlns="http://www.w3.org/2000/svg">
<line x1="0" x2="2000" y1="100" y2="100" stroke="currentColor" stroke-width="20" stroke-linecap="round" stroke-dasharray="1, 45"/> <line x1="0" x2="3000" y1="100" y2="100" stroke="currentColor" stroke-width="20" stroke-linecap="round" stroke-dasharray="1, 45"/>
</svg> </svg>
import styled, { Color } from 'lib/theme'
import Row from './Row'
const Badge = styled(Row)<{ borderRadius?: number; padding?: string; color?: Color }>`
background-color: ${({ theme, color = 'outline' }) => theme[color]};
border-radius: ${({ borderRadius }) => `${borderRadius ?? 0.5}em`};
padding: ${({ padding }) => padding ?? '0.25em 0.375em'};
`
export default Badge
import { Plural, Trans } from '@lingui/macro' import { Plural, Trans } from '@lingui/macro'
import { Currency, TradeType } from '@uniswap/sdk-core' import { Currency, TradeType } from '@uniswap/sdk-core'
import { FeeAmount } from '@uniswap/v3-sdk' import { FeeAmount } from '@uniswap/v3-sdk'
import { ReactComponent as DotLineImage } from 'assets/svg/dot_line.svg' import { ReactComponent as DotLine } from 'assets/svg/dot_line.svg'
import Badge from 'lib/components/Badge'
import Column from 'lib/components/Column' import Column from 'lib/components/Column'
import Row from 'lib/components/Row' import Row from 'lib/components/Row'
import Rule from 'lib/components/Rule' import Rule from 'lib/components/Rule'
...@@ -14,53 +13,72 @@ import { InterfaceTrade } from 'state/routing/types' ...@@ -14,53 +13,72 @@ import { InterfaceTrade } from 'state/routing/types'
import { getTokenPath, RoutingDiagramEntry } from './utils' import { getTokenPath, RoutingDiagramEntry } from './utils'
const Wrapper = styled(Column)` const StyledAutoRouterLabel = styled(ThemedText.ButtonSmall)`
padding: 0.25em; @supports (-webkit-background-clip: text) and (-webkit-text-fill-color: transparent) {
` background-image: linear-gradient(90deg, #2172e5 0%, #54e521 163.16%);
-webkit-background-clip: text;
const RouteRow = styled(Row)` -webkit-text-fill-color: transparent;
grid-template-columns: 1em 1.15em 1fr 1em; }
min-width: 430px;
` `
const RouteDetailsContainer = styled(Row)` function Header({ routes }: { routes: RoutingDiagramEntry[] }) {
padding: 0.1em 0.5em; return (
position: relative; <Row justify="space-between" gap={1}>
` <ThemedText.Subhead2>
<Row gap={0.25}>
<AutoRouter />
<StyledAutoRouterLabel color="primary" lineHeight={'16px'}>
<Trans>Auto Router</Trans>
</StyledAutoRouterLabel>
</Row>
</ThemedText.Subhead2>
<ThemedText.Body2>
<Plural value={routes.length} _1="Best route via 1 hop" other="Best route via # hops" />
</ThemedText.Body2>
</Row>
)
}
const DotsContainer = styled.div` const Dots = styled(DotLine)`
align-items: center; color: ${({ theme }) => theme.outline};
display: flex;
opacity: 0.5;
position: absolute; position: absolute;
width: calc(100% - 1em);
z-index: ${Layer.UNDERLAYER}; z-index: ${Layer.UNDERLAYER};
` `
const DotsContainerShort = styled(DotsContainer)` const RouteRow = styled(Row)`
overflow: hidden; flex-wrap: nowrap;
position: relative;
width: 71px;
` `
const Dots = styled(DotLineImage)` const RouteNode = styled(Row)`
path { background-color: ${({ theme }) => theme.interactive};
stroke: ${({ theme }) => theme.secondary}; border-radius: ${({ theme }) => `${(theme.borderRadius ?? 1) * 0.5}em`};
} margin-left: 1.625em;
padding: 0.25em 0.375em;
width: max-content;
` `
const DetailsRow = styled(Row)` const RouteBadge = styled.div`
display: grid; background-color: ${({ theme }) => theme.module};
grid-template-columns: 4.8125em 1fr; border-radius: ${({ theme }) => `${(theme.borderRadius ?? 1) * 0.25}em`};
width: 100%; padding: 0.125em;
` `
const StyledAutoRouterLabel = styled(ThemedText.ButtonSmall)` function RouteDetail({ route }: { route: RoutingDiagramEntry }) {
@supports (-webkit-background-clip: text) and (-webkit-text-fill-color: transparent) { const protocol = route.protocol.toUpperCase()
background-image: linear-gradient(90deg, #2172e5 0%, #54e521 163.16%); return (
-webkit-background-clip: text; <RouteNode>
-webkit-text-fill-color: transparent; <Row gap={0.375}>
} <ThemedText.Caption>{route.percent.toSignificant(2)}%</ThemedText.Caption>
<RouteBadge>
<ThemedText.Badge color="secondary">{protocol}</ThemedText.Badge>
</RouteBadge>
</Row>
</RouteNode>
)
}
const RoutePool = styled(RouteNode)`
margin: 0 0.75em;
` `
function Pool({ function Pool({
...@@ -73,15 +91,36 @@ function Pool({ ...@@ -73,15 +91,36 @@ function Pool({
feeAmount: FeeAmount feeAmount: FeeAmount
}) { }) {
return ( return (
<Badge padding="0 4px" color="dialog"> <RoutePool>
<Badge gap={0.375}> <ThemedText.Caption>
<Row> <Row gap={0.25}>
<TokenImg token={originCurrency} /> <TokenImg token={originCurrency} />
<TokenImg token={targetCurrency} style={{ marginLeft: '-0.65em' }} />
{feeAmount / 10_000}%
</Row>
</ThemedText.Caption>
</RoutePool>
)
}
function Route({ route }: { route: RoutingDiagramEntry }) {
const [originCurrency] = route.path[0]
const [, targetCurrency] = route.path[route.path.length - 1]
return (
<Row align="center" style={{ gridTemplateColumns: '1em 1fr 1em' }}>
<TokenImg token={originCurrency} />
<RouteRow flex style={{ position: 'relative' }}>
<Dots />
<RouteDetail route={route} />
<RouteRow justify="space-evenly" flex>
{route.path.map(([originCurrency, targetCurrency, feeAmount], index) => (
<Pool key={index} originCurrency={originCurrency} targetCurrency={targetCurrency} feeAmount={feeAmount} />
))}
</RouteRow>
</RouteRow>
<TokenImg token={targetCurrency} /> <TokenImg token={targetCurrency} />
</Row> </Row>
<ThemedText.Subhead2>{feeAmount / 10_000}%</ThemedText.Subhead2>
</Badge>
</Badge>
) )
} }
...@@ -89,55 +128,12 @@ export default function RoutingDiagram({ trade }: { trade: InterfaceTrade<Curren ...@@ -89,55 +128,12 @@ export default function RoutingDiagram({ trade }: { trade: InterfaceTrade<Curren
const routes: RoutingDiagramEntry[] = useMemo(() => getTokenPath(trade), [trade]) const routes: RoutingDiagramEntry[] = useMemo(() => getTokenPath(trade), [trade])
return ( return (
<Wrapper gap={0.75}> <Column gap={0.75}>
<Row justify="space-between"> <Header routes={routes} />
<Row gap={0.25}>
<AutoRouter />
<StyledAutoRouterLabel color="primary" lineHeight={'16px'}>
<Trans>Auto Router</Trans>
</StyledAutoRouterLabel>
</Row>
<ThemedText.ButtonSmall>
<Plural value={routes.length} _1="Best route via 1 hop" other="Best route via # hops" />
</ThemedText.ButtonSmall>
</Row>
<Rule /> <Rule />
{routes.map((route, index) => ( {routes.map((route, index) => (
<RouteRow key={index} align="center"> <Route key={index} route={route} />
<TokenImg token={trade.inputAmount.currency} />
<DotsContainerShort>
<Dots />
</DotsContainerShort>
<RouteDetailsContainer justify="flex-start" flex>
<DotsContainer>
<Dots />
</DotsContainer>
<DetailsRow>
<Badge padding="0 4px" color="dialog">
<Badge gap={0.375}>
<ThemedText.ButtonSmall color="secondary">{route.percent.toSignificant(2)}%</ThemedText.ButtonSmall>
<Badge padding="0.125em" borderRadius={0.25} color="module">
<ThemedText.Badge color="secondary" fontSize={'0.5rem'}>
{route.protocol.toUpperCase()}
</ThemedText.Badge>
</Badge>
</Badge>
</Badge>
<Row justify="space-evenly" flex style={{ width: '100%' }}>
{route.path.map(([originCurrency, targetCurrency, feeAmount], index) => (
<Pool
key={index}
originCurrency={originCurrency}
targetCurrency={targetCurrency}
feeAmount={feeAmount}
/>
))}
</Row>
</DetailsRow>
</RouteDetailsContainer>
<TokenImg token={trade.outputAmount.currency} />
</RouteRow>
))} ))}
</Wrapper> </Column>
) )
} }
...@@ -65,7 +65,7 @@ export function Caption(props: TextProps) { ...@@ -65,7 +65,7 @@ export function Caption(props: TextProps) {
} }
export function Badge(props: TextProps) { export function Badge(props: TextProps) {
return <TextWrapper className="badge" fontSize={8} fontWeight={600} lineHeight="8px" noWrap /> return <TextWrapper className="badge" fontSize="8px" fontWeight={600} lineHeight="8px" noWrap {...props} />
} }
export function ButtonLarge(props: TextProps) { export function ButtonLarge(props: TextProps) {
......
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