feat: wallet hover styling and moving wallet to correct navbar (#4444)

* updating wallet to have correct hover highlighting and have correct scrolling

Co-authored-by: Alex Ball <alexball@UNISWAP-MAC-038.local>
This commit is contained in:
aballerr 2022-08-23 11:00:36 -04:00 committed by GitHub
parent 9873491db1
commit 68db8b3e23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 116 additions and 69 deletions

@ -25,6 +25,11 @@ const Grid = styled.a`
text-decoration: none;
border-bottom: ${({ theme }) => `1px solid ${theme.backgroundOutline}`};
padding: 12px;
&:hover {
background-color: ${({ theme }) => theme.backgroundModule};
transition: 250ms background-color ease;
}
`
const TextContainer = styled.span`

@ -5,7 +5,6 @@ import { RedesignVariant, useRedesignFlag } from 'featureFlags/flags/redesign'
import { TokensVariant, useTokensFlag } from 'featureFlags/flags/tokens'
import { TokenSafetyVariant, useTokenSafetyFlag } from 'featureFlags/flags/tokenSafety'
import { TokensNetworkFilterVariant, useTokensNetworkFilterFlag } from 'featureFlags/flags/tokensNetworkFilter'
import { useWalletFlag, WalletVariant } from 'featureFlags/flags/wallet'
import { useAtomValue } from 'jotai/utils'
import { ReactNode, useState } from 'react'
import { X } from 'react-feather'
@ -203,12 +202,6 @@ export default function FeatureFlagModal() {
featureFlag={FeatureFlag.tokenSafety}
label="Token Safety"
/>
<FeatureFlagOption
variants={Object.values(WalletVariant)}
value={useWalletFlag()}
featureFlag={FeatureFlag.wallet}
label="Wallet Flag"
/>
<SaveButton onClick={() => window.location.reload()}>Save Settings</SaveButton>
</Modal>
)

@ -1,11 +1,9 @@
import { Trans } from '@lingui/macro'
import useScrollPosition from '@react-hook/window-scroll'
import { useWeb3React } from '@web3-react/core'
import WalletDropdown from 'components/WalletDropdown'
import { getChainInfoOrDefault } from 'constants/chainInfo'
import { SupportedChainId } from 'constants/chains'
import { TokensVariant, useTokensFlag } from 'featureFlags/flags/tokens'
import { useWalletFlag, WalletVariant } from 'featureFlags/flags/wallet'
import { darken } from 'polished'
import { NavLink, useLocation } from 'react-router-dom'
import { Text } from 'rebass'
@ -219,12 +217,6 @@ const StyledNavLink = styled(NavLink)`
}
`
const WalletDropdownWrapper = styled.div`
position: absolute;
top: 75px;
right: 20px;
`
const StyledExternalLink = styled(ExternalLink)`
${({ theme }) => theme.flexRowNoWrap}
align-items: left;
@ -252,7 +244,6 @@ const StyledExternalLink = styled(ExternalLink)`
`
export default function Header() {
const walletFlag = useWalletFlag()
const tokensFlag = useTokensFlag()
const { account, chainId } = useWeb3React()
@ -355,11 +346,6 @@ export default function Header() {
) : null}
<Web3Status />
</AccountElement>
{walletFlag === WalletVariant.Enabled && (
<WalletDropdownWrapper>
<WalletDropdown />
</WalletDropdownWrapper>
)}
</HeaderElement>
<HeaderElement>
<Menu />

@ -81,6 +81,10 @@ const HeaderWrapper = styled.div`
justify-content: space-between;
`
const AuthenticatedHeaderWrapper = styled.div`
padding: 0 16px;
`
const AuthenticatedHeader = () => {
const { account, chainId, connector } = useWeb3React()
const [isCopied, setCopied] = useCopyClipboard()
@ -115,7 +119,7 @@ const AuthenticatedHeader = () => {
}, [balanceString, nativeCurrencyPrice])
return (
<>
<AuthenticatedHeaderWrapper>
<HeaderWrapper>
<StatusWrapper>
<FlexContainer>
@ -144,7 +148,7 @@ const AuthenticatedHeader = () => {
</UNIbutton>
)}
</Column>
</>
</AuthenticatedHeaderWrapper>
)
}

