Commit 3f1d7ab3 authored by Ian Lapham's avatar Ian Lapham Committed by GitHub

add basic structure for advanced mode (#703)

* add basic structure for advanced mode

* auto dismiss popup

* Remove test code

* remove shadow

* Update advanced section, ui tweaks, balances back inline

* fix memory leak
Co-authored-by: default avatarCallil Capuozzo <callil.capuozzo@gmail.com>
parent 60d7bc45
import React, { useState } from 'react'
import Copy from '../AccountDetails/Copy'
import TokenLogo from '../TokenLogo'
import { Link } from '../../theme/components'
import { TYPE } from '../../theme'
import { Hover } from '../../theme'
import { GreyCard } from '../Card'
import { AutoColumn } from '../Column'
import { RowBetween, RowFixed } from '../Row'
import { ChevronDown, ChevronUp } from 'react-feather'
import { useWeb3React } from '../../hooks'
import { getEtherscanLink } from '../../utils'
export default function BalanceCard({ token0, balance0, import0, token1, balance1, import1 }) {
const [details0, setDetails0] = useState(false)
const [details1, setDetails1] = useState(false)
const { chainId } = useWeb3React()
return (
<AutoColumn gap="lg">
<GreyCard>
<AutoColumn gap="md">
<TYPE.black>Selected Tokens</TYPE.black>
{token0 && balance0 && (
<Hover onClick={() => setDetails0(!details0)}>
<RowBetween>
<RowFixed>
<TokenLogo address={token0?.address || ''} />
<TYPE.black marginLeft="10px">
{token0?.name} ({token0?.symbol})
</TYPE.black>
</RowFixed>
<RowFixed>
<TYPE.black>{balance0?.toSignificant(6)}</TYPE.black>
{details0 ? (
<ChevronUp size="20" style={{ marginLeft: '10px' }} color="black" />
) : (
<ChevronDown size="20" style={{ marginLeft: '10px' }} color="black" />
)}
</RowFixed>
</RowBetween>
{import0 && <TYPE.yellow style={{ paddingLeft: '32px' }}>Token imported by user</TYPE.yellow>}
</Hover>
)}
{details0 && (
<AutoColumn gap="sm" style={{ marginTop: '2px', marginBottom: '6px' }}>
<RowFixed>
<TYPE.blue style={{ paddingLeft: '32px' }}>Copy token address</TYPE.blue>
<Copy toCopy={token0?.address} />
</RowFixed>
<Link href={getEtherscanLink(chainId, token0?.address, 'address')} style={{ paddingLeft: '32px' }}>
View on etherscan
</Link>
</AutoColumn>
)}
{token1 && balance1 && (
<Hover onClick={() => setDetails1(!details1)}>
<RowBetween>
<RowFixed>
<TokenLogo address={token1?.address || ''} />
<TYPE.black marginLeft="10px">
{token1?.name} ({token1?.symbol})
</TYPE.black>
</RowFixed>
<RowFixed>
<TYPE.black>{balance1?.toSignificant(6)}</TYPE.black>
{details1 ? (
<ChevronUp size="20" style={{ marginLeft: '10px' }} color="black" />
) : (
<ChevronDown size="20" style={{ marginLeft: '10px' }} color="black" />
)}
</RowFixed>
</RowBetween>
{import0 && <TYPE.yellow style={{ paddingLeft: '32px' }}>Token imported by user</TYPE.yellow>}
</Hover>
)}
{details1 && (
<AutoColumn gap="sm" style={{ marginTop: '2px', marginBottom: '6px' }}>
<RowFixed>
<TYPE.blue style={{ paddingLeft: '32px' }}>Copy token address</TYPE.blue>
<Copy toCopy={token1?.address} />
</RowFixed>
<Link href={getEtherscanLink(chainId, token1?.address, 'address')} style={{ paddingLeft: '32px' }}>
View on etherscan
</Link>
</AutoColumn>
)}
</AutoColumn>
</GreyCard>
</AutoColumn>
)
}
...@@ -20,6 +20,10 @@ const Base = styled(RebassButton)` ...@@ -20,6 +20,10 @@ const Base = styled(RebassButton)`
&:disabled { &:disabled {
cursor: auto; cursor: auto;
} }
> * {
user-select: none;
}
` `
export const ButtonPrimary = styled(Base)` export const ButtonPrimary = styled(Base)`
......
...@@ -22,7 +22,7 @@ export const GreyCard = styled(Card)` ...@@ -22,7 +22,7 @@ export const GreyCard = styled(Card)`
` `
export const YellowCard = styled(Card)` export const YellowCard = styled(Card)`
background-color: rgba(243, 190, 30, 0.3); background-color: rgba(243, 132, 30, 0.05);
color: ${({ theme }) => theme.yellow2}; color: ${({ theme }) => theme.yellow2};
font-weight: 500; font-weight: 500;
` `
......
...@@ -6,10 +6,14 @@ import { darken } from 'polished' ...@@ -6,10 +6,14 @@ import { darken } from 'polished'
import TokenLogo from '../TokenLogo' import TokenLogo from '../TokenLogo'
import DoubleLogo from '../DoubleLogo' import DoubleLogo from '../DoubleLogo'
import SearchModal from '../SearchModal' import SearchModal from '../SearchModal'
import { RowBetween } from '../Row'
import { TYPE, Hover } from '../../theme'
import { Input as NumericalInput } from '../NumericalInput' import { Input as NumericalInput } from '../NumericalInput'
import { ReactComponent as DropDown } from '../../assets/images/dropdown.svg' import { ReactComponent as DropDown } from '../../assets/images/dropdown.svg'
import { useWeb3React } from '../../hooks'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { useAddressBalance } from '../../contexts/Balances'
const InputRow = styled.div` const InputRow = styled.div`
${({ theme }) => theme.flexRowNoWrap} ${({ theme }) => theme.flexRowNoWrap}
...@@ -39,6 +43,27 @@ const CurrencySelect = styled.button` ...@@ -39,6 +43,27 @@ const CurrencySelect = styled.button`
} }
` `
const LabelRow = styled.div`
${({ theme }) => theme.flexRowNoWrap}
align-items: center;
color: ${({ theme }) => theme.text1};
font-size: 0.75rem;
line-height: 1rem;
padding: 0 1.25rem 1rem 1rem;
span:hover {
cursor: pointer;
color: ${({ theme }) => darken(0.2, theme.text2)};
}
`
const ErrorSpan = styled.span`
color: ${({ error, theme }) => error && theme.red1};
:hover {
cursor: pointer;
color: ${({ error, theme }) => error && darken(0.1, theme.red1)};
}
`
const Aligner = styled.span` const Aligner = styled.span`
display: flex; display: flex;
align-items: center; align-items: center;
...@@ -65,9 +90,7 @@ const InputPanel = styled.div` ...@@ -65,9 +90,7 @@ const InputPanel = styled.div`
const Container = styled.div` const Container = styled.div`
border-radius: ${({ hideInput }) => (hideInput ? '8px' : '20px')}; border-radius: ${({ hideInput }) => (hideInput ? '8px' : '20px')};
/* border: 1px solid ${({ error, theme }) => (error ? theme.red1 : theme.bg2)}; */
border: 1px solid ${({ theme }) => theme.bg2}; border: 1px solid ${({ theme }) => theme.bg2};
background-color: ${({ theme }) => theme.bg1}; background-color: ${({ theme }) => theme.bg1};
` `
...@@ -118,6 +141,8 @@ export default function CurrencyInputPanel({ ...@@ -118,6 +141,8 @@ export default function CurrencyInputPanel({
const { t } = useTranslation() const { t } = useTranslation()
const [modalOpen, setModalOpen] = useState(false) const [modalOpen, setModalOpen] = useState(false)
const { account } = useWeb3React()
const userTokenBalance = useAddressBalance(account, token)
return ( return (
<InputPanel> <InputPanel>
...@@ -164,6 +189,16 @@ export default function CurrencyInputPanel({ ...@@ -164,6 +189,16 @@ export default function CurrencyInputPanel({
</Aligner> </Aligner>
</CurrencySelect> </CurrencySelect>
</InputRow> </InputRow>
{!hideBalance && !!token && (
<LabelRow>
<RowBetween>
<ErrorSpan data-tip={'Enter max'} error={!!error} onClick={() => {}}></ErrorSpan>
<Hover onClick={onMax}>
<TYPE.body fontWeight={500}>Balance: {userTokenBalance?.toSignificant(6)}</TYPE.body>
</Hover>
</RowBetween>
</LabelRow>
)}
</Container> </Container>
{!disableTokenSelect && ( {!disableTokenSelect && (
<SearchModal <SearchModal
......
...@@ -5,24 +5,24 @@ import { withRouter } from 'react-router-dom' ...@@ -5,24 +5,24 @@ import { withRouter } from 'react-router-dom'
import { parseUnits, parseEther } from '@ethersproject/units' import { parseUnits, parseEther } from '@ethersproject/units'
import { WETH, TradeType, Pair, Trade, TokenAmount, JSBI, Percent } from '@uniswap/sdk' import { WETH, TradeType, Pair, Trade, TokenAmount, JSBI, Percent } from '@uniswap/sdk'
import Copy from '../AccountDetails/Copy'
import TokenLogo from '../TokenLogo' import TokenLogo from '../TokenLogo'
import SlippageTabs from '../SlippageTabs'
import QuestionHelper from '../Question' import QuestionHelper from '../Question'
import NumericalInput from '../NumericalInput' import NumericalInput from '../NumericalInput'
import AdvancedSettings from '../AdvancedSettings'
import AddressInputPanel from '../AddressInputPanel' import AddressInputPanel from '../AddressInputPanel'
import ConfirmationModal from '../ConfirmationModal' import ConfirmationModal from '../ConfirmationModal'
import CurrencyInputPanel from '../CurrencyInputPanel' import CurrencyInputPanel from '../CurrencyInputPanel'
import Copy from '../AccountDetails/Copy'
import { Link } from '../../theme/components' import { Link } from '../../theme/components'
import { Text } from 'rebass' import { Text } from 'rebass'
import { TYPE } from '../../theme' import { TYPE } from '../../theme'
import { Hover } from '../../theme' import { Hover } from '../../theme'
import { ArrowDown } from 'react-feather'
import { AutoColumn, ColumnCenter } from '../../components/Column' import { AutoColumn, ColumnCenter } from '../../components/Column'
import { RowBetween, RowFixed, AutoRow } from '../../components/Row' import { RowBetween, RowFixed, AutoRow } from '../../components/Row'
import { GreyCard, BlueCard, YellowCard } from '../../components/Card' import { ArrowDown, ChevronDown, ChevronUp } from 'react-feather'
import { ButtonPrimary, ButtonError, ButtonLight } from '../Button' import { ButtonPrimary, ButtonError, ButtonLight } from '../Button'
import { GreyCard, BlueCard, YellowCard, LightCard } from '../../components/Card'
import { usePair } from '../../contexts/Pairs' import { usePair } from '../../contexts/Pairs'
import { useToken } from '../../contexts/Tokens' import { useToken } from '../../contexts/Tokens'
...@@ -33,7 +33,7 @@ import { useAddressBalance, useAllBalances } from '../../contexts/Balances' ...@@ -33,7 +33,7 @@ import { useAddressBalance, useAllBalances } from '../../contexts/Balances'
import { useTransactionAdder, usePendingApproval } from '../../contexts/Transactions' import { useTransactionAdder, usePendingApproval } from '../../contexts/Transactions'
import { ROUTER_ADDRESSES } from '../../constants' import { ROUTER_ADDRESSES } from '../../constants'
import { INITIAL_TOKENS_CONTEXT } from '../../contexts/Tokens' // import { INITIAL_TOKENS_CONTEXT } from '../../contexts/Tokens'
import { getRouterContract, calculateGasMargin, getProviderOrSigner, getEtherscanLink } from '../../utils' import { getRouterContract, calculateGasMargin, getProviderOrSigner, getEtherscanLink } from '../../utils'
const Wrapper = styled.div` const Wrapper = styled.div`
...@@ -60,6 +60,41 @@ const FixedBottom = styled.div` ...@@ -60,6 +60,41 @@ const FixedBottom = styled.div`
margin-bottom: 40px; margin-bottom: 40px;
` `
const AdvancedDropwdown = styled.div`
position: absolute;
margin-top: 2px;
left: -8px;
width: 339px;
margin-bottom: 40px;
padding: 10px 0;
padding-top: 24px;
border-bottom-left-radius: 20px;
border-bottom-right-radius: 20px;
color: #565a69;
background-color: rgba(237, 238, 242, 0.8);
color: ${({ theme }) => theme.text2};
z-index: -1;
`
// const PseudoBottom = styled.div`
// height: 14px;
// width: 340px;
// background: white;
// position: absolute;
// border-bottom-left-radius: 41px;
// top: 0px;
// border-bottom-right-radius: 40px;
// left: -1px;
// /* box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.01), 0px 4px 8px rgba(0, 0, 0, 0.04), 0px 16px 24px rgba(0, 0, 0, 0.04),
// 0px 24px 32px rgba(0, 0, 0, 0.01); */
// `
const SectionBreak = styled.div`
height: 2px;
width: 100%;
background-color: ${({ theme }) => theme.bg1};
`
const BottomGrouping = styled.div` const BottomGrouping = styled.div`
margin-top: 20px; margin-top: 20px;
position: relative; position: relative;
...@@ -67,7 +102,7 @@ const BottomGrouping = styled.div` ...@@ -67,7 +102,7 @@ const BottomGrouping = styled.div`
const ErrorText = styled(Text)` const ErrorText = styled(Text)`
color: ${({ theme, warningLow, warningMedium, warningHigh }) => color: ${({ theme, warningLow, warningMedium, warningHigh }) =>
warningHigh ? theme.red1 : warningMedium ? theme.yellow2 : warningLow ? theme.green1 : theme.text3}; warningHigh ? theme.red1 : warningMedium ? theme.yellow2 : warningLow ? theme.green1 : theme.text1};
` `
const InputGroup = styled(AutoColumn)` const InputGroup = styled(AutoColumn)`
...@@ -313,9 +348,9 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -313,9 +348,9 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
const pendingApprovalInput = usePendingApproval(tokens[Field.INPUT]?.address) const pendingApprovalInput = usePendingApproval(tokens[Field.INPUT]?.address)
// check for imported tokens to show warning // check for imported tokens to show warning
const importedTokenInput = tokens[Field.INPUT] && !!!INITIAL_TOKENS_CONTEXT?.[chainId]?.[tokens[Field.INPUT]?.address] // const importedTokenInput = tokens[Field.INPUT] && !!!INITIAL_TOKENS_CONTEXT?.[chainId]?.[tokens[Field.INPUT]?.address]
const importedTokenOutput = // const importedTokenOutput =
tokens[Field.OUTPUT] && !!!INITIAL_TOKENS_CONTEXT?.[chainId]?.[tokens[Field.OUTPUT]?.address] // tokens[Field.OUTPUT] && !!!INITIAL_TOKENS_CONTEXT?.[chainId]?.[tokens[Field.OUTPUT]?.address]
// entities for swap // entities for swap
const pair: Pair = usePair(tokens[Field.INPUT], tokens[Field.OUTPUT]) const pair: Pair = usePair(tokens[Field.INPUT], tokens[Field.OUTPUT])
...@@ -378,6 +413,16 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -378,6 +413,16 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
[dependentField]: parsedAmounts[dependentField] ? parsedAmounts[dependentField].toSignificant(8) : '' [dependentField]: parsedAmounts[dependentField] ? parsedAmounts[dependentField].toSignificant(8) : ''
} }
const priceSlippage =
slippageFromTrade &&
new Percent(
JSBI.subtract(
JSBI.multiply(slippageFromTrade.numerator, JSBI.BigInt('1000')),
JSBI.multiply(JSBI.BigInt('3'), slippageFromTrade.denominator)
),
JSBI.multiply(slippageFromTrade.denominator, JSBI.BigInt('1000'))
)
const onTokenSelection = useCallback((field: Field, address: string) => { const onTokenSelection = useCallback((field: Field, address: string) => {
dispatch({ dispatch({
type: SwapAction.SELECT_TOKEN, type: SwapAction.SELECT_TOKEN,
...@@ -915,16 +960,6 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -915,16 +960,6 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
</AutoColumn> </AutoColumn>
) )
} }
if (showAdvanced) {
return (
<AdvancedSettings
setIsOpen={setShowAdvanced}
setDeadline={setDeadline}
setAllowedSlippage={setAllowedSlippage}
allowedSlippage={allowedSlippage}
/>
)
}
if (!sending || (sending && sendingWithSwap)) { if (!sending || (sending && sendingWithSwap)) {
return ( return (
...@@ -949,13 +984,6 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -949,13 +984,6 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
} or the transaction will revert.`} } or the transaction will revert.`}
</TYPE.italic> </TYPE.italic>
)} )}
<Link
onClick={() => {
setShowAdvanced(true)
}}
>
Advanced
</Link>
</AutoColumn> </AutoColumn>
</> </>
) )
...@@ -989,10 +1017,14 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -989,10 +1017,14 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
warningMedium={warningMedium} warningMedium={warningMedium}
warningHigh={warningHigh} warningHigh={warningHigh}
> >
{slippageFromTrade ? slippageFromTrade.toFixed(4) : '0'}% {priceSlippage
? priceSlippage.toFixed(4) === '0.0000'
? '<0.0001%'
: priceSlippage.toFixed(4) + '%'
: '-'}
</ErrorText> </ErrorText>
<Text fontWeight={500} fontSize={14} color="#888D9B" pt={1}> <Text fontWeight={500} fontSize={14} color="#888D9B" pt={1}>
Slippage Price Slippage
</Text> </Text>
</AutoColumn> </AutoColumn>
</AutoRow> </AutoRow>
...@@ -1167,6 +1199,11 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -1167,6 +1199,11 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
/> />
</AutoColumn> </AutoColumn>
)} )}
{!noRoute && tokens[Field.OUTPUT] && tokens[Field.INPUT] && (
<LightCard padding="1rem" borderRadius={'20px'}>
<PriceBar />
</LightCard>
)}
</AutoColumn> </AutoColumn>
<BottomGrouping> <BottomGrouping>
{noRoute ? ( {noRoute ? (
...@@ -1225,64 +1262,144 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params } ...@@ -1225,64 +1262,144 @@ function ExchangePage({ sendingInput = false, history, initialCurrency, params }
</ButtonError> </ButtonError>
)} )}
</BottomGrouping> </BottomGrouping>
<FixedBottom> {tokens[Field.INPUT] && tokens[Field.OUTPUT] && !noRoute && (
{!noRoute && tokens[Field.OUTPUT] && tokens[Field.INPUT] && ( <AdvancedDropwdown>
<GreyCard pt={2} mb={2}> {!showAdvanced && (
<PriceBar /> <Hover>
</GreyCard> <RowBetween onClick={() => setShowAdvanced(true)} padding={'0 20px'}>
<Text fontSize={14} fontWeight={500} style={{ userSelect: 'none' }}>
Show Advanced
</Text>
<ChevronDown color={'#565A69'} />
</RowBetween>
</Hover>
)} )}
<AutoColumn gap="lg"> {showAdvanced && (
{importedTokenInput && ( <AutoColumn gap="md">
<YellowCard style={{ paddingTop: '1rem' }}> <Hover>
<AutoColumn gap="sm"> <RowBetween onClick={() => setShowAdvanced(false)} padding={'0 20px'}>
<TYPE.mediumHeader>Token imported via address</TYPE.mediumHeader> <Text fontSize={14} color="#565A69" fontWeight={500} style={{ userSelect: 'none' }}>
<AutoRow gap="4px"> Hide Advanced
<TokenLogo address={tokens[Field.INPUT]?.address || ''} /> </Text>
<TYPE.body>({tokens[Field.INPUT]?.symbol})</TYPE.body> <ChevronUp color="#565A69" />
<Link href={getEtherscanLink(chainId, tokens[Field.INPUT]?.address, 'address')}> </RowBetween>
(View on Etherscan) </Hover>
</Link> <SectionBreak />
<Copy toCopy={tokens[Field.INPUT]?.address} /> <AutoColumn style={{ padding: '0 20px' }}>
</AutoRow> <RowBetween>
<TYPE.subHeader> <RowFixed>
Please verify the legitimacy of this token before making any transactions. <TYPE.black fontSize={14} fontWeight={400}>
</TYPE.subHeader> {independentField === Field.INPUT
</AutoColumn> ? sending
</YellowCard> ? 'Maximum amount sent'
: 'Maximum amount received'
: 'Minimum amount sold'}
</TYPE.black>
<QuestionHelper text="" />
</RowFixed>
<RowFixed>
<TYPE.black fontSize={14}>
{independentField === Field.INPUT
? slippageAdjustedAmounts[Field.OUTPUT]
? slippageAdjustedAmounts[Field.OUTPUT]?.toFixed(5) === '0.00000'
? '<0.00001'
: slippageAdjustedAmounts[Field.OUTPUT]?.toFixed(5)
: '-'
: slippageAdjustedAmounts[Field.INPUT]
? slippageAdjustedAmounts[Field.INPUT]?.toFixed(5) === '0.00000'
? '<0.00001'
: slippageAdjustedAmounts[Field.INPUT]?.toFixed(5)
: '-'}
</TYPE.black>
{parsedAmounts[Field.OUTPUT] && parsedAmounts[Field.INPUT] && (
<TYPE.black fontSize={14} marginLeft={'4px'}>
{independentField === Field.INPUT
? parsedAmounts[Field.OUTPUT] && tokens[Field.OUTPUT]?.symbol
: parsedAmounts[Field.INPUT] && tokens[Field.INPUT]?.symbol}
</TYPE.black>
)} )}
{importedTokenOutput && ( </RowFixed>
<YellowCard style={{ paddingTop: '1rem' }}> </RowBetween>
<AutoColumn gap="sm"> <RowBetween>
<TYPE.mediumHeader>Token imported via address</TYPE.mediumHeader> <RowFixed>
<AutoRow gap="4px"> <TYPE.black fontSize={14} fontWeight={400}>
<TokenLogo address={tokens[Field.OUTPUT]?.address || ''} /> Price Slippage
<TYPE.body>({tokens[Field.OUTPUT]?.symbol})</TYPE.body> </TYPE.black>
<Link href={getEtherscanLink(chainId, tokens[Field.OUTPUT]?.address, 'address')}> <QuestionHelper text="" />
(View on Etherscan) </RowFixed>
</Link> <ErrorText
</AutoRow> fontWeight={500}
<TYPE.subHeader> fontSize={14}
Please verify the legitimacy of this token before making any transactions. warningLow={warningLow}
</TYPE.subHeader> warningMedium={warningMedium}
warningHigh={warningHigh}
>
{priceSlippage
? priceSlippage.toFixed(4) === '0.0000'
? '<0.0001%'
: priceSlippage.toFixed(4) + '%'
: '-'}
</ErrorText>
</RowBetween>
<RowBetween>
<RowFixed>
<TYPE.black fontSize={14} fontWeight={400}>
Total Slippage
</TYPE.black>
<QuestionHelper text="" />
</RowFixed>
<TYPE.black fontSize={14}>
{slippageFromTrade ? slippageFromTrade.toSignificant(4) + '%' : '-'}
</TYPE.black>
</RowBetween>
</AutoColumn>
<SectionBreak />
<RowFixed padding={'0 20px'}>
<TYPE.black fontSize={14}>Set front running resistance</TYPE.black>
<QuestionHelper text="" />
</RowFixed>
<SlippageTabs
rawSlippage={allowedSlippage}
setRawSlippage={setAllowedSlippage}
deadline={deadline}
setDeadline={setDeadline}
/>
</AutoColumn> </AutoColumn>
</YellowCard>
)} )}
<FixedBottom>
<AutoColumn gap="lg">
{warningHigh && ( {warningHigh && (
<GreyCard style={{ paddingTop: '1rem' }}> <YellowCard style={{ padding: '20px', paddingTop: '10px', marginBottom: '10px' }}>
<AutoColumn gap="md" mt={2}> <AutoColumn gap="md" mt={2}>
<RowBetween> <RowBetween>
<Text fontWeight={500}>Slippage Warning</Text> <RowFixed>
<QuestionHelper text="" /> <span role="img" aria-label="warning">
⚠️
</span>{' '}
<Text fontWeight={500} marginLeft="4px">
Slippage Warning
</Text>
</RowFixed>
</RowBetween> </RowBetween>
<Text color="#565A69" lineHeight="145.23%;"> <Text lineHeight="145.23%;" fontSize={14} fontWeight={400}>
This trade will move the price by {slippageFromTrade.toFixed(2)}%. This pool probably doesn’t have This trade will move the price by {slippageFromTrade.toFixed(2)}%. This pool probably doesn’t have
enough liquidity to support this trade. Are you sure you want to continue this trade? enough liquidity to support this trade.
</Text> </Text>
</AutoColumn> </AutoColumn>
</GreyCard> </YellowCard>
)} )}
{/* <BalanceCard
token0={tokens[Field.INPUT]}
token1={tokens[Field.OUTPUT]}
import0={importedTokenInput}
balance0={userBalances[Field.INPUT]}
balance1={userBalances[Field.OUTPUT]}
import1={importedTokenOutput}
/> */}
</AutoColumn> </AutoColumn>
</FixedBottom> </FixedBottom>
</AdvancedDropwdown>
)}
</Wrapper> </Wrapper>
) )
} }
......
...@@ -30,6 +30,7 @@ const HeaderFrame = styled.div` ...@@ -30,6 +30,7 @@ const HeaderFrame = styled.div`
padding: 10px; padding: 10px;
width: calc(100% - 20px); width: calc(100% - 20px);
`}; `};
z-index: 2;
` `
const HeaderElement = styled.div` const HeaderElement = styled.div`
......
...@@ -45,9 +45,9 @@ const MobilePopupInner = styled.div` ...@@ -45,9 +45,9 @@ const MobilePopupInner = styled.div`
const FixedPopupColumn = styled(AutoColumn)` const FixedPopupColumn = styled(AutoColumn)`
position: absolute; position: absolute;
top: 80px; top: 56px;
right: 20px right: 24px;
width: 380px; width: 355px;
${({ theme }) => theme.mediaWidth.upToSmall` ${({ theme }) => theme.mediaWidth.upToSmall`
display: none; display: none;
...@@ -57,7 +57,6 @@ const FixedPopupColumn = styled(AutoColumn)` ...@@ -57,7 +57,6 @@ const FixedPopupColumn = styled(AutoColumn)`
const Popup = styled.div` const Popup = styled.div`
display: inline-block; display: inline-block;
width: 100%; width: 100%;
min-height: 120px;
padding: 1em; padding: 1em;
box-sizing: border-box; box-sizing: border-box;
background-color: white; background-color: white;
...@@ -67,6 +66,7 @@ const Popup = styled.div` ...@@ -67,6 +66,7 @@ const Popup = styled.div`
padding: 20px; padding: 20px;
padding-right: 35px; padding-right: 35px;
z-index: 2; z-index: 2;
overflow: hidden;
${({ theme }) => theme.mediaWidth.upToSmall` ${({ theme }) => theme.mediaWidth.upToSmall`
min-width: 290px; min-width: 290px;
...@@ -96,7 +96,7 @@ export default function App() { ...@@ -96,7 +96,7 @@ export default function App() {
return ( return (
<Popup key={item.key}> <Popup key={item.key}>
<StyledClose color="#888D9B" onClick={() => removePopup(item.key)} /> <StyledClose color="#888D9B" onClick={() => removePopup(item.key)} />
{item.content} {React.cloneElement(item.content, { popKey: item.key })}
</Popup> </Popup>
) )
})} })}
...@@ -127,7 +127,7 @@ export default function App() { ...@@ -127,7 +127,7 @@ export default function App() {
return ( return (
<Popup key={item.key}> <Popup key={item.key}>
<StyledClose color="#888D9B" onClick={() => removePopup(item.key)} /> <StyledClose color="#888D9B" onClick={() => removePopup(item.key)} />
{item.content} {React.cloneElement(item.content, { popKey: item.key })}
</Popup> </Popup>
) )
})} })}
......
...@@ -26,8 +26,8 @@ const QuestionWrapper = styled.div` ...@@ -26,8 +26,8 @@ const QuestionWrapper = styled.div`
` `
const HelpCircleStyled = styled.img` const HelpCircleStyled = styled.img`
height: 24px; height: 20px;
width: 23px; width: 20px;
` `
const fadeIn = keyframes` const fadeIn = keyframes`
......
...@@ -72,8 +72,6 @@ export default function InputSlider({ value, onChange, override }) { ...@@ -72,8 +72,6 @@ export default function InputSlider({ value, onChange, override }) {
function handleChange(e, val) { function handleChange(e, val) {
setInternalVal(val) setInternalVal(val)
console.log(val)
console.log(debouncedInternalValue)
if (val === debouncedInternalValue) { if (val === debouncedInternalValue) {
onChange(e, val) onChange(e, val)
} }
......
import React, { useState, useEffect, useRef, useCallback } from 'react'
import styled, { css } from 'styled-components'
import QuestionHelper from '../Question'
import { Text } from 'rebass'
import { TYPE } from '../../theme'
import { AutoColumn } from '../Column'
import { RowBetween, RowFixed } from '../Row'
import { darken } from 'polished'
import { useDebounce } from '../../hooks'
const WARNING_TYPE = Object.freeze({
none: 'none',
emptyInput: 'emptyInput',
invalidEntryBound: 'invalidEntryBound',
riskyEntryHigh: 'riskyEntryHigh',
riskyEntryLow: 'riskyEntryLow'
})
const FancyButton = styled.button`
color: ${({ theme }) => theme.textColor};
align-items: center;
min-width: 55px;
height: 2rem;
border-radius: 36px;
font-size: 12px;
border: 1px solid ${({ theme }) => theme.bg3};
outline: none;
background: ${({ theme }) => theme.bg1};
:hover {
cursor: inherit;
border: 1px solid ${({ theme }) => theme.bg4};
}
:focus {
border: 1px solid ${({ theme }) => theme.blue1};
}
`
const Option = styled(FancyButton)`
margin-right: 8px;
:hover {
cursor: pointer;
}
background-color: ${({ active, theme }) => active && theme.blue1};
color: ${({ active, theme }) => (active ? theme.white : theme.text1)};
`
const Input = styled.input`
background: ${({ theme }) => theme.bg1};
flex-grow: 1;
font-size: 12px;
min-width: 20px;
outline: none;
box-sizing: border-box;
&::-webkit-outer-spin-button,
&::-webkit-inner-spin-button {
-webkit-appearance: none;
}
cursor: inherit;
color: ${({ theme }) => theme.text1};
text-align: left;
${({ active }) =>
active &&
css`
color: initial;
cursor: initial;
text-align: right;
`}
${({ placeholder }) =>
placeholder !== 'Custom' &&
css`
text-align: right;
color: ${({ theme }) => theme.text1};
`}
${({ color }) =>
color === 'red' &&
css`
color: ${({ theme }) => theme.red1};
`}
`
const BottomError = styled(Text)`
font-size: 14px;
font-weight: 400;
${({ show }) =>
show &&
css`
padding-top: 12px;
`}
`
const OptionCustom = styled(FancyButton)`
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))};
}
`}
input {
width: 100%;
height: 100%;
border: 0px;
border-radius: 2rem;
}
`
const SlippageSelector = styled.div`
padding: 0 20px;
`
const Percent = styled.div`
color: inherit;
font-size: 0, 8rem;
flex-grow: 0;
${({ color, theme }) =>
(color === 'faded' &&
css`
color: ${theme.bg1};
`) ||
(color === 'red' &&
css`
color: ${theme.red1};
`)};
`
export default function TransactionDetails({ setRawSlippage, rawSlippage, deadline, setDeadline }) {
const [activeIndex, setActiveIndex] = useState(2)
const [warningType, setWarningType] = useState(WARNING_TYPE.none)
const inputRef = useRef()
const [userInput, setUserInput] = useState('')
const debouncedInput = useDebounce(userInput, 150)
const [initialSlippage] = useState(rawSlippage)
const [deadlineInput, setDeadlineInput] = useState(deadline / 60)
function parseCustomDeadline(e) {
let val = e.target.value
const acceptableValues = [/^$/, /^\d+$/]
if (acceptableValues.some(re => re.test(val))) {
setDeadlineInput(val)
setDeadline(val * 60)
}
}
const setFromCustom = () => {
setActiveIndex(4)
inputRef.current.focus()
// if there's a value, evaluate the bounds
checkBounds(debouncedInput)
}
const updateSlippage = useCallback(
newSlippage => {
// round to 2 decimals to prevent ethers error
let numParsed = parseInt(newSlippage * 100)
// set both slippage values in parents
setRawSlippage(numParsed)
},
[setRawSlippage]
)
// used for slippage presets
const setFromFixed = useCallback(
(index, slippage) => {
// update slippage in parent, reset errors and input state
updateSlippage(slippage)
setWarningType(WARNING_TYPE.none)
setActiveIndex(index)
},
[updateSlippage]
)
useEffect(() => {
switch (Number.parseInt(initialSlippage)) {
case 10:
setFromFixed(1, 0.1)
break
case 50:
setFromFixed(2, 0.5)
break
case 100:
setFromFixed(3, 1)
break
default:
// 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)
setActiveIndex(4)
}
}
}, [initialSlippage, setFromFixed])
const checkBounds = useCallback(
slippageValue => {
setWarningType(WARNING_TYPE.none)
if (slippageValue === '' || slippageValue === '.') {
return setWarningType(WARNING_TYPE.emptyInput)
}
// check bounds and set errors
if (Number(slippageValue) < 0 || Number(slippageValue) > 50) {
return setWarningType(WARNING_TYPE.invalidEntryBound)
}
if (Number(slippageValue) >= 0 && Number(slippageValue) < 0.1) {
setWarningType(WARNING_TYPE.riskyEntryLow)
}
if (Number(slippageValue) > 5) {
setWarningType(WARNING_TYPE.riskyEntryHigh)
}
//update the actual slippage value in parent
updateSlippage(Number(slippageValue))
},
[updateSlippage]
)
// check that the theyve entered number and correct decimal
const parseInput = e => {
let input = e.target.value
// 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(a => a.test(input))) {
setUserInput(input)
}
}
useEffect(() => {
if (activeIndex === 4) {
checkBounds(debouncedInput)
}
})
const dropDownContent = () => {
return (
<>
<SlippageSelector>
<RowBetween>
<Option
onClick={() => {
setFromFixed(1, 0.1)
}}
active={activeIndex === 1}
>
0.1%
</Option>
<Option
onClick={() => {
setFromFixed(2, 0.5)
}}
active={activeIndex === 2}
>
0.5%
</Option>
<Option
onClick={() => {
setFromFixed(3, 1)
}}
active={activeIndex === 3}
>
1%
</Option>
<OptionCustom
active={activeIndex === 4}
warning={
warningType !== WARNING_TYPE.none &&
warningType !== WARNING_TYPE.emptyInput &&
warningType !== WARNING_TYPE.riskyEntryLow
}
onClick={() => {
setFromCustom()
}}
>
<RowBetween>
{!(warningType === WARNING_TYPE.none || warningType === WARNING_TYPE.emptyInput) && (
<span
role="img"
aria-label="warning"
style={{
color:
warningType !== WARNING_TYPE.none && warningType !== WARNING_TYPE.riskyEntryLow
? 'red'
: warningType === WARNING_TYPE.riskyEntryLow
? '#F3841E'
: ''
}}
>
⚠️
</span>
)}
<Input
tabIndex={-1}
ref={inputRef}
active={activeIndex === 4}
placeholder={
activeIndex === 4
? !!userInput
? ''
: '0'
: activeIndex !== 4 && userInput !== ''
? userInput
: 'Custom'
}
value={activeIndex === 4 ? userInput : ''}
onChange={parseInput}
color={
warningType === WARNING_TYPE.emptyInput
? ''
: warningType !== WARNING_TYPE.none && warningType !== WARNING_TYPE.riskyEntryLow
? 'red'
: ''
}
/>
<Percent
color={
activeIndex !== 4
? 'faded'
: warningType === WARNING_TYPE.riskyEntryHigh || warningType === WARNING_TYPE.invalidEntryBound
? 'red'
: ''
}
>
%
</Percent>
</RowBetween>
</OptionCustom>
</RowBetween>
<RowBetween>
<BottomError
show={activeIndex === 4}
color={
warningType === WARNING_TYPE.emptyInput
? '#565A69'
: warningType !== WARNING_TYPE.none && warningType !== WARNING_TYPE.riskyEntryLow
? 'red'
: warningType === WARNING_TYPE.riskyEntryLow
? '#F3841E'
: ''
}
>
{warningType === WARNING_TYPE.emptyInput && 'Enter a slippage percentage'}
{warningType === WARNING_TYPE.invalidEntryBound && 'Please select a value no greater than 50%'}
{warningType === WARNING_TYPE.riskyEntryHigh && 'Your transaction may be frontrun'}
{warningType === WARNING_TYPE.riskyEntryLow && 'Your transaction may fail'}
</BottomError>
</RowBetween>
</SlippageSelector>
<AutoColumn gap="md">
<RowFixed padding={'0 20px'}>
<TYPE.black fontSize={14}>Deadline</TYPE.black>
<QuestionHelper text="Deadline in minutes. If your transaction takes longer than this it will revert." />
</RowFixed>
<RowBetween padding={'0 20px'}>
<OptionCustom style={{ width: '80px' }}>
<Input tabIndex={-1} placeholder={deadlineInput} value={deadlineInput} onChange={parseCustomDeadline} />
</OptionCustom>
</RowBetween>
</AutoColumn>
</>
)
}
return dropDownContent()
}
import React from 'react' import React, { useState, useEffect, useRef } from 'react'
import { Link } from '../../theme/components' import { Link } from '../../theme/components'
import { TYPE } from '../../theme' import { TYPE } from '../../theme'
import { AutoColumn } from '../Column' import { AutoColumn } from '../Column'
import { AutoRow } from '../Row'
import { useWeb3React } from '../../hooks' import { useWeb3React } from '../../hooks'
import { getEtherscanLink } from '../../utils' import { getEtherscanLink } from '../../utils'
import { usePopups } from '../../contexts/Application'
export default function TxnPopup({ hash, success, summary }) { import { CheckCircle, AlertCircle } from 'react-feather'
import styled from 'styled-components'
const Fader = styled.div`
position: absolute;
bottom: 0px;
left: 0px;
width: ${({ count }) => `calc(100% - (100% / ${150 / count}))`};
height: 2px;
background-color: ${({ theme }) => theme.bg3};
transition: width 100ms linear;
`
function useInterval(callback, delay) {
const savedCallback = useRef()
// Remember the latest callback.
useEffect(() => {
savedCallback.current = callback
return () => {}
}, [callback])
// Set up the interval.
useEffect(() => {
function tick() {
savedCallback.current()
}
if (delay !== null) {
let id = setInterval(tick, delay)
return () => clearInterval(id)
}
return () => {}
}, [delay])
}
const delay = 100
export default function TxnPopup({ hash, success, summary, popKey }) {
const { chainId } = useWeb3React() const { chainId } = useWeb3React()
let [count, setCount] = useState(1)
const [isRunning, setIsRunning] = useState(true)
const [, , removePopup] = usePopups()
useInterval(
() => {
count > 150 && removePopup(popKey)
setCount(count + 1)
},
isRunning ? delay : null
)
return ( return (
<AutoColumn gap="12px"> <AutoRow onMouseEnter={() => setIsRunning(false)} onMouseLeave={() => setIsRunning(true)}>
<TYPE.body>Transaction {success ? 'confirmed.' : 'failed.'}</TYPE.body> {success ? (
<TYPE.green>{summary ? summary : 'Hash: ' + hash.slice(0, 8) + '...' + hash.slice(58, 65)}</TYPE.green> <CheckCircle color={'#27AE60'} size={24} style={{ paddingRight: '24px' }} />
) : (
<AlertCircle color={'#FF6871'} size={24} style={{ paddingRight: '24px' }} />
)}
<AutoColumn gap="8px">
<TYPE.body fontWeight={500}>
{summary ? summary : 'Hash: ' + hash.slice(0, 8) + '...' + hash.slice(58, 65)}
</TYPE.body>
<Link href={getEtherscanLink(chainId, hash, 'transaction')}>View on Etherscan</Link> <Link href={getEtherscanLink(chainId, hash, 'transaction')}>View on Etherscan</Link>
</AutoColumn> </AutoColumn>
<Fader count={count} />
</AutoRow>
) )
} }
...@@ -414,7 +414,6 @@ export function useAllBalances(): Array<TokenAmount> { ...@@ -414,7 +414,6 @@ export function useAllBalances(): Array<TokenAmount> {
let newBalances = {} let newBalances = {}
Object.keys(state[chainId]).map(address => { Object.keys(state[chainId]).map(address => {
return Object.keys(state[chainId][address]).map(tokenAddress => { return Object.keys(state[chainId][address]).map(tokenAddress => {
// console.log(allTokens[tokenAddress])
if (state[chainId][address][tokenAddress].value) { if (state[chainId][address][tokenAddress].value) {
// fix if ETH found in local storage from old storage // fix if ETH found in local storage from old storage
if (tokenAddress === 'ETH') { if (tokenAddress === 'ETH') {
......
...@@ -46,6 +46,8 @@ const BodyWrapper = styled.div` ...@@ -46,6 +46,8 @@ const BodyWrapper = styled.div`
max-width: calc(355px + 4rem); max-width: calc(355px + 4rem);
width: 90%; width: 90%;
} }
z-index: 1;
` `
const Body = styled.div` const Body = styled.div`
...@@ -72,7 +74,6 @@ export default function App() { ...@@ -72,7 +74,6 @@ export default function App() {
</HeaderWrapper> </HeaderWrapper>
<BodyWrapper> <BodyWrapper>
<Popups /> <Popups />
<Body> <Body>
<Web3ReactManager> <Web3ReactManager>
<BrowserRouter> <BrowserRouter>
......
...@@ -14,9 +14,9 @@ import CurrencyInputPanel from '../../components/CurrencyInputPanel' ...@@ -14,9 +14,9 @@ import CurrencyInputPanel from '../../components/CurrencyInputPanel'
import { Text } from 'rebass' import { Text } from 'rebass'
import { TYPE } from '../../theme' import { TYPE } from '../../theme'
import { Plus } from 'react-feather' import { Plus } from 'react-feather'
import { BlueCard, LightCard } from '../../components/Card'
import { AutoColumn, ColumnCenter } from '../../components/Column' import { AutoColumn, ColumnCenter } from '../../components/Column'
import { ButtonPrimary, ButtonLight } from '../../components/Button' import { ButtonPrimary, ButtonLight } from '../../components/Button'
import { BlueCard, LightCard, GreyCard } from '../../components/Card'
import Row, { AutoRow, RowBetween, RowFlat, RowFixed } from '../../components/Row' import Row, { AutoRow, RowBetween, RowFlat, RowFixed } from '../../components/Row'
import { useToken } from '../../contexts/Tokens' import { useToken } from '../../contexts/Tokens'
...@@ -688,6 +688,11 @@ function AddLiquidity({ token0, token1, step = false }) { ...@@ -688,6 +688,11 @@ function AddLiquidity({ token0, token1, step = false }) {
error={outputError} error={outputError}
pair={pair} pair={pair}
/> />
{tokens[Field.OUTPUT] && tokens[Field.INPUT] && (
<LightCard padding="1rem" borderRadius={'20px'}>
<PriceBar />
</LightCard>
)}
{showOutputApprove ? ( {showOutputApprove ? (
<ButtonLight <ButtonLight
onClick={() => { onClick={() => {
...@@ -721,11 +726,6 @@ function AddLiquidity({ token0, token1, step = false }) { ...@@ -721,11 +726,6 @@ function AddLiquidity({ token0, token1, step = false }) {
{!noLiquidity && ( {!noLiquidity && (
<FixedBottom> <FixedBottom>
<AutoColumn> <AutoColumn>
{tokens[Field.OUTPUT] && (
<GreyCard pt={2} mb={2}>
<PriceBar />
</GreyCard>
)}
<PositionCard <PositionCard
pairAddress={pair?.liquidityToken?.address} pairAddress={pair?.liquidityToken?.address}
token0={tokens[Field.INPUT]} token0={tokens[Field.INPUT]}
......
...@@ -7,7 +7,6 @@ import { TokenAmount, JSBI, Route, WETH, Percent, Token, Pair } from '@uniswap/s ...@@ -7,7 +7,6 @@ import { TokenAmount, JSBI, Route, WETH, Percent, Token, Pair } from '@uniswap/s
import TokenLogo from '../../components/TokenLogo' import TokenLogo from '../../components/TokenLogo'
import DoubleLogo from '../../components/DoubleLogo' import DoubleLogo from '../../components/DoubleLogo'
import PositionCard from '../../components/PositionCard' import PositionCard from '../../components/PositionCard'
// import NumericalInput from '../../components/NumericalInput'
import ConfirmationModal from '../../components/ConfirmationModal' import ConfirmationModal from '../../components/ConfirmationModal'
import CurrencyInputPanel from '../../components/CurrencyInputPanel' import CurrencyInputPanel from '../../components/CurrencyInputPanel'
import { TYPE } from '../../theme' import { TYPE } from '../../theme'
...@@ -266,9 +265,6 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -266,9 +265,6 @@ export default function RemoveLiquidity({ token0, token1 }) {
parsedAmounts[Field.LIQUIDITY] && parsedAmounts[Field.LIQUIDITY] &&
pair.getLiquidityValue(tokens[Field.TOKEN1], totalPoolTokens, parsedAmounts[Field.LIQUIDITY], false) pair.getLiquidityValue(tokens[Field.TOKEN1], totalPoolTokens, parsedAmounts[Field.LIQUIDITY], false)
// controlled input for percetange input
// const [percentageInput, setPercentageInput] = useState(0)
// derived percent for advanced mode // derived percent for advanced mode
const derivedPerecent = const derivedPerecent =
userLiquidity && userLiquidity &&
...@@ -285,15 +281,6 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -285,15 +281,6 @@ export default function RemoveLiquidity({ token0, token1 }) {
) )
} }
// update controlled perctenage when derived is updated
// useEffect(() => {
// if (derivedPerecent) {
// setPercentageInput(parseFloat(derivedPerecent))
// } else {
// setPercentageInput(0)
// }
// }, [derivedPerecent])
// get formatted amounts // get formatted amounts
const formattedAmounts = { const formattedAmounts = {
[Field.LIQUIDITY]: [Field.LIQUIDITY]:
...@@ -608,7 +595,7 @@ export default function RemoveLiquidity({ token0, token1 }) { ...@@ -608,7 +595,7 @@ export default function RemoveLiquidity({ token0, token1 }) {
pendingText={pendingText} pendingText={pendingText}
title="You will recieve" title="You will recieve"
/> />
<AutoColumn gap="20px"> <AutoColumn gap="md">
<LightCard> <LightCard>
<AutoColumn gap="20px"> <AutoColumn gap="20px">
<RowBetween> <RowBetween>
......
...@@ -106,6 +106,11 @@ export const TYPE = { ...@@ -106,6 +106,11 @@ export const TYPE = {
{children} {children}
</Text> </Text>
), ),
black: ({ children, ...rest }) => (
<Text fontWeight={500} color={theme().text1} {...rest}>
{children}
</Text>
),
largeHeader: ({ children, ...rest }) => ( largeHeader: ({ children, ...rest }) => (
<Text fontWeight={600} fontSize={24} {...rest}> <Text fontWeight={600} fontSize={24} {...rest}>
{children} {children}
...@@ -122,7 +127,7 @@ export const TYPE = { ...@@ -122,7 +127,7 @@ export const TYPE = {
</Text> </Text>
), ),
body: ({ children, ...rest }) => ( body: ({ children, ...rest }) => (
<Text fontWeight={400} fontSize={16} color={'#888D9B'} {...rest}> <Text fontWeight={400} fontSize={16} color={'#191B1F'} {...rest}>
{children} {children}
</Text> </Text>
), ),
...@@ -131,6 +136,11 @@ export const TYPE = { ...@@ -131,6 +136,11 @@ export const TYPE = {
{children} {children}
</Text> </Text>
), ),
yellow: ({ children, ...rest }) => (
<Text fontWeight={500} color={theme().yellow2} {...rest}>
{children}
</Text>
),
green: ({ children, ...rest }) => ( green: ({ children, ...rest }) => (
<Text fontWeight={500} color={theme().green1} {...rest}> <Text fontWeight={500} color={theme().green1} {...rest}>
{children} {children}
......
...@@ -12927,10 +12927,12 @@ react-error-overlay@^6.0.4: ...@@ -12927,10 +12927,12 @@ react-error-overlay@^6.0.4:
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.4.tgz#0d165d6d27488e660bc08e57bdabaad741366f7a" resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.4.tgz#0d165d6d27488e660bc08e57bdabaad741366f7a"
integrity sha512-ueZzLmHltszTshDMwyfELDq8zOA803wQ1ZuzCccXa1m57k1PxSHfflPD5W9YIiTXLs0JTLzoj6o1LuM5N6zzNA== integrity sha512-ueZzLmHltszTshDMwyfELDq8zOA803wQ1ZuzCccXa1m57k1PxSHfflPD5W9YIiTXLs0JTLzoj6o1LuM5N6zzNA==
react-feather@^1.1.6: react-feather@^2.0.8:
version "1.1.6" version "2.0.8"
resolved "https://registry.yarnpkg.com/react-feather/-/react-feather-1.1.6.tgz#2a547e3d5cd5e383d3da0128d593cbdb3c1b32f7" resolved "https://registry.yarnpkg.com/react-feather/-/react-feather-2.0.8.tgz#455baf1470f756a57e2ad6c72545444ce5925781"
integrity sha512-iCofWhTjX+vQwvDmg7o6vg0XrUg1c41yBDZG+l83nz1FiCsleJoUgd3O+kHpOeWMXuPrRIFfCixvcqyOLGOgIg== integrity sha512-J0dCEOvOxpovHeOVj3+8mAhN3/UERTfX6rSxnV6x4E+0s+STY536jhSjRfpSvTQA0SSFjYr4KrpPfdsLmK+zZg==
dependencies:
prop-types "^15.7.2"
react-focus-lock@^1.17.7: react-focus-lock@^1.17.7:
version "1.19.1" version "1.19.1"
......
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