Commit 2adb0a3d authored by Moody Salem's avatar Moody Salem Committed by GitHub

Ts almost everywhere (#736)

* First 2

* More typescript

* More and more

* Almost there

* More

* More typescript

* Fix remove liquidity button

* Make the error chain more readable

* Slippage tabs
parent 86fa969d
/// <reference types="cypress" /> /// <reference types="cypress" />
// *********************************************************** // ***********************************************************
// This example plugins/index.js can be used to load plugins // This example plugins/index.tsx can be used to load plugins
// //
// You can change the location of this file or turn off loading // You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option. // the plugins file with the 'pluginsFile' configuration option.
......
...@@ -15,7 +15,7 @@ const InputPanel = styled.div` ...@@ -15,7 +15,7 @@ const InputPanel = styled.div`
height: 60px; height: 60px;
` `
const ContainerRow = styled.div` const ContainerRow = styled.div<{ error: boolean }>`
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
...@@ -35,7 +35,7 @@ const InputRow = styled.div` ...@@ -35,7 +35,7 @@ const InputRow = styled.div`
padding: 0.75rem; padding: 0.75rem;
` `
const Input = styled.input` const Input = styled.input<{ error: boolean }>`
font-size: 1rem; font-size: 1rem;
outline: none; outline: none;
border: none; border: none;
...@@ -66,12 +66,12 @@ const Input = styled.input` ...@@ -66,12 +66,12 @@ const Input = styled.input`
export default function AddressInputPanel({ initialInput = '', onChange, onError }) { export default function AddressInputPanel({ initialInput = '', onChange, onError }) {
const { library } = useWeb3React() const { library } = useWeb3React()
const [input, setInput] = useState(initialInput.address ? initialInput.address : '') const [input, setInput] = useState(initialInput ? initialInput : '')
const debouncedInput = useDebounce(input, 150) const debouncedInput = useDebounce(input, 150)
const [data, setData] = useState({ address: undefined, name: undefined }) const [data, setData] = useState({ address: undefined, name: undefined })
const [error, setError] = useState(false) const [error, setError] = useState<boolean>(false)
// keep data and errors in sync // keep data and errors in sync
useEffect(() => { useEffect(() => {
...@@ -153,7 +153,7 @@ export default function AddressInputPanel({ initialInput = '', onChange, onError ...@@ -153,7 +153,7 @@ export default function AddressInputPanel({ initialInput = '', onChange, onError
setData({ address: undefined, name: undefined }) setData({ address: undefined, name: undefined })
} }
if (error !== undefined) { if (error !== undefined) {
setError() setError(true)
} }
const input = event.target.value const input = event.target.value
const checksummedInput = isAddress(input) const checksummedInput = isAddress(input)
......
...@@ -8,7 +8,7 @@ import { TYPE } from '../../theme' ...@@ -8,7 +8,7 @@ import { TYPE } from '../../theme'
import { AutoColumn } from '../Column' import { AutoColumn } from '../Column'
import { ButtonRadio } from '../Button' import { ButtonRadio } from '../Button'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import Row, { RowBetween, RowFixed } from '../../components/Row' import Row, { RowBetween, RowFixed } from '../Row'
const InputWrapper = styled(RowBetween)` const InputWrapper = styled(RowBetween)`
width: 200px; width: 200px;
...@@ -17,7 +17,7 @@ const InputWrapper = styled(RowBetween)` ...@@ -17,7 +17,7 @@ const InputWrapper = styled(RowBetween)`
padding: 4px 8px; padding: 4px 8px;
border: 1px solid transparent; border: 1px solid transparent;
border: ${({ active, error, theme }) => border: ${({ active, error, theme }) =>
error ? '1px solid ' + theme.red1 : active ? '1px solid ' + theme.blue1 : ''}; error ? '1px solid ' + theme.red1 : active ? '1px solid ' + theme.blue1 : ''};
` `
const SLIPPAGE_INDEX = { const SLIPPAGE_INDEX = {
...@@ -27,12 +27,19 @@ const SLIPPAGE_INDEX = { ...@@ -27,12 +27,19 @@ const SLIPPAGE_INDEX = {
4: 4 4: 4
} }
export default function AdvancedSettings({ setIsOpen, setDeadline, allowedSlippage, setAllowedSlippage }) { interface AdvancedSettingsProps {
setIsOpen: (boolean) => void
setDeadline: (number) => void
allowedSlippage: number
setAllowedSlippage: (number) => void
}
export default function AdvancedSettings({ setIsOpen, setDeadline, allowedSlippage, setAllowedSlippage }: AdvancedSettingsProps) {
// text translation // text translation
const { t } = useTranslation() const { t } = useTranslation()
const [deadlineInput, setDeadlineInput] = useState(20) const [deadlineInput, setDeadlineInput] = useState(20)
const [slippageInput, setSlippageInput] = useState() const [slippageInput, setSlippageInput] = useState<string>('')
const [activeIndex, setActiveIndex] = useState(SLIPPAGE_INDEX[2]) const [activeIndex, setActiveIndex] = useState(SLIPPAGE_INDEX[2])
const [slippageInputError, setSlippageInputError] = useState(null) // error const [slippageInputError, setSlippageInputError] = useState(null) // error
...@@ -71,7 +78,7 @@ export default function AdvancedSettings({ setIsOpen, setDeadline, allowedSlippa ...@@ -71,7 +78,7 @@ export default function AdvancedSettings({ setIsOpen, setDeadline, allowedSlippa
setActiveIndex(3) setActiveIndex(3)
} else { } else {
setActiveIndex(4) setActiveIndex(4)
setSlippageInput(allowedSlippage / 100) setSlippageInput('' + (allowedSlippage / 100))
parseCustomInput(allowedSlippage) parseCustomInput(allowedSlippage)
} }
}, [allowedSlippage, parseCustomInput]) }, [allowedSlippage, parseCustomInput])
...@@ -87,7 +94,7 @@ export default function AdvancedSettings({ setIsOpen, setDeadline, allowedSlippa ...@@ -87,7 +94,7 @@ export default function AdvancedSettings({ setIsOpen, setDeadline, allowedSlippa
</Link> </Link>
<RowBetween> <RowBetween>
<TYPE.main>Front-running tolerance</TYPE.main> <TYPE.main>Front-running tolerance</TYPE.main>
<QuestionHelper text={t('toleranceExplanation')} /> <QuestionHelper text={t('toleranceExplanation')}/>
</RowBetween> </RowBetween>
<Row> <Row>
<ButtonRadio <ButtonRadio
......
import React from 'react' import React, { useCallback } from 'react'
import styled from 'styled-components' import styled from 'styled-components'
import { withRouter } from 'react-router-dom' import { RouteComponentProps, withRouter } from 'react-router-dom'
import Modal from '../Modal' import Modal from '../Modal'
import Loader from '../Loader' import Loader from '../Loader'
...@@ -32,29 +32,41 @@ const ConfirmedIcon = styled(ColumnCenter)` ...@@ -32,29 +32,41 @@ const ConfirmedIcon = styled(ColumnCenter)`
padding: 60px 0; padding: 60px 0;
` `
interface ConfirmationModalProps extends RouteComponentProps<{}> {
isOpen: boolean
onDismiss: () => void
hash: string
topContent: () => React.ReactChild
bottomContent: () => React.ReactChild
attemptingTxn: boolean
pendingConfirmation: boolean
pendingText: string
title?: string
}
function ConfirmationModal({ function ConfirmationModal({
history, history,
isOpen, isOpen,
onDismiss, onDismiss,
hash, hash,
topContent, topContent,
bottomContent, bottomContent,
attemptingTxn, attemptingTxn,
pendingConfirmation, pendingConfirmation,
pendingText, pendingText,
title = '' title = ''
}) { }: ConfirmationModalProps) {
const { chainId } = useWeb3React() const { chainId } = useWeb3React()
function WrappedOnDismissed(returnToPool = false) { const dismissAndReturn = useCallback(() => {
if (returnToPool && (history.location.pathname.match('/add') || history.location.pathname.match('/remove'))) { if (history.location.pathname.match('/add') || history.location.pathname.match('/remove')) {
history.push('/pool') history.push('/pool')
} }
onDismiss() onDismiss()
} }, [onDismiss, history])
return ( return (
<Modal isOpen={isOpen} onDismiss={WrappedOnDismissed} maxHeight={90}> <Modal isOpen={isOpen} onDismiss={onDismiss} maxHeight={90}>
{!attemptingTxn ? ( {!attemptingTxn ? (
<Wrapper> <Wrapper>
<Section> <Section>
...@@ -62,7 +74,7 @@ function ConfirmationModal({ ...@@ -62,7 +74,7 @@ function ConfirmationModal({
<Text fontWeight={500} fontSize={20}> <Text fontWeight={500} fontSize={20}>
{title} {title}
</Text> </Text>
<CloseIcon onClick={WrappedOnDismissed} /> <CloseIcon onClick={onDismiss}/>
</RowBetween> </RowBetween>
{topContent()} {topContent()}
</Section> </Section>
...@@ -72,14 +84,14 @@ function ConfirmationModal({ ...@@ -72,14 +84,14 @@ function ConfirmationModal({
<Wrapper> <Wrapper>
<Section> <Section>
<RowBetween> <RowBetween>
<div /> <div/>
<CloseIcon onClick={WrappedOnDismissed} /> <CloseIcon onClick={onDismiss}/>
</RowBetween> </RowBetween>
<ConfirmedIcon> <ConfirmedIcon>
{pendingConfirmation ? ( {pendingConfirmation ? (
<Loader size="90px" /> <Loader size="90px"/>
) : ( ) : (
<ArrowUpCircle strokeWidth={0.5} size={90} color="#ff007a" /> <ArrowUpCircle strokeWidth={0.5} size={90} color="#ff007a"/>
)} )}
</ConfirmedIcon> </ConfirmedIcon>
<AutoColumn gap="12px" justify={'center'}> <AutoColumn gap="12px" justify={'center'}>
...@@ -98,7 +110,7 @@ function ConfirmationModal({ ...@@ -98,7 +110,7 @@ function ConfirmationModal({
View on Etherscan View on Etherscan
</Text> </Text>
</Link> </Link>
<ButtonPrimary onClick={() => WrappedOnDismissed(true)} style={{ margin: '20px 0 0 0' }}> <ButtonPrimary onClick={dismissAndReturn} style={{ margin: '20px 0 0 0' }}>
<Text fontWeight={500} fontSize={20}> <Text fontWeight={500} fontSize={20}>
Close Close
</Text> </Text>
......
import { Pair, Token } from '@uniswap/sdk'
import React, { useState, useContext } from 'react' import React, { useState, useContext } from 'react'
import styled, { ThemeContext } from 'styled-components' import styled, { ThemeContext } from 'styled-components'
import '@reach/tooltip/styles.css' import '@reach/tooltip/styles.css'
...@@ -15,13 +16,13 @@ import { useWeb3React } from '../../hooks' ...@@ -15,13 +16,13 @@ import { useWeb3React } from '../../hooks'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { useAddressBalance } from '../../contexts/Balances' import { useAddressBalance } from '../../contexts/Balances'
const InputRow = styled.div` const InputRow = styled.div<{ selected: boolean }>`
${({ theme }) => theme.flexRowNoWrap} ${({ theme }) => theme.flexRowNoWrap}
align-items: center; align-items: center;
padding: ${({ selected }) => (selected ? '0.75rem 0.5rem 0.75rem 1rem' : '0.75rem 0.75rem 0.75rem 1rem')}; padding: ${({ selected }) => (selected ? '0.75rem 0.5rem 0.75rem 1rem' : '0.75rem 0.75rem 0.75rem 1rem')};
` `
const CurrencySelect = styled.button` const CurrencySelect = styled.button<{ selected: boolean }>`
align-items: center; align-items: center;
height: 2.2rem; height: 2.2rem;
font-size: 20px; font-size: 20px;
...@@ -63,7 +64,7 @@ const Aligner = styled.span` ...@@ -63,7 +64,7 @@ const Aligner = styled.span`
justify-content: space-between; justify-content: space-between;
` `
const StyledDropDown = styled(DropDown)` const StyledDropDown = styled(DropDown)<{ selected: boolean }>`
margin: 0 0.25rem 0 0.5rem; margin: 0 0.25rem 0 0.5rem;
height: 35%; height: 35%;
...@@ -73,7 +74,7 @@ const StyledDropDown = styled(DropDown)` ...@@ -73,7 +74,7 @@ const StyledDropDown = styled(DropDown)`
} }
` `
const InputPanel = styled.div` const InputPanel = styled.div<{ hideInput?: boolean }>`
${({ theme }) => theme.flexColumnNoWrap} ${({ theme }) => theme.flexColumnNoWrap}
position: relative; position: relative;
border-radius: ${({ hideInput }) => (hideInput ? '8px' : '20px')}; border-radius: ${({ hideInput }) => (hideInput ? '8px' : '20px')};
...@@ -81,13 +82,13 @@ const InputPanel = styled.div` ...@@ -81,13 +82,13 @@ const InputPanel = styled.div`
z-index: 1; z-index: 1;
` `
const Container = styled.div` const Container = styled.div<{ hideInput: boolean }>`
border-radius: ${({ hideInput }) => (hideInput ? '8px' : '20px')}; border-radius: ${({ hideInput }) => (hideInput ? '8px' : '20px')};
border: 1px solid ${({ theme }) => theme.bg2}; border: 1px solid ${({ theme }) => theme.bg2};
background-color: ${({ theme }) => theme.bg1}; background-color: ${({ theme }) => theme.bg1};
` `
const StyledTokenName = styled.span` const StyledTokenName = styled.span<{ active?: boolean }>`
${({ active }) => (active ? ' margin: 0 0.25rem 0 0.75rem;' : ' margin: 0 0.25rem 0 0.25rem;')} ${({ active }) => (active ? ' margin: 0 0.25rem 0 0.75rem;' : ' margin: 0 0.25rem 0 0.25rem;')}
font-size: ${({ active }) => (active ? '20px' : '16px')}; font-size: ${({ active }) => (active ? '20px' : '16px')};
...@@ -132,28 +133,47 @@ const StyledBalanceMax = styled.button` ...@@ -132,28 +133,47 @@ const StyledBalanceMax = styled.button`
// } // }
// ` // `
interface CurrencyInputPanelProps {
value: string
field: number
onUserInput: (field: number, val: string) => void
onMax: () => void
atMax: boolean
label?: string,
urlAddedTokens?: Token[]
onTokenSelection?: (tokenAddress: string) => void
token?: Token | null,
disableTokenSelect?: boolean,
hideBalance?: boolean,
isExchange?: boolean,
pair?: Pair | null,
hideInput?: boolean,
showSendWithSwap?: boolean,
otherSelectedTokenAddress?: string | null,
advanced?: boolean,
inputId: string
}
export default function CurrencyInputPanel({ export default function CurrencyInputPanel({
value, value,
field, field,
onUserInput, onUserInput,
onMax, onMax,
atMax, atMax,
error, label = 'Input',
type = '', urlAddedTokens = [], // used
label = 'Input', onTokenSelection = null,
urlAddedTokens = [], // used token = null,
onTokenSelection = null, disableTokenSelect = false,
token = null, hideBalance = false,
disableTokenSelect = false, isExchange = false,
hideBalance = false, pair = null, // used for double token logo
isExchange = false, hideInput = false,
pair = null, // used for double token logo showSendWithSwap = false,
hideInput = false, otherSelectedTokenAddress = null,
showSendWithSwap = false, advanced = false,
otherSelectedTokenAddress = null, inputId,
advanced = false, }: CurrencyInputPanelProps) {
inputId,
}) {
const { t } = useTranslation() const { t } = useTranslation()
const [modalOpen, setModalOpen] = useState(false) const [modalOpen, setModalOpen] = useState(false)
...@@ -163,7 +183,7 @@ export default function CurrencyInputPanel({ ...@@ -163,7 +183,7 @@ export default function CurrencyInputPanel({
return ( return (
<InputPanel> <InputPanel>
<Container error={!!error} hideInput={hideInput}> <Container hideInput={hideInput}>
{!hideInput && ( {!hideInput && (
<LabelRow> <LabelRow>
<RowBetween> <RowBetween>
...@@ -189,7 +209,6 @@ export default function CurrencyInputPanel({ ...@@ -189,7 +209,6 @@ export default function CurrencyInputPanel({
)} )}
<InputRow <InputRow
style={hideInput ? { padding: '0', borderRadius: '8px' } : {}} style={hideInput ? { padding: '0', borderRadius: '8px' } : {}}
hideInput={hideInput}
selected={disableTokenSelect} selected={disableTokenSelect}
> >
{!hideInput && ( {!hideInput && (
...@@ -213,24 +232,23 @@ export default function CurrencyInputPanel({ ...@@ -213,24 +232,23 @@ export default function CurrencyInputPanel({
setModalOpen(true) setModalOpen(true)
} }
}} }}
disableTokenSelect={disableTokenSelect}
> >
<Aligner> <Aligner>
{isExchange ? ( {isExchange ? (
<DoubleLogo a0={pair?.token0.address} a1={pair?.token1.address} size={24} margin={true} /> <DoubleLogo a0={pair?.token0.address} a1={pair?.token1.address} size={24} margin={true}/>
) : token?.address ? ( ) : token?.address ? (
<TokenLogo address={token?.address} size={'24px'} /> <TokenLogo address={token?.address} size={'24px'}/>
) : null} ) : null}
{isExchange ? ( {isExchange ? (
<StyledTokenName> <StyledTokenName>
{pair?.token0.symbol}:{pair?.token1.symbol} {pair?.token0.symbol}:{pair?.token1.symbol}
</StyledTokenName> </StyledTokenName>
) : ( ) : (
<StyledTokenName active={token && token.symbol}> <StyledTokenName active={Boolean(token && token.symbol)}>
{(token && token.symbol) || t('selectToken')} {(token && token.symbol) || t('selectToken')}
</StyledTokenName> </StyledTokenName>
)} )}
{!disableTokenSelect && <StyledDropDown selected={!!token?.address} />} {!disableTokenSelect && <StyledDropDown selected={!!token?.address}/>}
</Aligner> </Aligner>
</CurrencySelect> </CurrencySelect>
</InputRow> </InputRow>
......
...@@ -2,27 +2,33 @@ import React from 'react' ...@@ -2,27 +2,33 @@ import React from 'react'
import styled from 'styled-components' import styled from 'styled-components'
import TokenLogo from '../TokenLogo' import TokenLogo from '../TokenLogo'
export default function DoubleTokenLogo({ a0, a1, size = 16, margin = false }) { const TokenWrapper = styled.div<{ margin: boolean; sizeraw: number }>`
const TokenWrapper = styled.div`
position: relative; position: relative;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
margin-right: ${({ sizeraw, margin }) => margin && (sizeraw / 3 + 8).toString() + 'px'}; margin-right: ${({ sizeraw, margin }) => margin && (sizeraw / 3 + 8).toString() + 'px'};
` `
const HigherLogo = styled(TokenLogo)` interface DoubleTokenLogoProps {
margin?: boolean
size?: number
a0: string
a1: string
}
const HigherLogo = styled(TokenLogo)`
z-index: 2; z-index: 2;
` `
const CoveredLogo = styled(TokenLogo)<{ sizeraw: number }>`
const CoveredLogo = styled(TokenLogo)`
position: absolute; position: absolute;
left: ${({ sizeraw }) => (sizeraw / 2).toString() + 'px'}; left: ${({ sizeraw }) => (sizeraw / 2).toString() + 'px'};
` `
export default function DoubleTokenLogo({ a0, a1, size = 16, margin = false }: DoubleTokenLogoProps) {
return ( return (
<TokenWrapper sizeraw={size} margin={margin}> <TokenWrapper sizeraw={size} margin={margin}>
<HigherLogo address={a0} size={size.toString() + 'px'} /> <HigherLogo address={a0} size={size.toString() + 'px'}/>
<CoveredLogo address={a1} size={size.toString() + 'px'} sizeraw={size} /> <CoveredLogo address={a1} size={size.toString() + 'px'} sizeraw={size}/>
</TokenWrapper> </TokenWrapper>
) )
} }
...@@ -2,7 +2,7 @@ import React, { useState, useCallback, useEffect } from 'react' ...@@ -2,7 +2,7 @@ import React, { useState, useCallback, useEffect } from 'react'
import { parseEther, parseUnits } from '@ethersproject/units' import { parseEther, parseUnits } from '@ethersproject/units'
import { Fraction, JSBI, Percent, TokenAmount, TradeType, WETH } from '@uniswap/sdk' import { Fraction, JSBI, Percent, TokenAmount, TradeType, WETH } from '@uniswap/sdk'
import { ArrowDown, ChevronDown, ChevronUp, Repeat } from 'react-feather' import { ArrowDown, ChevronDown, ChevronUp, Repeat } from 'react-feather'
import { withRouter,RouteComponentProps } from 'react-router-dom' import { withRouter, RouteComponentProps } from 'react-router-dom'
import { BigNumber } from '@ethersproject/bignumber' import { BigNumber } from '@ethersproject/bignumber'
import { Zero, MaxUint256 } from '@ethersproject/constants' import { Zero, MaxUint256 } from '@ethersproject/constants'
import { Contract } from '@ethersproject/contracts' import { Contract } from '@ethersproject/contracts'
...@@ -10,7 +10,7 @@ import { Field, SwapAction, useSwapStateReducer } from './swap-store' ...@@ -10,7 +10,7 @@ import { Field, SwapAction, useSwapStateReducer } from './swap-store'
import { Text } from 'rebass' import { Text } from 'rebass'
import Card, { BlueCard, GreyCard, YellowCard } from '../../components/Card' import Card, { BlueCard, GreyCard, YellowCard } from '../../components/Card'
import { AutoColumn, ColumnCenter } from '../../components/Column' import { AutoColumn, ColumnCenter } from '../../components/Column'
import { AutoRow, RowBetween, RowFixed } from '../../components/Row' import { AutoRow, RowBetween, RowFixed } from '../Row'
import { ROUTER_ADDRESS } from '../../constants' import { ROUTER_ADDRESS } from '../../constants'
import { useAddressAllowance } from '../../contexts/Allowances' import { useAddressAllowance } from '../../contexts/Allowances'
import { useUserAdvanced } from '../../contexts/Application' import { useUserAdvanced } from '../../contexts/Application'
...@@ -23,7 +23,14 @@ import { useTokenContract, useWeb3React } from '../../hooks' ...@@ -23,7 +23,14 @@ import { useTokenContract, useWeb3React } from '../../hooks'
import { useTradeExactIn, useTradeExactOut } from '../../hooks/Trades' import { useTradeExactIn, useTradeExactOut } from '../../hooks/Trades'
import { Hover, theme, TYPE } from '../../theme' import { Hover, theme, TYPE } from '../../theme'
import { Link } from '../../theme/components' import { Link } from '../../theme/components'
import { calculateGasMargin, getEtherscanLink, getProviderOrSigner, getRouterContract, isWETH, QueryParams } from '../../utils' import {
calculateGasMargin,
getEtherscanLink,
getProviderOrSigner,
getRouterContract,
isWETH,
QueryParams
} from '../../utils'
import Copy from '../AccountDetails/Copy' import Copy from '../AccountDetails/Copy'
import AddressInputPanel from '../AddressInputPanel' import AddressInputPanel from '../AddressInputPanel'
import { ButtonError, ButtonLight, ButtonPrimary } from '../Button' import { ButtonError, ButtonLight, ButtonPrimary } from '../Button'
...@@ -721,7 +728,7 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro ...@@ -721,7 +728,7 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
</Text> </Text>
</RowFixed> </RowFixed>
</RowBetween> </RowBetween>
<AutoColumn justify="flex-start" gap="sm" style={{padding: '20px 0 0 0px'}}> <AutoColumn justify="flex-start" gap="sm" style={{ padding: '20px 0 0 0px' }}>
{independentField === Field.INPUT ? ( {independentField === Field.INPUT ? (
<TYPE.italic textAlign="left" style={{ width: '100%', paddingTop: '.5rem' }}> <TYPE.italic textAlign="left" style={{ width: '100%', paddingTop: '.5rem' }}>
{`Output is estimated. You will receive at least `} {`Output is estimated. You will receive at least `}
...@@ -976,14 +983,13 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro ...@@ -976,14 +983,13 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
<CurrencyInputPanel <CurrencyInputPanel
field={Field.INPUT} field={Field.INPUT}
value={formattedAmounts[Field.INPUT]} value={formattedAmounts[Field.INPUT]}
onUserInput={val => onUserInput(Field.INPUT, val)} onUserInput={(field, val) => onUserInput(Field.INPUT, val)}
onMax={() => { onMax={() => {
maxAmountInput && onMaxInput(maxAmountInput.toExact()) maxAmountInput && onMaxInput(maxAmountInput.toExact())
}} }}
atMax={atMaxAmountInput} atMax={atMaxAmountInput}
token={tokens[Field.INPUT]} token={tokens[Field.INPUT]}
onTokenSelection={address => _onTokenSelect(address)} onTokenSelection={address => _onTokenSelect(address)}
error={inputError}
pair={pair} pair={pair}
hideBalance={true} hideBalance={true}
hideInput={true} hideInput={true}
...@@ -1005,7 +1011,6 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro ...@@ -1005,7 +1011,6 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
value={formattedAmounts[Field.INPUT]} value={formattedAmounts[Field.INPUT]}
atMax={atMaxAmountInput} atMax={atMaxAmountInput}
token={tokens[Field.INPUT]} token={tokens[Field.INPUT]}
error={inputError}
pair={pair} pair={pair}
advanced={advanced} advanced={advanced}
onUserInput={onUserInput} onUserInput={onUserInput}
...@@ -1029,7 +1034,7 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro ...@@ -1029,7 +1034,7 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
</ColumnCenter> </ColumnCenter>
) : ( ) : (
<Hover> <Hover>
<ColumnCenter style={{padding: '0 1rem'}}> <ColumnCenter style={{ padding: '0 1rem' }}>
<ArrowWrapper> <ArrowWrapper>
<ArrowDown <ArrowDown
size="16" size="16"
...@@ -1051,7 +1056,6 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro ...@@ -1051,7 +1056,6 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
atMax={atMaxAmountOutput} atMax={atMaxAmountOutput}
token={tokens[Field.OUTPUT]} token={tokens[Field.OUTPUT]}
onTokenSelection={address => onTokenSelection(Field.OUTPUT, address)} onTokenSelection={address => onTokenSelection(Field.OUTPUT, address)}
error={outputError}
pair={pair} pair={pair}
advanced={advanced} advanced={advanced}
otherSelectedTokenAddress={tokens[Field.INPUT]?.address} otherSelectedTokenAddress={tokens[Field.INPUT]?.address}
...@@ -1185,23 +1189,9 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro ...@@ -1185,23 +1189,9 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
<Text fontSize={20} fontWeight={500}> <Text fontSize={20} fontWeight={500}>
{!account {!account
? 'Connect Wallet' ? 'Connect Wallet'
: generalError : (generalError || inputError || outputError || recipientError || tradeError) ||
? generalError (`${sending ? 'Send' : 'Swap'}${warningHigh ? ' Anyway' : ''}`)
: inputError }
? inputError
: outputError
? outputError
: recipientError
? recipientError
: tradeError
? tradeError
: warningHigh
? sendingWithSwap
? 'Send Anyway'
: 'Swap Anyway'
: sending
? 'Send'
: 'Swap'}
</Text> </Text>
</ButtonError> </ButtonError>
)} )}
......
...@@ -13,7 +13,7 @@ const StyledIdenticon = styled.div` ...@@ -13,7 +13,7 @@ const StyledIdenticon = styled.div`
` `
export default function Identicon() { export default function Identicon() {
const ref = useRef() const ref = useRef<HTMLDivElement>()
const { account } = useWeb3React() const { account } = useWeb3React()
...@@ -24,5 +24,5 @@ export default function Identicon() { ...@@ -24,5 +24,5 @@ export default function Identicon() {
} }
}, [account]) }, [account])
return <StyledIdenticon ref={ref} /> return <StyledIdenticon ref={ref}/>
} }
...@@ -5,11 +5,11 @@ import styled from 'styled-components' ...@@ -5,11 +5,11 @@ import styled from 'styled-components'
import { Spinner } from '../../theme' import { Spinner } from '../../theme'
import Circle from '../../assets/images/blue-loader.svg' import Circle from '../../assets/images/blue-loader.svg'
const SpinnerWrapper = styled(Spinner)` const SpinnerWrapper = styled(Spinner)<{ size: string }>`
height: ${({ size }) => size}; height: ${({ size }) => size};
width: ${({ size }) => size}; width: ${({ size }) => size};
` `
export default function Loader({ size }) { export default function Loader({ size }: { size: string }) {
return <SpinnerWrapper src={Circle} alt="loader" size={size} /> return <SpinnerWrapper src={Circle} alt="loader" size={size}/>
} }
...@@ -22,8 +22,8 @@ const StyledDialogOverlay = styled(WrappedDialogOverlay).attrs({ ...@@ -22,8 +22,8 @@ const StyledDialogOverlay = styled(WrappedDialogOverlay).attrs({
background-color: ${({ theme }) => 'transparent'}; background-color: ${({ theme }) => 'transparent'};
${({ mobile }) => ${({ mobile }) =>
mobile && mobile &&
css` css`
align-items: flex-end; align-items: flex-end;
`} `}
...@@ -56,13 +56,13 @@ const StyledDialogContent = styled(FilteredDialogContent)` ...@@ -56,13 +56,13 @@ const StyledDialogContent = styled(FilteredDialogContent)`
max-width: 420px; max-width: 420px;
${({ maxHeight }) => ${({ maxHeight }) =>
maxHeight && maxHeight &&
css` css`
max-height: ${maxHeight}vh; max-height: ${maxHeight}vh;
`} `}
${({ minHeight }) => ${({ minHeight }) =>
minHeight && minHeight &&
css` css`
min-height: ${minHeight}vh; min-height: ${minHeight}vh;
`} `}
display: flex; display: flex;
...@@ -77,7 +77,7 @@ const StyledDialogContent = styled(FilteredDialogContent)` ...@@ -77,7 +77,7 @@ const StyledDialogContent = styled(FilteredDialogContent)`
width: 85vw; width: 85vw;
max-height: 66vh; max-height: 66vh;
${mobile && ${mobile &&
css` css`
width: 100vw; width: 100vw;
border-radius: 20px; border-radius: 20px;
border-bottom-left-radius: 0; border-bottom-left-radius: 0;
...@@ -95,14 +95,23 @@ const HiddenCloseButton = styled.button` ...@@ -95,14 +95,23 @@ const HiddenCloseButton = styled.button`
border: none; border: none;
` `
interface ModalProps {
isOpen: boolean
onDismiss: () => void
minHeight?: number | false
maxHeight?: number
initialFocusRef?: React.Ref<any>
children?: React.ReactNode
}
export default function Modal({ export default function Modal({
isOpen, isOpen,
onDismiss, onDismiss,
minHeight = false, minHeight = false,
maxHeight = 50, maxHeight = 50,
initialFocusRef = null, initialFocusRef = null,
children children
}) { }: ModalProps) {
const transitions = useTransition(isOpen, null, { const transitions = useTransition(isOpen, null, {
config: { duration: 200 }, config: { duration: 200 },
from: { opacity: 0 }, from: { opacity: 0 },
...@@ -131,68 +140,76 @@ export default function Modal({ ...@@ -131,68 +140,76 @@ export default function Modal({
}) })
if (isMobile) { if (isMobile) {
return transitions.map( return (
({ item, key, props }) => <>
item && ( {transitions.map(
<StyledDialogOverlay ({ item, key, props }) =>
key={key} item && (
style={props} <StyledDialogOverlay
onDismiss={onDismiss} key={key}
initialFocusRef={initialFocusRef} style={props}
mobile={isMobile} onDismiss={onDismiss}
> initialFocusRef={initialFocusRef}
<Spring // animation for entrance and exit mobile={isMobile}
from={{ >
transform: isOpen ? 'translateY(200px)' : 'translateY(100px)' <Spring // animation for entrance and exit
}} from={{
to={{ transform: isOpen ? 'translateY(200px)' : 'translateY(100px)'
transform: isOpen ? 'translateY(0px)' : 'translateY(200px)' }}
}} to={{
> transform: isOpen ? 'translateY(0px)' : 'translateY(200px)'
{props => ( }}
<animated.div
{...bind()}
style={{ transform: xy.interpolate((x, y) => `translate3d(${0}px,${y > 0 ? y : 0}px,0)`) }}
> >
<StyledDialogContent {props => (
style={props} <animated.div
hidden={true} {...bind()}
minHeight={minHeight} style={{ transform: (xy as any).interpolate((x, y) => `translate3d(${0}px,${y > 0 ? y : 0}px,0)`) }}
maxHeight={maxHeight} >
mobile={isMobile} <StyledDialogContent
> style={props}
<HiddenCloseButton onClick={onDismiss} /> hidden={true}
{children} minHeight={minHeight}
</StyledDialogContent> maxHeight={maxHeight}
</animated.div> mobile={isMobile}
)} >
</Spring> <HiddenCloseButton onClick={onDismiss}/>
</StyledDialogOverlay> {children}
) </StyledDialogContent>
</animated.div>
)}
</Spring>
</StyledDialogOverlay>
)
)}
</>
) )
} else { } else {
return transitions.map( return (
({ item, key, props }) => <>
item && ( {transitions.map(
<StyledDialogOverlay ({ item, key, props }) =>
key={key} item && (
style={props} <StyledDialogOverlay
onDismiss={onDismiss} key={key}
initialFocusRef={initialFocusRef} style={props}
mobile={isMobile} onDismiss={onDismiss}
> initialFocusRef={initialFocusRef}
<StyledDialogContent mobile={isMobile}
hidden={true} >
minHeight={minHeight} <StyledDialogContent
maxHeight={maxHeight} hidden={true}
isOpen={isOpen} minHeight={minHeight}
mobile={isMobile} maxHeight={maxHeight}
> isOpen={isOpen}
<HiddenCloseButton onClick={onDismiss} /> mobile={isMobile}
{children} >
</StyledDialogContent> <HiddenCloseButton onClick={onDismiss}/>
</StyledDialogOverlay> {children}
) </StyledDialogContent>
</StyledDialogOverlay>
)
)}
</>
) )
} }
} }
import React, { useCallback } from 'react' import React, { useCallback } from 'react';
import styled from 'styled-components' import styled from 'styled-components';
import { darken } from 'polished' import { darken } from 'polished';
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next';
import { withRouter, NavLink, Link as HistoryLink } from 'react-router-dom' import { withRouter, NavLink, Link as HistoryLink, RouteComponentProps } from 'react-router-dom';
import { Hover } from '../../theme' import { Hover } from '../../theme';
import { ArrowLeft } from 'react-feather' import { ArrowLeft } from 'react-feather';
import { RowBetween } from '../Row' import { RowBetween } from '../Row';
import QuestionHelper from '../Question' import QuestionHelper from '../Question';
import { useBodyKeyDown } from '../../hooks' import { useBodyKeyDown } from '../../hooks';
const tabOrder = [ const tabOrder = [
{ {
...@@ -27,16 +27,16 @@ const tabOrder = [ ...@@ -27,16 +27,16 @@ const tabOrder = [
textKey: 'pool', textKey: 'pool',
regex: /\/pool/ regex: /\/pool/
} }
] ];
const Tabs = styled.div` const Tabs = styled.div`
${({ theme }) => theme.flexRowNoWrap} ${({ theme }) => theme.flexRowNoWrap}
align-items: center; align-items: center;
border-radius: 3rem; border-radius: 3rem;
margin-bottom: 20px; margin-bottom: 20px;
` `;
const activeClassName = 'ACTIVE' const activeClassName = 'ACTIVE';
const StyledNavLink = styled(NavLink).attrs({ const StyledNavLink = styled(NavLink).attrs({
activeClassName activeClassName
...@@ -65,41 +65,41 @@ const StyledNavLink = styled(NavLink).attrs({ ...@@ -65,41 +65,41 @@ const StyledNavLink = styled(NavLink).attrs({
:focus { :focus {
color: ${({ theme }) => darken(0.1, theme.text1)}; color: ${({ theme }) => darken(0.1, theme.text1)};
} }
` `;
const ActiveText = styled.div` const ActiveText = styled.div`
font-weight: 500; font-weight: 500;
font-size: 20px; font-size: 20px;
` `;
const ArrowLink = styled(ArrowLeft)` const ArrowLink = styled(ArrowLeft)`
color: ${({ theme }) => theme.text1}; color: ${({ theme }) => theme.text1};
` `;
function NavigationTabs({ location: { pathname }, history }) { function NavigationTabs({ location: { pathname }, history }: RouteComponentProps<{}>) {
const { t } = useTranslation() const { t } = useTranslation();
const navigate = useCallback( const navigate = useCallback(
direction => { direction => {
const tabIndex = tabOrder.findIndex(({ regex }) => pathname.match(regex)) const tabIndex = tabOrder.findIndex(({ regex }) => pathname.match(regex));
history.push(tabOrder[(tabIndex + tabOrder.length + direction) % tabOrder.length].path) history.push(tabOrder[ (tabIndex + tabOrder.length + direction) % tabOrder.length ].path);
}, },
[pathname, history] [pathname, history]
) );
const navigateRight = useCallback(() => { const navigateRight = useCallback(() => {
navigate(1) navigate(1);
}, [navigate]) }, [navigate]);
const navigateLeft = useCallback(() => { const navigateLeft = useCallback(() => {
navigate(-1) navigate(-1);
}, [navigate]) }, [navigate]);
useBodyKeyDown('ArrowRight', navigateRight) useBodyKeyDown('ArrowRight', navigateRight);
useBodyKeyDown('ArrowLeft', navigateLeft) useBodyKeyDown('ArrowLeft', navigateLeft);
const adding = pathname.match('/add') const adding = pathname.match('/add');
const removing = pathname.match('/remove') const removing = pathname.match('/remove');
const finding = pathname.match('/find') const finding = pathname.match('/find');
const creating = pathname.match('/create') const creating = pathname.match('/create');
return ( return (
<> <>
...@@ -107,7 +107,7 @@ function NavigationTabs({ location: { pathname }, history }) { ...@@ -107,7 +107,7 @@ function NavigationTabs({ location: { pathname }, history }) {
<Tabs> <Tabs>
<RowBetween style={{ padding: '1rem 1rem 0 1rem' }}> <RowBetween style={{ padding: '1rem 1rem 0 1rem' }}>
<Hover onClick={() => history.goBack()}> <Hover onClick={() => history.goBack()}>
<ArrowLink /> <ArrowLink/>
</Hover> </Hover>
<ActiveText>{adding ? 'Add' : 'Remove'} Liquidity</ActiveText> <ActiveText>{adding ? 'Add' : 'Remove'} Liquidity</ActiveText>
<QuestionHelper <QuestionHelper
...@@ -123,33 +123,33 @@ function NavigationTabs({ location: { pathname }, history }) { ...@@ -123,33 +123,33 @@ function NavigationTabs({ location: { pathname }, history }) {
<Tabs> <Tabs>
<RowBetween style={{ padding: '1rem' }}> <RowBetween style={{ padding: '1rem' }}>
<HistoryLink to="/pool"> <HistoryLink to="/pool">
<ArrowLink /> <ArrowLink/>
</HistoryLink> </HistoryLink>
<ActiveText>Import Pool</ActiveText> <ActiveText>Import Pool</ActiveText>
<QuestionHelper text={"Use this tool to find pairs that don't automatically appear in the interface."} /> <QuestionHelper text={'Use this tool to find pairs that don\'t automatically appear in the interface.'}/>
</RowBetween> </RowBetween>
</Tabs> </Tabs>
) : creating ? ( ) : creating ? (
<Tabs> <Tabs>
<RowBetween style={{ padding: '1rem' }}> <RowBetween style={{ padding: '1rem' }}>
<HistoryLink to="/pool"> <HistoryLink to="/pool">
<ArrowLink /> <ArrowLink/>
</HistoryLink> </HistoryLink>
<ActiveText>Create Pool</ActiveText> <ActiveText>Create Pool</ActiveText>
<QuestionHelper text={'Use this interface to create a new pool.'} /> <QuestionHelper text={'Use this interface to create a new pool.'}/>
</RowBetween> </RowBetween>
</Tabs> </Tabs>
) : ( ) : (
<Tabs> <Tabs>
{tabOrder.map(({ path, textKey, regex }) => ( {tabOrder.map(({ path, textKey, regex }) => (
<StyledNavLink key={path} to={path} isActive={(_, { pathname }) => pathname.match(regex)}> <StyledNavLink key={path} to={path} isActive={(_, { pathname }) => !!pathname.match(regex)}>
{t(textKey)} {t(textKey)}
</StyledNavLink> </StyledNavLink>
))} ))}
</Tabs> </Tabs>
)} )}
</> </>
) );
} }
export default withRouter(NavigationTabs) export default withRouter(NavigationTabs);
import React from 'react'
import styled from 'styled-components'
const Panel = styled.div`
position: relative;
background-color: ${({ theme }) => theme.bg1};
width: calc(100% - 1rem);
margin: 0 auto;
border-radius: 0.625rem;
`
const PanelTop = styled.div`
content: '';
position: absolute;
top: -0.5rem;
left: 0;
height: 1rem;
width: 100%;
background-color: ${({ theme }) => theme.bg1};
`
const PanelBottom = styled.div`
position: absolute;
top: 80%;
left: 0;
height: 1rem;
width: 100%;
background-color: ${({ theme }) => theme.bg1};
`
export default function OversizedPanel({ hideTop, hideBottom, children }) {
return (
<Panel>
{hideTop || <PanelTop />}
{children}
{hideBottom || <PanelBottom />}
</Panel>
)
}
...@@ -16,7 +16,7 @@ const StyledClose = styled(X)` ...@@ -16,7 +16,7 @@ const StyledClose = styled(X)`
} }
` `
const MobilePopupWrapper = styled.div` const MobilePopupWrapper = styled.div<{ height: string | number }>`
position: relative; position: relative;
max-width: 100%; max-width: 100%;
height: ${({ height }) => height}; height: ${({ height }) => height};
...@@ -79,7 +79,7 @@ export default function App() { ...@@ -79,7 +79,7 @@ export default function App() {
{activePopups.map(item => { {activePopups.map(item => {
return ( return (
<Popup key={item.key}> <Popup key={item.key}>
<StyledClose color="#888D9B" onClick={() => removePopup(item.key)} /> <StyledClose color="#888D9B" onClick={() => removePopup(item.key)}/>
{React.cloneElement(item.content, { popKey: item.key })} {React.cloneElement(item.content, { popKey: item.key })}
</Popup> </Popup>
) )
...@@ -98,7 +98,7 @@ export default function App() { ...@@ -98,7 +98,7 @@ export default function App() {
.map(item => { .map(item => {
return ( return (
<Popup key={item.key}> <Popup key={item.key}>
<StyledClose color="#888D9B" onClick={() => removePopup(item.key)} /> <StyledClose color="#888D9B" onClick={() => removePopup(item.key)}/>
{React.cloneElement(item.content, { popKey: item.key })} {React.cloneElement(item.content, { popKey: item.key })}
</Popup> </Popup>
) )
......
import React, { useState } from 'react' import React, { useState } from 'react'
import styled from 'styled-components' import styled from 'styled-components'
import { darken } from 'polished' import { darken } from 'polished'
import { withRouter } from 'react-router-dom' import { RouteComponentProps, withRouter } from 'react-router-dom'
import { Percent, Pair } from '@uniswap/sdk' import { Percent, Pair, Token } from '@uniswap/sdk'
import { useWeb3React } from '@web3-react/core' import { useWeb3React } from '@web3-react/core'
import { useAllBalances } from '../../contexts/Balances' import { useAllBalances } from '../../contexts/Balances'
...@@ -30,7 +30,15 @@ const HoverCard = styled(Card)` ...@@ -30,7 +30,15 @@ const HoverCard = styled(Card)`
} }
` `
function PositionCard({ pairAddress, token0, token1, history, minimal = false, ...rest }) { interface PositionCardProps extends RouteComponentProps<{}> {
pairAddress: string;
token0: Token
token1: Token
minimal?: boolean
border?: string
}
function PositionCard({ pairAddress, token0, token1, history, border, minimal = false }: PositionCardProps) {
const { account } = useWeb3React() const { account } = useWeb3React()
const allBalances = useAllBalances() const allBalances = useAllBalances()
...@@ -67,7 +75,7 @@ function PositionCard({ pairAddress, token0, token1, history, minimal = false, . ...@@ -67,7 +75,7 @@ function PositionCard({ pairAddress, token0, token1, history, minimal = false, .
return ( return (
<> <>
{userPoolBalance && userPoolBalance.toFixed(6) > 0 && ( {userPoolBalance && userPoolBalance.toFixed(6) > 0 && (
<GreyCard {...rest}> <GreyCard border={border}>
<AutoColumn gap="12px"> <AutoColumn gap="12px">
<FixedHeightRow> <FixedHeightRow>
<RowFixed> <RowFixed>
...@@ -78,7 +86,7 @@ function PositionCard({ pairAddress, token0, token1, history, minimal = false, . ...@@ -78,7 +86,7 @@ function PositionCard({ pairAddress, token0, token1, history, minimal = false, .
</FixedHeightRow> </FixedHeightRow>
<FixedHeightRow onClick={() => setShowMore(!showMore)}> <FixedHeightRow onClick={() => setShowMore(!showMore)}>
<RowFixed> <RowFixed>
<DoubleLogo a0={token0?.address || ''} a1={token1?.address || ''} margin={true} size={20} /> <DoubleLogo a0={token0?.address || ''} a1={token1?.address || ''} margin={true} size={20}/>
<Text fontWeight={500} fontSize={20}> <Text fontWeight={500} fontSize={20}>
{token0?.symbol}:{token1?.symbol} {token0?.symbol}:{token1?.symbol}
</Text> </Text>
...@@ -96,7 +104,7 @@ function PositionCard({ pairAddress, token0, token1, history, minimal = false, . ...@@ -96,7 +104,7 @@ function PositionCard({ pairAddress, token0, token1, history, minimal = false, .
</Text> </Text>
{token0Deposited ? ( {token0Deposited ? (
<RowFixed> <RowFixed>
{!minimal && <TokenLogo address={token0?.address || ''} />} {!minimal && <TokenLogo address={token0?.address || ''}/>}
<Text color="#888D9B" fontSize={16} fontWeight={500} marginLeft={'6px'}> <Text color="#888D9B" fontSize={16} fontWeight={500} marginLeft={'6px'}>
{token0Deposited?.toFixed(8)} {token0Deposited?.toFixed(8)}
</Text> </Text>
...@@ -111,7 +119,7 @@ function PositionCard({ pairAddress, token0, token1, history, minimal = false, . ...@@ -111,7 +119,7 @@ function PositionCard({ pairAddress, token0, token1, history, minimal = false, .
</Text> </Text>
{token1Deposited ? ( {token1Deposited ? (
<RowFixed> <RowFixed>
{!minimal && <TokenLogo address={token1?.address || ''} />} {!minimal && <TokenLogo address={token1?.address || ''}/>}
<Text color="#888D9B" fontSize={16} fontWeight={500} marginLeft={'6px'}> <Text color="#888D9B" fontSize={16} fontWeight={500} marginLeft={'6px'}>
{token1Deposited?.toFixed(8)} {token1Deposited?.toFixed(8)}
</Text> </Text>
...@@ -128,20 +136,20 @@ function PositionCard({ pairAddress, token0, token1, history, minimal = false, . ...@@ -128,20 +136,20 @@ function PositionCard({ pairAddress, token0, token1, history, minimal = false, .
) )
} else } else
return ( return (
<HoverCard {...rest}> <HoverCard border={border}>
<AutoColumn gap="12px"> <AutoColumn gap="12px">
<FixedHeightRow onClick={() => setShowMore(!showMore)} style={{ cursor: 'pointer' }}> <FixedHeightRow onClick={() => setShowMore(!showMore)} style={{ cursor: 'pointer' }}>
<RowFixed> <RowFixed>
<DoubleLogo a0={token0?.address || ''} a1={token1?.address || ''} margin={true} size={20} /> <DoubleLogo a0={token0?.address || ''} a1={token1?.address || ''} margin={true} size={20}/>
<Text fontWeight={500} fontSize={20}> <Text fontWeight={500} fontSize={20}>
{token0?.symbol}:{token1?.symbol} {token0?.symbol}:{token1?.symbol}
</Text> </Text>
</RowFixed> </RowFixed>
<RowFixed> <RowFixed>
{showMore ? ( {showMore ? (
<ChevronUp size="20" style={{ marginLeft: '10px' }} /> <ChevronUp size="20" style={{ marginLeft: '10px' }}/>
) : ( ) : (
<ChevronDown size="20" style={{ marginLeft: '10px' }} /> <ChevronDown size="20" style={{ marginLeft: '10px' }}/>
)} )}
</RowFixed> </RowFixed>
</FixedHeightRow> </FixedHeightRow>
...@@ -159,7 +167,7 @@ function PositionCard({ pairAddress, token0, token1, history, minimal = false, . ...@@ -159,7 +167,7 @@ function PositionCard({ pairAddress, token0, token1, history, minimal = false, .
{token0Deposited?.toFixed(8)} {token0Deposited?.toFixed(8)}
</Text> </Text>
{!minimal && ( {!minimal && (
<TokenLogo size="20px" style={{ marginLeft: '8px' }} address={token0?.address || ''} /> <TokenLogo size="20px" style={{ marginLeft: '8px' }} address={token0?.address || ''}/>
)} )}
</RowFixed> </RowFixed>
) : ( ) : (
...@@ -179,7 +187,7 @@ function PositionCard({ pairAddress, token0, token1, history, minimal = false, . ...@@ -179,7 +187,7 @@ function PositionCard({ pairAddress, token0, token1, history, minimal = false, .
{token1Deposited?.toFixed(8)} {token1Deposited?.toFixed(8)}
</Text> </Text>
{!minimal && ( {!minimal && (
<TokenLogo size="20px" style={{ marginLeft: '8px' }} address={token1?.address || ''} /> <TokenLogo size="20px" style={{ marginLeft: '8px' }} address={token1?.address || ''}/>
)} )}
</RowFixed> </RowFixed>
) : ( ) : (
......
...@@ -2,8 +2,6 @@ import React, { useState } from 'react' ...@@ -2,8 +2,6 @@ import React, { useState } from 'react'
import styled, { keyframes } from 'styled-components' import styled, { keyframes } from 'styled-components'
import { HelpCircle as Question } from 'react-feather' import { HelpCircle as Question } from 'react-feather'
// import question from '../../assets/images/question.svg'
const Wrapper = styled.div` const Wrapper = styled.div`
position: relative; position: relative;
` `
......
import styled from 'styled-components' import styled from 'styled-components'
import { Box } from 'rebass/styled-components' import { Box } from 'rebass/styled-components'
const Row = styled(Box)` const Row = styled(Box)<{ align?: string; padding?: string; border?: string; borderRadius?: string }>`
width: 100%; width: 100%;
display: flex; display: flex;
padding: 0; padding: 0;
...@@ -21,7 +21,7 @@ export const RowFlat = styled.div` ...@@ -21,7 +21,7 @@ export const RowFlat = styled.div`
align-items: flex-end; align-items: flex-end;
` `
export const AutoRow = styled(Row)` export const AutoRow = styled(Row)<{ gap: string; justify?: string }>`
flex-wrap: wrap; flex-wrap: wrap;
margin: -${({ gap }) => gap}; margin: -${({ gap }) => gap};
justify-content: ${({ justify }) => justify && justify}; justify-content: ${({ justify }) => justify && justify};
......
import React, { useState, useEffect } from 'react' import React, { useState, useEffect, useCallback } from 'react'
import Slider from '@material-ui/core/Slider' import Slider from '@material-ui/core/Slider'
import { withStyles } from '@material-ui/core/styles' import { withStyles } from '@material-ui/core/styles'
import { useDebounce } from '../../hooks' import { useDebounce } from '../../hooks'
// const marks = [
// {
// value: 0
// },
// {
// value: 25
// },
// {
// value: 50
// },
// {
// value: 75
// },
// {
// value: 100
// }
// ]
const StyledSlider = withStyles({ const StyledSlider = withStyles({
root: { root: {
width: '95%', width: '95%',
...@@ -66,16 +48,22 @@ const StyledSlider = withStyles({ ...@@ -66,16 +48,22 @@ const StyledSlider = withStyles({
} }
})(Slider) })(Slider)
export default function InputSlider({ value, onChange, override }) { interface InputSliderProps {
const [internalVal, setInternalVal] = useState(100) value: number
const debouncedInternalValue = useDebounce(internalVal, 10) onChange: (val: number) => void
override?: boolean
}
export default function InputSlider({ value, onChange, override }: InputSliderProps) {
const [internalVal, setInternalVal] = useState<number>(value)
const debouncedInternalValue = useDebounce(internalVal, 100)
function handleChange(e, val) { const handleChange = useCallback((e, val) => {
setInternalVal(val) setInternalVal(val)
if (val === debouncedInternalValue) { if (val !== debouncedInternalValue) {
onChange(e, val) onChange(val)
} }
} }, [setInternalVal, onChange, debouncedInternalValue])
useEffect(() => { useEffect(() => {
if (override) { if (override) {
......
...@@ -19,7 +19,7 @@ const WARNING_TYPE = Object.freeze({ ...@@ -19,7 +19,7 @@ const WARNING_TYPE = Object.freeze({
}) })
const FancyButton = styled.button` const FancyButton = styled.button`
color: ${({ theme }) => theme.textColor}; color: ${({ theme }) => theme.text1};
align-items: center; align-items: center;
min-width: 55px; min-width: 55px;
height: 2rem; height: 2rem;
...@@ -37,7 +37,7 @@ const FancyButton = styled.button` ...@@ -37,7 +37,7 @@ const FancyButton = styled.button`
} }
` `
const Option = styled(FancyButton)` const Option = styled(FancyButton)<{ active: boolean }>`
margin-right: 8px; margin-right: 8px;
:hover { :hover {
cursor: pointer; cursor: pointer;
...@@ -46,7 +46,7 @@ const Option = styled(FancyButton)` ...@@ -46,7 +46,7 @@ const Option = styled(FancyButton)`
color: ${({ active, theme }) => (active ? theme.white : theme.text1)}; color: ${({ active, theme }) => (active ? theme.white : theme.text1)};
` `
const Input = styled.input` const Input = styled.input<{ active?: boolean }>`
background: ${({ theme }) => theme.bg1}; background: ${({ theme }) => theme.bg1};
flex-grow: 1; flex-grow: 1;
font-size: 12px; font-size: 12px;
...@@ -61,21 +61,21 @@ const Input = styled.input` ...@@ -61,21 +61,21 @@ const Input = styled.input`
color: ${({ theme }) => theme.text1}; color: ${({ theme }) => theme.text1};
text-align: left; text-align: left;
${({ active }) => ${({ active }) =>
active && active &&
css` css`
color: initial; color: initial;
cursor: initial; cursor: initial;
text-align: right; text-align: right;
`} `}
${({ placeholder }) => ${({ placeholder }) =>
placeholder !== 'Custom' && placeholder !== 'Custom' &&
css` css`
text-align: right; text-align: right;
color: ${({ theme }) => theme.text1}; color: ${({ theme }) => theme.text1};
`} `}
${({ color }) => ${({ color }) =>
color === 'red' && color === 'red' &&
css` css`
color: ${({ theme }) => theme.red1}; color: ${({ theme }) => theme.red1};
`} `}
` `
...@@ -84,24 +84,20 @@ const BottomError = styled(Text)` ...@@ -84,24 +84,20 @@ const BottomError = styled(Text)`
font-size: 14px; font-size: 14px;
font-weight: 400; font-weight: 400;
${({ show }) => ${({ show }) =>
show && show &&
css` css`
padding-top: 12px; padding-top: 12px;
`} `}
` `
const OptionCustom = styled(FancyButton)` const OptionCustom = styled(FancyButton)<{ active?: boolean; warning?: boolean }>`
height: 2rem; height: 2rem;
position: relative; position: relative;
padding: 0 0.75rem; padding: 0 0.75rem;
${({ active }) => border: ${({ theme, active, warning }) => active && `1px solid ${(warning ? theme.red1 : theme.blue1)}`};
active && :hover {
css` border: ${({ theme, active, warning }) => active && `1px solid ${(warning ? darken(0.1, theme.red1) : darken(0.1, theme.blue1))}`};
border: 1px solid ${({ theme, warning }) => (warning ? theme.red1 : theme.blue1)}; }
:hover {
border: 1px solid ${({ theme, warning }) => (warning ? darken(0.1, theme.red1) : darken(0.1, theme.blue1))};
}
`}
input { input {
width: 100%; width: 100%;
...@@ -120,22 +116,29 @@ const Percent = styled.div` ...@@ -120,22 +116,29 @@ const Percent = styled.div`
font-size: 0, 8rem; font-size: 0, 8rem;
flex-grow: 0; flex-grow: 0;
${({ color, theme }) => ${({ color, theme }) =>
(color === 'faded' && (color === 'faded' &&
css` css`
color: ${theme.bg1}; color: ${theme.bg1};
`) || `) ||
(color === 'red' && (color === 'red' &&
css` css`
color: ${theme.red1}; color: ${theme.red1};
`)}; `)};
` `
export default function TransactionDetails({ setRawSlippage, rawSlippage, deadline, setDeadline }) { interface TransactionDetailsProps {
rawSlippage: number
setRawSlippage: (rawSlippage: number) => void
deadline: number
setDeadline: (deadline: number) => void
}
export default function TransactionDetails({ setRawSlippage, rawSlippage, deadline, setDeadline }: TransactionDetailsProps) {
const [activeIndex, setActiveIndex] = useState(2) const [activeIndex, setActiveIndex] = useState(2)
const [warningType, setWarningType] = useState(WARNING_TYPE.none) const [warningType, setWarningType] = useState(WARNING_TYPE.none)
const inputRef = useRef() const inputRef = useRef<HTMLInputElement>()
const [userInput, setUserInput] = useState('') const [userInput, setUserInput] = useState('')
const debouncedInput = useDebounce(userInput, 150) const debouncedInput = useDebounce(userInput, 150)
...@@ -163,7 +166,7 @@ export default function TransactionDetails({ setRawSlippage, rawSlippage, deadli ...@@ -163,7 +166,7 @@ export default function TransactionDetails({ setRawSlippage, rawSlippage, deadli
const updateSlippage = useCallback( const updateSlippage = useCallback(
newSlippage => { newSlippage => {
// round to 2 decimals to prevent ethers error // round to 2 decimals to prevent ethers error
let numParsed = parseInt(newSlippage * 100) let numParsed = newSlippage * 100
// set both slippage values in parents // set both slippage values in parents
setRawSlippage(numParsed) setRawSlippage(numParsed)
...@@ -183,7 +186,7 @@ export default function TransactionDetails({ setRawSlippage, rawSlippage, deadli ...@@ -183,7 +186,7 @@ export default function TransactionDetails({ setRawSlippage, rawSlippage, deadli
) )
useEffect(() => { useEffect(() => {
switch (Number.parseInt(initialSlippage)) { switch (initialSlippage) {
case 10: case 10:
setFromFixed(1, 0.1) setFromFixed(1, 0.1)
break break
...@@ -197,8 +200,8 @@ export default function TransactionDetails({ setRawSlippage, rawSlippage, deadli ...@@ -197,8 +200,8 @@ export default function TransactionDetails({ setRawSlippage, rawSlippage, deadli
// restrict to 2 decimal places // restrict to 2 decimal places
let acceptableValues = [/^$/, /^\d{1,2}$/, /^\d{0,2}\.\d{0,2}$/] let acceptableValues = [/^$/, /^\d{1,2}$/, /^\d{0,2}\.\d{0,2}$/]
// if its within accepted decimal limit, update the input state // if its within accepted decimal limit, update the input state
if (acceptableValues.some(val => val.test(initialSlippage / 100))) { if (acceptableValues.some(val => val.test('' + (initialSlippage / 100)))) {
setUserInput(initialSlippage / 100) setUserInput('' + (initialSlippage / 100))
setActiveIndex(4) setActiveIndex(4)
} }
} }
...@@ -310,8 +313,8 @@ export default function TransactionDetails({ setRawSlippage, rawSlippage, deadli ...@@ -310,8 +313,8 @@ export default function TransactionDetails({ setRawSlippage, rawSlippage, deadli
placeholder={ placeholder={
activeIndex === 4 activeIndex === 4
? !!userInput ? !!userInput
? '' ? ''
: '0' : '0'
: activeIndex !== 4 && userInput !== '' : activeIndex !== 4 && userInput !== ''
? userInput ? userInput
: 'Custom' : 'Custom'
...@@ -349,8 +352,8 @@ export default function TransactionDetails({ setRawSlippage, rawSlippage, deadli ...@@ -349,8 +352,8 @@ export default function TransactionDetails({ setRawSlippage, rawSlippage, deadli
: warningType !== WARNING_TYPE.none && warningType !== WARNING_TYPE.riskyEntryLow : warningType !== WARNING_TYPE.none && warningType !== WARNING_TYPE.riskyEntryLow
? 'red' ? 'red'
: warningType === WARNING_TYPE.riskyEntryLow : warningType === WARNING_TYPE.riskyEntryLow
? '#F3841E' ? '#F3841E'
: '' : ''
} }
> >
{warningType === WARNING_TYPE.emptyInput && 'Enter a slippage percentage'} {warningType === WARNING_TYPE.emptyInput && 'Enter a slippage percentage'}
...@@ -363,11 +366,12 @@ export default function TransactionDetails({ setRawSlippage, rawSlippage, deadli ...@@ -363,11 +366,12 @@ export default function TransactionDetails({ setRawSlippage, rawSlippage, deadli
<AutoColumn gap="sm"> <AutoColumn gap="sm">
<RowFixed padding={'0 20px'}> <RowFixed padding={'0 20px'}>
<TYPE.body fontSize={14}>Deadline</TYPE.body> <TYPE.body fontSize={14}>Deadline</TYPE.body>
<QuestionHelper text="Deadline in minutes. If your transaction takes longer than this it will revert." /> <QuestionHelper text="Deadline in minutes. If your transaction takes longer than this it will revert."/>
</RowFixed> </RowFixed>
<RowFixed padding={'0 20px'}> <RowFixed padding={'0 20px'}>
<OptionCustom style={{ width: '80px' }}> <OptionCustom style={{ width: '80px' }}>
<Input tabIndex={-1} placeholder={deadlineInput} value={deadlineInput} onChange={parseCustomDeadline} /> <Input tabIndex={-1} placeholder={'' + deadlineInput} value={deadlineInput}
onChange={parseCustomDeadline}/>
</OptionCustom> </OptionCustom>
<TYPE.body style={{ paddingLeft: '8px' }} fontSize={14}> <TYPE.body style={{ paddingLeft: '8px' }} fontSize={14}>
minutes minutes
......
import { Token } from '@uniswap/sdk'
import React, { useState } from 'react' import React, { useState } from 'react'
import styled, { keyframes } from 'styled-components' import styled, { keyframes } from 'styled-components'
...@@ -125,8 +126,14 @@ const Text = styled.div` ...@@ -125,8 +126,14 @@ const Text = styled.div`
color: ${({ theme }) => theme.text1}; color: ${({ theme }) => theme.text1};
` `
function WarningCard({ onDismiss, urlAddedTokens, currency }) { interface WarningCardProps {
const [showPopup, setPopup] = useState() onDismiss: () => void
urlAddedTokens: Token[]
currency: string
}
function WarningCard({ onDismiss, urlAddedTokens, currency }: WarningCardProps) {
const [showPopup, setPopup] = useState<boolean>(false)
const { chainId } = useWeb3React() const { chainId } = useWeb3React()
const { symbol: inputSymbol, name: inputName } = useToken(currency) const { symbol: inputSymbol, name: inputName } = useToken(currency)
const fromURL = urlAddedTokens.hasOwnProperty(currency) const fromURL = urlAddedTokens.hasOwnProperty(currency)
...@@ -134,7 +141,7 @@ function WarningCard({ onDismiss, urlAddedTokens, currency }) { ...@@ -134,7 +141,7 @@ function WarningCard({ onDismiss, urlAddedTokens, currency }) {
return ( return (
<Wrapper> <Wrapper>
<CloseIcon onClick={() => onDismiss()}> <CloseIcon onClick={() => onDismiss()}>
<CloseColor alt={'close icon'} /> <CloseColor />
</CloseIcon> </CloseIcon>
<Row style={{ fontSize: '12px' }}> <Row style={{ fontSize: '12px' }}>
<Text>{fromURL ? 'Token imported by URL ' : 'Token imported by user'}</Text> <Text>{fromURL ? 'Token imported by URL ' : 'Token imported by user'}</Text>
......
...@@ -28,7 +28,7 @@ const SpinnerWrapper = styled(Spinner)` ...@@ -28,7 +28,7 @@ const SpinnerWrapper = styled(Spinner)`
margin: 0 0.25rem 0 0.25rem; margin: 0 0.25rem 0 0.25rem;
` `
const IconWrapper = styled.div` const IconWrapper = styled.div<{ size?: number }>`
${({ theme }) => theme.flexColumnNoWrap}; ${({ theme }) => theme.flexColumnNoWrap};
align-items: center; align-items: center;
justify-content: center; justify-content: center;
...@@ -76,8 +76,8 @@ const Web3StatusConnect = styled(Web3StatusGeneric)` ...@@ -76,8 +76,8 @@ const Web3StatusConnect = styled(Web3StatusGeneric)`
} }
${({ faded }) => ${({ faded }) =>
faded && faded &&
css` css`
background-color: ${({ theme }) => theme.blue5}; background-color: ${({ theme }) => theme.blue5};
border: 1px solid ${({ theme }) => theme.blue5}; border: 1px solid ${({ theme }) => theme.blue5};
color: ${({ theme }) => theme.buttonSecondaryText}; color: ${({ theme }) => theme.buttonSecondaryText};
...@@ -140,29 +140,29 @@ export default function Web3Status() { ...@@ -140,29 +140,29 @@ export default function Web3Status() {
// handle the logo we want to show with the account // handle the logo we want to show with the account
function getStatusIcon() { function getStatusIcon() {
if (connector === injected) { if (connector === injected) {
return <Identicon /> return <Identicon/>
} else if (connector === walletconnect) { } else if (connector === walletconnect) {
return ( return (
<IconWrapper size={16}> <IconWrapper size={16}>
<img src={WalletConnectIcon} alt={''} /> <img src={WalletConnectIcon} alt={''}/>
</IconWrapper> </IconWrapper>
) )
} else if (connector === walletlink) { } else if (connector === walletlink) {
return ( return (
<IconWrapper size={16}> <IconWrapper size={16}>
<img src={CoinbaseWalletIcon} alt={''} /> <img src={CoinbaseWalletIcon} alt={''}/>
</IconWrapper> </IconWrapper>
) )
} else if (connector === fortmatic) { } else if (connector === fortmatic) {
return ( return (
<IconWrapper size={16}> <IconWrapper size={16}>
<img src={FortmaticIcon} alt={''} /> <img src={FortmaticIcon} alt={''}/>
</IconWrapper> </IconWrapper>
) )
} else if (connector === portis) { } else if (connector === portis) {
return ( return (
<IconWrapper size={16}> <IconWrapper size={16}>
<img src={PortisIcon} alt={''} /> <img src={PortisIcon} alt={''}/>
</IconWrapper> </IconWrapper>
) )
} }
...@@ -174,7 +174,7 @@ export default function Web3Status() { ...@@ -174,7 +174,7 @@ export default function Web3Status() {
<Web3StatusConnected onClick={toggleWalletModal} pending={hasPendingTransactions}> <Web3StatusConnected onClick={toggleWalletModal} pending={hasPendingTransactions}>
{hasPendingTransactions ? ( {hasPendingTransactions ? (
<RowBetween> <RowBetween>
<Text>{pending?.length} Pending</Text> <SpinnerWrapper src={LightCircle} alt="loader" /> <Text>{pending?.length} Pending</Text> <SpinnerWrapper src={LightCircle} alt="loader"/>
</RowBetween> </RowBetween>
) : ( ) : (
<Text>{ENSName || shortenAddress(account)}</Text> <Text>{ENSName || shortenAddress(account)}</Text>
...@@ -185,7 +185,7 @@ export default function Web3Status() { ...@@ -185,7 +185,7 @@ export default function Web3Status() {
} else if (error) { } else if (error) {
return ( return (
<Web3StatusError onClick={toggleWalletModal}> <Web3StatusError onClick={toggleWalletModal}>
<NetworkIcon /> <NetworkIcon/>
<Text>{error instanceof UnsupportedChainIdError ? 'Wrong Network' : 'Error'}</Text> <Text>{error instanceof UnsupportedChainIdError ? 'Wrong Network' : 'Error'}</Text>
</Web3StatusError> </Web3StatusError>
) )
...@@ -205,7 +205,7 @@ export default function Web3Status() { ...@@ -205,7 +205,7 @@ export default function Web3Status() {
return ( return (
<> <>
{getWeb3Status()} {getWeb3Status()}
<WalletModal ENSName={ENSName} pendingTransactions={pending} confirmedTransactions={confirmed} /> <WalletModal ENSName={ENSName} pendingTransactions={pending} confirmedTransactions={confirmed}/>
</> </>
) )
} }
...@@ -92,8 +92,8 @@ export function useInactiveListener(suppress = false) { ...@@ -92,8 +92,8 @@ export function useInactiveListener(suppress = false) {
} }
// modified from https://usehooks.com/useDebounce/ // modified from https://usehooks.com/useDebounce/
export function useDebounce(value, delay) { export function useDebounce<T>(value: T, delay: number): T {
const [debouncedValue, setDebouncedValue] = useState(value) const [debouncedValue, setDebouncedValue] = useState<T>(value)
useEffect(() => { useEffect(() => {
// Update debounced value after delay // Update debounced value after delay
......
...@@ -724,7 +724,6 @@ function AddLiquidity({ token0, token1 }: AddLiquidityProps) { ...@@ -724,7 +724,6 @@ function AddLiquidity({ token0, token1 }: AddLiquidityProps) {
atMax={atMaxAmountInput} atMax={atMaxAmountInput}
token={tokens[Field.INPUT]} token={tokens[Field.INPUT]}
onTokenSelection={address => onTokenSelection(Field.INPUT, address)} onTokenSelection={address => onTokenSelection(Field.INPUT, address)}
error={inputError}
pair={pair} pair={pair}
label="Input" label="Input"
inputId="addLiquidityInput" inputId="addLiquidityInput"
...@@ -742,7 +741,6 @@ function AddLiquidity({ token0, token1 }: AddLiquidityProps) { ...@@ -742,7 +741,6 @@ function AddLiquidity({ token0, token1 }: AddLiquidityProps) {
atMax={atMaxAmountOutput} atMax={atMaxAmountOutput}
token={tokens[Field.OUTPUT]} token={tokens[Field.OUTPUT]}
onTokenSelection={address => onTokenSelection(Field.OUTPUT, address)} onTokenSelection={address => onTokenSelection(Field.OUTPUT, address)}
error={outputError}
pair={pair} pair={pair}
inputId="addLiquidityOutput" inputId="addLiquidityOutput"
/> />
......
...@@ -282,7 +282,7 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -282,7 +282,7 @@ export default function RemoveLiquidity({ token0, token1 }) {
) )
} }
const handleSliderChange = (event, newPercent) => { const handleSliderChange = (newPercent) => {
onUserInput( onUserInput(
Field.LIQUIDITY, Field.LIQUIDITY,
new TokenAmount( new TokenAmount(
...@@ -699,7 +699,6 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -699,7 +699,6 @@ export default function RemoveLiquidity({ token0, token1 }) {
onUserInput={onUserInput} onUserInput={onUserInput}
onMax={onMax} onMax={onMax}
atMax={atMaxAmount} atMax={atMaxAmount}
error={poolTokenError}
disableTokenSelect disableTokenSelect
token={pair?.liquidityToken} token={pair?.liquidityToken}
isExchange={true} isExchange={true}
...@@ -716,7 +715,6 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -716,7 +715,6 @@ export default function RemoveLiquidity({ token0, token1 }) {
onMax={onMax} onMax={onMax}
atMax={atMaxAmount} atMax={atMaxAmount}
token={tokens[Field.TOKEN0]} token={tokens[Field.TOKEN0]}
error={inputError}
label={'Output'} label={'Output'}
disableTokenSelect disableTokenSelect
inputId="removeLiquidityToken0" inputId="removeLiquidityToken0"
...@@ -731,7 +729,6 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -731,7 +729,6 @@ export default function RemoveLiquidity({ token0, token1 }) {
onMax={onMax} onMax={onMax}
atMax={atMaxAmount} atMax={atMaxAmount}
token={tokens[Field.TOKEN1]} token={tokens[Field.TOKEN1]}
error={outputError}
label={'Output'} label={'Output'}
disableTokenSelect disableTokenSelect
inputId="removeLiquidityToken1" inputId="removeLiquidityToken1"
...@@ -758,15 +755,7 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -758,15 +755,7 @@ export default function RemoveLiquidity({ token0, token1 }) {
disabled={!isValid} disabled={!isValid}
> >
<Text fontSize={20} fontWeight={500}> <Text fontSize={20} fontWeight={500}>
{inputError {inputError || outputError || poolTokenError || generalError || 'Remove'}
? inputError
: outputError
? outputError
: poolTokenError
? poolTokenError
: generalError
? generalError
: 'Remove'}
</Text> </Text>
</ButtonPrimary> </ButtonPrimary>
<FixedBottom> <FixedBottom>
......
...@@ -33,10 +33,8 @@ export const Button = styled.button.attrs<{ warning: boolean }, { backgroundColo ...@@ -33,10 +33,8 @@ export const Button = styled.button.attrs<{ warning: boolean }, { backgroundColo
} }
` `
export const CloseIcon = styled(X)` export const CloseIcon = styled(X)<{ onClick: () => void}>`
:hover { cursor: pointer;
cursor: pointer;
}
` `
export const Link = styled.a.attrs({ export const Link = styled.a.attrs({
......
...@@ -18,7 +18,10 @@ ...@@ -18,7 +18,10 @@
"isolatedModules": true, "isolatedModules": true,
"jsx": "preserve", "jsx": "preserve",
"downlevelIteration": true, "downlevelIteration": true,
"allowSyntheticDefaultImports": true "allowSyntheticDefaultImports": true,
"types": [
"react-spring"
]
}, },
"exclude": [ "exclude": [
"node_modules", "node_modules",
......
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