Commit 6798bf3c authored by Charles Bachmeier's avatar Charles Bachmeier Committed by GitHub

feat: [info] add PDP loading skeleton (#7494)

* initial skeleton setup

* responsive table skeleton

* correct table widht

* right side column added

* add comments

* move loading components to their corresponding component

* remove extra bubble and adjust some styles

* move table skeleton to its own file

* add shared styles and skele file

* add loading skeleton tests

* design style nits

* update tests

* bips_base

* fix regression
parent 8734ee59
......@@ -13,6 +13,13 @@ describe('PoolDetailsHeader', () => {
toggleReversed: jest.fn(),
}
it('loading skeleton is shown', () => {
const { asFragment } = render(<PoolDetailsHeader {...mockProps} loading={true} />)
expect(asFragment()).toMatchSnapshot()
expect(screen.getByTestId('pdp-header-loading-skeleton')).toBeInTheDocument()
})
it('renders header text correctly', () => {
const { asFragment } = render(<PoolDetailsHeader {...mockProps} />)
expect(asFragment()).toMatchSnapshot()
......
......@@ -4,6 +4,7 @@ import blankTokenUrl from 'assets/svg/blank_token.svg'
import Column from 'components/Column'
import { ChainLogo } from 'components/Logo/ChainLogo'
import Row from 'components/Row'
import { LoadingBubble } from 'components/Tokens/loading'
import { BIPS_BASE } from 'constants/misc'
import { chainIdToBackendName } from 'graphql/data/util'
import { useCurrency } from 'hooks/Tokens'
......@@ -15,6 +16,7 @@ import { ClickableStyle, ThemedText } from 'theme/components'
import { shortenAddress } from 'utils'
import { ReversedArrowsIcon } from './icons'
import { DetailBubble } from './shared'
const HeaderColumn = styled(Column)`
gap: 36px;
......@@ -35,6 +37,12 @@ const ToggleReverseArrows = styled(ReversedArrowsIcon)`
${ClickableStyle}
`
const IconBubble = styled(LoadingBubble)`
width: 32px;
height: 32px;
border-radius: 50%;
`
interface Token {
id: string
symbol: string
......@@ -47,6 +55,7 @@ interface PoolDetailsHeaderProps {
token1?: Token
feeTier?: number
toggleReversed: React.DispatchWithoutAction
loading?: boolean
}
export function PoolDetailsHeader({
......@@ -56,10 +65,25 @@ export function PoolDetailsHeader({
token1,
feeTier,
toggleReversed,
loading,
}: PoolDetailsHeaderProps) {
const currencies = [useCurrency(token0?.id, chainId) ?? undefined, useCurrency(token1?.id, chainId) ?? undefined]
const chainName = chainIdToBackendName(chainId)
const origin = `/tokens/${chainName}`
if (loading)
return (
<HeaderColumn data-testid="pdp-header-loading-skeleton">
<DetailBubble $width={300} />
<Column gap="sm">
<Row gap="8px">
<IconBubble />
<DetailBubble $width={137} />
</Row>
</Column>
</HeaderColumn>
)
return (
<HeaderColumn>
<Row>
......
......@@ -2,6 +2,7 @@ import { Trans } from '@lingui/macro'
import Column from 'components/Column'
import CurrencyLogo from 'components/Logo/CurrencyLogo'
import Row from 'components/Row'
import { LoadingBubble } from 'components/Tokens/loading'
import { DeltaArrow } from 'components/Tokens/TokenDetails/Delta'
import { PoolData } from 'graphql/thegraph/PoolData'
import { useCurrency } from 'hooks/Tokens'
......@@ -15,6 +16,8 @@ import { colors } from 'theme/colors'
import { ThemedText } from 'theme/components'
import { NumberType, useFormatter } from 'utils/formatNumbers'
import { DetailBubble } from './shared'
const HeaderText = styled(Text)`
font-weight: 485;
font-size: 24px;
......@@ -90,13 +93,25 @@ const BalanceChartSide = styled.div<{ percent: number; $color: string; isLeft: b
${({ isLeft }) => (isLeft ? leftBarChartStyles : rightBarChartStyles)}
`
const StatSectionBubble = styled(LoadingBubble)`
width: 180px;
height: 40px;
`
const StatHeaderBubble = styled(LoadingBubble)`
width: 116px;
height: 24px;
border-radius: 8px;
`
interface PoolDetailsStatsProps {
poolData: PoolData
isReversed: boolean
poolData?: PoolData
isReversed?: boolean
chainId?: number
loading?: boolean
}
export function PoolDetailsStats({ poolData, isReversed, chainId }: PoolDetailsStatsProps) {
export function PoolDetailsStats({ poolData, isReversed, chainId, loading }: PoolDetailsStatsProps) {
const isScreenSize = useScreenSize()
const screenIsNotLarge = isScreenSize['lg']
const { formatNumber } = useFormatter()
......@@ -112,26 +127,46 @@ export function PoolDetailsStats({ poolData, isReversed, chainId }: PoolDetailsS
}
const [token0, token1] = useMemo(() => {
const fullWidth = poolData?.tvlToken0 / poolData?.token0Price + poolData?.tvlToken1
const token0FullData = {
...poolData?.token0,
price: poolData?.token0Price,
tvl: poolData?.tvlToken0,
color: color0,
percent: poolData?.tvlToken0 / poolData?.token0Price / fullWidth,
currency: currency0,
}
const token1FullData = {
...poolData?.token1,
price: poolData?.token1Price,
tvl: poolData?.tvlToken1,
color: color1,
percent: poolData?.tvlToken1 / fullWidth,
currency: currency1,
if (poolData) {
const fullWidth = poolData?.tvlToken0 / poolData?.token0Price + poolData?.tvlToken1
const token0FullData = {
...poolData?.token0,
price: poolData?.token0Price,
tvl: poolData?.tvlToken0,
color: color0,
percent: poolData?.tvlToken0 / poolData?.token0Price / fullWidth,
currency: currency0,
}
const token1FullData = {
...poolData?.token1,
price: poolData?.token1Price,
tvl: poolData?.tvlToken1,
color: color1,
percent: poolData?.tvlToken1 / fullWidth,
currency: currency1,
}
return isReversed ? [token1FullData, token0FullData] : [token0FullData, token1FullData]
} else {
return [undefined, undefined]
}
return isReversed ? [token1FullData, token0FullData] : [token0FullData, token1FullData]
}, [color0, color1, currency0, currency1, isReversed, poolData])
if (loading || !token0 || !token1 || !poolData) {
return (
<StatsWrapper>
<HeaderText>
<StatHeaderBubble />
</HeaderText>
{Array.from({ length: 4 }).map((_, i) => (
<Column gap="md" key={`loading-info-row-${i}`}>
<DetailBubble />
<StatSectionBubble />
</Column>
))}
</StatsWrapper>
)
}
return (
<StatsWrapper>
<HeaderText>
......
......@@ -26,6 +26,13 @@ describe('PoolDetailsStatsButton', () => {
mocked(useMultiChainPositions).mockReturnValue(useMultiChainPositionsReturnValue)
})
it('loading skeleton shown correctly', () => {
const { asFragment } = render(<PoolDetailsStatsButtons {...mockProps} loading={true} />)
expect(asFragment()).toMatchSnapshot()
expect(screen.getByTestId('pdp-buttons-loading-skeleton')).toBeVisible()
})
it('renders both buttons correctly', () => {
const { asFragment } = render(<PoolDetailsStatsButtons {...mockProps} />)
expect(asFragment()).toMatchSnapshot()
......
......@@ -4,6 +4,7 @@ import { PositionInfo } from 'components/AccountDrawer/MiniPortfolio/Pools/cache
import useMultiChainPositions from 'components/AccountDrawer/MiniPortfolio/Pools/useMultiChainPositions'
import { ButtonEmphasis, ButtonSize, ThemeButton } from 'components/Button'
import Row from 'components/Row'
import { LoadingBubble } from 'components/Tokens/loading'
import { Token } from 'graphql/thegraph/__generated__/types-and-hooks'
import { useCurrency } from 'hooks/Tokens'
import { useSwitchChain } from 'hooks/useSwitchChain'
......@@ -26,11 +27,18 @@ const PoolButton = styled(ThemeButton)`
width: 50%;
`
const ButtonBubble = styled(LoadingBubble)`
height: 44px;
width: 175px;
border-radius: 900px;
`
interface PoolDetailsStatsButtonsProps {
chainId?: number
token0?: Token
token1?: Token
feeTier?: number
loading?: boolean
}
function findMatchingPosition(positions: PositionInfo[], token0?: Token, token1?: Token, feeTier?: number) {
......@@ -45,7 +53,7 @@ function findMatchingPosition(positions: PositionInfo[], token0?: Token, token1?
)
}
export function PoolDetailsStatsButtons({ chainId, token0, token1, feeTier }: PoolDetailsStatsButtonsProps) {
export function PoolDetailsStatsButtons({ chainId, token0, token1, feeTier, loading }: PoolDetailsStatsButtonsProps) {
const { chainId: walletChainId, connector, account } = useWeb3React()
const { positions: userOwnedPositions } = useMultiChainPositions(account ?? '', chainId ? [chainId] : undefined)
const position = userOwnedPositions && findMatchingPosition(userOwnedPositions, token0, token1, feeTier)
......@@ -64,7 +72,15 @@ export function PoolDetailsStatsButtons({ chainId, token0, token1, feeTier }: Po
)
}
}
if (!currency0 || !currency1) return null
if (loading || !currency0 || !currency1)
return (
<PoolDetailsStatsButtonsRow data-testid="pdp-buttons-loading-skeleton">
<ButtonBubble />
<ButtonBubble />
</PoolDetailsStatsButtonsRow>
)
return (
<PoolDetailsStatsButtonsRow>
<PoolButton
......@@ -75,7 +91,6 @@ export function PoolDetailsStatsButtons({ chainId, token0, token1, feeTier }: Po
>
<Trans>Add liquidity</Trans>
</PoolButton>
<PoolButton
size={ButtonSize.medium}
emphasis={ButtonEmphasis.highSoft}
......
import { Trans } from '@lingui/macro'
import Column from 'components/Column'
import { ScrollBarStyles } from 'components/Common'
import Row from 'components/Row'
import { ArrowDown } from 'react-feather'
import styled from 'styled-components'
import { ThemedText } from 'theme/components'
import { DetailBubble, SmallDetailBubble } from './shared'
const Table = styled(Column)`
gap: 24px;
border-radius: 20px;
border: 1px solid ${({ theme }) => theme.surface3};
padding-bottom: 12px;
overflow-y: hidden;
${ScrollBarStyles}
`
const TableRow = styled(Row)<{ $borderBottom?: boolean }>`
justify-content: space-between;
border-bottom: ${({ $borderBottom, theme }) => ($borderBottom ? `1px solid ${theme.surface3}` : 'none')}};
padding: 12px;
min-width: max-content;
`
const TableElement = styled(ThemedText.BodySecondary)<{
alignRight?: boolean
small?: boolean
large?: boolean
}>`
display: flex;
padding: 0px 8px;
flex: ${({ small }) => (small ? 'unset' : '1')};
width: ${({ small }) => (small ? '44px' : 'auto')};
min-width: ${({ large, small }) => (large ? '136px' : small ? 'unset' : '121px')} !important;
justify-content: ${({ alignRight }) => (alignRight ? 'flex-end' : 'flex-start')};
`
{
/* TODO(WEB-2735): When making real datatable, merge in this code and deprecate this skeleton file */
}
export function PoolDetailsTableSkeleton() {
return (
<Table $isHorizontalScroll>
<TableRow $borderBottom>
<TableElement large>
<Row>
<ArrowDown size={16} />
<Trans>Time</Trans>
</Row>
</TableElement>
<TableElement>
<Trans>Type</Trans>
</TableElement>
<TableElement alignRight>
<Trans>USD</Trans>
</TableElement>
<TableElement alignRight>
<DetailBubble />
</TableElement>
<TableElement alignRight>
<DetailBubble />
</TableElement>
<TableElement alignRight>
<Trans>Maker</Trans>
</TableElement>
<TableElement alignRight small>
<Trans>Txn</Trans>
</TableElement>
</TableRow>
{Array.from({ length: 10 }).map((_, i) => (
<TableRow key={`loading-table-row-${i}`}>
<TableElement large>
<DetailBubble />
</TableElement>
<TableElement>
<DetailBubble />
</TableElement>
<TableElement alignRight>
<DetailBubble />
</TableElement>
<TableElement alignRight>
<DetailBubble />
</TableElement>
<TableElement alignRight>
<DetailBubble />
</TableElement>
<TableElement alignRight>
<DetailBubble />
</TableElement>
<TableElement alignRight small>
<SmallDetailBubble />
</TableElement>
</TableRow>
))}
</Table>
)
}
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`PoolDetailsHeader loading skeleton is shown 1`] = `
<DocumentFragment>
.c5 {
box-sizing: border-box;
margin: 0;
min-width: 0;
}
.c6 {
width: 100%;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
padding: 0;
-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;
gap: 8px;
}
.c0 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
}
.c4 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
gap: 8px;
}
.c2 {
border-radius: 12px;
border-radius: 12px;
height: 24px;
width: 50%;
width: 50%;
-webkit-animation: fAQEyV 1.5s infinite;
animation: fAQEyV 1.5s infinite;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
background: linear-gradient( to left, #22222212 25%, rgba(53,53,53,0.07) 50%, #22222212 75% );
will-change: background-position;
background-size: 400%;
}
.c3 {
height: 16px;
width: 300px;
}
.c8 {
height: 16px;
width: 137px;
}
.c1 {
gap: 36px;
}
.c7 {
width: 32px;
height: 32px;
border-radius: 50%;
}
<div
class="c0 c1"
data-testid="pdp-header-loading-skeleton"
>
<div
class="c2 c3"
/>
<div
class="c4"
>
<div
class="c5 c6"
>
<div
class="c2 c7"
/>
<div
class="c2 c8"
/>
</div>
</div>
</div>
</DocumentFragment>
`;
exports[`PoolDetailsHeader renders header text correctly 1`] = `
<DocumentFragment>
.c2 {
......
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`PoolDetailsStatsButton loading skeleton shown correctly 1`] = `
<DocumentFragment>
.c0 {
box-sizing: border-box;
margin: 0;
min-width: 0;
}
.c1 {
width: 100%;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
padding: 0;
-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;
}
.c3 {
border-radius: 12px;
border-radius: 12px;
height: 24px;
width: 50%;
width: 50%;
-webkit-animation: fAQEyV 1.5s infinite;
animation: fAQEyV 1.5s infinite;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
background: linear-gradient( to left, #22222212 25%, rgba(53,53,53,0.07) 50%, #22222212 75% );
will-change: background-position;
background-size: 400%;
}
.c2 {
gap: 12px;
}
.c4 {
height: 44px;
width: 175px;
border-radius: 900px;
}
@media (max-width:1023px) {
.c2 {
display: none;
}
}
<div
class="c0 c1 c2"
data-testid="pdp-buttons-loading-skeleton"
>
<div
class="c3 c4"
/>
<div
class="c3 c4"
/>
</div>
</DocumentFragment>
`;
exports[`PoolDetailsStatsButton renders both buttons correctly 1`] = `
<DocumentFragment>
.c0 {
......
......@@ -8,7 +8,7 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
min-width: 0;
}
.c9 {
.c11 {
box-sizing: border-box;
margin: 0;
min-width: 0;
......@@ -17,7 +17,7 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
width: max-content;
}
.c31 {
.c52 {
box-sizing: border-box;
margin: 0;
min-width: 0;
......@@ -44,7 +44,7 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
justify-content: flex-start;
}
.c8 {
.c10 {
width: 100%;
display: -webkit-box;
display: -webkit-flex;
......@@ -62,7 +62,7 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
gap: 18px;
}
.c10 {
.c12 {
width: -webkit-max-content;
width: -moz-max-content;
width: max-content;
......@@ -82,7 +82,7 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
gap: 8px;
}
.c32 {
.c53 {
width: -webkit-max-content;
width: -moz-max-content;
width: max-content;
......@@ -102,15 +102,15 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
padding: 4px 0px;
}
.c6 {
.c8 {
color: #7D7D7D;
}
.c7 {
.c9 {
color: #222222;
}
.c43 {
.c64 {
-webkit-text-decoration: none;
text-decoration: none;
cursor: pointer;
......@@ -121,11 +121,11 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
font-weight: 500;
}
.c43:hover {
.c64:hover {
opacity: 0.6;
}
.c43:active {
.c64:active {
opacity: 0.4;
}
......@@ -143,7 +143,113 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
justify-content: flex-start;
}
.c40 {
.c5 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
gap: 8px;
}
.c19 {
border-radius: 12px;
border-radius: 12px;
height: 24px;
width: 50%;
width: 50%;
-webkit-animation: fAQEyV 1.5s infinite;
animation: fAQEyV 1.5s infinite;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
background: linear-gradient( to left, #22222212 25%, rgba(53,53,53,0.07) 50%, #22222212 75% );
will-change: background-position;
background-size: 400%;
}
.c42 {
background-color: transparent;
bottom: 0;
border-radius: inherit;
height: 100%;
left: 0;
position: absolute;
right: 0;
top: 0;
-webkit-transition: 150ms ease background-color;
transition: 150ms ease background-color;
width: 100%;
}
.c39 {
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
background-color: #FFEFFF;
border-radius: 16px;
border: 0;
color: #FC72FF;
cursor: pointer;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
font-size: 16px;
font-weight: 535;
gap: 12px;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
line-height: 20px;
padding: 10px 12px;
position: relative;
-webkit-transition: 150ms ease opacity;
transition: 150ms ease opacity;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.c39:active .c41 {
background-color: #B8C0DC3d;
}
.c39:focus .c41 {
background-color: #B8C0DC3d;
}
.c39:hover .c41 {
background-color: #98A1C014;
}
.c39:disabled {
cursor: default;
opacity: 0.6;
}
.c39:disabled:active .c41,
.c39:disabled:focus .c41,
.c39:disabled:hover .c41 {
background-color: transparent;
}
.c54 {
color: #FF5F52;
}
.c61 {
opacity: 0;
-webkit-transition: opacity 250ms ease-in;
transition: opacity 250ms ease-in;
......@@ -152,7 +258,7 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
border-radius: 50%;
}
.c39 {
.c60 {
width: 20px;
height: 20px;
background: #22222212;
......@@ -162,7 +268,7 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
border-radius: 50%;
}
.c38 {
.c59 {
position: relative;
display: -webkit-box;
display: -webkit-flex;
......@@ -170,35 +276,100 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
display: flex;
}
.c46 {
.c67 {
color: #CECECE;
font-weight: 485;
font-size: 16px;
}
.c36 {
.c18 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
height: 436px;
margin-bottom: 24px;
-webkit-align-items: flex-start;
-webkit-box-align: flex-start;
-ms-flex-align: flex-start;
align-items: flex-start;
width: 100%;
}
.c24 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
-webkit-align-items: flex-end;
-webkit-box-align: flex-end;
-ms-flex-align: flex-end;
align-items: flex-end;
height: 100%;
margin-bottom: 44px;
padding-bottom: 66px;
overflow: hidden;
}
.c20 {
height: 16px;
width: 180px;
}
.c21 {
height: 32px;
border-radius: 8px;
}
.c22 {
margin-top: 4px;
height: 40px;
}
.c25 {
-webkit-animation: wave 8s cubic-bezier(0.36,0.45,0.63,0.53) infinite;
animation: wave 8s cubic-bezier(0.36,0.45,0.63,0.53) infinite;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
overflow: hidden;
margin-top: 90px;
}
.c23 {
height: 6px;
}
.c57 {
gap: 12px;
width: 100%;
}
.c37 {
.c58 {
gap: 8px;
width: 100%;
}
.c41 {
.c62 {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.c42 {
.c63 {
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
}
.c44 {
.c65 {
gap: 8px;
padding: 8px 12px;
border-radius: 20px;
......@@ -217,15 +388,15 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
transition-duration: 125ms;
}
.c44:hover {
.c65:hover {
opacity: 0.6;
}
.c44:active {
.c65:active {
opacity: 0.4;
}
.c45 {
.c66 {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
......@@ -234,83 +405,22 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
white-space: pre-wrap;
}
.c21 {
background-color: transparent;
bottom: 0;
border-radius: inherit;
height: 100%;
left: 0;
position: absolute;
right: 0;
top: 0;
-webkit-transition: 150ms ease background-color;
transition: 150ms ease background-color;
width: 100%;
}
.c18 {
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
background-color: #FFEFFF;
border-radius: 16px;
border: 0;
color: #FC72FF;
cursor: pointer;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
font-size: 16px;
font-weight: 535;
gap: 12px;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
line-height: 20px;
padding: 10px 12px;
position: relative;
-webkit-transition: 150ms ease opacity;
transition: 150ms ease opacity;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.c18:active .c20 {
background-color: #B8C0DC3d;
}
.c18:focus .c20 {
background-color: #B8C0DC3d;
}
.c18:hover .c20 {
background-color: #98A1C014;
}
.c18:disabled {
cursor: default;
opacity: 0.6;
.c33 {
height: 16px;
width: 80px;
}
.c18:disabled:active .c20,
.c18:disabled:focus .c20,
.c18:disabled:hover .c20 {
background-color: transparent;
.c36 {
height: 20px;
width: 20px;
border-radius: 100px;
}
.c4 {
.c6 {
gap: 36px;
}
.c5 {
.c7 {
-webkit-text-decoration: none;
text-decoration: none;
-webkit-text-decoration: none;
......@@ -320,21 +430,21 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
transition-duration: 125ms;
}
.c5:hover {
.c7:hover {
opacity: 0.6;
}
.c5:active {
.c7:active {
opacity: 0.4;
}
.c14 {
.c16 {
background: #F9F9F9;
padding: 2px 6px;
border-radius: 4px;
}
.c15 {
.c17 {
-webkit-text-decoration: none;
text-decoration: none;
cursor: pointer;
......@@ -342,21 +452,21 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
transition-duration: 125ms;
}
.c15:hover {
.c17:hover {
opacity: 0.6;
}
.c15:active {
.c17:active {
opacity: 0.4;
}
.c11 {
.c13 {
position: relative;
top: 0;
left: 0;
}
.c12 {
.c14 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
......@@ -367,39 +477,35 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
left: 0;
}
.c12 img {
.c14 img {
width: 16px;
height: 32px;
object-fit: cover;
}
.c12 img:first-child {
.c14 img:first-child {
border-radius: 16px 0 0 16px;
object-position: 0 0;
}
.c12 img:last-child {
.c14 img:last-child {
border-radius: 0 16px 16px 0;
object-position: 100% 0;
}
.c13 {
.c15 {
width: 32px;
height: 32px;
border-radius: 50%;
}
.c33 {
color: #FF5F52;
}
.c23 {
.c44 {
font-weight: 485;
font-size: 24px;
line-height: 36px;
}
.c22 {
.c43 {
gap: 24px;
padding: 20px;
border-radius: 20px;
......@@ -407,7 +513,7 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
width: 100%;
}
.c24 {
.c45 {
gap: 8px;
-webkit-flex: 1;
-ms-flex: 1;
......@@ -415,14 +521,14 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
min-width: 180px;
}
.c25 {
.c46 {
-webkit-box-pack: justify;
-webkit-justify-content: space-between;
-ms-flex-pack: justify;
justify-content: space-between;
}
.c26 {
.c47 {
font-weight: 485;
font-size: 18px;
line-height: 24px;
......@@ -431,7 +537,7 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
width: max-content;
}
.c27 {
.c48 {
height: 8px;
width: 40.698463777008904%;
background: #FC72FF;
......@@ -440,7 +546,7 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
border-right: 1px solid #F9F9F9;
}
.c28 {
.c49 {
height: 8px;
width: 59.3015362229911%;
background: #4C82FB;
......@@ -449,7 +555,7 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
border-left: 1px solid #F9F9F9;
}
.c29 {
.c50 {
gap: 4px;
width: 100%;
-webkit-align-items: flex-end;
......@@ -458,23 +564,143 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
align-items: flex-end;
}
.c30 {
.c51 {
color: #222222;
font-size: 36px;
font-weight: 485;
line-height: 44px;
}
.c17 {
.c38 {
gap: 12px;
}
.c19 {
.c40 {
padding: 12px 16px 12px 12px;
border-radius: 900px;
width: 50%;
}
.c28 {
gap: 24px;
border-radius: 20px;
border: 1px solid #22222212;
padding-bottom: 12px;
overflow-y: hidden;
-webkit-scrollbar-width: thin;
-moz-scrollbar-width: thin;
-ms-scrollbar-width: thin;
scrollbar-width: thin;
-webkit-scrollbar-color: #22222212 transparent;
-moz-scrollbar-color: #22222212 transparent;
-ms-scrollbar-color: #22222212 transparent;
scrollbar-color: #22222212 transparent;
height: 100%;
}
.c28::-webkit-scrollbar {
background: transparent;
height: 4px;
overflow-x: scroll;
}
.c28::-webkit-scrollbar-thumb {
background: #22222212;
border-radius: 8px;
}
.c29 {
-webkit-box-pack: justify;
-webkit-justify-content: space-between;
-ms-flex-pack: justify;
justify-content: space-between;
border-bottom: 1px solid #22222212;
padding: 12px;
min-width: -webkit-max-content;
min-width: -moz-max-content;
min-width: max-content;
}
.c35 {
-webkit-box-pack: justify;
-webkit-justify-content: space-between;
-ms-flex-pack: justify;
justify-content: space-between;
border-bottom: none;
padding: 12px;
min-width: -webkit-max-content;
min-width: -moz-max-content;
min-width: max-content;
}
.c30 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
padding: 0px 8px;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
width: auto;
min-width: 136px !important;
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
}
.c31 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
padding: 0px 8px;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
width: auto;
min-width: 121px !important;
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
}
.c32 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
padding: 0px 8px;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
width: auto;
min-width: 121px !important;
-webkit-box-pack: end;
-webkit-justify-content: flex-end;
-ms-flex-pack: end;
justify-content: flex-end;
}
.c34 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
padding: 0px 8px;
-webkit-flex: unset;
-ms-flex: unset;
flex: unset;
width: 44px;
min-width: unset !important;
-webkit-box-pack: end;
-webkit-justify-content: flex-end;
-ms-flex-pack: end;
justify-content: flex-end;
}
.c2 {
padding: 48px;
width: 100%;
......@@ -482,21 +708,43 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
-webkit-box-align: flex-start;
-ms-flex-align: flex-start;
align-items: flex-start;
gap: 60px;
}
.c16 {
.c4 {
gap: 24px;
width: 65vw;
overflow: hidden;
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
}
.c26 {
border: 0.5px solid #22222212;
margin: 16px 0px;
width: 100%;
}
.c27 {
width: 180px;
height: 32px;
}
.c37 {
gap: 24px;
margin: 0 48px 0 auto;
width: 22vw;
min-width: 360px;
}
.c34 {
.c55 {
gap: 24px;
padding: 20px;
}
.c35 {
.c56 {
width: 100%;
font-size: 24px;
font-weight: 485;
......@@ -504,19 +752,19 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
}
@media (max-width:1023px) and (min-width:640px) {
.c36 {
.c57 {
max-width: 45%;
}
}
@media (max-width:1023px) {
.c23 {
.c44 {
width: 100%;
}
}
@media (max-width:1023px) {
.c22 {
.c43 {
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
......@@ -533,13 +781,13 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
}
@media (max-width:640px) {
.c24 {
.c45 {
min-width: 150px;
}
}
@media (max-width:1023px) {
.c25 {
.c46 {
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
......@@ -547,7 +795,7 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
}
@media (max-width:1023px) {
.c26 {
.c47 {
font-size: 20px;
line-height: 28px;
width: 100%;
......@@ -555,7 +803,7 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
}
@media (max-width:1023px) {
.c29 {
.c50 {
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
......@@ -568,14 +816,14 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
}
@media (max-width:1023px) {
.c30 {
.c51 {
font-size: 20px;
line-height: 28px;
}
}
@media (max-width:1023px) {
.c17 {
.c38 {
display: none;
}
}
......@@ -585,6 +833,7 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
gap: unset;
}
}
......@@ -595,7 +844,13 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
}
@media (max-width:1023px) {
.c16 {
.c4 {
width: 100%;
}
}
@media (max-width:1023px) {
.c37 {
margin: 44px 0px;
width: 100%;
min-width: unset;
......@@ -603,7 +858,7 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
}
@media (max-width:1023px) and (min-width:640px) {
.c34 {
.c55 {
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
......@@ -615,7 +870,7 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
}
@media (max-width:639px) {
.c34 {
.c55 {
padding: unset;
}
}
......@@ -627,147 +882,847 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
class="c3 c4"
>
<div
class="c0 c1"
class="c5"
>
<a
class="c5"
href="/tokens/ETHEREUM"
<div
class="c3 c6"
>
<div
class="c6 css-1urox24"
class="c0 c1"
>
Explore
<a
class="c7"
href="/tokens/ETHEREUM"
>
<div
class="c8 css-1urox24"
>
Explore
</div>
</a>
<div
class="c8 css-1urox24"
>
 &gt; 
</div>
<a
class="c7"
href="/tokens/ETHEREUM"
>
<div
class="c8 css-1urox24"
>
Pool
</div>
</a>
<div
class="c8 css-1urox24"
>
 &gt; 
</div>
<div
class="c9 css-1urox24"
>
USDC / WETH (0x88e6...5640)
</div>
</div>
</a>
<div
class="c6 css-1urox24"
>
 &gt; 
</div>
<a
class="c5"
href="/tokens/ETHEREUM"
>
<div
class="c6 css-1urox24"
class="c0 c10"
>
Pool
<div
class="c11 c12"
width="max-content"
>
<div
class="c13"
>
<div
class="c14"
>
<img
class="c15"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/logo.png"
/>
<img
class="c15"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2/logo.png"
/>
</div>
</div>
<div
class="c9 css-1jyz67g"
>
USDC / WETH
</div>
</div>
<div
class="c8 c16 css-1m65e73"
>
0.05%
</div>
<svg
class="c17"
data-testid="toggle-tokens-reverse-arrows"
fill="none"
height="20"
viewBox="0 0 20 20"
width="20"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M18.125 10V12.5C18.125 14.2233 16.7225 15.625 15 15.625H4.0092L5.4425 17.0583C5.68667 17.3025 5.68667 17.6983 5.4425 17.9425C5.32084 18.0642 5.16081 18.1258 5.00081 18.1258C4.84081 18.1258 4.68079 18.065 4.55912 17.9425L2.05912 15.4425C2.00162 15.385 1.9559 15.3159 1.92424 15.2393C1.8609 15.0868 1.8609 14.9143 1.92424 14.7618C1.9559 14.6851 2.00162 14.6158 2.05912 14.5583L4.55912 12.0583C4.80329 11.8141 5.19915 11.8141 5.44332 12.0583C5.68749 12.3025 5.68749 12.6983 5.44332 12.9425L4.01001 14.3758H15C16.0333 14.3758 16.875 13.535 16.875 12.5008V10.0008C16.875 9.65581 17.155 9.37581 17.5 9.37581C17.845 9.37581 18.125 9.655 18.125 10ZM2.5 10.625C2.845 10.625 3.125 10.345 3.125 10V7.5C3.125 6.46583 3.96667 5.625 5 5.625H15.9908L14.5575 7.05831C14.3133 7.30247 14.3133 7.69834 14.5575 7.9425C14.6792 8.06417 14.8392 8.12581 14.9992 8.12581C15.1592 8.12581 15.3192 8.065 15.4409 7.9425L17.9409 5.4425C17.9984 5.385 18.0441 5.31592 18.0758 5.23926C18.1391 5.08676 18.1391 4.91426 18.0758 4.76176C18.0441 4.68509 17.9984 4.61581 17.9409 4.55831L15.4409 2.05831C15.1967 1.81414 14.8008 1.81414 14.5567 2.05831C14.3125 2.30247 14.3125 2.69834 14.5567 2.9425L15.99 4.37581H5C3.2775 4.37581 1.875 5.77748 1.875 7.50081V10.0008C1.875 10.345 2.155 10.625 2.5 10.625Z"
fill="#5E5E5E"
/>
</svg>
</div>
</a>
<div
class="c6 css-1urox24"
>
 &gt; 
</div>
<div
class="c7 css-1urox24"
class="c18"
>
USDC / WETH (0x88e6...5640)
<div
class="c9 css-15popx1"
>
<div
class="c19 c20 c21 c22"
/>
</div>
<div
class="c23"
/>
<div
class="c24"
>
<div>
<div
class="c25"
>
<svg
height="160"
width="416"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M 0 80 Q 104 10, 208 80 T 416 80"
fill="transparent"
stroke="#22222212"
stroke-width="2"
/>
</svg>
<svg
height="160"
width="416"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M 0 80 Q 104 10, 208 80 T 416 80"
fill="transparent"
stroke="#22222212"
stroke-width="2"
/>
</svg>
<svg
height="160"
width="416"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M 0 80 Q 104 10, 208 80 T 416 80"
fill="transparent"
stroke="#22222212"
stroke-width="2"
/>
</svg>
<svg
height="160"
width="416"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M 0 80 Q 104 10, 208 80 T 416 80"
fill="transparent"
stroke="#22222212"
stroke-width="2"
/>
</svg>
<svg
height="160"
width="416"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M 0 80 Q 104 10, 208 80 T 416 80"
fill="transparent"
stroke="#22222212"
stroke-width="2"
/>
</svg>
</div>
</div>
</div>
</div>
</div>
<hr
class="c26"
/>
<div
class="c19 c27"
/>
<div
class="c0 c8"
class="c3 c28"
>
<div
class="c9 c10"
width="max-content"
class="c0 c1 c29"
>
<div
class="c11"
class="c8 c30 css-1urox24"
>
<div
class="c12"
class="c0 c1"
>
<img
class="c13"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/logo.png"
/>
<img
class="c13"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2/logo.png"
/>
<svg
fill="none"
height="16"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<line
x1="12"
x2="12"
y1="5"
y2="19"
/>
<polyline
points="19 12 12 19 5 12"
/>
</svg>
Time
</div>
</div>
<div
class="c7 css-1jyz67g"
class="c8 c31 css-1urox24"
>
Type
</div>
<div
class="c8 c32 css-1urox24"
>
USD
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
USDC / WETH
Maker
</div>
<div
class="c8 c34 css-1urox24"
>
Txn
</div>
</div>
<div
class="c6 c14 css-1m65e73"
>
0.05%
</div>
<svg
class="c15"
data-testid="toggle-tokens-reverse-arrows"
fill="none"
height="20"
viewBox="0 0 20 20"
width="20"
xmlns="http://www.w3.org/2000/svg"
class="c0 c1 c35"
>
<path
d="M18.125 10V12.5C18.125 14.2233 16.7225 15.625 15 15.625H4.0092L5.4425 17.0583C5.68667 17.3025 5.68667 17.6983 5.4425 17.9425C5.32084 18.0642 5.16081 18.1258 5.00081 18.1258C4.84081 18.1258 4.68079 18.065 4.55912 17.9425L2.05912 15.4425C2.00162 15.385 1.9559 15.3159 1.92424 15.2393C1.8609 15.0868 1.8609 14.9143 1.92424 14.7618C1.9559 14.6851 2.00162 14.6158 2.05912 14.5583L4.55912 12.0583C4.80329 11.8141 5.19915 11.8141 5.44332 12.0583C5.68749 12.3025 5.68749 12.6983 5.44332 12.9425L4.01001 14.3758H15C16.0333 14.3758 16.875 13.535 16.875 12.5008V10.0008C16.875 9.65581 17.155 9.37581 17.5 9.37581C17.845 9.37581 18.125 9.655 18.125 10ZM2.5 10.625C2.845 10.625 3.125 10.345 3.125 10V7.5C3.125 6.46583 3.96667 5.625 5 5.625H15.9908L14.5575 7.05831C14.3133 7.30247 14.3133 7.69834 14.5575 7.9425C14.6792 8.06417 14.8392 8.12581 14.9992 8.12581C15.1592 8.12581 15.3192 8.065 15.4409 7.9425L17.9409 5.4425C17.9984 5.385 18.0441 5.31592 18.0758 5.23926C18.1391 5.08676 18.1391 4.91426 18.0758 4.76176C18.0441 4.68509 17.9984 4.61581 17.9409 4.55831L15.4409 2.05831C15.1967 1.81414 14.8008 1.81414 14.5567 2.05831C14.3125 2.30247 14.3125 2.69834 14.5567 2.9425L15.99 4.37581H5C3.2775 4.37581 1.875 5.77748 1.875 7.50081V10.0008C1.875 10.345 2.155 10.625 2.5 10.625Z"
fill="#5E5E5E"
/>
</svg>
<div
class="c8 c30 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c31 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c34 css-1urox24"
>
<div
class="c19 c36"
/>
</div>
</div>
<div
class="c0 c1 c35"
>
<div
class="c8 c30 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c31 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c34 css-1urox24"
>
<div
class="c19 c36"
/>
</div>
</div>
<div
class="c0 c1 c35"
>
<div
class="c8 c30 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c31 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c34 css-1urox24"
>
<div
class="c19 c36"
/>
</div>
</div>
<div
class="c0 c1 c35"
>
<div
class="c8 c30 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c31 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c34 css-1urox24"
>
<div
class="c19 c36"
/>
</div>
</div>
<div
class="c0 c1 c35"
>
<div
class="c8 c30 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c31 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c34 css-1urox24"
>
<div
class="c19 c36"
/>
</div>
</div>
<div
class="c0 c1 c35"
>
<div
class="c8 c30 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c31 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c34 css-1urox24"
>
<div
class="c19 c36"
/>
</div>
</div>
<div
class="c0 c1 c35"
>
<div
class="c8 c30 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c31 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c34 css-1urox24"
>
<div
class="c19 c36"
/>
</div>
</div>
<div
class="c0 c1 c35"
>
<div
class="c8 c30 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c31 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c34 css-1urox24"
>
<div
class="c19 c36"
/>
</div>
</div>
<div
class="c0 c1 c35"
>
<div
class="c8 c30 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c31 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c34 css-1urox24"
>
<div
class="c19 c36"
/>
</div>
</div>
<div
class="c0 c1 c35"
>
<div
class="c8 c30 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c31 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c8 c34 css-1urox24"
>
<div
class="c19 c36"
/>
</div>
</div>
</div>
</div>
<div
class="c3 c16"
class="c3 c37"
>
<div
class="c0 c1 c17"
class="c0 c1 c38"
>
<button
class="c18 c19"
class="c39 c40"
data-testid="pool-details-add-liquidity-button"
size="1"
>
<div
class="c20 c21"
class="c41 c42"
/>
Add liquidity
</button>
<button
class="c18 c19"
class="c39 c40"
data-testid="pool-details-swap-button"
size="1"
>
<div
class="c20 c21"
class="c41 c42"
/>
Swap
</button>
</div>
<div
class="c3 c22"
class="c3 c43"
>
<div
class="c23 css-vurnku"
class="c44 css-vurnku"
>
Stats
</div>
<div
class="c3 c24"
class="c3 c45"
>
<div
class="c6 css-1urox24"
class="c8 css-1urox24"
>
Pool balances
</div>
<div
class="c0 c1 c25"
class="c0 c1 c46"
>
<div
class="c0 c1 c26"
class="c0 c1 c47"
>
90.93M USDC
</div>
<div
class="c0 c1 c26"
class="c0 c1 c47"
>
82,526.49 WETH
</div>
......@@ -777,36 +1732,36 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
data-testid="pool-balance-chart"
>
<div
class="c27"
class="c48"
/>
<div
class="c28"
class="c49"
/>
</div>
</div>
<div
class="c3 c24"
class="c3 c45"
>
<div
class="c6 css-1urox24"
class="c8 css-1urox24"
>
TVL
</div>
<div
class="c0 c1 c29"
class="c0 c1 c50"
>
<div
class="c30 css-vurnku"
class="c51 css-vurnku"
>
$223.2M
</div>
<div
class="c31 c32"
class="c52 c53"
width="max-content"
>
<svg
aria-label="down"
class="c33"
class="c54"
fill="none"
height="16"
viewBox="0 0 24 24"
......@@ -819,7 +1774,7 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
/>
</svg>
<div
class="c6 css-1urox24"
class="c8 css-1urox24"
>
0.37%
</div>
......@@ -827,28 +1782,28 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
</div>
</div>
<div
class="c3 c24"
class="c3 c45"
>
<div
class="c6 css-1urox24"
class="c8 css-1urox24"
>
24H volume
</div>
<div
class="c0 c1 c29"
class="c0 c1 c50"
>
<div
class="c30 css-vurnku"
class="c51 css-vurnku"
>
$233.4M
</div>
<div
class="c31 c32"
class="c52 c53"
width="max-content"
>
<svg
aria-label="down"
class="c33"
class="c54"
fill="none"
height="16"
viewBox="0 0 24 24"
......@@ -861,7 +1816,7 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
/>
</svg>
<div
class="c6 css-1urox24"
class="c8 css-1urox24"
>
17.75%
</div>
......@@ -869,18 +1824,18 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
</div>
</div>
<div
class="c3 c24"
class="c3 c45"
>
<div
class="c6 css-1urox24"
class="c8 css-1urox24"
>
24H fees
</div>
<div
class="c0 c1 c29"
class="c0 c1 c50"
>
<div
class="c30 css-vurnku"
class="c51 css-vurnku"
>
$116.7K
</div>
......@@ -888,56 +1843,56 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
</div>
</div>
<div
class="c3 c34"
class="c3 c55"
>
<div
class="c35 css-vurnku"
class="c56 css-vurnku"
>
Info
</div>
<div
class="c3 c36"
class="c3 c57"
>
<div
class="c0 c1 c37"
class="c0 c1 c58"
>
<div
class="c38"
class="c59"
style="height: 20px; width: 20px;"
>
<div
class="c39"
class="c60"
>
<img
alt="UNKNOWN logo"
class="c40"
class="c61"
loading="lazy"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/logo.png"
/>
</div>
</div>
<div
class="c7 c41 css-1urox24"
class="c9 c62 css-1urox24"
>
Unknown Token
</div>
<div
class="c6 css-1urox24"
class="c8 css-1urox24"
>
UNKNOWN
</div>
</div>
<div
class="c0 c1 c37 c42"
class="c0 c1 c58 c63"
>
<a
class="c43"
class="c64"
href="https://etherscan.io/token/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
rel="noopener noreferrer"
target="_blank"
>
<div
class="c0 c1 c44"
class="c0 c1 c65"
>
<svg
fill="#FC72FF"
......@@ -961,58 +1916,58 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
</a>
</div>
<div
class="c7 c45 css-1urox24"
class="c9 c66 css-1urox24"
>
<span
class="c46"
class="c67"
>
No token information available
</span>
</div>
</div>
<div
class="c3 c36"
class="c3 c57"
>
<div
class="c0 c1 c37"
class="c0 c1 c58"
>
<div
class="c38"
class="c59"
style="height: 20px; width: 20px;"
>
<div
class="c39"
class="c60"
>
<img
alt="WETH logo"
class="c40"
class="c61"
loading="lazy"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2/logo.png"
/>
</div>
</div>
<div
class="c7 c41 css-1urox24"
class="c9 c62 css-1urox24"
>
Wrapped Ether
</div>
<div
class="c6 css-1urox24"
class="c8 css-1urox24"
>
WETH
</div>
</div>
<div
class="c0 c1 c37 c42"
class="c0 c1 c58 c63"
>
<a
class="c43"
class="c64"
href="https://etherscan.io/token/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
rel="noopener noreferrer"
target="_blank"
>
<div
class="c0 c1 c44"
class="c0 c1 c65"
>
<svg
fill="#FC72FF"
......@@ -1036,10 +1991,10 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
</a>
</div>
<div
class="c7 c45 css-1urox24"
class="c9 c66 css-1urox24"
>
<span
class="c46"
class="c67"
>
No token information available
</span>
......
......@@ -76,7 +76,6 @@ describe('PoolDetailsPage', () => {
})
})
// TODO replace with loading skeleton when designed
it('nothing displayed while data is loading', () => {
mocked(usePoolData).mockReturnValue({
data: undefined,
......@@ -86,7 +85,7 @@ describe('PoolDetailsPage', () => {
render(<PoolDetails />)
waitFor(() => {
expect(screen.getByText(/not found/i)).not.toBeInTheDocument()
expect(screen.getByTestId('pdp-links-loading-skeleton')).toBeInTheDocument()
})
})
......
import { Trans } from '@lingui/macro'
import Column from 'components/Column'
import Row from 'components/Row'
import { LoadingBubble } from 'components/Tokens/loading'
import { LoadingChart } from 'components/Tokens/TokenDetails/Skeleton'
import { TokenDescription } from 'components/Tokens/TokenDetails/TokenDescription'
import { getValidUrlChainName, supportedChainIdFromGQLChain } from 'graphql/data/util'
import { usePoolData } from 'graphql/thegraph/PoolData'
......@@ -15,14 +17,18 @@ import { isAddress } from 'utils'
import { PoolDetailsHeader } from './PoolDetailsHeader'
import { PoolDetailsStats } from './PoolDetailsStats'
import { PoolDetailsStatsButtons } from './PoolDetailsStatsButtons'
import { PoolDetailsTableSkeleton } from './PoolDetailsTableSkeleton'
import { DetailBubble, SmallDetailBubble } from './shared'
const PageWrapper = styled(Row)`
padding: 48px;
width: 100%;
align-items: flex-start;
gap: 60px;
@media (max-width: ${BREAKPOINTS.lg - 1}px) {
flex-direction: column;
gap: unset;
}
@media (max-width: ${BREAKPOINTS.sm - 1}px) {
......@@ -30,6 +36,33 @@ const PageWrapper = styled(Row)`
}
`
const LeftColumn = styled(Column)`
gap: 24px;
width: 65vw;
overflow: hidden;
justify-content: flex-start;
@media (max-width: ${BREAKPOINTS.lg - 1}px) {
width: 100%;
}
`
const HR = styled.hr`
border: 0.5px solid ${({ theme }) => theme.surface3};
margin: 16px 0px;
width: 100%;
`
const ChartHeaderBubble = styled(LoadingBubble)`
width: 180px;
height: 32px;
`
const LinkColumn = styled(Column)`
gap: 16px;
padding: 20px;
`
const RightColumn = styled(Column)`
gap: 24px;
margin: 0 48px 0 auto;
......@@ -79,31 +112,55 @@ export default function PoolDetailsPage() {
const isInvalidPool = !chainName || !poolAddress || !getValidUrlChainName(chainName) || !isAddress(poolAddress)
const poolNotFound = (!loading && !poolData) || isInvalidPool
// TODO(WEB-2814): Add skeleton once designed
if (loading) return null
if (poolNotFound) return <NotFound />
return (
<PageWrapper>
<PoolDetailsHeader
chainId={chainId}
poolAddress={poolAddress}
token0={token0}
token1={token1}
feeTier={poolData?.feeTier}
toggleReversed={toggleReversed}
/>
<LeftColumn>
<Column gap="sm">
<PoolDetailsHeader
chainId={chainId}
poolAddress={poolAddress}
token0={token0}
token1={token1}
feeTier={poolData?.feeTier}
toggleReversed={toggleReversed}
loading={loading}
/>
<LoadingChart />
</Column>
<HR />
<ChartHeaderBubble />
<PoolDetailsTableSkeleton />
</LeftColumn>
<RightColumn>
<PoolDetailsStatsButtons chainId={chainId} token0={token0} token1={token1} feeTier={poolData?.feeTier} />
{poolData && <PoolDetailsStats poolData={poolData} isReversed={isReversed} chainId={chainId} />}
{(token0 || token1) && (
<TokenDetailsWrapper>
<TokenDetailsHeader>
<Trans>Info</Trans>
</TokenDetailsHeader>
{token0 && <TokenDescription tokenAddress={token0.id} chainId={chainId} />}
{token1 && <TokenDescription tokenAddress={token1.id} chainId={chainId} />}
</TokenDetailsWrapper>
)}
<PoolDetailsStatsButtons
chainId={chainId}
token0={token0}
token1={token1}
feeTier={poolData?.feeTier}
loading={loading}
/>
<PoolDetailsStats poolData={poolData} isReversed={isReversed} chainId={chainId} loading={loading} />
{(token0 || token1 || loading) &&
(loading ? (
<LinkColumn data-testid="pdp-links-loading-skeleton">
<DetailBubble $height={24} $width={116} />
{Array.from({ length: 3 }).map((_, i) => (
<Row gap="8px" key={`loading-link-row-${i}`}>
<SmallDetailBubble />
<DetailBubble $width={117} />
</Row>
))}
</LinkColumn>
) : (
<TokenDetailsWrapper>
<TokenDetailsHeader>
<Trans>Info</Trans>
</TokenDetailsHeader>
{token0 && <TokenDescription tokenAddress={token0.id} chainId={chainId} />}
{token1 && <TokenDescription tokenAddress={token1.id} chainId={chainId} />}
</TokenDetailsWrapper>
))}
</RightColumn>
</PageWrapper>
)
......
import { LoadingBubble } from 'components/Tokens/loading'
import styled from 'styled-components'
export const DetailBubble = styled(LoadingBubble)<{ $height?: number; $width?: number }>`
height: ${({ $height }) => ($height ? `${$height}px` : '16px')};
width: ${({ $width }) => ($width ? `${$width}px` : '80px')};
`
export const SmallDetailBubble = styled(LoadingBubble)`
height: 20px;
width: 20px;
border-radius: 100px;
`
......@@ -139,7 +139,11 @@ export const routes: RouteDefinition[] = [
}),
createRouteDefinition({
path: 'explore/pools/:chainName/:poolAddress',
getElement: () => <PoolDetails />,
getElement: () => (
<Suspense fallback={null}>
<PoolDetails />
</Suspense>
),
enabled: (args) => Boolean(args.infoExplorePageEnabled && args.infoPoolPageEnabled),
}),
createRouteDefinition({
......
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