@ -18,6 +18,8 @@ const ConnectButton = styled(ButtonPrimary)`
width: 288px;
font-weight: 600;
font-size: 16px;
margin-left: auto;
margin-right: auto;
`
const Divider = styled.div`
@ -35,16 +37,16 @@ const ToggleMenuItem = styled.button`
flex: 1;
flex-direction: row;
align-items: center;
padding: 8px 0px;
justify-content: space-between;
font-size: 14px;
font-weight: 400;
width: 100%;
margin-bottom: 8px;
padding: 12px 16px;
color: ${({ theme }) => theme.textSecondary};
:hover {
color: ${({ theme }) => theme.textPrimary};
transition: 250ms color ease;
background-color: ${({ theme }) => theme.backgroundModule};
transition: 250ms all ease;
}
`
@ -69,7 +71,6 @@ const IconWrap = styled.span`
`
const DefaultMenuWrap = styled.div`
padding: 0 16px;
width: 100%;
height: 100%;
`

@ -24,7 +24,7 @@ const IconStyles = css`
color: ${({ theme }) => theme.textPrimary};
:hover {
background-color: ${({ theme }) => theme.hoverState};
transition: background-color 200ms linear;
transition: 250ms background-color ease;
${IconHoverText} {
opacity: 1;

@ -29,6 +29,8 @@ const InternalLinkMenuItem = styled(InternalMenuItem)<{ isActive: boolean }>`
color: ${({ theme }) => theme.textPrimary};
:hover {
cursor: pointer;
background-color: ${({ isActive, theme }) => !isActive && theme.backgroundModule};
transition: 250ms background-color ease;
}
`

@ -1,17 +1,6 @@
import { ChevronLeft } from 'react-feather'
import styled from 'styled-components/macro'
const BackSection = styled.div`
position: relative;
display: flex;
padding: 0 16px;
color: ${({ theme }) => theme.textSecondary};
cursor: default;
:hover {
text-decoration: none;
}
`
const Menu = styled.div`
width: 100%;
height: 100%;
@ -29,12 +18,16 @@ const Header = styled.span`
const ClearAll = styled.div`
display: inline-block;
cursor: pointer;
margin-left: auto;
color: ${({ theme }) => theme.accentAction};
font-weight: 600;
font-size: 14px;
margin-top: auto;
margin-bottom: auto;
:hover {
opacity: 0.6;
transition: 250ms opacity ease;
}
`
const StyledChevron = styled(ChevronLeft)`
@ -46,6 +39,28 @@ const StyledChevron = styled(ChevronLeft)`
}
`
const BackSection = styled.div`
position: absolute;
background-color: ${({ theme }) => theme.backgroundSurface};
width: 100%;
padding: 0 16px 16px 16px;
color: ${({ theme }) => theme.textSecondary};
cursor: default;
display: flex;
justify-content: space-between;
`
const BackSectionContainer = styled.div`
display: flex;
justify-content: space-between;
position: relative;
width: 100%;
`
const ChildrenContainer = styled.div`
margin-top: 40px;
`
export const SlideOutMenu = ({
children,
onClose,
@ -59,10 +74,13 @@ export const SlideOutMenu = ({
}) => (
<Menu>
<BackSection>
<BackSectionContainer>
<StyledChevron onClick={onClose} size={24} />
<Header>{title}</Header>
{onClear && <ClearAll onClick={onClear}>Clear All</ClearAll>}
</BackSectionContainer>
</BackSection>
{children}
<ChildrenContainer>{children}</ChildrenContainer>
</Menu>
)

@ -1,6 +1,8 @@
import { useState } from 'react'
import styled from 'styled-components/macro'
import { useModalIsOpen } from '../../state/application/hooks'
import { ApplicationModal } from '../../state/application/reducer'
import DefaultMenu from './DefaultMenu'
import LanguageMenu from './LanguageMenu'
import { TransactionHistoryMenu } from './TransactionMenu'
@ -9,7 +11,6 @@ const WalletWrapper = styled.div`
border-radius: 12px;
width: 320px;
max-height: 376px;
display: flex;
flex-direction: column;
font-size: 16px;
@ -25,15 +26,37 @@ export enum MenuState {
TRANSACTIONS = 'TRANSACTIONS',
}
const WalletDropdownWrapper = styled.div`
position: absolute;
@media only screen and (min-width: 1280px) {
top: 65px;
right: 20px;
}
@media only screen and (max-width: 1280px) {
left: 50%;
bottom: 45px;
transform: translateX(-50%);
}
`
const WalletDropdown = () => {
const [menu, setMenu] = useState<MenuState>(MenuState.DEFAULT)
const walletDropdownOpen = useModalIsOpen(ApplicationModal.WALLET_DROPDOWN)
return (
<>
{walletDropdownOpen && (
<WalletDropdownWrapper>
<WalletWrapper>
{menu === MenuState.TRANSACTIONS && <TransactionHistoryMenu onClose={() => setMenu(MenuState.DEFAULT)} />}
{menu === MenuState.LANGUAGE && <LanguageMenu onClose={() => setMenu(MenuState.DEFAULT)} />}
{menu === MenuState.DEFAULT && <DefaultMenu setMenu={setMenu} />}
</WalletWrapper>
</WalletDropdownWrapper>
)}
</>
)
}

@ -3,17 +3,22 @@ import { t, Trans } from '@lingui/macro'
import { useWeb3React } from '@web3-react/core'
import { ElementName, Event, EventName } from 'components/AmplitudeAnalytics/constants'
import { TraceEvent } from 'components/AmplitudeAnalytics/TraceEvent'
import WalletDropdown from 'components/WalletDropdown'
import { getConnection } from 'connection/utils'
import { NavBarVariant, useNavBarFlag } from 'featureFlags/flags/navBar'
import { getIsValidSwapQuote } from 'pages/Swap'
import { darken } from 'polished'
import { useMemo } from 'react'
import { useMemo, useRef } from 'react'
import { AlertTriangle } from 'react-feather'
import { useAppSelector } from 'state/hooks'
import { useDerivedSwapInfo } from 'state/swap/hooks'
import styled, { css } from 'styled-components/macro'
import { useOnClickOutside } from '../../hooks/useOnClickOutside'
import { useHasSocks } from '../../hooks/useSocksBalance'
import { useToggleWalletModal } from '../../state/application/hooks'
import { useModalIsOpen, useToggleWalletDropdown, useToggleWalletModal } from '../../state/application/hooks'
import { useCloseModal } from '../../state/application/hooks'
import { ApplicationModal } from '../../state/application/reducer'
import { isTransactionRecent, useAllTransactions } from '../../state/transactions/hooks'
import { TransactionDetails } from '../../state/transactions/types'
import { shortenAddress } from '../../utils'
@ -133,6 +138,9 @@ function Web3StatusInner() {
inputError: swapInputError,
} = useDerivedSwapInfo()
const validSwapQuote = getIsValidSwapQuote(trade, tradeState, swapInputError)
const navbarFlag = useNavBarFlag()
const toggleWalletDropdown = useToggleWalletDropdown()
const toggleWalletModal = useToggleWalletModal()
const error = useAppSelector((state) => state.connection.errorByConnectionType[getConnection(connector).type])
@ -147,13 +155,13 @@ function Web3StatusInner() {
const hasPendingTransactions = !!pending.length
const hasSocks = useHasSocks()
const toggleWalletModal = useToggleWalletModal()
const toggleWallet = navbarFlag === NavBarVariant.Enabled ? toggleWalletDropdown : toggleWalletModal
if (!chainId) {
return null
} else if (error) {
return (
<Web3StatusError onClick={toggleWalletModal}>
<Web3StatusError onClick={toggleWallet}>
<NetworkIcon />
<Text>
<Trans>Error</Trans>
@ -162,11 +170,7 @@ function Web3StatusInner() {
)
} else if (account) {
return (
<Web3StatusConnected
data-testid="web3-status-connected"
onClick={toggleWalletModal}
pending={hasPendingTransactions}
>
<Web3StatusConnected data-testid="web3-status-connected" onClick={toggleWallet} pending={hasPendingTransactions}>
{hasPendingTransactions ? (
<RowBetween>
<Text>
@ -191,7 +195,7 @@ function Web3StatusInner() {
properties={{ received_swap_quote: validSwapQuote }}
element={ElementName.CONNECT_WALLET_BUTTON}
>
<Web3StatusConnect onClick={toggleWalletModal} faded={!account}>
<Web3StatusConnect onClick={toggleWallet} faded={!account}>
<Text>
<Trans>Connect Wallet</Trans>
</Text>
@ -201,10 +205,22 @@ function Web3StatusInner() {
}
}
const useIsOpen = () => {
const walletDropdownOpen = useModalIsOpen(ApplicationModal.WALLET_DROPDOWN)
const navbarFlag = useNavBarFlag()
return useMemo(() => navbarFlag === NavBarVariant.Enabled && walletDropdownOpen, [navbarFlag, walletDropdownOpen])
}
export default function Web3Status() {
const { ENSName } = useWeb3React()
const allTransactions = useAllTransactions()
const ref = useRef<HTMLDivElement>(null)
const closeModal = useCloseModal(ApplicationModal.WALLET_DROPDOWN)
const isOpen = useIsOpen()
useOnClickOutside(ref, isOpen ? closeModal : undefined)
const sortedRecentTransactions = useMemo(() => {
const txs = Object.values(allTransactions)
@ -215,9 +231,10 @@ export default function Web3Status() {
const confirmed = sortedRecentTransactions.filter((tx) => tx.receipt).map((tx) => tx.hash)
return (
<>
<span ref={ref}>
<Web3StatusInner />
<WalletModal ENSName={ENSName ?? undefined} pendingTransactions={pending} confirmedTransactions={confirmed} />
</>
<WalletDropdown />
</span>
)
}

@ -1,7 +0,0 @@
import { BaseVariant, FeatureFlag, useBaseFlag } from '../index'
export function useWalletFlag(): BaseVariant {
return useBaseFlag(FeatureFlag.wallet)
}
export { BaseVariant as WalletVariant }

@ -30,6 +30,10 @@ export function useToggleWalletModal(): () => void {
return useToggleModal(ApplicationModal.WALLET)
}
export function useToggleWalletDropdown(): () => void {
return useToggleModal(ApplicationModal.WALLET_DROPDOWN)
}
export function useToggleSettingsMenu(): () => void {
return useToggleModal(ApplicationModal.SETTINGS)
}

@ -26,6 +26,7 @@ export enum ApplicationModal {
SETTINGS,
VOTE,
WALLET,
WALLET_DROPDOWN,
QUEUE,
EXECUTE,
TIME_SELECTOR,