Skip to content

Commit

Permalink
feat: Add copy token address button to currency input panel (#3334)
Browse files Browse the repository at this point in the history
To review 

1. Go to swap
2. Select token from list
3. See copy address button
  • Loading branch information
memoyil authored Mar 1, 2022
1 parent ecff5a4 commit 54866ae
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 83 deletions.
72 changes: 72 additions & 0 deletions src/components/CopyButton/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { useState } from 'react'
import { CopyIcon, SvgProps } from '@pancakeswap/uikit'
import { copyText } from 'utils/copyText'
import styled from 'styled-components'

const Tooltip = styled.div<{
isTooltipDisplayed: boolean
tooltipTop: number
tooltipRight: number
tooltipFontSize?: number
}>`
display: ${({ isTooltipDisplayed }) => (isTooltipDisplayed ? 'inline' : 'none')};
position: absolute;
padding: 8px;
top: ${({ tooltipTop }) => `${tooltipTop}px`};
right: ${({ tooltipRight }) => (tooltipRight ? `${tooltipRight}px` : 0)};
text-align: center;
font-size: ${({ tooltipFontSize }) => `${tooltipFontSize}px` ?? '100%'};
background-color: ${({ theme }) => theme.colors.contrast};
color: ${({ theme }) => theme.colors.invertedContrast};
border-radius: 16px;
opacity: 0.7;
width: max-content;
`

interface CopyButtonProps extends SvgProps {
text: string
tooltipMessage: string
tooltipTop: number
tooltipRight?: number
tooltipFontSize?: number
buttonColor?: string
}

export const CopyButton: React.FC<CopyButtonProps> = ({
text,
tooltipMessage,
width,
tooltipTop,
tooltipRight,
tooltipFontSize,
buttonColor = 'primary',
...props
}) => {
const [isTooltipDisplayed, setIsTooltipDisplayed] = useState(false)

const displayTooltip = () => {
setIsTooltipDisplayed(true)
setTimeout(() => {
setIsTooltipDisplayed(false)
}, 1000)
}
return (
<>
<CopyIcon
style={{ cursor: 'pointer' }}
color={buttonColor}
width={width}
onClick={() => copyText(text, displayTooltip)}
{...props}
/>
<Tooltip
isTooltipDisplayed={isTooltipDisplayed}
tooltipTop={tooltipTop}
tooltipRight={tooltipRight}
tooltipFontSize={tooltipFontSize}
>
{tooltipMessage}
</Tooltip>
</>
)
}
111 changes: 62 additions & 49 deletions src/components/CurrencyInputPanel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { CurrencyLogo, DoubleCurrencyLogo } from '../Logo'

import { RowBetween } from '../Layout/Row'
import { Input as NumericalInput } from './NumericalInput'
import { CopyButton } from '../CopyButton'

const InputRow = styled.div<{ selected: boolean }>`
display: flex;
Expand Down Expand Up @@ -93,57 +94,69 @@ export default function CurrencyInputPanel({
/>,
)
return (
<Box id={id}>
<Box position="relative" id={id}>
<Flex mb="6px" alignItems="center" justifyContent="space-between">
<CurrencySelectButton
className="open-currency-select-button"
selected={!!currency}
onClick={() => {
if (!disableCurrencySelect) {
onPresentCurrencyModal()
}
}}
>
<Flex alignItems="center" justifyContent="space-between">
{pair ? (
<DoubleCurrencyLogo currency0={pair.token0} currency1={pair.token1} size={16} margin />
) : currency ? (
<CurrencyLogo currency={currency} size="24px" style={{ marginRight: '8px' }} />
) : null}
{pair ? (
<Text id="pair" bold>
{pair?.token0.symbol}:{pair?.token1.symbol}
</Text>
) : (
<Text id="pair" bold>
{(currency && currency.symbol && currency.symbol.length > 20
? `${currency.symbol.slice(0, 4)}...${currency.symbol.slice(
currency.symbol.length - 5,
currency.symbol.length,
)}`
: currency?.symbol) || t('Select a currency')}
</Text>
)}
{!disableCurrencySelect && <ChevronDownIcon />}
</Flex>
</CurrencySelectButton>
<Flex style={{ gap: '8px' }}>
{token && tokenAddress && library?.provider?.isMetaMask && (
<MetamaskIcon
style={{ cursor: 'pointer' }}
width="16px"
ml="6px"
onClick={() => registerToken(tokenAddress, token.symbol, token.decimals)}
/>
)}
{account && (
<Text onClick={onMax} color="textSubtle" fontSize="14px" style={{ display: 'inline', cursor: 'pointer' }}>
{!hideBalance && !!currency
? t('Balance: %balance%', { balance: selectedCurrencyBalance?.toSignificant(6) ?? t('Loading') })
: ' -'}
</Text>
)}
<Flex>
<CurrencySelectButton
className="open-currency-select-button"
selected={!!currency}
onClick={() => {
if (!disableCurrencySelect) {
onPresentCurrencyModal()
}
}}
>
<Flex alignItems="center" justifyContent="space-between">
{pair ? (
<DoubleCurrencyLogo currency0={pair.token0} currency1={pair.token1} size={16} margin />
) : currency ? (
<CurrencyLogo currency={currency} size="24px" style={{ marginRight: '8px' }} />
) : null}
{pair ? (
<Text id="pair" bold>
{pair?.token0.symbol}:{pair?.token1.symbol}
</Text>
) : (
<Text id="pair" bold>
{(currency && currency.symbol && currency.symbol.length > 20
? `${currency.symbol.slice(0, 4)}...${currency.symbol.slice(
currency.symbol.length - 5,
currency.symbol.length,
)}`
: currency?.symbol) || t('Select a currency')}
</Text>
)}
{!disableCurrencySelect && <ChevronDownIcon />}
</Flex>
</CurrencySelectButton>
{token && tokenAddress ? (
<Flex style={{ gap: '4px' }} alignItems="center">
<CopyButton
width="16px"
buttonColor="textSubtle"
text={tokenAddress}
tooltipMessage={t('Token address copied')}
tooltipTop={-20}
tooltipRight={40}
tooltipFontSize={12}
/>
{library?.provider?.isMetaMask && (
<MetamaskIcon
style={{ cursor: 'pointer' }}
width="16px"
onClick={() => registerToken(tokenAddress, token.symbol, token.decimals)}
/>
)}
</Flex>
) : null}
</Flex>
{account && (
<Text onClick={onMax} color="textSubtle" fontSize="14px" style={{ display: 'inline', cursor: 'pointer' }}>
{!hideBalance && !!currency
? t('Balance: %balance%', { balance: selectedCurrencyBalance?.toSignificant(6) ?? t('Loading') })
: ' -'}
</Text>
)}
</Flex>
<InputPanel>
<Container>
Expand Down
39 changes: 5 additions & 34 deletions src/components/Menu/UserMenu/CopyAddress.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { useState } from 'react'
import { Box, CopyIcon, Flex, FlexProps, IconButton } from '@pancakeswap/uikit'
import { Box, Flex, FlexProps } from '@pancakeswap/uikit'
import styled from 'styled-components'
import { useTranslation } from 'contexts/Localization'
import { copyText } from 'utils/copyText'
import { CopyButton } from '../../CopyButton'

interface CopyAddressProps extends FlexProps {
account: string
Expand Down Expand Up @@ -51,46 +50,18 @@ const Address = styled.div`
}
`

const Tooltip = styled.div<{ isTooltipDisplayed: boolean }>`
display: ${({ isTooltipDisplayed }) => (isTooltipDisplayed ? 'inline-block' : 'none')};
position: absolute;
padding: 8px;
top: -38px;
right: 0;
text-align: center;
background-color: ${({ theme }) => theme.colors.contrast};
color: ${({ theme }) => theme.colors.invertedContrast};
border-radius: 16px;
opacity: 0.7;
width: 100px;
`

const CopyAddress: React.FC<CopyAddressProps> = ({ account, ...props }) => {
const [isTooltipDisplayed, setIsTooltipDisplayed] = useState(false)
const { t } = useTranslation()

const copyAddress = () => {
copyText(account, displayTooltip)
}

function displayTooltip() {
setIsTooltipDisplayed(true)
setTimeout(() => {
setIsTooltipDisplayed(false)
}, 1000)
}

return (
<Box position="relative" {...props}>
<Wrapper>
<Address title={account}>
<input type="text" readOnly value={account} />
</Address>
<IconButton variant="text" onClick={copyAddress}>
<CopyIcon color="primary" width="24px" />
</IconButton>
<Flex margin="12px">
<CopyButton width="24px" text={account} tooltipMessage={t('Copied')} tooltipTop={-40} />
</Flex>
</Wrapper>
<Tooltip isTooltipDisplayed={isTooltipDisplayed}>{t('Copied')}</Tooltip>
</Box>
)
}
Expand Down

0 comments on commit 54866ae

Please sign in to comment.