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,6 +127,7 @@ export function PoolDetailsStats({ poolData, isReversed, chainId }: PoolDetailsS
}
const [token0, token1] = useMemo(() => {
if (poolData) {
const fullWidth = poolData?.tvlToken0 / poolData?.token0Price + poolData?.tvlToken1
const token0FullData = {
...poolData?.token0,
......@@ -130,8 +146,27 @@ export function PoolDetailsStats({ poolData, isReversed, chainId }: PoolDetailsS
currency: currency1,
}
return isReversed ? [token1FullData, token0FullData] : [token0FullData, token1FullData]
} else {
return [undefined, undefined]
}
}, [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;
}
}
......@@ -625,82 +880,88 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
>
<div
class="c3 c4"
>
<div
class="c5"
>
<div
class="c3 c6"
>
<div
class="c0 c1"
>
<a
class="c5"
class="c7"
href="/tokens/ETHEREUM"
>
<div
class="c6 css-1urox24"
class="c8 css-1urox24"
>
Explore
</div>
</a>
<div
class="c6 css-1urox24"
class="c8 css-1urox24"
>
 &gt; 
</div>
<a
class="c5"
class="c7"
href="/tokens/ETHEREUM"
>
<div
class="c6 css-1urox24"
class="c8 css-1urox24"
>
Pool
</div>
</a>
<div
class="c6 css-1urox24"
class="c8 css-1urox24"
>
 &gt; 
</div>
<div
class="c7 css-1urox24"
class="c9 css-1urox24"
>
USDC / WETH (0x88e6...5640)
</div>
</div>
<div
class="c0 c8"
class="c0 c10"
>
<div
class="c9 c10"
class="c11 c12"
width="max-content"
>
<div
class="c11"
class="c13"
>
<div
class="c12"
class="c14"
>
<img
class="c13"
class="c15"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/logo.png"
/>
<img
class="c13"
class="c15"
src="https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/ethereum/assets/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2/logo.png"
/>
</div>
</div>
<div
class="c7 css-1jyz67g"
class="c9 css-1jyz67g"
>
USDC / WETH
</div>
</div>
<div
class="c6 c14 css-1m65e73"
class="c8 c16 css-1m65e73"
>
0.05%
</div>
<svg
class="c15"
class="c17"
data-testid="toggle-tokens-reverse-arrows"
fill="none"
height="20"
......@@ -716,171 +977,865 @@ exports[`PoolDetailsPage pool header is displayed when data is received from the
</div>
</div>
<div
class="c3 c16"
class="c18"
>
<div
class="c0 c1 c17"
>
<button
class="c18 c19"
data-testid="pool-details-add-liquidity-button"
size="1"
class="c9 css-15popx1"
>
<div
class="c20 c21"
class="c19 c20 c21 c22"
/>
Add liquidity
</button>
<button
class="c18 c19"
data-testid="pool-details-swap-button"
size="1"
>
</div>
<div
class="c20 c21"
class="c23"
/>
Swap
</button>
</div>
<div
class="c3 c22"
class="c24"
>
<div>
<div
class="c23 css-vurnku"
class="c25"
>
Stats
</div>
<div
class="c3 c24"
<svg
height="160"
width="416"
xmlns="http://www.w3.org/2000/svg"
>
<div
class="c6 css-1urox24"
<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"
>
Pool balances
</div>
<div
class="c0 c1 c25"
<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"
>
<div
class="c0 c1 c26"
<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"
>
90.93M USDC
</div>
<div
class="c0 c1 c26"
<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"
>
82,526.49 WETH
<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
class="c0 c1"
data-testid="pool-balance-chart"
>
<div
class="c27"
/>
<div
class="c28"
/>
</div>
</div>
<hr
class="c26"
/>
<div
class="c3 c24"
>
class="c19 c27"
/>
<div
class="c6 css-1urox24"
class="c3 c28"
>
TVL
</div>
<div
class="c0 c1 c29"
>
<div
class="c30 css-vurnku"
class="c8 c30 css-1urox24"
>
$223.2M
</div>
<div
class="c31 c32"
width="max-content"
class="c0 c1"
>
<svg
aria-label="down"
class="c33"
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"
>
<path
d="M10.6979 16.2453L6.31787 9.75247C5.58184 8.66118 6.2058 7 7.35185 7L16.6482 7C17.7942 7 18.4182 8.66243 17.6821 9.75247L13.3021 16.2453C12.623 17.2516 11.377 17.2516 10.6979 16.2453Z"
fill="currentColor"
<line
x1="12"
x2="12"
y1="5"
y2="19"
/>
<polyline
points="19 12 12 19 5 12"
/>
</svg>
Time
</div>
</div>
<div
class="c6 css-1urox24"
class="c8 c31 css-1urox24"
>
0.37%
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"
>
Maker
</div>
<div
class="c3 c24"
class="c8 c34 css-1urox24"
>
Txn
</div>
</div>
<div
class="c6 css-1urox24"
class="c0 c1 c35"
>
24H volume
<div
class="c8 c30 css-1urox24"
>
<div
class="c19 c33"
/>
</div>
<div
class="c0 c1 c29"
class="c8 c31 css-1urox24"
>
<div
class="c30 css-vurnku"
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
$233.4M
<div
class="c19 c33"
/>
</div>
<div
class="c31 c32"
width="max-content"
class="c8 c32 css-1urox24"
>
<svg
aria-label="down"
class="c33"
fill="none"
height="16"
viewBox="0 0 24 24"
width="16"
xmlns="http://www.w3.org/2000/svg"
<div
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
<path
d="M10.6979 16.2453L6.31787 9.75247C5.58184 8.66118 6.2058 7 7.35185 7L16.6482 7C17.7942 7 18.4182 8.66243 17.6821 9.75247L13.3021 16.2453C12.623 17.2516 11.377 17.2516 10.6979 16.2453Z"
fill="currentColor"
<div
class="c19 c33"
/>
</svg>
</div>
<div
class="c6 css-1urox24"
class="c8 c32 css-1urox24"
>
17.75%
<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="c3 c24"
class="c8 c31 css-1urox24"
>
<div
class="c6 css-1urox24"
class="c19 c33"
/>
</div>
<div
class="c8 c32 css-1urox24"
>
24H fees
<div
class="c19 c33"
/>
</div>
<div
class="c0 c1 c29"
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 c37"
>
<div
class="c0 c1 c38"
>
<button
class="c39 c40"
data-testid="pool-details-add-liquidity-button"
size="1"
>
<div
class="c41 c42"
/>
Add liquidity
</button>
<button
class="c39 c40"
data-testid="pool-details-swap-button"
size="1"
>
<div
class="c41 c42"
/>
Swap
</button>
</div>
<div
class="c3 c43"
>
<div
class="c44 css-vurnku"
>
Stats
</div>
<div
class="c3 c45"
>
<div
class="c8 css-1urox24"
>
Pool balances
</div>
<div
class="c0 c1 c46"
>
<div
class="c0 c1 c47"
>
90.93M USDC
</div>
<div
class="c0 c1 c47"
>
82,526.49 WETH
</div>
</div>
<div
class="c0 c1"
data-testid="pool-balance-chart"
>
<div
class="c48"
/>
<div
class="c49"
/>
</div>
</div>
<div
class="c3 c45"
>
<div
class="c8 css-1urox24"
>
TVL
</div>
<div
class="c0 c1 c50"
>
<div
class="c51 css-vurnku"
>
$223.2M
</div>
<div
class="c52 c53"
width="max-content"
>
<svg
aria-label="down"
class="c54"
fill="none"
height="16"
viewBox="0 0 24 24"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M10.6979 16.2453L6.31787 9.75247C5.58184 8.66118 6.2058 7 7.35185 7L16.6482 7C17.7942 7 18.4182 8.66243 17.6821 9.75247L13.3021 16.2453C12.623 17.2516 11.377 17.2516 10.6979 16.2453Z"
fill="currentColor"
/>
</svg>
<div
class="c8 css-1urox24"
>
0.37%
</div>
</div>
</div>
</div>
<div
class="c3 c45"
>
<div
class="c8 css-1urox24"
>
24H volume
</div>
<div
class="c0 c1 c50"
>
<div
class="c51 css-vurnku"
>
$233.4M
</div>
<div
class="c52 c53"
width="max-content"
>
<svg
aria-label="down"
class="c54"
fill="none"
height="16"
viewBox="0 0 24 24"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M10.6979 16.2453L6.31787 9.75247C5.58184 8.66118 6.2058 7 7.35185 7L16.6482 7C17.7942 7 18.4182 8.66243 17.6821 9.75247L13.3021 16.2453C12.623 17.2516 11.377 17.2516 10.6979 16.2453Z"
fill="currentColor"
/>
</svg>
<div
class="c8 css-1urox24"
>
17.75%
</div>
</div>
</div>
</div>
<div
class="c3 c45"
>
<div
class="c8 css-1urox24"
>
24H fees
</div>
<div
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,11 +112,11 @@ 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>
<LeftColumn>
<Column gap="sm">
<PoolDetailsHeader
chainId={chainId}
poolAddress={poolAddress}
......@@ -91,11 +124,35 @@ export default function PoolDetailsPage() {
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) && (
<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>
......@@ -103,7 +160,7 @@ export default function PoolDetailsPage() {
{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