Skip to content

Commit

Permalink
feat: revamp swap form
Browse files Browse the repository at this point in the history
  • Loading branch information
viet-nv committed Apr 12, 2024
1 parent 77d0006 commit e7998f4
Show file tree
Hide file tree
Showing 22 changed files with 159 additions and 362 deletions.
2 changes: 1 addition & 1 deletion src/components/SwapForm/RefreshButton/LoadingIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const LoadingIcon = React.forwardRef<SVGSVGElement, Props>((props, ref) => {
className="arrow-loading"
width={size}
height={size}
color={theme.subText}
color={theme.text}
>
<path
stroke="none"
Expand Down
18 changes: 13 additions & 5 deletions src/components/SwapForm/ReverseTokenSelectionButton.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { useState } from 'react'
import styled from 'styled-components'

import ArrowRotate from 'components/ArrowRotate'
import useTheme from 'hooks/useTheme'

const Wrapper = styled.div`
margin: -18px auto;
z-index: 10;
`

type Props = {
onClick: () => void
}
Expand All @@ -16,11 +22,13 @@ const ReverseTokenSelectionButton: React.FC<Props> = ({ onClick }) => {
}

return (
<ArrowRotate
rotate={rotated}
onClick={handleClick}
style={{ width: 25, height: 25, padding: 4, background: theme.buttonGray }}
/>
<Wrapper>
<ArrowRotate
rotate={rotated}
onClick={handleClick}
style={{ width: 28, height: 28, padding: 4, background: theme.background }}
/>
</Wrapper>
)
}

Expand Down
9 changes: 8 additions & 1 deletion src/components/SwapForm/SlippageSettingGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,15 @@ export default function SlippageSettingGroup({
if (chainId === ChainId.ZKSYNC && !isPartnerSwap) {
rightButton = (
<Flex alignItems="center" width="fit-content" role="button" sx={{ cursor: 'pointer' }} onClick={onOpenGasToken}>
<svg focusable="false" aria-hidden="true" viewBox="0 0 24 24" data-testid="EvStationRoundedIcon" width="16px">
<path
d="m19.77 7.23.01-.01-3.19-3.19c-.29-.29-.77-.29-1.06 0-.29.29-.29.77 0 1.06l1.58 1.58c-1.05.4-1.76 1.47-1.58 2.71.16 1.1 1.1 1.99 2.2 2.11.47.05.88-.03 1.27-.2v7.21c0 .55-.45 1-1 1s-1-.45-1-1V14c0-1.1-.9-2-2-2h-1V5c0-1.1-.9-2-2-2H6c-1.1 0-2 .9-2 2v15c0 .55.45 1 1 1h8c.55 0 1-.45 1-1v-6.5h1.5v4.86c0 1.31.94 2.5 2.24 2.63 1.5.15 2.76-1.02 2.76-2.49V9c0-.69-.28-1.32-.73-1.77zM18 10c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zM8 16.12V13.5H6.83c-.38 0-.62-.4-.44-.74l2.67-5c.24-.45.94-.28.94.24v3h1.14c.38 0 .62.41.43.75l-2.64 4.62c-.25.44-.93.26-.93-.25z"
fill="#A8ABFF"
/>
</svg>

<MouseoverTooltip text="Pay network fees in the token of your choice." placement="top">
<TextDashed>
<TextDashed marginLeft="6px" lineHeight="16px" fontWeight="500" marginTop="2px">
<Trans>Gas Token</Trans>
</TextDashed>
</MouseoverTooltip>
Expand Down
1 change: 0 additions & 1 deletion src/components/SwapForm/SwapFormContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ type SwapFormContextProps = {
slippage: number
routeSummary: DetailedRouteSummary | undefined
typedValue: string
isSaveGas: boolean
recipient: string | null
isStablePairSwap: boolean
isAdvancedMode: boolean
Expand Down
204 changes: 86 additions & 118 deletions src/components/SwapForm/TradeSummary.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,28 @@
import { ChainId } from '@kyberswap/ks-sdk-core'
import { Trans } from '@lingui/macro'
import React, { useEffect, useState } from 'react'
import { NavLink, useSearchParams } from 'react-router-dom'
import { Text } from 'rebass'
import { Flex, Text } from 'rebass'
import styled from 'styled-components'

import { ReactComponent as DropdownSVG } from 'assets/svg/down.svg'
import { ButtonLight } from 'components/Button'
import { AutoColumn } from 'components/Column'
import Divider from 'components/Divider'
import { RowBetween, RowFixed } from 'components/Row'
import { useSwapFormContext } from 'components/SwapForm/SwapFormContext'
import { MouseoverTooltip, TextDashed } from 'components/Tooltip'
import TradePrice from 'components/swapv2/TradePrice'
import { APP_PATHS, BIPS_BASE } from 'constants/index'
import { useActiveWeb3React } from 'hooks'
import { isSupportKyberDao, useGasRefundTier } from 'hooks/kyberdao'
import useMixpanel, { MIXPANEL_TYPE } from 'hooks/useMixpanel'
import useTheme from 'hooks/useTheme'
import { usePaymentToken } from 'state/user/hooks'
import { ExternalLink, TYPE } from 'theme'
import { DetailedRouteSummary } from 'types/route'
import { formattedNum } from 'utils'
import { minimumAmountAfterSlippage } from 'utils/currencyAmount'
import { formatDisplayNumber } from 'utils/numbers'
import { checkPriceImpact, formatPriceImpact } from 'utils/prices'

const IconWrapper = styled.div<{ $flip: boolean }>`
transform: rotate(${({ $flip }) => (!$flip ? '0deg' : '-180deg')});
transition: transform 300ms;
`
const ContentWrapper = styled(AutoColumn)<{ $expanded: boolean }>`
max-height: ${({ $expanded }) => ($expanded ? '500px' : 0)};
margin-top: ${({ $expanded }) => ($expanded ? '12px' : 0)};
transition: margin-top 300ms ease, height 300ms ease;
overflow: hidden;
`
import RefreshButton from './RefreshButton'

type WrapperProps = {
$visible: boolean
Expand All @@ -49,7 +37,6 @@ const Wrapper = styled.div.attrs<WrapperProps>(props => ({
width: 100%;
max-width: 425px;
border-radius: 16px;
background-color: ${({ theme }) => theme.buttonBlack};
max-height: 0;
transition: height 300ms ease-in-out, transform 300ms;
border: 1px solid ${({ theme }) => theme.border};
Expand Down Expand Up @@ -146,14 +133,15 @@ const SwapFee: React.FC = () => {
type Props = {
routeSummary: DetailedRouteSummary | undefined
slippage: number
disableRefresh: boolean
refreshCallback: () => void
}
const TradeSummary: React.FC<Props> = ({ routeSummary, slippage }) => {
const TradeSummary: React.FC<Props> = ({ routeSummary, slippage, disableRefresh, refreshCallback }) => {
const { account, chainId } = useActiveWeb3React()
const theme = useTheme()
const { gasRefundPercentage } = useGasRefundTier()
const [expanded, setExpanded] = useState(true)
const [alreadyVisible, setAlreadyVisible] = useState(false)
const { parsedAmountOut, priceImpact, gasUsd } = routeSummary || {}
const { parsedAmountOut, priceImpact } = routeSummary || {}
const hasTrade = !!routeSummary?.route

const priceImpactResult = checkPriceImpact(priceImpact)
Expand All @@ -177,133 +165,113 @@ const TradeSummary: React.FC<Props> = ({ routeSummary, slippage }) => {
)

const { mixpanelHandler } = useMixpanel()
const handleClickExpand = () => {
setExpanded(prev => !prev)
mixpanelHandler(MIXPANEL_TYPE.SWAP_MORE_INFO_CLICK, { option: expanded ? 'Close' : 'Open' })
}

useEffect(() => {
if (hasTrade) {
setAlreadyVisible(true)
}
}, [hasTrade])

const [paymentToken] = usePaymentToken()
const isHold = paymentToken?.address.toLowerCase() === '0xed4040fD47629e7c8FBB7DA76bb50B3e7695F0f2'.toLowerCase()
const isPartnerSwap = window.location.pathname.includes(APP_PATHS.PARTNER_SWAP)
return (
<Wrapper $visible={alreadyVisible} $disabled={!hasTrade}>
<AutoColumn>
<RowBetween style={{ cursor: 'pointer' }} onClick={handleClickExpand} role="button">
<Text fontSize={12} fontWeight={500} color={theme.text}>
<Trans>MORE INFORMATION</Trans>
<AutoColumn gap="0.75rem">
<RowBetween>
<Text fontSize={12} fontWeight={400} color={theme.subText}>
<Trans>Rate</Trans>
</Text>
<IconWrapper $flip={expanded}>
<DropdownSVG color={theme.text} />
</IconWrapper>
</RowBetween>
<ContentWrapper $expanded={expanded} gap="0.75rem">
<Divider />
<RowBetween>
<RowFixed>
<TextDashed fontSize={12} fontWeight={400} color={theme.subText}>
<MouseoverTooltip
width="200px"
text={<Trans>You will receive at least this amount or your transaction will revert.</Trans>}
placement="right"
>
<Trans>Minimum Received</Trans>
</MouseoverTooltip>
</TextDashed>
</RowFixed>
<RowFixed>
<TYPE.black color={theme.text} fontSize={12}>
{minimumAmountOutStr || '--'}
</TYPE.black>
</RowFixed>
</RowBetween>

<RowBetween>
<RowFixed>
<TextDashed fontSize={12} fontWeight={400} color={theme.subText}>
<MouseoverTooltip text={<Trans>Estimated network fee for your transaction.</Trans>} placement="right">
{chainId === ChainId.SCROLL ? <Trans>Est. L2 Gas Fee</Trans> : <Trans>Est. Gas Fee</Trans>}
</MouseoverTooltip>
</TextDashed>
</RowFixed>
<Flex alignItems="center" sx={{ gap: '4px' }}>
<RefreshButton shouldDisable={disableRefresh} callback={refreshCallback} size={16} />
<TradePrice price={routeSummary?.executionPrice} color={theme.text} />
</Flex>
</RowBetween>
<RowBetween>
<RowFixed>
<TextDashed fontSize={12} fontWeight={400} color={theme.subText}>
<MouseoverTooltip
width="200px"
text={<Trans>You will receive at least this amount or your transaction will revert.</Trans>}
placement="right"
>
<Trans>Minimum Received</Trans>
</MouseoverTooltip>
</TextDashed>
</RowFixed>
<RowFixed>
<TYPE.black color={theme.text} fontSize={12}>
{gasUsd ? formattedNum(isHold ? +gasUsd * 0.8 : gasUsd, true) : '--'}
{minimumAmountOutStr || '--'}
</TYPE.black>
</RowBetween>
</RowFixed>
</RowBetween>

<RowBetween>
<RowFixed>
<TextDashed fontSize={12} fontWeight={400} color={theme.subText}>
<MouseoverTooltip
text={
<div>
<Trans>Estimated change in price due to the size of your transaction.</Trans>
<Text fontSize={12}>
<Trans>
Read more{' '}
<a
href="https://docs.kyberswap.com/getting-started/foundational-topics/decentralized-finance/price-impact"
target="_blank"
rel="noreferrer"
>
<b>here ↗</b>
</a>
</Trans>
</Text>
</div>
}
placement="right"
>
<Trans>Price Impact</Trans>
</MouseoverTooltip>
</TextDashed>
</RowFixed>
<TYPE.black
fontSize={12}
color={priceImpactResult.isVeryHigh ? theme.red : priceImpactResult.isHigh ? theme.warning : theme.text}
>
{priceImpactResult.isInvalid || typeof priceImpact !== 'number' ? '--' : formatPriceImpact(priceImpact)}
</TYPE.black>
</RowBetween>

{!isPartnerSwap && isSupportKyberDao(chainId) && (
<RowBetween>
<RowFixed>
<TextDashed fontSize={12} fontWeight={400} color={theme.subText}>
<MouseoverTooltip
text={
<div>
<Trans>Estimated change in price due to the size of your transaction.</Trans>
<Text fontSize={12}>
<Trans>
Read more{' '}
<a
href="https://docs.kyberswap.com/getting-started/foundational-topics/decentralized-finance/price-impact"
target="_blank"
rel="noreferrer"
>
<b>here ↗</b>
</a>
</Trans>
</Text>
</div>
<Trans>
Stake KNC in KyberDAO to get gas refund. Read more{' '}
<ExternalLink href="https://docs.kyberswap.com/governance/knc-token/gas-refund-program">
here ↗
</ExternalLink>
</Trans>
}
placement="right"
>
<Trans>Price Impact</Trans>
<Trans>Gas Refund</Trans>
</MouseoverTooltip>
</TextDashed>
</RowFixed>
<TYPE.black
fontSize={12}
color={priceImpactResult.isVeryHigh ? theme.red : priceImpactResult.isHigh ? theme.warning : theme.text}
<NavLink
to={APP_PATHS.KYBERDAO_KNC_UTILITY}
onClick={() => {
mixpanelHandler(MIXPANEL_TYPE.GAS_REFUND_SOURCE_CLICK, { source: 'Swap_page_more_info' })
}}
>
{priceImpactResult.isInvalid || typeof priceImpact !== 'number' ? '--' : formatPriceImpact(priceImpact)}
</TYPE.black>
<ButtonLight padding="0px 8px" width="fit-content" fontSize={10} fontWeight={500} lineHeight="16px">
<Trans>{account ? gasRefundPercentage * 100 : '--'}% Refund</Trans>
</ButtonLight>
</NavLink>
</RowBetween>

{!isPartnerSwap && isSupportKyberDao(chainId) && (
<RowBetween>
<RowFixed>
<TextDashed fontSize={12} fontWeight={400} color={theme.subText}>
<MouseoverTooltip
text={
<Trans>
Stake KNC in KyberDAO to get gas refund. Read more{' '}
<ExternalLink href="https://docs.kyberswap.com/governance/knc-token/gas-refund-program">
here ↗
</ExternalLink>
</Trans>
}
placement="right"
>
<Trans>Gas Refund</Trans>
</MouseoverTooltip>
</TextDashed>
</RowFixed>
<NavLink
to={APP_PATHS.KYBERDAO_KNC_UTILITY}
onClick={() => {
mixpanelHandler(MIXPANEL_TYPE.GAS_REFUND_SOURCE_CLICK, { source: 'Swap_page_more_info' })
}}
>
<ButtonLight padding="0px 8px" width="fit-content" fontSize={10} fontWeight={500} lineHeight="16px">
<Trans>{account ? gasRefundPercentage * 100 : '--'}% Refund</Trans>
</ButtonLight>
</NavLink>
</RowBetween>
)}
<SwapFee />
</ContentWrapper>
)}
<SwapFee />
</AutoColumn>
</Wrapper>
)
Expand Down
Loading

0 comments on commit e7998f4

Please sign in to comment.