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:
parent
9873491db1
commit
68db8b3e23
@ -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>
|
||||
<StyledChevron onClick={onClose} size={24} />
|
||||
<Header>{title}</Header>
|
||||
{onClear && <ClearAll onClick={onClear}>Clear All</ClearAll>}
|
||||
<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 (
|
||||
<WalletWrapper>
|
||||
{menu === MenuState.TRANSACTIONS && <TransactionHistoryMenu onClose={() => setMenu(MenuState.DEFAULT)} />}
|
||||
{menu === MenuState.LANGUAGE && <LanguageMenu onClose={() => setMenu(MenuState.DEFAULT)} />}
|
||||
{menu === MenuState.DEFAULT && <DefaultMenu setMenu={setMenu} />}
|
||||
</WalletWrapper>
|
||||
<>
|
||||
{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,
|
||||
|
Loading…
Reference in New Issue
Block a user