Commit a1b37766 authored by Jordan Frankfurt's avatar Jordan Frankfurt Committed by GitHub

feat: vertical LP (#7000)

* Re-organize add liquidity page

* fix title alignment

* Update styles

* Update logic for disable/enable input on creation

* lint and clean up a couple small things

* lint and clean up a couple small things

* Tweak UI

* clean up code

* add back range selector

* remove inline styles

---------
Co-authored-by: default avatarCallil Capuozzo <callil@uniswap.org>
parent dc2225a2
...@@ -4,12 +4,10 @@ import { Currency, CurrencyAmount } from '@uniswap/sdk-core' ...@@ -4,12 +4,10 @@ import { Currency, CurrencyAmount } from '@uniswap/sdk-core'
import { Pair } from '@uniswap/v2-sdk' import { Pair } from '@uniswap/v2-sdk'
import { useWeb3React } from '@web3-react/core' import { useWeb3React } from '@web3-react/core'
import { TraceEvent } from 'analytics' import { TraceEvent } from 'analytics'
import { AutoColumn } from 'components/Column'
import { LoadingOpacityContainer, loadingOpacityMixin } from 'components/Loader/styled' import { LoadingOpacityContainer, loadingOpacityMixin } from 'components/Loader/styled'
import { isSupportedChain } from 'constants/chains' import { isSupportedChain } from 'constants/chains'
import { darken } from 'polished' import { darken } from 'polished'
import { ReactNode, useCallback, useState } from 'react' import { ReactNode, useCallback, useState } from 'react'
import { Lock } from 'react-feather'
import styled, { useTheme } from 'styled-components/macro' import styled, { useTheme } from 'styled-components/macro'
import { flexColumnNoWrap, flexRowNoWrap } from 'theme/styles' import { flexColumnNoWrap, flexRowNoWrap } from 'theme/styles'
import { formatCurrencyAmount } from 'utils/formatCurrencyAmount' import { formatCurrencyAmount } from 'utils/formatCurrencyAmount'
...@@ -36,18 +34,6 @@ const InputPanel = styled.div<{ hideInput?: boolean }>` ...@@ -36,18 +34,6 @@ const InputPanel = styled.div<{ hideInput?: boolean }>`
will-change: height; will-change: height;
` `
const FixedContainer = styled.div`
width: 100%;
height: 100%;
position: absolute;
border-radius: 16px;
background-color: ${({ theme }) => theme.backgroundInteractive};
display: flex;
align-items: center;
justify-content: center;
z-index: 2;
`
const Container = styled.div<{ hideInput: boolean; disabled: boolean }>` const Container = styled.div<{ hideInput: boolean; disabled: boolean }>`
border-radius: ${({ hideInput }) => (hideInput ? '16px' : '20px')}; border-radius: ${({ hideInput }) => (hideInput ? '16px' : '20px')};
border: 1px solid ${({ theme }) => theme.backgroundSurface}; border: 1px solid ${({ theme }) => theme.backgroundSurface};
...@@ -226,16 +212,8 @@ export default function CurrencyInputPanel({ ...@@ -226,16 +212,8 @@ export default function CurrencyInputPanel({
return ( return (
<InputPanel id={id} hideInput={hideInput} {...rest}> <InputPanel id={id} hideInput={hideInput} {...rest}>
{locked && ( {!locked && (
<FixedContainer> <>
<AutoColumn gap="sm" justify="center">
<Lock />
<ThemedText.DeprecatedLabel fontSize="12px" textAlign="center" padding="0 12px">
<Trans>The market price is outside your specified price range. Single-asset deposit only.</Trans>
</ThemedText.DeprecatedLabel>
</AutoColumn>
</FixedContainer>
)}
<Container hideInput={hideInput} disabled={!chainAllowed}> <Container hideInput={hideInput} disabled={!chainAllowed}>
<InputRow style={hideInput ? { padding: '0', borderRadius: '8px' } : {}} selected={!onCurrencySelect}> <InputRow style={hideInput ? { padding: '0', borderRadius: '8px' } : {}} selected={!onCurrencySelect}>
{!hideInput && ( {!hideInput && (
...@@ -267,9 +245,9 @@ export default function CurrencyInputPanel({ ...@@ -267,9 +245,9 @@ export default function CurrencyInputPanel({
<span style={{ marginRight: '0.5rem' }}> <span style={{ marginRight: '0.5rem' }}>
<DoubleCurrencyLogo currency0={pair.token0} currency1={pair.token1} size={24} margin={true} /> <DoubleCurrencyLogo currency0={pair.token0} currency1={pair.token1} size={24} margin={true} />
</span> </span>
) : currency ? ( ) : (
<CurrencyLogo style={{ marginRight: '0.5rem' }} currency={currency} size="24px" /> currency && <CurrencyLogo style={{ marginRight: '0.5rem' }} currency={currency} size="24px" />
) : null} )}
{pair ? ( {pair ? (
<StyledTokenName className="pair-name-container"> <StyledTokenName className="pair-name-container">
{pair?.token0.symbol}:{pair?.token1.symbol} {pair?.token0.symbol}:{pair?.token1.symbol}
...@@ -288,13 +266,13 @@ export default function CurrencyInputPanel({ ...@@ -288,13 +266,13 @@ export default function CurrencyInputPanel({
</Aligner> </Aligner>
</CurrencySelect> </CurrencySelect>
</InputRow> </InputRow>
{!hideInput && !hideBalance && currency && ( {Boolean(!hideInput && !hideBalance && currency) && (
<FiatRow> <FiatRow>
<RowBetween> <RowBetween>
<LoadingOpacityContainer $loading={loading}> <LoadingOpacityContainer $loading={loading}>
{fiatValue && <FiatValue fiatValue={fiatValue} />} {fiatValue && <FiatValue fiatValue={fiatValue} />}
</LoadingOpacityContainer> </LoadingOpacityContainer>
{account ? ( {account && (
<RowFixed style={{ height: '17px' }}> <RowFixed style={{ height: '17px' }}>
<ThemedText.DeprecatedBody <ThemedText.DeprecatedBody
onClick={onMax} onClick={onMax}
...@@ -303,15 +281,12 @@ export default function CurrencyInputPanel({ ...@@ -303,15 +281,12 @@ export default function CurrencyInputPanel({
fontSize={14} fontSize={14}
style={{ display: 'inline', cursor: 'pointer' }} style={{ display: 'inline', cursor: 'pointer' }}
> >
{!hideBalance && currency && selectedCurrencyBalance ? ( {Boolean(!hideBalance && currency && selectedCurrencyBalance) &&
renderBalance ? ( (renderBalance?.(selectedCurrencyBalance as CurrencyAmount<Currency>) || (
renderBalance(selectedCurrencyBalance)
) : (
<Trans>Balance: {formatCurrencyAmount(selectedCurrencyBalance, 4)}</Trans> <Trans>Balance: {formatCurrencyAmount(selectedCurrencyBalance, 4)}</Trans>
) ))}
) : null}
</ThemedText.DeprecatedBody> </ThemedText.DeprecatedBody>
{showMaxButton && selectedCurrencyBalance ? ( {Boolean(showMaxButton && selectedCurrencyBalance) && (
<TraceEvent <TraceEvent
events={[BrowserEvent.onClick]} events={[BrowserEvent.onClick]}
name={SwapEventName.SWAP_MAX_TOKEN_AMOUNT_SELECTED} name={SwapEventName.SWAP_MAX_TOKEN_AMOUNT_SELECTED}
...@@ -321,15 +296,15 @@ export default function CurrencyInputPanel({ ...@@ -321,15 +296,15 @@ export default function CurrencyInputPanel({
<Trans>MAX</Trans> <Trans>MAX</Trans>
</StyledBalanceMax> </StyledBalanceMax>
</TraceEvent> </TraceEvent>
) : null} )}
</RowFixed> </RowFixed>
) : (
<span />
)} )}
</RowBetween> </RowBetween>
</FiatRow> </FiatRow>
)} )}
</Container> </Container>
</>
)}
{onCurrencySelect && ( {onCurrencySelect && (
<CurrencySearchModal <CurrencySearchModal
isOpen={modalOpen} isOpen={modalOpen}
......
...@@ -25,9 +25,7 @@ const pulse = (color: string) => keyframes` ...@@ -25,9 +25,7 @@ const pulse = (color: string) => keyframes`
` `
const InputRow = styled.div` const InputRow = styled.div`
display: grid; display: flex;
grid-template-columns: 30px 1fr 30px;
` `
const SmallButton = styled(ButtonGray)` const SmallButton = styled(ButtonGray)`
...@@ -43,18 +41,17 @@ const FocusedOutlineCard = styled(OutlineCard)<{ active?: boolean; pulsing?: boo ...@@ -43,18 +41,17 @@ const FocusedOutlineCard = styled(OutlineCard)<{ active?: boolean; pulsing?: boo
const StyledInput = styled(NumericalInput)<{ usePercent?: boolean }>` const StyledInput = styled(NumericalInput)<{ usePercent?: boolean }>`
background-color: transparent; background-color: transparent;
text-align: center;
width: 100%;
font-weight: 500; font-weight: 500;
padding: 0 10px; text-align: left;
width: 100%;
${({ theme }) => theme.deprecated_mediaWidth.deprecated_upToSmall` ${({ theme }) => theme.deprecated_mediaWidth.deprecated_upToSmall`
font-size: 16px; font-size: 16px;
`}; `};
`
${({ theme }) => theme.deprecated_mediaWidth.deprecated_upToExtraSmall` const InputColumn = styled(AutoColumn)`
font-size: 12px; width: 100%;
`};
` `
const InputTitle = styled(ThemedText.DeprecatedSmall)` const InputTitle = styled(ThemedText.DeprecatedSmall)`
...@@ -142,20 +139,11 @@ const StepCounter = ({ ...@@ -142,20 +139,11 @@ const StepCounter = ({
return ( return (
<FocusedOutlineCard pulsing={pulsing} active={active} onFocus={handleOnFocus} onBlur={handleOnBlur} width={width}> <FocusedOutlineCard pulsing={pulsing} active={active} onFocus={handleOnFocus} onBlur={handleOnBlur} width={width}>
<AutoColumn gap="6px"> <InputRow>
<InputColumn justify="flex-start">
<InputTitle fontSize={12} textAlign="center"> <InputTitle fontSize={12} textAlign="center">
{title} {title}
</InputTitle> </InputTitle>
<InputRow>
{!locked && (
<SmallButton data-testid="decrement-price-range" onClick={handleDecrement} disabled={decrementDisabled}>
<ButtonLabel disabled={decrementDisabled} fontSize="12px">
<Minus size={18} />
</ButtonLabel>
</SmallButton>
)}
<StyledInput <StyledInput
className="rate-input-0" className="rate-input-0"
value={localValue} value={localValue}
...@@ -165,7 +153,14 @@ const StepCounter = ({ ...@@ -165,7 +153,14 @@ const StepCounter = ({
setLocalValue(val) setLocalValue(val)
}} }}
/> />
<InputTitle fontSize={12} textAlign="left">
<Trans>
{tokenB} per {tokenA}
</Trans>
</InputTitle>
</InputColumn>
<AutoColumn gap="8px">
{!locked && ( {!locked && (
<SmallButton data-testid="increment-price-range" onClick={handleIncrement} disabled={incrementDisabled}> <SmallButton data-testid="increment-price-range" onClick={handleIncrement} disabled={incrementDisabled}>
<ButtonLabel disabled={incrementDisabled} fontSize="12px"> <ButtonLabel disabled={incrementDisabled} fontSize="12px">
...@@ -173,14 +168,15 @@ const StepCounter = ({ ...@@ -173,14 +168,15 @@ const StepCounter = ({
</ButtonLabel> </ButtonLabel>
</SmallButton> </SmallButton>
)} )}
</InputRow> {!locked && (
<SmallButton data-testid="decrement-price-range" onClick={handleDecrement} disabled={decrementDisabled}>
<InputTitle fontSize={12} textAlign="center"> <ButtonLabel disabled={decrementDisabled} fontSize="12px">
<Trans> <Minus size={18} />
{tokenB} per {tokenA} </ButtonLabel>
</Trans> </SmallButton>
</InputTitle> )}
</AutoColumn> </AutoColumn>
</InputRow>
</FocusedOutlineCard> </FocusedOutlineCard>
) )
} }
......
...@@ -12,7 +12,7 @@ const Wrapper = styled.div<{ count: number }>` ...@@ -12,7 +12,7 @@ const Wrapper = styled.div<{ count: number }>`
grid-gap: 6px; grid-gap: 6px;
position: absolute; position: absolute;
top: -75px; top: -32px;
right: 0; right: 0;
` `
......
...@@ -6,7 +6,7 @@ import Loader from 'components/Icons/LoadingSpinner' ...@@ -6,7 +6,7 @@ import Loader from 'components/Icons/LoadingSpinner'
import { format } from 'd3' import { format } from 'd3'
import { useColor } from 'hooks/useColor' import { useColor } from 'hooks/useColor'
import { saturate } from 'polished' import { saturate } from 'polished'
import React, { ReactNode, useCallback, useMemo } from 'react' import { ReactNode, useCallback, useMemo } from 'react'
import { BarChart2, CloudOff, Inbox } from 'react-feather' import { BarChart2, CloudOff, Inbox } from 'react-feather'
import { batch } from 'react-redux' import { batch } from 'react-redux'
import { Bound } from 'state/mint/v3/actions' import { Bound } from 'state/mint/v3/actions'
...@@ -46,7 +46,8 @@ const ZOOM_LEVELS: Record<FeeAmount, ZoomLevels> = { ...@@ -46,7 +46,8 @@ const ZOOM_LEVELS: Record<FeeAmount, ZoomLevels> = {
const ChartWrapper = styled.div` const ChartWrapper = styled.div`
position: relative; position: relative;
width: 100%;
max-height: 200px;
justify-content: center; justify-content: center;
align-content: center; align-content: center;
` `
...@@ -180,7 +181,7 @@ export default function LiquidityChartRangeInput({ ...@@ -180,7 +181,7 @@ export default function LiquidityChartRangeInput({
<ChartWrapper> <ChartWrapper>
<Chart <Chart
data={{ series: formattedData, current: price }} data={{ series: formattedData, current: price }}
dimensions={{ width: 400, height: 200 }} dimensions={{ width: 560, height: 200 }}
margins={{ top: 10, right: 2, bottom: 20, left: 0 }} margins={{ top: 10, right: 2, bottom: 20, left: 0 }}
styles={{ styles={{
area: { area: {
......
...@@ -3,7 +3,7 @@ import { Percent } from '@uniswap/sdk-core' ...@@ -3,7 +3,7 @@ import { Percent } from '@uniswap/sdk-core'
import { useWeb3React } from '@web3-react/core' import { useWeb3React } from '@web3-react/core'
import { ReactNode } from 'react' import { ReactNode } from 'react'
import { ArrowLeft } from 'react-feather' import { ArrowLeft } from 'react-feather'
import { Link as HistoryLink, useLocation } from 'react-router-dom' import { Link, useLocation } from 'react-router-dom'
import { Box } from 'rebass' import { Box } from 'rebass'
import { useAppDispatch } from 'state/hooks' import { useAppDispatch } from 'state/hooks'
import { resetMintState } from 'state/mint/actions' import { resetMintState } from 'state/mint/actions'
...@@ -12,7 +12,7 @@ import styled, { useTheme } from 'styled-components/macro' ...@@ -12,7 +12,7 @@ import styled, { useTheme } from 'styled-components/macro'
import { ThemedText } from 'theme' import { ThemedText } from 'theme'
import { flexRowNoWrap } from 'theme/styles' import { flexRowNoWrap } from 'theme/styles'
import Row, { RowBetween } from '../Row' import { RowBetween } from '../Row'
import SettingsTab from '../Settings' import SettingsTab from '../Settings'
const Tabs = styled.div` const Tabs = styled.div`
...@@ -22,7 +22,7 @@ const Tabs = styled.div` ...@@ -22,7 +22,7 @@ const Tabs = styled.div`
justify-content: space-evenly; justify-content: space-evenly;
` `
const StyledHistoryLink = styled(HistoryLink)<{ flex?: string }>` const StyledLink = styled(Link)<{ flex?: string }>`
flex: ${({ flex }) => flex ?? 'none'}; flex: ${({ flex }) => flex ?? 'none'};
${({ theme }) => theme.deprecated_mediaWidth.deprecated_upToMedium` ${({ theme }) => theme.deprecated_mediaWidth.deprecated_upToMedium`
...@@ -31,9 +31,10 @@ const StyledHistoryLink = styled(HistoryLink)<{ flex?: string }>` ...@@ -31,9 +31,10 @@ const StyledHistoryLink = styled(HistoryLink)<{ flex?: string }>`
`}; `};
` `
const ActiveText = styled.div` const FindPoolTabsText = styled(ThemedText.SubHeaderLarge)`
font-weight: 500; position: absolute;
font-size: 20px; left: 50%;
transform: translateX(-50%);
` `
const StyledArrowLeft = styled(ArrowLeft)` const StyledArrowLeft = styled(ArrowLeft)`
...@@ -44,17 +45,22 @@ export function FindPoolTabs({ origin }: { origin: string }) { ...@@ -44,17 +45,22 @@ export function FindPoolTabs({ origin }: { origin: string }) {
return ( return (
<Tabs> <Tabs>
<RowBetween style={{ padding: '1rem 1rem 0 1rem', position: 'relative' }}> <RowBetween style={{ padding: '1rem 1rem 0 1rem', position: 'relative' }}>
<HistoryLink to={origin}> <Link to={origin}>
<StyledArrowLeft /> <StyledArrowLeft />
</HistoryLink> </Link>
<ActiveText style={{ position: 'absolute', left: '50%', transform: 'translateX(-50%)' }}> <FindPoolTabsText>
<Trans>Import V2 Pool</Trans> <Trans>Import V2 Pool</Trans>
</ActiveText> </FindPoolTabsText>
</RowBetween> </RowBetween>
</Tabs> </Tabs>
) )
} }
const AddRemoveTitleText = styled(ThemedText.SubHeaderLarge)`
flex: 1;
margin: auto;
`
export function AddRemoveTabs({ export function AddRemoveTabs({
adding, adding,
creating, creating,
...@@ -83,7 +89,7 @@ export function AddRemoveTabs({ ...@@ -83,7 +89,7 @@ export function AddRemoveTabs({
return ( return (
<Tabs> <Tabs>
<RowBetween style={{ padding: '1rem 1rem 0 1rem' }}> <RowBetween style={{ padding: '1rem 1rem 0 1rem' }}>
<StyledHistoryLink <StyledLink
to={poolLink} to={poolLink}
onClick={() => { onClick={() => {
if (adding) { if (adding) {
...@@ -95,12 +101,8 @@ export function AddRemoveTabs({ ...@@ -95,12 +101,8 @@ export function AddRemoveTabs({
flex={children ? '1' : undefined} flex={children ? '1' : undefined}
> >
<StyledArrowLeft stroke={theme.textSecondary} /> <StyledArrowLeft stroke={theme.textSecondary} />
</StyledHistoryLink> </StyledLink>
<ThemedText.DeprecatedMediumHeader <AddRemoveTitleText textAlign={children ? 'start' : 'center'}>
fontWeight={500}
fontSize={20}
style={{ flex: '1', margin: 'auto', textAlign: children ? 'start' : 'center' }}
>
{creating ? ( {creating ? (
<Trans>Create a pair</Trans> <Trans>Create a pair</Trans>
) : adding ? ( ) : adding ? (
...@@ -108,23 +110,10 @@ export function AddRemoveTabs({ ...@@ -108,23 +110,10 @@ export function AddRemoveTabs({
) : ( ) : (
<Trans>Remove Liquidity</Trans> <Trans>Remove Liquidity</Trans>
)} )}
</ThemedText.DeprecatedMediumHeader> </AddRemoveTitleText>
<Box style={{ marginRight: '.5rem' }}>{children}</Box> {children && <Box style={{ marginRight: '.5rem' }}>{children}</Box>}
<SettingsTab autoSlippage={autoSlippage} chainId={chainId} /> <SettingsTab autoSlippage={autoSlippage} chainId={chainId} />
</RowBetween> </RowBetween>
</Tabs> </Tabs>
) )
} }
export function CreateProposalTabs() {
return (
<Tabs>
<Row style={{ padding: '1rem 1rem 0 1rem' }}>
<HistoryLink to="/vote">
<StyledArrowLeft />
</HistoryLink>
<ActiveText style={{ marginLeft: 'auto', marginRight: 'auto' }}>Create Proposal</ActiveText>
</Row>
</Tabs>
)
}
...@@ -5,7 +5,7 @@ import styled from 'styled-components/macro' ...@@ -5,7 +5,7 @@ import styled from 'styled-components/macro'
import { ThemedText } from 'theme' import { ThemedText } from 'theme'
const Button = styled(ButtonOutlined).attrs(() => ({ const Button = styled(ButtonOutlined).attrs(() => ({
padding: '8px', padding: '6px',
$borderRadius: '8px', $borderRadius: '8px',
}))` }))`
color: ${({ theme }) => theme.textPrimary}; color: ${({ theme }) => theme.textPrimary};
......
import { Trans } from '@lingui/macro' import { Trans } from '@lingui/macro'
import { Currency, Price, Token } from '@uniswap/sdk-core' import { Currency, Price, Token } from '@uniswap/sdk-core'
import { AutoColumn } from 'components/Column'
import StepCounter from 'components/InputStepCounter/InputStepCounter' import StepCounter from 'components/InputStepCounter/InputStepCounter'
import { RowBetween } from 'components/Row' import { AutoRow } from 'components/Row'
import { Bound } from 'state/mint/v3/actions' import { Bound } from 'state/mint/v3/actions'
// currencyA is the base token // currencyA is the base token
...@@ -41,26 +40,23 @@ export default function RangeSelector({ ...@@ -41,26 +40,23 @@ export default function RangeSelector({
const rightPrice = isSorted ? priceUpper : priceLower?.invert() const rightPrice = isSorted ? priceUpper : priceLower?.invert()
return ( return (
<AutoColumn gap="md"> <AutoRow gap="md">
<RowBetween>
<StepCounter <StepCounter
value={ticksAtLimit[isSorted ? Bound.LOWER : Bound.UPPER] ? '0' : leftPrice?.toSignificant(5) ?? ''} value={ticksAtLimit[isSorted ? Bound.LOWER : Bound.UPPER] ? '0' : leftPrice?.toSignificant(8) ?? ''}
onUserInput={onLeftRangeInput} onUserInput={onLeftRangeInput}
width="48%"
decrement={isSorted ? getDecrementLower : getIncrementUpper} decrement={isSorted ? getDecrementLower : getIncrementUpper}
increment={isSorted ? getIncrementLower : getDecrementUpper} increment={isSorted ? getIncrementLower : getDecrementUpper}
decrementDisabled={leftPrice === undefined || ticksAtLimit[isSorted ? Bound.LOWER : Bound.UPPER]} decrementDisabled={leftPrice === undefined || ticksAtLimit[isSorted ? Bound.LOWER : Bound.UPPER]}
incrementDisabled={leftPrice === undefined || ticksAtLimit[isSorted ? Bound.LOWER : Bound.UPPER]} incrementDisabled={leftPrice === undefined || ticksAtLimit[isSorted ? Bound.LOWER : Bound.UPPER]}
feeAmount={feeAmount} feeAmount={feeAmount}
label={leftPrice ? `${currencyB?.symbol}` : '-'} label={leftPrice ? `${currencyB?.symbol}` : '-'}
title={<Trans>Min Price</Trans>} title={<Trans>Low price</Trans>}
tokenA={currencyA?.symbol} tokenA={currencyA?.symbol}
tokenB={currencyB?.symbol} tokenB={currencyB?.symbol}
/> />
<StepCounter <StepCounter
value={ticksAtLimit[isSorted ? Bound.UPPER : Bound.LOWER] ? '' : rightPrice?.toSignificant(5) ?? ''} value={ticksAtLimit[isSorted ? Bound.UPPER : Bound.LOWER] ? '' : rightPrice?.toSignificant(8) ?? ''}
onUserInput={onRightRangeInput} onUserInput={onRightRangeInput}
width="48%"
decrement={isSorted ? getDecrementUpper : getIncrementLower} decrement={isSorted ? getDecrementUpper : getIncrementLower}
increment={isSorted ? getIncrementUpper : getDecrementLower} increment={isSorted ? getIncrementUpper : getDecrementLower}
incrementDisabled={rightPrice === undefined || ticksAtLimit[isSorted ? Bound.UPPER : Bound.LOWER]} incrementDisabled={rightPrice === undefined || ticksAtLimit[isSorted ? Bound.UPPER : Bound.LOWER]}
...@@ -69,9 +65,8 @@ export default function RangeSelector({ ...@@ -69,9 +65,8 @@ export default function RangeSelector({
label={rightPrice ? `${currencyB?.symbol}` : '-'} label={rightPrice ? `${currencyB?.symbol}` : '-'}
tokenA={currencyA?.symbol} tokenA={currencyA?.symbol}
tokenB={currencyB?.symbol} tokenB={currencyB?.symbol}
title={<Trans>Max Price</Trans>} title={<Trans>High price</Trans>}
/> />
</RowBetween> </AutoRow>
</AutoColumn>
) )
} }
...@@ -13,6 +13,7 @@ import UnsupportedCurrencyFooter from 'components/swap/UnsupportedCurrencyFooter ...@@ -13,6 +13,7 @@ import UnsupportedCurrencyFooter from 'components/swap/UnsupportedCurrencyFooter
import { isSupportedChain } from 'constants/chains' import { isSupportedChain } from 'constants/chains'
import usePrevious from 'hooks/usePrevious' import usePrevious from 'hooks/usePrevious'
import { useSingleCallResult } from 'lib/hooks/multicall' import { useSingleCallResult } from 'lib/hooks/multicall'
import { BodyWrapper } from 'pages/AppBody'
import { PositionPageUnsupportedContent } from 'pages/Pool/PositionPage' import { PositionPageUnsupportedContent } from 'pages/Pool/PositionPage'
import { useCallback, useEffect, useMemo, useState } from 'react' import { useCallback, useEffect, useMemo, useState } from 'react'
import { AlertTriangle } from 'react-feather' import { AlertTriangle } from 'react-feather'
...@@ -24,7 +25,7 @@ import { ...@@ -24,7 +25,7 @@ import {
useV3MintActionHandlers, useV3MintActionHandlers,
useV3MintState, useV3MintState,
} from 'state/mint/v3/hooks' } from 'state/mint/v3/hooks'
import { useTheme } from 'styled-components/macro' import styled, { useTheme } from 'styled-components/macro'
import { addressesAreEquivalent } from 'utils/addressesAreEquivalent' import { addressesAreEquivalent } from 'utils/addressesAreEquivalent'
import { ButtonError, ButtonLight, ButtonPrimary, ButtonText } from '../../components/Button' import { ButtonError, ButtonLight, ButtonPrimary, ButtonText } from '../../components/Button'
...@@ -39,7 +40,7 @@ import { PositionPreview } from '../../components/PositionPreview' ...@@ -39,7 +40,7 @@ import { PositionPreview } from '../../components/PositionPreview'
import RangeSelector from '../../components/RangeSelector' import RangeSelector from '../../components/RangeSelector'
import PresetsButtons from '../../components/RangeSelector/PresetsButtons' import PresetsButtons from '../../components/RangeSelector/PresetsButtons'
import RateToggle from '../../components/RateToggle' import RateToggle from '../../components/RateToggle'
import Row, { AutoRow, RowBetween, RowFixed } from '../../components/Row' import Row, { RowBetween, RowFixed } from '../../components/Row'
import { SwitchLocaleLink } from '../../components/SwitchLocaleLink' import { SwitchLocaleLink } from '../../components/SwitchLocaleLink'
import TransactionConfirmationModal, { ConfirmationModalContent } from '../../components/TransactionConfirmationModal' import TransactionConfirmationModal, { ConfirmationModalContent } from '../../components/TransactionConfirmationModal'
import { ZERO_PERCENT } from '../../constants/misc' import { ZERO_PERCENT } from '../../constants/misc'
...@@ -67,20 +68,20 @@ import { Review } from './Review' ...@@ -67,20 +68,20 @@ import { Review } from './Review'
import { import {
CurrencyDropdown, CurrencyDropdown,
DynamicSection, DynamicSection,
HideMedium,
MediumOnly, MediumOnly,
PageWrapper,
ResponsiveTwoColumns, ResponsiveTwoColumns,
RightContainer,
ScrollablePage, ScrollablePage,
StackedContainer,
StackedItem,
StyledInput, StyledInput,
Wrapper, Wrapper,
} from './styled' } from './styled'
const DEFAULT_ADD_IN_RANGE_SLIPPAGE_TOLERANCE = new Percent(50, 10_000) const DEFAULT_ADD_IN_RANGE_SLIPPAGE_TOLERANCE = new Percent(50, 10_000)
const StyledBodyWrapper = styled(BodyWrapper)<{ $hasExistingPosition: boolean }>`
padding: ${({ $hasExistingPosition }) => ($hasExistingPosition ? '10px' : 0)};
max-width: 640px;
`
export default function AddLiquidityWrapper() { export default function AddLiquidityWrapper() {
const { chainId } = useWeb3React() const { chainId } = useWeb3React()
if (isSupportedChain(chainId)) { if (isSupportedChain(chainId)) {
...@@ -97,7 +98,12 @@ function AddLiquidity() { ...@@ -97,7 +98,12 @@ function AddLiquidity() {
currencyIdB, currencyIdB,
feeAmount: feeAmountFromUrl, feeAmount: feeAmountFromUrl,
tokenId, tokenId,
} = useParams<{ currencyIdA?: string; currencyIdB?: string; feeAmount?: string; tokenId?: string }>() } = useParams<{
currencyIdA?: string
currencyIdB?: string
feeAmount?: string
tokenId?: string
}>()
const { account, chainId, provider } = useWeb3React() const { account, chainId, provider } = useWeb3React()
const theme = useTheme() const theme = useTheme()
...@@ -600,7 +606,7 @@ function AddLiquidity() { ...@@ -600,7 +606,7 @@ function AddLiquidity() {
)} )}
pendingText={pendingText} pendingText={pendingText}
/> />
<PageWrapper wide={!hasExistingPosition}> <StyledBodyWrapper $hasExistingPosition={hasExistingPosition}>
<AddRemoveTabs <AddRemoveTabs
creating={false} creating={false}
adding={true} adding={true}
...@@ -611,28 +617,12 @@ function AddLiquidity() { ...@@ -611,28 +617,12 @@ function AddLiquidity() {
{!hasExistingPosition && ( {!hasExistingPosition && (
<Row justifyContent="flex-end" style={{ width: 'fit-content', minWidth: 'fit-content' }}> <Row justifyContent="flex-end" style={{ width: 'fit-content', minWidth: 'fit-content' }}>
<MediumOnly> <MediumOnly>
<ButtonText onClick={clearAll} margin="0 15px 0 0"> <ButtonText onClick={clearAll}>
<ThemedText.DeprecatedBlue fontSize="12px"> <ThemedText.DeprecatedBlue fontSize="12px">
<Trans>Clear All</Trans> <Trans>Clear All</Trans>
</ThemedText.DeprecatedBlue> </ThemedText.DeprecatedBlue>
</ButtonText> </ButtonText>
</MediumOnly> </MediumOnly>
{baseCurrency && quoteCurrency ? (
<RateToggle
currencyA={baseCurrency}
currencyB={quoteCurrency}
handleRateToggle={() => {
if (!ticksAtLimit[Bound.LOWER] && !ticksAtLimit[Bound.UPPER]) {
onLeftRangeInput((invertPrice ? priceLower : priceUpper?.invert())?.toSignificant(6) ?? '')
onRightRangeInput((invertPrice ? priceUpper : priceLower?.invert())?.toSignificant(6) ?? '')
onFieldAInput(formattedAmounts[Field.CURRENCY_B] ?? '')
}
navigate(
`/add/${currencyIdB as string}/${currencyIdA as string}${feeAmount ? '/' + feeAmount : ''}`
)
}}
/>
) : null}
</Row> </Row>
)} )}
</AddRemoveTabs> </AddRemoveTabs>
...@@ -698,90 +688,108 @@ function AddLiquidity() { ...@@ -698,90 +688,108 @@ function AddLiquidity() {
/> />
)} )}
</AutoColumn> </AutoColumn>
<div>
<DynamicSection {!hasExistingPosition && (
disabled={tickLower === undefined || tickUpper === undefined || invalidPool || invalidRange} <>
> <DynamicSection gap="md" disabled={!feeAmount || invalidPool}>
<AutoColumn gap="md"> <RowBetween>
<ThemedText.DeprecatedLabel> <ThemedText.DeprecatedLabel>
{hasExistingPosition ? <Trans>Add more liquidity</Trans> : <Trans>Deposit Amounts</Trans>} <Trans>Set Price Range</Trans>
</ThemedText.DeprecatedLabel> </ThemedText.DeprecatedLabel>
<CurrencyInputPanel {Boolean(baseCurrency && quoteCurrency) && (
value={formattedAmounts[Field.CURRENCY_A]} <RowFixed gap="8px">
onUserInput={onFieldAInput} <PresetsButtons onSetFullRange={handleSetFullRange} />
onMax={() => { <RateToggle
onFieldAInput(maxAmounts[Field.CURRENCY_A]?.toExact() ?? '') currencyA={baseCurrency as Currency}
currencyB={quoteCurrency as Currency}
handleRateToggle={() => {
if (!ticksAtLimit[Bound.LOWER] && !ticksAtLimit[Bound.UPPER]) {
onLeftRangeInput(
(invertPrice ? priceLower : priceUpper?.invert())?.toSignificant(6) ?? ''
)
onRightRangeInput(
(invertPrice ? priceUpper : priceLower?.invert())?.toSignificant(6) ?? ''
)
onFieldAInput(formattedAmounts[Field.CURRENCY_B] ?? '')
}
navigate(
`/add/${currencyIdB as string}/${currencyIdA as string}${
feeAmount ? '/' + feeAmount : ''
}`
)
}} }}
showMaxButton={!atMaxAmounts[Field.CURRENCY_A]}
currency={currencies[Field.CURRENCY_A] ?? null}
id="add-liquidity-input-tokena"
fiatValue={currencyAFiat}
showCommonBases
locked={depositADisabled}
/> />
</RowFixed>
)}
</RowBetween>
<CurrencyInputPanel <RangeSelector
value={formattedAmounts[Field.CURRENCY_B]} priceLower={priceLower}
onUserInput={onFieldBInput} priceUpper={priceUpper}
onMax={() => { getDecrementLower={getDecrementLower}
onFieldBInput(maxAmounts[Field.CURRENCY_B]?.toExact() ?? '') getIncrementLower={getIncrementLower}
}} getDecrementUpper={getDecrementUpper}
showMaxButton={!atMaxAmounts[Field.CURRENCY_B]} getIncrementUpper={getIncrementUpper}
fiatValue={currencyBFiat} onLeftRangeInput={onLeftRangeInput}
currency={currencies[Field.CURRENCY_B] ?? null} onRightRangeInput={onRightRangeInput}
id="add-liquidity-input-tokenb" currencyA={baseCurrency}
showCommonBases currencyB={quoteCurrency}
locked={depositBDisabled} feeAmount={feeAmount}
ticksAtLimit={ticksAtLimit}
/> />
</AutoColumn>
{outOfRange && (
<YellowCard padding="8px 12px" $borderRadius="12px">
<RowBetween>
<AlertTriangle stroke={theme.deprecated_yellow3} size="16px" />
<ThemedText.DeprecatedYellow ml="12px" fontSize="12px">
<Trans>
Your position will not earn fees or be used in trades until the market price moves into
your range.
</Trans>
</ThemedText.DeprecatedYellow>
</RowBetween>
</YellowCard>
)}
{invalidRange && (
<YellowCard padding="8px 12px" $borderRadius="12px">
<RowBetween>
<AlertTriangle stroke={theme.deprecated_yellow3} size="16px" />
<ThemedText.DeprecatedYellow ml="12px" fontSize="12px">
<Trans>Invalid range selected. The min price must be lower than the max price.</Trans>
</ThemedText.DeprecatedYellow>
</RowBetween>
</YellowCard>
)}
</DynamicSection> </DynamicSection>
</div>
{!hasExistingPosition ? (
<>
<HideMedium>
<Buttons />
</HideMedium>
<RightContainer gap="lg">
<DynamicSection gap="md" disabled={!feeAmount || invalidPool}> <DynamicSection gap="md" disabled={!feeAmount || invalidPool}>
{!noLiquidity ? ( {!noLiquidity ? (
<> <>
<RowBetween> {Boolean(price && baseCurrency && quoteCurrency && !noLiquidity) && (
<ThemedText.DeprecatedLabel> <AutoColumn gap="2px" style={{ marginTop: '0.5rem' }}>
<Trans>Set Price Range</Trans>
</ThemedText.DeprecatedLabel>
</RowBetween>
{price && baseCurrency && quoteCurrency && !noLiquidity && (
<AutoRow gap="4px" justify="center" style={{ marginTop: '0.5rem' }}>
<Trans> <Trans>
<ThemedText.DeprecatedMain <ThemedText.DeprecatedMain fontWeight={500} fontSize={12} color="text1">
fontWeight={500}
textAlign="center"
fontSize={12}
color="text1"
>
Current Price: Current Price:
</ThemedText.DeprecatedMain> </ThemedText.DeprecatedMain>
<ThemedText.DeprecatedBody <ThemedText.DeprecatedBody fontWeight={500} fontSize={20} color="text1">
fontWeight={500} {price && (
textAlign="center"
fontSize={12}
color="text1"
>
<HoverInlineText <HoverInlineText
maxCharacters={20} maxCharacters={20}
text={invertPrice ? price.invert().toSignificant(6) : price.toSignificant(6)} text={invertPrice ? price.invert().toSignificant(6) : price.toSignificant(6)}
/> />
)}
</ThemedText.DeprecatedBody> </ThemedText.DeprecatedBody>
{baseCurrency && (
<ThemedText.DeprecatedBody color="text2" fontSize={12}> <ThemedText.DeprecatedBody color="text2" fontSize={12}>
{quoteCurrency?.symbol} per {baseCurrency.symbol} {quoteCurrency?.symbol} per {baseCurrency.symbol}
</ThemedText.DeprecatedBody> </ThemedText.DeprecatedBody>
)}
</Trans> </Trans>
</AutoRow> </AutoColumn>
)} )}
<LiquidityChartRangeInput <LiquidityChartRangeInput
currencyA={baseCurrency ?? undefined} currencyA={baseCurrency ?? undefined}
currencyB={quoteCurrency ?? undefined} currencyB={quoteCurrency ?? undefined}
...@@ -799,11 +807,6 @@ function AddLiquidity() { ...@@ -799,11 +807,6 @@ function AddLiquidity() {
</> </>
) : ( ) : (
<AutoColumn gap="md"> <AutoColumn gap="md">
<RowBetween>
<ThemedText.DeprecatedLabel>
<Trans>Set Starting Price</Trans>
</ThemedText.DeprecatedLabel>
</RowBetween>
{noLiquidity && ( {noLiquidity && (
<BlueCard <BlueCard
style={{ style={{
...@@ -821,8 +824,8 @@ function AddLiquidity() { ...@@ -821,8 +824,8 @@ function AddLiquidity() {
> >
<Trans> <Trans>
This pool must be initialized before you can add liquidity. To initialize, select a This pool must be initialized before you can add liquidity. To initialize, select a
starting price for the pool. Then, enter your liquidity price range and deposit starting price for the pool. Then, enter your liquidity price range and deposit amount.
amount. Gas fees will be higher than usual due to the initialization transaction. Gas fees will be higher than usual due to the initialization transaction.
</Trans> </Trans>
</ThemedText.DeprecatedBody> </ThemedText.DeprecatedBody>
</BlueCard> </BlueCard>
...@@ -835,10 +838,14 @@ function AddLiquidity() { ...@@ -835,10 +838,14 @@ function AddLiquidity() {
/> />
</OutlineCard> </OutlineCard>
<RowBetween <RowBetween
style={{ backgroundColor: theme.deprecated_bg1, padding: '12px', borderRadius: '12px' }} style={{
backgroundColor: theme.deprecated_bg1,
padding: '12px',
borderRadius: '12px',
}}
> >
<ThemedText.DeprecatedMain> <ThemedText.DeprecatedMain>
<Trans>Current {baseCurrency?.symbol} Price:</Trans> <Trans>Starting {baseCurrency?.symbol} Price:</Trans>
</ThemedText.DeprecatedMain> </ThemedText.DeprecatedMain>
<ThemedText.DeprecatedMain> <ThemedText.DeprecatedMain>
{price ? ( {price ? (
...@@ -846,9 +853,11 @@ function AddLiquidity() { ...@@ -846,9 +853,11 @@ function AddLiquidity() {
<RowFixed> <RowFixed>
<HoverInlineText <HoverInlineText
maxCharacters={20} maxCharacters={20}
text={invertPrice ? price?.invert()?.toSignificant(5) : price?.toSignificant(5)} text={invertPrice ? price?.invert()?.toSignificant(8) : price?.toSignificant(8)}
/>{' '} />{' '}
<span style={{ marginLeft: '4px' }}>{quoteCurrency?.symbol}</span> <span style={{ marginLeft: '4px' }}>
{quoteCurrency?.symbol} per {baseCurrency?.symbol}
</span>
</RowFixed> </RowFixed>
</ThemedText.DeprecatedMain> </ThemedText.DeprecatedMain>
) : ( ) : (
...@@ -859,77 +868,49 @@ function AddLiquidity() { ...@@ -859,77 +868,49 @@ function AddLiquidity() {
</AutoColumn> </AutoColumn>
)} )}
</DynamicSection> </DynamicSection>
</>
<DynamicSection )}
gap="md" <div>
disabled={!feeAmount || invalidPool || (noLiquidity && !startPriceTypedValue)} <DynamicSection disabled={invalidPool || invalidRange || (noLiquidity && !startPriceTypedValue)}>
>
<StackedContainer>
<StackedItem>
<AutoColumn gap="md"> <AutoColumn gap="md">
{noLiquidity && (
<RowBetween>
<ThemedText.DeprecatedLabel> <ThemedText.DeprecatedLabel>
<Trans>Set Price Range</Trans> {hasExistingPosition ? <Trans>Add more liquidity</Trans> : <Trans>Deposit Amounts</Trans>}
</ThemedText.DeprecatedLabel> </ThemedText.DeprecatedLabel>
</RowBetween>
)}
<RangeSelector
priceLower={priceLower}
priceUpper={priceUpper}
getDecrementLower={getDecrementLower}
getIncrementLower={getIncrementLower}
getDecrementUpper={getDecrementUpper}
getIncrementUpper={getIncrementUpper}
onLeftRangeInput={onLeftRangeInput}
onRightRangeInput={onRightRangeInput}
currencyA={baseCurrency}
currencyB={quoteCurrency}
feeAmount={feeAmount}
ticksAtLimit={ticksAtLimit}
/>
<PresetsButtons onSetFullRange={handleSetFullRange} />
</AutoColumn>
</StackedItem>
</StackedContainer>
{outOfRange ? ( <CurrencyInputPanel
<YellowCard padding="8px 12px" $borderRadius="12px"> value={formattedAmounts[Field.CURRENCY_A]}
<RowBetween> onUserInput={onFieldAInput}
<AlertTriangle stroke={theme.deprecated_yellow3} size="16px" /> onMax={() => {
<ThemedText.DeprecatedYellow ml="12px" fontSize="12px"> onFieldAInput(maxAmounts[Field.CURRENCY_A]?.toExact() ?? '')
<Trans> }}
Your position will not earn fees or be used in trades until the market price moves into showMaxButton={!atMaxAmounts[Field.CURRENCY_A]}
your range. currency={currencies[Field.CURRENCY_A] ?? null}
</Trans> id="add-liquidity-input-tokena"
</ThemedText.DeprecatedYellow> fiatValue={currencyAFiat}
</RowBetween> showCommonBases
</YellowCard> locked={depositADisabled}
) : null} />
{invalidRange ? ( <CurrencyInputPanel
<YellowCard padding="8px 12px" $borderRadius="12px"> value={formattedAmounts[Field.CURRENCY_B]}
<RowBetween> onUserInput={onFieldBInput}
<AlertTriangle stroke={theme.deprecated_yellow3} size="16px" /> onMax={() => {
<ThemedText.DeprecatedYellow ml="12px" fontSize="12px"> onFieldBInput(maxAmounts[Field.CURRENCY_B]?.toExact() ?? '')
<Trans>Invalid range selected. The min price must be lower than the max price.</Trans> }}
</ThemedText.DeprecatedYellow> showMaxButton={!atMaxAmounts[Field.CURRENCY_B]}
</RowBetween> fiatValue={currencyBFiat}
</YellowCard> currency={currencies[Field.CURRENCY_B] ?? null}
) : null} id="add-liquidity-input-tokenb"
showCommonBases
locked={depositBDisabled}
/>
</AutoColumn>
</DynamicSection> </DynamicSection>
</div>
<MediumOnly>
<Buttons />
</MediumOnly>
</RightContainer>
</>
) : (
<Buttons /> <Buttons />
)}
</ResponsiveTwoColumns> </ResponsiveTwoColumns>
</Wrapper> </Wrapper>
</PageWrapper> </StyledBodyWrapper>
{showOwnershipWarning && <OwnershipWarning ownerAddress={owner} />} {showOwnershipWarning && <OwnershipWarning ownerAddress={owner} />}
{addIsUnsupported && ( {addIsUnsupported && (
<UnsupportedCurrencyFooter <UnsupportedCurrencyFooter
......
import { AutoColumn } from 'components/Column' import { AutoColumn } from 'components/Column'
import CurrencyInputPanel from 'components/CurrencyInputPanel' import CurrencyInputPanel from 'components/CurrencyInputPanel'
import Input from 'components/NumericalInput' import Input from 'components/NumericalInput'
import { BodyWrapper } from 'pages/AppBody'
import styled from 'styled-components/macro' import styled from 'styled-components/macro'
export const PageWrapper = styled(BodyWrapper)<{ wide: boolean }>`
max-width: ${({ wide }) => (wide ? '880px' : '480px')};
width: 100%;
padding: ${({ wide }) => (wide ? '10px' : '0')};
${({ theme }) => theme.deprecated_mediaWidth.deprecated_upToMedium`
max-width: 480px;
`};
`
export const Wrapper = styled.div` export const Wrapper = styled.div`
position: relative; position: relative;
padding: 26px 16px; padding: 26px 16px;
min-width: 480px;
${({ theme }) => theme.deprecated_mediaWidth.deprecated_upToMedium`
min-width: 400px;
`};
${({ theme }) => theme.deprecated_mediaWidth.deprecated_upToExtraSmall`
min-width: 340px;
`};
` `
export const ScrollablePage = styled.div` export const ScrollablePage = styled.div`
padding: 68px 8px 0px; padding: 20px 8px 0px;
position: relative; position: relative;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
${({ theme }) => theme.deprecated_mediaWidth.deprecated_upToMedium` ${({ theme }) => theme.deprecated_mediaWidth.deprecated_upToMedium`
max-width: 480px;
margin: 0 auto; margin: 0 auto;
`}; `};
...@@ -67,56 +45,19 @@ export const StyledInput = styled(Input)` ...@@ -67,56 +45,19 @@ export const StyledInput = styled(Input)`
/* two-column layout where DepositAmount is moved at the very end on mobile. */ /* two-column layout where DepositAmount is moved at the very end on mobile. */
export const ResponsiveTwoColumns = styled.div<{ wide: boolean }>` export const ResponsiveTwoColumns = styled.div<{ wide: boolean }>`
display: grid; display: flex;
grid-column-gap: 50px; flex-direction: column;
grid-row-gap: 15px; gap: 20px;
grid-template-columns: ${({ wide }) => (wide ? '1fr 1fr' : '1fr')};
grid-template-rows: max-content;
grid-auto-flow: row;
padding-top: 20px; padding-top: 20px;
border-top: 1px solid ${({ theme }) => theme.backgroundInteractive}; border-top: 1px solid ${({ theme }) => theme.backgroundInteractive};
${({ theme }) => theme.deprecated_mediaWidth.deprecated_upToMedium` ${({ theme }) => theme.deprecated_mediaWidth.deprecated_upToMedium`
grid-template-columns: 1fr;
margin-top: 0; margin-top: 0;
`}; `};
` `
export const RightContainer = styled(AutoColumn)`
grid-row: 1 / 3;
grid-column: 2;
height: fit-content;
${({ theme }) => theme.deprecated_mediaWidth.deprecated_upToMedium`
grid-row: 2 / 3;
grid-column: 1;
`};
`
export const StackedContainer = styled.div`
display: grid;
`
export const StackedItem = styled.div<{ zIndex?: number }>`
grid-column: 1;
grid-row: 1;
height: 100%;
z-index: ${({ zIndex }) => zIndex};
`
export const MediumOnly = styled.div` export const MediumOnly = styled.div`
${({ theme }) => theme.deprecated_mediaWidth.deprecated_upToMedium` ${({ theme }) => theme.deprecated_mediaWidth.deprecated_upToMedium`
display: none; display: none;
`}; `};
` `
export const HideMedium = styled.div`
display: none;
${({ theme }) => theme.deprecated_mediaWidth.deprecated_upToMedium`
display: block;
`};
`
import React, { PropsWithChildren } from 'react' import { PropsWithChildren } from 'react'
import styled from 'styled-components/macro' import styled from 'styled-components/macro'
import { Z_INDEX } from 'theme/zIndex' import { Z_INDEX } from 'theme/zIndex'
......
...@@ -12,6 +12,8 @@ import JSBI from 'jsbi' ...@@ -12,6 +12,8 @@ import JSBI from 'jsbi'
import tryParseCurrencyAmount from 'lib/utils/tryParseCurrencyAmount' import tryParseCurrencyAmount from 'lib/utils/tryParseCurrencyAmount'
import { Wrapper } from 'pages/Pool/styleds' import { Wrapper } from 'pages/Pool/styleds'
import { useCallback, useMemo, useState } from 'react' import { useCallback, useMemo, useState } from 'react'
import { ArrowLeft } from 'react-feather'
import { Link } from 'react-router-dom'
import { import {
CreateProposalData, CreateProposalData,
ProposalState, ProposalState,
...@@ -24,7 +26,6 @@ import { ...@@ -24,7 +26,6 @@ import {
import styled from 'styled-components/macro' import styled from 'styled-components/macro'
import { ExternalLink, ThemedText } from 'theme' import { ExternalLink, ThemedText } from 'theme'
import { CreateProposalTabs } from '../../components/NavigationTabs'
import { LATEST_GOVERNOR_INDEX } from '../../constants/governance' import { LATEST_GOVERNOR_INDEX } from '../../constants/governance'
import { UNI } from '../../constants/tokens' import { UNI } from '../../constants/tokens'
import AppBody from '../AppBody' import AppBody from '../AppBody'
...@@ -45,6 +46,19 @@ const PageWrapper = styled(AutoColumn)` ...@@ -45,6 +46,19 @@ const PageWrapper = styled(AutoColumn)`
} }
` `
const BackArrow = styled(ArrowLeft)`
cursor: pointer;
color: ${({ theme }) => theme.textPrimary};
`
const Nav = styled(Link)`
align-items: center;
display: flex;
flex-direction: row;
justify-content: flex-start;
margin: 1em 0 0 1em;
text-decoration: none;
`
const CreateProposalButton = ({ const CreateProposalButton = ({
proposalThreshold, proposalThreshold,
hasActiveOrPendingProposal, hasActiveOrPendingProposal,
...@@ -242,7 +256,10 @@ ${bodyValue} ...@@ -242,7 +256,10 @@ ${bodyValue}
<Trace page={InterfacePageName.VOTE_PAGE} shouldLogImpression> <Trace page={InterfacePageName.VOTE_PAGE} shouldLogImpression>
<PageWrapper> <PageWrapper>
<AppBody $maxWidth="800px"> <AppBody $maxWidth="800px">
<CreateProposalTabs /> <Nav to="/vote">
<BackArrow />
<ThemedText.SubHeaderLarge>Create Proposal</ThemedText.SubHeaderLarge>
</Nav>
<CreateProposalWrapper> <CreateProposalWrapper>
<BlueCard> <BlueCard>
<AutoColumn gap="10px"> <AutoColumn gap="10px">
......
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