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