fix(L2): Design tweaks for L2 (Optimism) (#2038)

Style tweaks to header layout, network dropdown and pool pages

Co-authored-by: Jordan Frankfurt <jordanwfrankfurt@gmail.com>
This commit is contained in:
Callil Capuozzo 2021-07-13 15:08:23 -04:00 committed by GitHub
parent 730af2eed4
commit e1c3ad8f54
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 295 additions and 307 deletions

@ -41,10 +41,6 @@ const Base = styled(RebassButton)<
transition: transform 450ms ease;
transform: perspective(1px) translateZ(0);
&:hover {
transform: scale(0.99);
}
> * {
user-select: none;
}

@ -3,32 +3,24 @@ import { YellowCard } from 'components/Card'
import { useOnClickOutside } from 'hooks/useOnClickOutside'
import { useActiveWeb3React } from 'hooks/web3'
import { useEffect, useRef, useState } from 'react'
import { ArrowDownCircle } from 'react-feather'
import { ArrowDownCircle, ChevronDown, ToggleLeft } from 'react-feather'
import { ApplicationModal } from 'state/application/actions'
import { useModalOpen, useToggleModal } from 'state/application/hooks'
import styled, { css } from 'styled-components/macro'
import { ExternalLink, MEDIA_WIDTHS } from 'theme'
import { ExternalLink } from 'theme'
import { switchToNetwork } from 'utils/switchToNetwork'
import { CHAIN_INFO, L2_CHAIN_IDS, NETWORK_LABELS, SupportedChainId, SupportedL2ChainId } from '../../constants/chains'
const StopOverflowQuery = `@media screen and (min-width: ${MEDIA_WIDTHS.upToMedium + 1}px) and (max-width: ${
MEDIA_WIDTHS.upToMedium + 500
}px)`
const BaseWrapper = css`
position: relative;
${StopOverflowQuery} {
position: absolute;
top: 66px;
right: 16px;
}
margin-right: 8px;
${({ theme }) => theme.mediaWidth.upToMedium`
margin-left: 12px;
justify-self: end;
`};
${({ theme }) => theme.mediaWidth.upToSmall`
margin: 0 0.5rem 0 0;
width: initial;
overflow: hidden;
text-overflow: ellipsis;
flex-shrink: 1;
`};
@ -45,7 +37,7 @@ const BaseMenuItem = css`
display: flex;
flex: 1;
flex-direction: row;
font-size: 14px;
font-size: 16px;
font-weight: 400;
justify-content: space-between;
:hover {
@ -73,28 +65,26 @@ const FallbackWrapper = styled(YellowCard)`
width: auto;
border-radius: 12px;
padding: 8px 12px;
width: 100%;
`
const Icon = styled.img`
width: 17px;
`
const L1Tag = styled.div`
color: #c4d9f8;
opacity: 40%;
`
const L2Tag = styled.div<{ chainId: SupportedL2ChainId }>`
background-color: ${({ chainId }) => (chainId === SupportedChainId.ARBITRUM_ONE ? '#28A0F0' : '#FF0420')};
border-radius: 6px;
color: white;
font-size: 12px;
font-weight: 600;
padding: 2px 6px;
width: 16px;
margin-right: 2px;
${({ theme }) => theme.mediaWidth.upToSmall`
margin-right: 4px;
`};
`
const MenuFlyout = styled.span`
background-color: ${({ theme }) => theme.bg2};
background-color: ${({ theme }) => theme.bg1};
border: 1px solid ${({ theme }) => theme.bg0};
box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.01), 0px 4px 8px rgba(0, 0, 0, 0.04), 0px 16px 24px rgba(0, 0, 0, 0.04),
0px 24px 32px rgba(0, 0, 0, 0.01);
border-radius: 20px;
padding: 12px;
border-radius: 12px;
padding: 1rem;
display: flex;
flex-direction: column;
font-size: 1rem;
@ -104,7 +94,11 @@ const MenuFlyout = styled.span`
z-index: 100;
width: 237px;
${({ theme }) => theme.mediaWidth.upToMedium`
top: -10.25rem;
bottom: unset;
top: 4.5em
right: 0;
`};
> {
padding: 12px;
@ -115,15 +109,12 @@ const MenuFlyout = styled.span`
> :not(:last-child) {
margin-bottom: 8px;
}
${StopOverflowQuery} {
left: unset;
right: 0rem;
}
`
const LinkOutCircle = styled(ArrowDownCircle)`
transform: rotate(230deg);
width: 20px;
height: 20px;
width: 16px;
height: 16px;
opacity: 0.6;
`
const MenuItem = styled(ExternalLink)`
${BaseMenuItem}
@ -134,33 +125,40 @@ const ButtonMenuItem = styled.button`
box-shadow: none;
color: ${({ theme }) => theme.text2};
outline: none;
padding-left: 0;
padding: 0;
`
const NetworkInfo = styled.button`
const NetworkInfo = styled.button<{ chainId: SupportedChainId }>`
align-items: center;
background-color: ${({ theme }) => theme.bg2};
border-radius: 8px;
border: none;
background-color: ${({ theme }) => theme.bg0};
border-radius: 12px;
border: 1px solid ${({ theme }) => theme.bg0};
color: ${({ theme }) => theme.text1};
display: flex;
flex-direction: row;
font-weight: 500;
font-size: 12px;
height: 100%;
justify-content: space-between;
margin: 0;
padding: 8px;
width: 188px;
height: 38px;
padding: 0.7rem;
:hover,
:focus {
cursor: pointer;
outline: none;
background-color: ${({ theme }) => theme.bg3};
border: 1px solid ${({ theme }) => theme.bg3};
}
`
const NetworkLabel = styled.span`
flex: 1 1 auto;
const NetworkName = styled.div<{ chainId: SupportedChainId }>`
border-radius: 6px;
font-size: 16px;
font-weight: 500;
padding: 0 2px 0.5px 4px;
margin: 0 2px;
white-space: pre;
${({ theme }) => theme.mediaWidth.upToSmall`
display: none;
`};
`
export default function NetworkCard() {
@ -192,19 +190,19 @@ export default function NetworkCard() {
const isArbitrum = [SupportedChainId.ARBITRUM_ONE, SupportedChainId.ARBITRUM_RINKEBY].includes(chainId)
return (
<L2Wrapper ref={node}>
<NetworkInfo onClick={toggle}>
<NetworkInfo onClick={toggle} chainId={chainId}>
<Icon src={info.logoUrl} />
<NetworkLabel>{info.label}</NetworkLabel>
<L2Tag chainId={chainId}>L2</L2Tag>
<NetworkName chainId={chainId}>{info.label}</NetworkName>
<ChevronDown size={16} style={{ marginTop: '2px' }} strokeWidth={2.5} />
</NetworkInfo>
{open && (
<MenuFlyout>
<MenuItem href={info.bridge}>
<div>{isArbitrum ? <Trans>{info.label} Bridge</Trans> : <Trans>Optimism Gateway</Trans>}</div>
<div>{isArbitrum ? <Trans>{info.label} Bridge</Trans> : <Trans>Optimistic L2 Gateway</Trans>}</div>
<LinkOutCircle />
</MenuItem>
<MenuItem href={info.explorer}>
{isArbitrum ? <Trans>{info.label} Explorer</Trans> : <Trans>Etherscan</Trans>}
{isArbitrum ? <Trans>{info.label} Explorer</Trans> : <Trans>Optimistic Etherscan</Trans>}
<LinkOutCircle />
</MenuItem>
<MenuItem href={info.docs}>
@ -216,9 +214,9 @@ export default function NetworkCard() {
{implements3085 ? (
<ButtonMenuItem onClick={() => switchToNetwork({ library, chainId: SupportedChainId.MAINNET })}>
<div>
<Trans>Switch to Ethereum</Trans>
<Trans>Switch to L1 (Mainnet)</Trans>
</div>
<L1Tag>L1</L1Tag>
<ToggleLeft opacity={0.6} size={16} />
</ButtonMenuItem>
) : (
<DisabledMenuItem>

@ -3,7 +3,6 @@ import useScrollPosition from '@react-hook/window-scroll'
import { CHAIN_INFO, SupportedChainId } from 'constants/chains'
import { darken } from 'polished'
import { useState } from 'react'
import { Moon, Sun } from 'react-feather'
import { NavLink } from 'react-router-dom'
import { Text } from 'rebass'
import { useShowClaimPopup, useToggleSelfClaimModal } from 'state/application/hooks'
@ -20,7 +19,7 @@ import ClaimModal from '../claim/ClaimModal'
import { CardNoise } from '../earn/styled'
import Menu from '../Menu'
import Modal from '../Modal'
import Row, { RowFixed } from '../Row'
import Row from '../Row'
import { Dots } from '../swap/styleds'
import Web3Status from '../Web3Status'
import NetworkCard from './NetworkCard'
@ -39,22 +38,27 @@ const HeaderFrame = styled.div<{ showBackground: boolean }>`
padding: 1rem;
z-index: 21;
position: relative;
/* Background slide effect on scroll. */
background-image: ${({ theme }) => `linear-gradient(to bottom, transparent 50%, ${theme.bg0} 50% )}}`}
background-image: ${({ theme }) => `linear-gradient(to bottom, transparent 50%, ${theme.bg0} 50% )}}`};
background-position: ${({ showBackground }) => (showBackground ? '0 -100%' : '0 0')};
background-size: 100% 200%;
box-shadow: 0px 0px 0px 1px ${({ theme, showBackground }) => (showBackground ? theme.bg2 : 'transparent;')};
transition: background-position .1s, box-shadow .1s;
transition: background-position 0.1s, box-shadow 0.1s;
background-blend-mode: hard-light;
${({ theme }) => theme.mediaWidth.upToLarge`
grid-template-columns: 48px 1fr 1fr;
`};
${({ theme }) => theme.mediaWidth.upToMedium`
padding: 1rem;
grid-template-columns: auto 1fr;
grid-template-columns: 1fr 1fr;
`};
${({ theme }) => theme.mediaWidth.upToExtraSmall`
padding: 1rem;
`}
${({ theme }) => theme.mediaWidth.upToSmall`
padding: 1rem;
grid-template-columns: 36px 1fr;
`};
`
const HeaderControls = styled.div`
@ -62,23 +66,6 @@ const HeaderControls = styled.div`
flex-direction: row;
align-items: center;
justify-self: flex-end;
${({ theme }) => theme.mediaWidth.upToMedium`
flex-direction: row;
justify-content: space-between;
justify-self: center;
width: 100%;
max-width: 960px;
padding: 1rem;
position: fixed;
bottom: 0px;
left: 0px;
width: 100%;
z-index: 99;
height: 72px;
border-radius: 12px 12px 0 0;
background-color: ${({ theme }) => theme.bg1};
`};
`
const HeaderElement = styled.div`
@ -91,22 +78,10 @@ const HeaderElement = styled.div`
}
${({ theme }) => theme.mediaWidth.upToMedium`
flex-direction: row-reverse;
align-items: center;
`};
`
const HeaderElementWrap = styled.div`
display: flex;
align-items: center;
`
const HeaderRow = styled(RowFixed)`
${({ theme }) => theme.mediaWidth.upToMedium`
width: 100%;
`};
`
const HeaderLinks = styled(Row)`
justify-self: center;
background-color: ${({ theme }) => theme.bg0};
@ -117,8 +92,25 @@ const HeaderLinks = styled(Row)`
grid-auto-flow: column;
grid-gap: 10px;
overflow: auto;
align-items: center;
${({ theme }) => theme.mediaWidth.upToLarge`
justify-self: start;
`};
${({ theme }) => theme.mediaWidth.upToMedium`
justify-self: flex-end;
justify-self: center;
`};
${({ theme }) => theme.mediaWidth.upToMedium`
flex-direction: row;
justify-content: space-between;
justify-self: center;
z-index: 99;
position: fixed;
bottom: 0; right: 50%;
transform: translate(50%,-50%);
margin: 0 auto;
background-color: ${({ theme }) => theme.bg0};
border: 1px solid ${({ theme }) => theme.bg2};
box-shadow: 0px 6px 10px rgb(0 0 0 / 2%);
`};
`
@ -126,7 +118,7 @@ const AccountElement = styled.div<{ active: boolean }>`
display: flex;
flex-direction: row;
align-items: center;
background-color: ${({ theme, active }) => (!active ? theme.bg1 : theme.bg2)};
background-color: ${({ theme, active }) => (!active ? theme.bg1 : theme.bg1)};
border-radius: 12px;
white-space: nowrap;
width: 100%;
@ -160,12 +152,6 @@ const UNIWrapper = styled.span`
}
`
const HideSmall = styled.span`
${({ theme }) => theme.mediaWidth.upToSmall`
display: none;
`};
`
const BalanceText = styled(Text)`
${({ theme }) => theme.mediaWidth.upToExtraSmall`
display: none;
@ -250,47 +236,13 @@ const StyledExternalLink = styled(ExternalLink).attrs({
color: ${({ theme }) => darken(0.1, theme.text1)};
text-decoration: none;
}
${({ theme }) => theme.mediaWidth.upToExtraSmall`
display: none;
`}
`
const StyledMenuButton = styled.button`
position: relative;
width: 100%;
height: 100%;
border: none;
background-color: transparent;
margin: 0;
padding: 0;
height: 35px;
background-color: ${({ theme }) => theme.bg2};
margin-left: 8px;
padding: 0.15rem 0.5rem;
border-radius: 0.5rem;
:hover,
:focus {
cursor: pointer;
outline: none;
background-color: ${({ theme }) => theme.bg4};
}
svg {
margin-top: 2px;
}
> * {
stroke: ${({ theme }) => theme.text1};
}
`
export default function Header() {
const { account, chainId } = useActiveWeb3React()
const userEthBalance = useETHBalances(account ? [account] : [])?.[account ?? '']
// const [isDark] = useDarkModeManager()
const [darkMode, toggleDarkMode] = useDarkModeManager()
const [darkMode] = useDarkModeManager()
const toggleClaimModal = useToggleSelfClaimModal()
@ -310,13 +262,11 @@ export default function Header() {
<Modal isOpen={showUniBalanceModal} onDismiss={() => setShowUniBalanceModal(false)}>
<UniBalanceContent setShowUniBalanceModal={setShowUniBalanceModal} />
</Modal>
<HeaderRow>
<Title href=".">
<UniIcon>
<img width={'24px'} src={darkMode ? LogoDark : Logo} alt="logo" />
</UniIcon>
</Title>
</HeaderRow>
<Title href=".">
<UniIcon>
<img width={'24px'} src={darkMode ? LogoDark : Logo} alt="logo" />
</UniIcon>
</Title>
<HeaderLinks>
<StyledNavLink id={`swap-nav-link`} to={'/swap'}>
<Trans>Swap</Trans>
@ -334,19 +284,20 @@ export default function Header() {
>
<Trans>Pool</Trans>
</StyledNavLink>
<StyledNavLink id={`stake-nav-link`} to={'/vote'}>
<Trans>Vote</Trans>
</StyledNavLink>
{chainId && chainId === SupportedChainId.MAINNET && (
<StyledNavLink id={`stake-nav-link`} to={'/vote'}>
<Trans>Vote</Trans>
</StyledNavLink>
)}
<StyledExternalLink id={`stake-nav-link`} href={infoLink}>
<Trans>Charts</Trans>
<sup></sup>
</StyledExternalLink>
</HeaderLinks>
<HeaderControls>
<NetworkCard />
<HeaderElement>
<HideSmall>
<NetworkCard />
</HideSmall>
{availableClaim && !showClaimPopup && (
<UNIWrapper onClick={toggleClaimModal}>
<UNIAmount active={!!account && !availableClaim} style={{ pointerEvents: 'auto' }}>
@ -371,13 +322,8 @@ export default function Header() {
) : null}
<Web3Status />
</AccountElement>
</HeaderElement>
<HeaderElementWrap>
<StyledMenuButton onClick={() => toggleDarkMode()}>
{darkMode ? <Moon size={20} /> : <Sun size={20} />}
</StyledMenuButton>
<Menu />
</HeaderElementWrap>
</HeaderElement>
</HeaderControls>
</HeaderFrame>
)

@ -1,5 +1,5 @@
import React, { useRef } from 'react'
import { BookOpen, Code, Info, MessageCircle, PieChart } from 'react-feather'
import { BookOpen, Code, Info, MessageCircle, PieChart, Moon, Sun } from 'react-feather'
import { Link } from 'react-router-dom'
import styled, { css } from 'styled-components/macro'
import { ReactComponent as MenuIcon } from '../../assets/images/menu.svg'
@ -10,6 +10,8 @@ import { useModalOpen, useToggleModal } from '../../state/application/hooks'
import { Trans } from '@lingui/macro'
import { ExternalLink } from '../../theme'
import { ButtonPrimary } from '../Button'
import { useDarkModeManager } from 'state/user/hooks'
import { L2_CHAIN_IDS, CHAIN_INFO, SupportedChainId } from 'constants/chains'
export enum FlyoutAlignment {
@ -30,17 +32,18 @@ const StyledMenuButton = styled.button`
background-color: transparent;
margin: 0;
padding: 0;
height: 35px;
background-color: ${({ theme }) => theme.bg2};
height: 38px;
background-color: ${({ theme }) => theme.bg0};
border: 1px solid ${({ theme }) => theme.bg0};
padding: 0.15rem 0.5rem;
border-radius: 0.5rem;
border-radius: 12px;
:hover,
:focus {
cursor: pointer;
outline: none;
background-color: ${({ theme }) => theme.bg3};
border: 1px solid ${({ theme }) => theme.bg3};
}
svg {
@ -65,18 +68,20 @@ const StyledMenu = styled.div`
`
const MenuFlyout = styled.span<{ flyoutAlignment?: FlyoutAlignment }>`
min-width: 8.125rem;
background-color: ${({ theme }) => theme.bg2};
min-width: 196px;
background-color: ${({ theme }) => theme.bg1};
box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.01), 0px 4px 8px rgba(0, 0, 0, 0.04), 0px 16px 24px rgba(0, 0, 0, 0.04),
0px 24px 32px rgba(0, 0, 0, 0.01);
border: 1px solid ${({ theme }) => theme.bg0};
border-radius: 12px;
padding: 0.5rem;
display: flex;
flex-direction: column;
font-size: 1rem;
font-size: 16px;
position: absolute;
top: 3rem;
z-index: 100;
${({ flyoutAlignment = FlyoutAlignment.RIGHT }) =>
flyoutAlignment === FlyoutAlignment.RIGHT
? css`
@ -86,8 +91,9 @@ const MenuFlyout = styled.span<{ flyoutAlignment?: FlyoutAlignment }>`
left: 0rem;
`};
${({ theme }) => theme.mediaWidth.upToMedium`
top: unset;
bottom: 3em
bottom: unset;
right: 0;
left: unset;
`};
`
@ -97,15 +103,13 @@ const MenuItem = styled(ExternalLink)`
flex-direction: row;
align-items: center;
padding: 0.5rem 0.5rem;
justify-content: space-between;
color: ${({ theme }) => theme.text2};
:hover {
color: ${({ theme }) => theme.text1};
cursor: pointer;
text-decoration: none;
}
> svg {
margin-right: 8px;
}
`
const InternalMenuItem = styled(Link)`
@ -122,6 +126,27 @@ const InternalMenuItem = styled(Link)`
}
`
const ToggleMenuItem = styled.button`
background-color: transparent;
margin: 0;
padding: 0;
border: none;
display: flex;
flex: 1;
flex-direction: row;
align-items: center;
padding: 0.5rem 0.5rem;
justify-content: space-between;
font-size: 1rem;
font-weight: 500;
color: ${({ theme }) => theme.text2};
:hover {
color: ${({ theme }) => theme.text1};
cursor: pointer;
text-decoration: none;
}
`
const CODE_LINK = 'https://github.com/Uniswap/uniswap-interface'
export default function Menu() {
@ -134,6 +159,9 @@ export default function Menu() {
const openClaimModal = useToggleModal(ApplicationModal.ADDRESS_CLAIM)
const showUNIClaimOption = Boolean(!!account && !!chainId && !L2_CHAIN_IDS.includes(chainId))
const { infoLink } = CHAIN_INFO[chainId ? chainId : SupportedChainId.MAINNET]
const [darkMode, toggleDarkMode] = useDarkModeManager()
return (
// https://github.com/DefinitelyTyped/DefinitelyTyped/issues/30451
<StyledMenu ref={node as any}>
@ -144,35 +172,39 @@ export default function Menu() {
{open && (
<MenuFlyout>
<MenuItem href="https://uniswap.org/">
<Info size={14} />
<div>
<Trans>About</Trans>
</div>
<Info opacity={0.6} size={16} />
</MenuItem>
<MenuItem href="https://docs.uniswap.org/">
<BookOpen size={14} />
<div>
<Trans>Docs</Trans>
</div>
<BookOpen opacity={0.6} size={16} />
</MenuItem>
<MenuItem href={CODE_LINK}>
<Code size={14} />
<div>
<Trans>Code</Trans>
</div>
<Code opacity={0.6} size={16} />
</MenuItem>
<MenuItem href="https://discord.gg/FCfyBSbCU5">
<MessageCircle size={14} />
<div>
<Trans>Discord</Trans>
</div>
<MessageCircle opacity={0.6} size={16} />
</MenuItem>
<MenuItem href={infoLink}>
<PieChart size={14} />
<div>
<Trans>Analytics</Trans>
</div>
<PieChart opacity={0.6} size={16} />
</MenuItem>
<ToggleMenuItem onClick={() => toggleDarkMode()}>
<div>{darkMode ? <Trans>Light Theme</Trans> : <Trans>Dark Theme</Trans>}</div>
{darkMode ? <Moon opacity={0.6} size={16} /> : <Sun opacity={0.6} size={16} />}
</ToggleMenuItem>
{showUNIClaimOption && (
<UNIbutton onClick={openClaimModal} padding="8px 16px" width="100%" $borderRadius="12px" mt="0.5rem">
<Trans>Claim UNI</Trans>

@ -39,7 +39,7 @@ const StopOverflowQuery = `@media screen and (min-width: ${MEDIA_WIDTHS.upToMedi
const FixedPopupColumn = styled(AutoColumn)<{ extraPadding: boolean; xlPadding: boolean }>`
position: fixed;
top: ${({ extraPadding }) => (extraPadding ? '80px' : '88px')};
top: ${({ extraPadding }) => (extraPadding ? '64px' : '56px')};
right: 1rem;
max-width: 355px !important;
width: 100%;
@ -50,7 +50,7 @@ const FixedPopupColumn = styled(AutoColumn)<{ extraPadding: boolean; xlPadding:
`};
${StopOverflowQuery} {
top: ${({ extraPadding, xlPadding }) => (xlPadding ? '112px' : extraPadding ? '80px' : '88px')};
top: ${({ extraPadding, xlPadding }) => (xlPadding ? '64px' : extraPadding ? '64px' : '56px')};
}
`

@ -47,7 +47,7 @@ export default function PositionList({ positions }: PositionListProps) {
{positions && ' (' + positions.length + ')'}
</div>
<div>
<Trans>Price range</Trans>
<Trans>Status</Trans>
</div>
</DesktopHeader>
<MobileHeader>

@ -13,7 +13,7 @@ import { formatTickPrice } from 'utils/formatTickPrice'
import Loader from 'components/Loader'
import { unwrappedToken } from 'utils/unwrappedToken'
import RangeBadge from 'components/Badge/RangeBadge'
import { RowFixed } from 'components/Row'
import { RowBetween } from 'components/Row'
import HoverInlineText from 'components/HoverInlineText'
import { DAI, USDC, USDT, WBTC, WETH9_EXTENDED } from '../../constants/tokens'
import { Trans } from '@lingui/macro'
@ -26,6 +26,9 @@ const LinkRow = styled(Link)`
display: flex;
cursor: pointer;
user-select: none;
display: flex;
flex-direction: column;
justify-content: space-between;
color: ${({ theme }) => theme.text1};
margin: 8px 0;
@ -34,25 +37,23 @@ const LinkRow = styled(Link)`
font-weight: 500;
background-color: ${({ theme }) => theme.bg1};
&:first-of-type {
margin: 0 0 8px 0;
}
&:last-of-type {
margin: 8px 0 0 0;
}
& > div:not(:first-child) {
text-align: right;
text-align: center;
}
:hover {
background-color: ${({ theme }) => theme.bg2};
}
@media screen and (min-width: ${MEDIA_WIDTHS.upToSmall}px) {
flex-direction: row;
/* flex-direction: row; */
}
${({ theme }) => theme.mediaWidth.upToSmall`
flex-direction: column;
row-gap: 24px;
row-gap: 12px;
`};
`
@ -72,11 +73,14 @@ const RangeLineItem = styled(DataLineItem)`
display: flex;
flex-direction: row;
align-items: center;
justify-self: flex-end;
margin-top: 4px;
width: 100%;
${({ theme }) => theme.mediaWidth.upToSmall`
flex-direction: column;
row-gap: 4px;
background-color: ${({ theme }) => theme.bg2};
border-radius: 12px;
padding: 8px 0;
`};
`
@ -99,6 +103,9 @@ const ExtentsText = styled.span`
color: ${({ theme }) => theme.text3};
font-size: 14px;
margin-right: 4px;
${({ theme }) => theme.mediaWidth.upToSmall`
display: none;
`};
`
const PrimaryPositionIdData = styled.div`
@ -220,7 +227,7 @@ export default function PositionListItem({ positionDetails }: PositionListItemPr
return (
<LinkRow to={positionSummaryLink}>
<RowFixed>
<RowBetween>
<PrimaryPositionIdData>
<DoubleCurrencyLogo currency0={currencyBase} currency1={currencyQuote} size={18} margin />
<DataText>
@ -234,7 +241,7 @@ export default function PositionListItem({ positionDetails }: PositionListItemPr
</Badge>
</PrimaryPositionIdData>
<RangeBadge removed={removed} inRange={!outOfRange} />
</RowFixed>
</RowBetween>
{priceLower && priceUpper ? (
<RangeLineItem>
@ -251,7 +258,7 @@ export default function PositionListItem({ positionDetails }: PositionListItemPr
<DoubleArrow></DoubleArrow>{' '}
</HideSmall>
<SmallOnly>
<DoubleArrow></DoubleArrow>{' '}
<DoubleArrow></DoubleArrow>{' '}
</SmallOnly>
<RangeText>
<ExtentsText>

@ -8,7 +8,7 @@ const ToggleElement = styled.span<{ isActive?: boolean; isOnSwitch?: boolean }>`
border-radius: 9px;
background: ${({ theme, isActive, isOnSwitch }) => (isActive ? (isOnSwitch ? theme.primary1 : theme.bg4) : 'none')};
color: ${({ theme, isActive }) => (isActive ? theme.white : theme.text2)};
font-size: 1rem;
font-size: 14px;
font-weight: ${({ isOnSwitch }) => (isOnSwitch ? '500' : '400')};
:hover {
user-select: ${({ isOnSwitch }) => (isOnSwitch ? 'none' : 'initial')};
@ -20,9 +20,8 @@ const ToggleElement = styled.span<{ isActive?: boolean; isOnSwitch?: boolean }>`
const StyledToggle = styled.button<{ isActive?: boolean; activeElement?: boolean }>`
border-radius: 12px;
border: 2px solid;
border-color: ${({ theme, isActive }) => (isActive ? theme.primary1 : theme.bg3)};
background: ${({ theme }) => theme.bg1};
border: none;
background: ${({ theme }) => theme.bg0};
display: flex;
width: fit-content;
cursor: pointer;

@ -1,6 +1,6 @@
import { AbstractConnector } from '@web3-react/abstract-connector'
import { UnsupportedChainIdError, useWeb3React } from '@web3-react/core'
import { darken, lighten } from 'polished'
import { darken } from 'polished'
import { useMemo } from 'react'
import { Activity } from 'react-feather'
import { t, Trans } from '@lingui/macro'
@ -61,6 +61,7 @@ const Web3StatusError = styled(Web3StatusGeneric)`
const Web3StatusConnect = styled(Web3StatusGeneric)<{ faded?: boolean }>`
background-color: ${({ theme }) => theme.primary4};
border: none;
color: ${({ theme }) => theme.primaryText1};
font-weight: 500;
@ -86,13 +87,13 @@ const Web3StatusConnect = styled(Web3StatusGeneric)<{ faded?: boolean }>`
`
const Web3StatusConnected = styled(Web3StatusGeneric)<{ pending?: boolean }>`
background-color: ${({ pending, theme }) => (pending ? theme.primary1 : theme.bg1)};
border: 1px solid ${({ pending, theme }) => (pending ? theme.primary1 : theme.bg2)};
background-color: ${({ pending, theme }) => (pending ? theme.primary1 : theme.bg0)};
border: 1px solid ${({ pending, theme }) => (pending ? theme.primary1 : theme.bg1)};
color: ${({ pending, theme }) => (pending ? theme.white : theme.text1)};
font-weight: 500;
:hover,
:focus {
background-color: ${({ pending, theme }) => (pending ? darken(0.05, theme.primary1) : lighten(0.05, theme.bg1))};
border: 1px solid ${({ theme }) => darken(0.05, theme.bg3)};
:focus {
border: 1px solid ${({ pending, theme }) => (pending ? darken(0.1, theme.primary1) : darken(0.1, theme.bg2))};

@ -35,7 +35,7 @@ export const NETWORK_LABELS: { [chainId in SupportedChainId | number]: string }
[SupportedChainId.KOVAN]: 'Kovan',
[SupportedChainId.ARBITRUM_ONE]: 'Arbitrum',
[SupportedChainId.ARBITRUM_RINKEBY]: 'Arbitrum Rinkeby',
[SupportedChainId.OPTIMISM]: 'Optimistic Ethereum',
[SupportedChainId.OPTIMISM]: 'Optimism',
[SupportedChainId.OPTIMISTIC_KOVAN]: 'Optimistic Kovan',
} as const

@ -1,13 +1,11 @@
import { Trans } from '@lingui/macro'
import { AutoColumn } from 'components/Column'
import { MinimalNetworkAlert } from 'components/NetworkAlert/MinimalNetworkAlert'
import { RowBetween } from 'components/Row'
import { CHAIN_INFO, SupportedChainId } from 'constants/chains'
import { useActiveWeb3React } from 'hooks/web3'
import styled from 'styled-components/macro'
import { TYPE } from 'theme'
import Texture from '../../assets/images/sandtexture.webp'
import Squiggle from '../../assets/images/squiggle.png'
import { ExternalLink } from '../../theme'
const CTASection = styled.section`
@ -23,17 +21,22 @@ const CTASection = styled.section`
`
const CTA1 = styled(ExternalLink)`
background-size: 40px 40px;
background-image: linear-gradient(to right, ${({ theme }) => theme.bg3} 1px, transparent 1px),
linear-gradient(to bottom, ${({ theme }) => theme.bg3} 1px, transparent 1px);
background-color: ${({ theme }) => theme.bg2};
padding: 32px;
background: radial-gradient(
92.78% 103.09% at 50.06% 7.22%,
rgba(255, 58, 212, 0.072) 0%,
rgba(255, 255, 255, 0.042) 100%
),
radial-gradient(100% 97.16% at 0% 12.22%, rgba(235, 0, 255, 0.2) 0%, rgba(243, 19, 19, 0.2) 100%);
padding: 2rem;
border-radius: 20px;
display: flex;
flex-direction: column;
position: relative;
justify-content: space-between;
border: 1px solid ${({ theme }) => theme.bg3};
align-items: center;
overflow: hidden;
border: 1px solid transparent;
* {
color: ${({ theme }) => theme.text1};
@ -41,17 +44,25 @@ const CTA1 = styled(ExternalLink)`
}
:hover {
border: 1px solid ${({ theme }) => theme.bg5};
background-color: ${({ theme }) => theme.bg2};
border: 1px solid ${({ theme }) => theme.bg0};
text-decoration: none;
* {
text-decoration: none !important;
}
}
${({ theme }) => theme.mediaWidth.upToMedium`
padding: 1rem;
`};
:before {
content: '';
position: absolute;
width: 800%;
height: 480%;
top: -390px;
left: -310px;
z-index: -1;
opacity: 0.4;
background: url(${Texture}) 0 0 repeat;
transform: rotate(-4deg);
}
`
const CTA2 = styled(ExternalLink)`
@ -62,7 +73,7 @@ const CTA2 = styled(ExternalLink)`
display: flex;
flex-direction: column;
justify-content: space-between;
border: 1px solid ${({ theme }) => theme.bg4};
border: 1px solid transparent;
* {
color: ${({ theme }) => theme.text1};
@ -70,8 +81,7 @@ const CTA2 = styled(ExternalLink)`
}
:hover {
border: 1px solid ${({ theme }) => theme.bg5};
opacity: 0.7;
border: 1px solid ${({ theme }) => theme.bg0};
text-decoration: none !important;
* {
text-decoration: none !important;
@ -83,8 +93,9 @@ const CTA2 = styled(ExternalLink)`
position: absolute;
width: 340%;
height: 280%;
top: -130%;
top: -170%;
left: -134%;
opacity: 0.4;
z-index: -1;
background: url(${Texture}) 0 0 repeat;
transform: rotate(-4deg);
@ -104,6 +115,7 @@ const HeaderText = styled(TYPE.label)`
const ResponsiveColumn = styled(AutoColumn)`
grid-template-columns: 1fr;
width: 100%;
gap: 12px;
${({ theme }) => theme.mediaWidth.upToMedium`
gap: 8px;
@ -111,15 +123,6 @@ const ResponsiveColumn = styled(AutoColumn)`
justify-content: space-between;
`
const StyledImage = styled.img`
height: 114px;
margin-top: -28px;
${({ theme }) => theme.mediaWidth.upToMedium`
height: 80px;
padding-right: 1rem;
`};
`
export default function CTACards() {
const { chainId } = useActiveWeb3React()
const { infoLink } = CHAIN_INFO[chainId ? chainId : SupportedChainId.MAINNET]
@ -127,29 +130,24 @@ export default function CTACards() {
<div>
<MinimalNetworkAlert />
<CTASection>
<CTA1 href={'https://docs.uniswap.org/protocol/concepts/introduction/liquidity-user-guide'}>
<CTA1 href={'https://help.uniswap.org/en/articles/5391541-providing-liquidity-on-uniswap-v3'}>
<ResponsiveColumn>
<HeaderText>
<Trans>Uniswap V3 is here!</Trans>
<Trans>Learn about providing liquidity</Trans>
</HeaderText>
<TYPE.body fontWeight={300} style={{ alignItems: 'center', display: 'flex', maxWidth: '80%' }}>
<Trans>Check out our v3 LP walkthrough and migration guides.</Trans>
</TYPE.body>
<RowBetween align="flex-end">
<HeaderText></HeaderText>
<StyledImage src={Squiggle} />
</RowBetween>
</ResponsiveColumn>
</CTA1>
<CTA2 href={infoLink + '/pools'}>
<CTA2 href={infoLink + 'pools'}>
<ResponsiveColumn>
<HeaderText style={{ alignSelf: 'flex-start' }}>
<Trans>Top pools</Trans>
<Trans>Top pools</Trans>
</HeaderText>
<TYPE.body fontWeight={300} style={{ alignSelf: 'flex-start' }}>
<Trans>Explore popular pools on Uniswap Analytics.</Trans>
</TYPE.body>
<HeaderText style={{ alignSelf: 'flex-end' }}></HeaderText>
</ResponsiveColumn>
</CTA2>
</CTASection>

@ -6,12 +6,11 @@ import { SwapPoolTabs } from 'components/NavigationTabs'
import PositionList from 'components/PositionList'
import { RowBetween, RowFixed } from 'components/Row'
import { SwitchLocaleLink } from 'components/SwitchLocaleLink'
import Toggle from 'components/Toggle'
import { L2_CHAIN_IDS } from 'constants/chains'
import { useV3Positions } from 'hooks/useV3Positions'
import { useActiveWeb3React } from 'hooks/web3'
import { useContext } from 'react'
import { BookOpen, ChevronDown, ChevronsRight, Download, Inbox, Layers, PlusCircle } from 'react-feather'
import { BookOpen, ChevronDown, ChevronsRight, Inbox, Layers, PlusCircle } from 'react-feather'
import { Link } from 'react-router-dom'
import { useWalletModalToggle } from 'state/application/hooks'
import { useUserHideClosedPositions } from 'state/user/hooks'
@ -39,17 +38,18 @@ const TitleRow = styled(RowBetween)`
flex-wrap: wrap;
gap: 12px;
width: 100%;
flex-direction: column-reverse;
`};
`
const ButtonRow = styled(RowFixed)`
& > *:not(:last-child) {
margin-right: 8px;
margin-left: 8px;
}
${({ theme }) => theme.mediaWidth.upToSmall`
width: 100%;
flex-direction: row;
justify-content: space-between;
flex-direction: row-reverse;
`};
`
const Menu = styled(NewMenu)`
@ -57,17 +57,27 @@ const Menu = styled(NewMenu)`
${({ theme }) => theme.mediaWidth.upToSmall`
flex: 1 1 auto;
width: 49%;
right: 0px;
`};
a {
width: 100%;
}
`
const MenuItem = styled.div`
align-items: center;
display: flex;
justify-content: flex-start;
justify-content: space-between;
width: 100%;
font-weight: 500;
`
const MoreOptionsButton = styled(ButtonGray)`
border-radius: 12px;
flex: 1 1 auto;
padding: 6px 8px;
width: 100%;
background-color: ${({ theme }) => theme.bg0};
margin-right: 8px;
`
const NoLiquidity = styled.div`
align-items: center;
@ -84,7 +94,7 @@ const ResponsiveButtonPrimary = styled(ButtonPrimary)`
width: fit-content;
${({ theme }) => theme.mediaWidth.upToSmall`
flex: 1 1 auto;
width: 49%;
width: 100%;
`};
`
@ -97,13 +107,22 @@ const MainContentWrapper = styled.main`
`
const ShowInactiveToggle = styled.div`
display: grid;
display: flex;
align-items: center;
justify-items: end;
grid-template-columns: 1fr auto;
grid-column-gap: 8px;
grid-column-gap: 4px;
padding: 0 8px;
${({ theme }) => theme.mediaWidth.upToMedium`
margin-bottom: 12px;
`};
`
const ResponsiveRow = styled(RowFixed)`
justify-content: space-between;
width: 100%;
${({ theme }) => theme.mediaWidth.upToMedium`
flex-direction: column-reverse;
`};
`
export default function Pool() {
@ -131,8 +150,8 @@ export default function Pool() {
{
content: (
<MenuItem>
<PlusCircle size={16} style={{ marginRight: '12px' }} />
<Trans>Create a pool</Trans>
<PlusCircle size={16} />
</MenuItem>
),
link: '/add/ETH',
@ -141,8 +160,8 @@ export default function Pool() {
{
content: (
<MenuItem>
<ChevronsRight size={16} style={{ marginRight: '12px' }} />
<Trans>Migrate</Trans>
<ChevronsRight size={16} />
</MenuItem>
),
link: '/migrate/v2',
@ -151,8 +170,8 @@ export default function Pool() {
{
content: (
<MenuItem>
<Layers size={16} style={{ marginRight: '12px' }} />
<Trans>V2 liquidity</Trans>
<Layers size={16} />
</MenuItem>
),
link: '/pool/v2',
@ -161,8 +180,8 @@ export default function Pool() {
{
content: (
<MenuItem>
<BookOpen size={16} style={{ marginRight: '12px' }} />
<Trans>Learn</Trans>
<BookOpen size={16} />
</MenuItem>
),
link: 'https://docs.uniswap.org/',
@ -177,11 +196,9 @@ export default function Pool() {
<AutoColumn gap="lg" justify="center">
<AutoColumn gap="lg" style={{ width: '100%' }}>
<TitleRow style={{ marginTop: '1rem' }} padding={'0'}>
<HideSmall>
<TYPE.mediumHeader>
<Trans>Pools Overview</Trans>
</TYPE.mediumHeader>
</HideSmall>
<TYPE.body fontSize={'20px'}>
<Trans>Pools Overview</Trans>
</TYPE.body>
<ButtonRow>
{showV2Features && (
<Menu
@ -203,21 +220,9 @@ export default function Pool() {
</ButtonRow>
</TitleRow>
<CTACards />
{closedPositions.length > 0 ? (
<ShowInactiveToggle>
<TYPE.darkGray>
<Trans>Closed positions</Trans>
</TYPE.darkGray>
<Toggle
isActive={!userHideClosedPositions}
toggle={() => setUserHideClosedPositions(!userHideClosedPositions)}
checked={<Trans>Show</Trans>}
unchecked={<Trans>Hide</Trans>}
/>
</ShowInactiveToggle>
) : null}
<HideSmall>
<CTACards />
</HideSmall>
<MainContentWrapper>
{positionsLoading ? (
@ -239,53 +244,27 @@ export default function Pool() {
<PositionList positions={filteredPositions} />
) : (
<NoLiquidity>
<TYPE.mediumHeader color={theme.text3} textAlign="center">
<TYPE.body color={theme.text3} textAlign="center">
<Inbox size={48} strokeWidth={1} style={{ marginBottom: '.5rem' }} />
<div>
<Trans>Your V3 liquidity positions will appear here.</Trans>
</div>
</TYPE.mediumHeader>
</TYPE.body>
{showConnectAWallet && (
<ButtonPrimary style={{ marginTop: '2em', padding: '8px 16px' }} onClick={toggleWalletModal}>
<Trans>Connect a wallet</Trans>
</ButtonPrimary>
)}
{showV2Features && (
<ButtonGray
as={Link}
to="/migrate/v2"
id="import-pool-link"
style={{ marginTop: '2em', padding: '8px 16px', borderRadius: '12px', width: 'fit-content' }}
>
<Trans>Migrate V2 liquidity</Trans>?&nbsp;&nbsp;
<Download size={16} />
</ButtonGray>
)}
</NoLiquidity>
)}
</MainContentWrapper>
{showV2Features && (
<RowFixed justify="center" style={{ width: '100%' }}>
<ButtonOutlined
as={Link}
to="/pool/v2"
id="import-pool-link"
style={{
padding: '8px 16px',
margin: '0 4px',
borderRadius: '12px',
width: 'fit-content',
fontSize: '14px',
}}
>
<Layers size={14} style={{ marginRight: '8px' }} />
<Trans>View V2 Liquidity</Trans>
</ButtonOutlined>
{positions && positions.length > 0 && (
<ResponsiveRow>
{showV2Features && (
<RowFixed>
<ButtonOutlined
as={Link}
to="/migrate/v2"
to="/pool/v2"
id="import-pool-link"
style={{
padding: '8px 16px',
@ -295,13 +274,45 @@ export default function Pool() {
fontSize: '14px',
}}
>
<ChevronsRight size={16} style={{ marginRight: '8px' }} />
<Layers size={14} style={{ marginRight: '8px' }} />
<Trans>Migrate Liquidity</Trans>
<Trans>View V2 Liquidity</Trans>
</ButtonOutlined>
)}
</RowFixed>
)}
{positions && positions.length > 0 && (
<ButtonOutlined
as={Link}
to="/migrate/v2"
id="import-pool-link"
style={{
padding: '8px 16px',
margin: '0 4px',
borderRadius: '12px',
width: 'fit-content',
fontSize: '14px',
}}
>
<ChevronsRight size={16} style={{ marginRight: '8px' }} />
<Trans>Migrate Liquidity</Trans>
</ButtonOutlined>
)}
</RowFixed>
)}
{closedPositions.length > 0 ? (
<ShowInactiveToggle>
<label>
<TYPE.body onClick={() => setUserHideClosedPositions(!userHideClosedPositions)}>
<Trans>Show closed positions</Trans>
</TYPE.body>
</label>
<input
type="checkbox"
onClick={() => setUserHideClosedPositions(!userHideClosedPositions)}
checked={!userHideClosedPositions}
/>
</ShowInactiveToggle>
) : null}
</ResponsiveRow>
</AutoColumn>
</AutoColumn>
</PageWrapper>