feat: Mobile Nav (#4501)

* working and cleaned up mobile nav

* delete old files

* fix wallet position

* update searchbar breakpoint

* update full screen search

* delete old comments

* cleanup eslint

* Update MenuDropdown.tsx

* Update SearchBar.tsx

Co-authored-by: Charlie <charlie@uniswap.org>
This commit is contained in:
Charles Bachmeier 2022-08-26 04:39:58 -07:00 committed by GitHub
parent 748a5eadc0
commit 751ce8e6d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 151 additions and 552 deletions

@ -79,7 +79,7 @@ export const ChainSwitcher = ({ leftAlign }: ChainSwitcherProps) => {
const isSupported = !!info
const dropdown = (
<NavDropdown top={54} leftAligned={leftAlign} paddingBottom={8} paddingTop={8}>
<NavDropdown top="56" left="0">
<Column marginX="8">
{NETWORK_SELECTOR_CHAINS.map((chainId: SupportedChainId) => (
<ChainRow

@ -62,6 +62,6 @@ export const Separator = style([
export const IconRow = style([
sprinkles({
paddingX: '16',
marginTop: '4',
justifyContent: { sm: 'center', md: 'flex-start' },
}),
])

@ -129,7 +129,7 @@ export const MenuDropdown = () => {
</NavIcon>
{isOpen && (
<NavDropdown top={60}>
<NavDropdown top={{ sm: 'unset', xxl: '56' }} bottom={{ sm: '56', xxl: 'unset' }} right="0">
<Column gap="16">
<Column paddingX="8" gap="4">
{nftFlag === NftVariant.Enabled && (
@ -154,7 +154,13 @@ export const MenuDropdown = () => {
</PrimaryMenuRow>
</Column>
<Separator />
<Column paddingX="8">
<Box
display="flex"
flexDirection={{ sm: 'row', md: 'column' }}
flexWrap="wrap"
alignItems={{ sm: 'center', md: 'flex-start' }}
paddingX="8"
>
<SecondaryLinkedText href="https://help.uniswap.org/en/">Help center </SecondaryLinkedText>
<SecondaryLinkedText href="https://docs.uniswap.org/">Documentation </SecondaryLinkedText>
<SecondaryLinkedText
@ -166,7 +172,7 @@ export const MenuDropdown = () => {
{(isDevelopmentEnv() || isStagingEnv()) && (
<SecondaryLinkedText onClick={openFeatureFlagsModal}>{`Feature Flags`}</SecondaryLinkedText>
)}
</Column>
</Box>
<IconRow>
<Icon href="https://discord.com/invite/FCfyBSbCU5">
<DiscordIconMenu className={styles.hover} width={24} height={24} color={themeVars.colors.darkGray} />

@ -1,121 +0,0 @@
import { style } from '@vanilla-extract/css'
import { subhead } from 'nft/css/common.css'
import { sprinkles } from '../../nft/css/sprinkles.css'
export const sidebar = style([
sprinkles({
display: 'flex',
position: 'fixed',
background: 'white',
height: 'full',
top: '0',
left: '0',
right: '0',
bottom: '0',
paddingBottom: '16',
justifyContent: 'space-between',
}),
{
zIndex: 20,
},
])
export const icon = style([
sprinkles({
width: '32',
height: '32',
}),
])
export const iconContainer = style([
sprinkles({
position: 'relative',
display: 'flex',
flexDirection: 'column',
color: 'darkGray',
background: 'none',
border: 'none',
justifyContent: 'flex-end',
textAlign: 'center',
cursor: 'pointer',
padding: '6',
}),
])
export const linkRow = style([
subhead,
sprinkles({
color: 'blackBlue',
width: 'full',
paddingLeft: '16',
paddingY: '12',
cursor: 'pointer',
}),
{
lineHeight: '24px',
textDecoration: 'none',
},
])
export const activeLinkRow = style([
linkRow,
sprinkles({
background: 'lightGrayButton',
}),
])
export const separator = style([
sprinkles({
height: '0',
borderStyle: 'solid',
borderColor: 'medGray',
borderWidth: '1px',
marginY: '8',
marginX: '16',
}),
])
export const extraLinkRow = style([
subhead,
sprinkles({
width: 'full',
color: 'blackBlue',
paddingY: '12',
paddingLeft: '16',
cursor: 'pointer',
}),
{
lineHeight: '24px',
textDecoration: 'none',
},
])
export const bottomExternalLinks = style([
sprinkles({
gap: '4',
paddingX: '4',
width: 'max',
flexWrap: 'wrap',
}),
])
export const bottomJointExternalLinksContainer = style([
sprinkles({
paddingX: '8',
paddingY: '4',
color: 'darkGray',
fontWeight: 'medium',
fontSize: '12',
}),
{
lineHeight: '20px',
},
])
export const IconRow = style([
sprinkles({
gap: '12',
width: 'max',
}),
])

@ -1,249 +0,0 @@
import FeatureFlagModal from 'components/FeatureFlagModal/FeatureFlagModal'
import { PrivacyPolicyModal } from 'components/PrivacyPolicy'
import { NftVariant, useNftFlag } from 'featureFlags/flags/nft'
import { Box } from 'nft/components/Box'
import { Portal } from 'nft/components/common/Portal'
import { Column, Row } from 'nft/components/Flex'
import {
BarChartIconMobile,
BulletIcon,
CloseIcon,
DiscordIconMenuMobile,
GithubIconMenuMobile,
GovernanceIconMobile,
HamburgerIcon,
ThinTagIconMobile,
TwitterIconMenuMobile,
} from 'nft/components/icons'
import { themeVars } from 'nft/css/sprinkles.css'
import { ReactNode, useReducer } from 'react'
import { NavLink, NavLinkProps, useLocation } from 'react-router-dom'
import { useToggleModal, useTogglePrivacyPolicy } from 'state/application/hooks'
import { ApplicationModal } from 'state/application/reducer'
import { isDevelopmentEnv, isStagingEnv } from 'utils/env'
import * as styles from './MobileSidebar.css'
import { NavIcon } from './NavIcon'
interface NavLinkRowProps {
href: string
id?: NavLinkProps['id']
isActive?: boolean
close: () => void
children: ReactNode
}
const NavLinkRow = ({ href, id, isActive, close, children }: NavLinkRowProps) => {
return (
<NavLink to={href} className={isActive ? styles.activeLinkRow : styles.linkRow} id={id} onClick={close}>
{children}
</NavLink>
)
}
const ExtraLinkRow = ({
to,
href,
close,
children,
}: {
to?: NavLinkProps['to']
href?: string
close: () => void
children: ReactNode
}) => {
return (
<>
{to ? (
<NavLink to={to} className={styles.extraLinkRow}>
<Row gap="12" onClick={close}>
{children}
</Row>
</NavLink>
) : (
<Row
as="a"
href={href}
target={'_blank'}
rel={'noopener noreferrer'}
gap="12"
onClick={close}
className={styles.extraLinkRow}
>
{children}
</Row>
)}
</>
)
}
const BottomExternalLink = ({
href,
onClick,
children,
}: {
href?: string
onClick?: () => void
children: ReactNode
}) => {
return (
<Box
as={href ? 'a' : 'div'}
href={href ?? undefined}
target={href ? '_blank' : undefined}
rel={href ? 'noopener noreferrer' : undefined}
className={`${styles.bottomJointExternalLinksContainer}`}
onClick={onClick}
cursor="pointer"
>
{children}
</Box>
)
}
const Icon = ({ href, children }: { href?: string; children: ReactNode }) => {
return (
<>
<Box
as={href ? 'a' : 'div'}
href={href ?? undefined}
target={href ? '_blank' : undefined}
rel={href ? 'noopener noreferrer' : undefined}
display="flex"
flexDirection="column"
color="blackBlue"
background="none"
border="none"
justifyContent="center"
textAlign="center"
>
{children}
</Box>
</>
)
}
const IconRow = ({ children }: { children: ReactNode }) => {
return <Row className={styles.IconRow}>{children}</Row>
}
const Seperator = () => {
return <Box className={styles.separator} />
}
export const MobileSideBar = () => {
const [isOpen, toggleOpen] = useReducer((s) => !s, false)
const togglePrivacyPolicy = useTogglePrivacyPolicy()
const openFeatureFlagsModal = useToggleModal(ApplicationModal.FEATURE_FLAGS)
const { pathname } = useLocation()
const nftFlag = useNftFlag()
const isPoolActive =
pathname.startsWith('/pool') ||
pathname.startsWith('/add') ||
pathname.startsWith('/remove') ||
pathname.startsWith('/increase') ||
pathname.startsWith('/find')
return (
<>
<NavIcon isActive={isOpen} onClick={toggleOpen}>
<HamburgerIcon width={28} height={28} />
</NavIcon>
{isOpen && (
<Portal>
<Column className={styles.sidebar}>
<Column>
<Row justifyContent="flex-end" marginTop="14" marginBottom="20" marginRight="8">
<Box as="button" onClick={toggleOpen} className={styles.iconContainer}>
<CloseIcon className={styles.icon} />
</Box>
</Row>
<Column gap="4">
<NavLinkRow href="/swap" close={toggleOpen} isActive={pathname.startsWith('/swap')}>
Swap
</NavLinkRow>
<NavLinkRow href="/tokens" close={toggleOpen} isActive={pathname.startsWith('/tokens')}>
Tokens
</NavLinkRow>
{nftFlag === NftVariant.Enabled && (
<NavLinkRow href="/nfts" close={toggleOpen} isActive={pathname.startsWith('/nfts')}>
NFTs
</NavLinkRow>
)}
<NavLinkRow href="/pool" id={'pool-nav-link'} isActive={isPoolActive} close={toggleOpen}>
Pool
</NavLinkRow>
</Column>
<Seperator />
<Column gap="4">
{nftFlag === NftVariant.Enabled && (
<ExtraLinkRow to="/nft/sell" close={toggleOpen}>
<Icon>
<ThinTagIconMobile width={24} height={24} />
</Icon>
Sell NFTs
</ExtraLinkRow>
)}
<ExtraLinkRow to="/vote" close={toggleOpen}>
<Icon>
<GovernanceIconMobile width={24} height={24} />
</Icon>
Vote in governance
</ExtraLinkRow>
<ExtraLinkRow href="https://info.uniswap.org/#/" close={toggleOpen}>
<Icon>
<BarChartIconMobile width={24} height={24} />
</Icon>
View token analytics
</ExtraLinkRow>
</Column>
</Column>
<Column>
<Row justifyContent="center" marginBottom="12" flexWrap="wrap">
<Row className={styles.bottomExternalLinks}>
<BottomExternalLink href="https://help.uniswap.org/en/" onClick={toggleOpen}>
Help center
</BottomExternalLink>
<BulletIcon />
<BottomExternalLink href="https://docs.uniswap.org/" onClick={toggleOpen}>
Documentation
</BottomExternalLink>
<BulletIcon />
<BottomExternalLink
onClick={() => {
toggleOpen()
togglePrivacyPolicy()
}}
>
{`Legal & Privacy`}
</BottomExternalLink>
</Row>
{(isDevelopmentEnv() || isStagingEnv()) && (
<>
<BulletIcon />
<BottomExternalLink onClick={openFeatureFlagsModal}>{`Feature Flags`}</BottomExternalLink>
</>
)}
</Row>
<Row justifyContent="center">
<IconRow>
<Icon href="https://discord.com/invite/FCfyBSbCU5">
<DiscordIconMenuMobile width={32} height={32} color={themeVars.colors.darkGray} />
</Icon>
<Icon href="https://twitter.com/Uniswap">
<TwitterIconMenuMobile width={32} height={32} color={themeVars.colors.darkGray} />
</Icon>
<Icon href="https://github.com/Uniswap">
<GithubIconMenuMobile width={32} height={32} color={themeVars.colors.darkGray} />
</Icon>
</IconRow>
</Row>
</Column>
</Column>
</Portal>
)}
<PrivacyPolicyModal />
<FeatureFlagModal />
</>
)
}

@ -1,25 +1,40 @@
import { style } from '@vanilla-extract/css'
import { breakpoints, sprinkles } from '../../nft/css/sprinkles.css'
import { sprinkles } from '../../nft/css/sprinkles.css'
export const NavDropdown = style([
const baseNavDropdown = style([
sprinkles({
position: { sm: 'fixed', md: 'absolute' },
background: 'lightGray',
borderRadius: '12',
borderStyle: 'solid',
borderColor: 'medGray',
borderWidth: '1px',
bottom: { sm: '56', md: 'unset' },
paddingBottom: '8',
paddingTop: '8',
}),
{
boxShadow: '0px 4px 12px 0px #00000026',
zIndex: 10,
'@media': {
[`screen and (max-width: ${breakpoints.sm}px)`]: {
borderBottomLeftRadius: '0',
borderBottomRightRadius: '0',
},
},
},
])
export const NavDropdown = style([
baseNavDropdown,
sprinkles({
position: 'absolute',
borderRadius: '12',
}),
{},
])
export const mobileNavDropdown = style([
baseNavDropdown,
sprinkles({
position: 'fixed',
borderTopRightRadius: '12',
borderTopLeftRadius: '12',
top: 'unset',
bottom: '56',
left: '0',
right: '0',
}),
])

@ -1,45 +1,12 @@
import { Box } from 'nft/components/Box'
import { Box, BoxProps } from 'nft/components/Box'
import { useIsMobile } from 'nft/hooks'
import { ReactNode } from 'react'
import { ForwardedRef, forwardRef } from 'react'
import * as styles from './NavDropdown.css'
interface NavDropdownProps {
top: number
right?: number
leftAligned?: boolean
horizontalPadding?: boolean
centerHorizontally?: boolean
paddingBottom?: number
paddingTop?: number
children: ReactNode
}
export const NavDropdown = ({
top,
centerHorizontally,
leftAligned,
horizontalPadding,
paddingBottom,
paddingTop,
children,
}: NavDropdownProps) => {
export const NavDropdown = forwardRef((props: BoxProps, ref: ForwardedRef<HTMLElement>) => {
const isMobile = useIsMobile()
return (
<Box
paddingX={horizontalPadding ? '16' : undefined}
style={{
top: isMobile ? 'unset' : `${top}px`,
left: isMobile ? 0 : centerHorizontally ? '50%' : leftAligned ? '0px' : 'auto',
right: isMobile ? 0 : centerHorizontally || leftAligned ? 'auto' : '0px',
transform: centerHorizontally ? 'translateX(-50%)' : 'unset',
paddingBottom: paddingBottom ?? '24px',
paddingTop: paddingTop ?? '24px',
zIndex: 3,
}}
className={styles.NavDropdown}
>
{children}
</Box>
)
}
return <Box ref={ref} className={isMobile ? styles.mobileNavDropdown : styles.NavDropdown} {...props} />
})
NavDropdown.displayName = 'NavDropdown'

@ -7,7 +7,6 @@ export const navIcon = style([
position: 'relative',
display: 'flex',
flexDirection: 'column',
color: 'blackBlue',
border: 'none',
justifyContent: 'center',
textAlign: 'center',

@ -11,7 +11,13 @@ interface NavIconProps {
export const NavIcon = ({ children, isActive, onClick }: NavIconProps) => {
return (
<Box as="button" className={styles.navIcon} background={isActive ? 'accentActiveSoft' : 'none'} onClick={onClick}>
<Box
as="button"
className={styles.navIcon}
background={isActive ? 'accentActiveSoft' : 'none'}
color={isActive ? 'blackBlue' : 'darkGray'}
onClick={onClick}
>
{children}
</Box>
)

@ -38,15 +38,6 @@ export const baseContainer = style([
}),
])
export const baseMobileContainer = style([
sprinkles({
display: 'flex',
width: 'full',
alignItems: 'center',
marginY: '2',
}),
])
export const baseSideContainer = style([
baseContainer,
sprinkles({
@ -64,19 +55,13 @@ export const leftSideContainer = style([
}),
])
export const leftSideMobileContainer = style([
baseMobileContainer,
sprinkles({
justifyContent: 'flex-start',
}),
])
export const middleContainer = style([
baseContainer,
sprinkles({
flex: '1',
flexShrink: '1',
justifyContent: 'center',
display: { sm: 'none', lg: 'flex' },
}),
])
@ -95,6 +80,7 @@ const baseMenuItem = style([
marginY: '4',
borderRadius: '12',
transition: '250',
height: 'min',
}),
{
lineHeight: '24px',
@ -112,13 +98,6 @@ export const menuItem = style([
}),
])
export const rightSideMobileContainer = style([
baseMobileContainer,
sprinkles({
justifyContent: 'flex-end',
}),
])
export const activeMenuItem = style([
baseMenuItem,
sprinkles({
@ -127,16 +106,17 @@ export const activeMenuItem = style([
}),
])
export const mobileWalletContainer = style([
export const mobileBottomBar = style([
sprinkles({
position: 'fixed',
display: 'flex',
display: { sm: 'flex', xxl: 'none' },
bottom: '0',
right: '1/2',
marginY: '0',
marginX: 'auto',
right: '0',
left: '0',
justifyContent: 'space-between',
paddingY: '4',
paddingX: '8',
height: '56',
background: 'lightGray',
}),
{
transform: 'translate(50%,-50%)',
},
])

@ -1,16 +1,13 @@
import Web3Status from 'components/Web3Status'
import { NftVariant, useNftFlag } from 'featureFlags/flags/nft'
import { useWindowSize } from 'hooks/useWindowSize'
import { ReactNode } from 'react'
import { NavLink, NavLinkProps, useLocation } from 'react-router-dom'
import { Box } from '../../nft/components/Box'
import { Row } from '../../nft/components/Flex'
import { UniIcon, UniIconMobile } from '../../nft/components/icons'
import { breakpoints } from '../../nft/css/sprinkles.css'
import { UniIcon } from '../../nft/components/icons'
import { ChainSwitcher } from './ChainSwitcher'
import { MenuDropdown } from './MenuDropdown'
import { MobileSideBar } from './MobileSidebar'
import * as styles from './Navbar.css'
import { SearchBar } from './SearchBar'
@ -34,46 +31,10 @@ const MenuItem = ({ href, id, isActive, children }: MenuItemProps) => {
)
}
const MobileNavbar = () => {
return (
<>
<nav className={styles.nav}>
<Box display="flex" height="full" flexWrap="nowrap" alignItems="stretch">
<Box className={styles.leftSideMobileContainer}>
<Box as="a" href="#/swap" className={styles.logoContainer}>
<UniIconMobile width="44" height="44" className={styles.logo} />
</Box>
<ChainSwitcher leftAlign={true} />
</Box>
<Box className={styles.middleContainer} display={{ sm: 'none', md: 'flex' }}>
<SearchBar />
</Box>
<Box className={styles.rightSideMobileContainer}>
<Row gap="16">
<Box display={{ sm: 'flex', md: 'none' }}>
<SearchBar />
</Box>
<MobileSideBar />
</Row>
</Box>
</Box>
</nav>
<Box className={styles.mobileWalletContainer}>
<Web3Status />
</Box>
</>
)
}
const Navbar = () => {
const { width: windowWidth } = useWindowSize()
const PageTabs = () => {
const { pathname } = useLocation()
const nftFlag = useNftFlag()
if (windowWidth && windowWidth <= breakpoints.xl) {
return <MobileNavbar />
}
const isPoolActive =
pathname.startsWith('/pool') ||
pathname.startsWith('/add') ||
@ -82,41 +43,66 @@ const Navbar = () => {
pathname.startsWith('/find')
return (
<nav className={styles.nav}>
<Box display="flex" height="full" flexWrap="nowrap" alignItems="stretch">
<Box className={styles.leftSideContainer}>
<Box as="a" href="#/swap" className={styles.logoContainer}>
<UniIcon width="48" height="48" className={styles.logo} />
<>
<MenuItem href="/swap" isActive={pathname.startsWith('/swap')}>
Swap
</MenuItem>
<MenuItem href="/tokens" isActive={pathname.startsWith('/tokens')}>
Tokens
</MenuItem>
{nftFlag === NftVariant.Enabled && (
<MenuItem href="/nfts" isActive={pathname.startsWith('/nfts')}>
NFTs
</MenuItem>
)}
<MenuItem href="/pool" id={'pool-nav-link'} isActive={isPoolActive}>
Pool
</MenuItem>
</>
)
}
const Navbar = () => {
return (
<>
<nav className={styles.nav}>
<Box display="flex" height="full" flexWrap="nowrap" alignItems="stretch">
<Box className={styles.leftSideContainer}>
<Box as="a" href="#/swap" className={styles.logoContainer}>
<UniIcon width="48" height="48" className={styles.logo} />
</Box>
<Box display={{ sm: 'flex', xxl: 'none' }}>
<ChainSwitcher leftAlign={true} />
</Box>
<Row gap="8" display={{ sm: 'none', xxl: 'flex' }}>
<PageTabs />
</Row>
</Box>
<Box className={styles.middleContainer}>
<SearchBar />
</Box>
<Box className={styles.rightSideContainer}>
<Row gap="12">
<Box display={{ sm: 'flex', lg: 'none' }}>
<SearchBar />
</Box>
<Box display={{ sm: 'none', xxl: 'flex' }}>
<MenuDropdown />
</Box>
<Box display={{ sm: 'none', xxl: 'flex' }}>
<ChainSwitcher />
</Box>
<Web3Status />
</Row>
</Box>
<Row gap="8">
<MenuItem href="/swap" isActive={pathname.startsWith('/swap')}>
Swap
</MenuItem>
<MenuItem href="/tokens" isActive={pathname.startsWith('/tokens')}>
Tokens
</MenuItem>
{nftFlag === NftVariant.Enabled && (
<MenuItem href="/nfts" isActive={pathname.startsWith('/nfts')}>
NFTs
</MenuItem>
)}
<MenuItem href="/pool" id={'pool-nav-link'} isActive={isPoolActive}>
Pool
</MenuItem>
</Row>
</Box>
<Box className={styles.middleContainer} display="flex">
<SearchBar />
</Box>
<Box className={styles.rightSideContainer}>
<Row gap="12">
<MenuDropdown />
<ChainSwitcher />
<Web3Status />
</Row>
</Box>
</nav>
<Box className={styles.mobileBottomBar}>
<PageTabs />
<MenuDropdown />
</Box>
</nav>
</>
)
}

@ -15,7 +15,7 @@ const baseSearchStyle = style([
}),
{
'@media': {
[`screen and (min-width: ${breakpoints.sm}px)`]: {
[`screen and (min-width: ${breakpoints.md}px)`]: {
width: DESKTOP_NAVBAR_WIDTH,
},
},

@ -2,14 +2,12 @@ import clsx from 'clsx'
import { NftVariant, useNftFlag } from 'featureFlags/flags/nft'
import useDebounce from 'hooks/useDebounce'
import { useOnClickOutside } from 'hooks/useOnClickOutside'
import { useWindowSize } from 'hooks/useWindowSize'
import { organizeSearchResults } from 'lib/utils/searchBar'
import { Box } from 'nft/components/Box'
import { Column, Row } from 'nft/components/Flex'
import { Overlay } from 'nft/components/modals/Overlay'
import { magicalGradientOnHover, subheadSmall } from 'nft/css/common.css'
import { breakpoints } from 'nft/css/sprinkles.css'
import { useSearchHistory } from 'nft/hooks'
import { useIsMobile, useSearchHistory } from 'nft/hooks'
import { fetchSearchCollections, fetchTrendingCollections } from 'nft/queries'
import { fetchSearchTokens } from 'nft/queries/genie/SearchTokensFetcher'
import { fetchTrendingTokens } from 'nft/queries/genie/TrendingTokensFetcher'
@ -267,8 +265,8 @@ export const SearchBar = () => {
const debouncedSearchValue = useDebounce(searchValue, 300)
const searchRef = useRef<HTMLDivElement>(null)
const { pathname } = useLocation()
const { width: windowWidth } = useWindowSize()
const phase1Flag = useNftFlag()
const isMobile = useIsMobile()
useOnClickOutside(searchRef, () => {
isOpen && toggleOpen()
@ -318,15 +316,13 @@ export const SearchBar = () => {
setSearchValue('')
}, [pathname])
const isMobile = useMemo(() => windowWidth && windowWidth <= breakpoints.sm, [windowWidth])
return (
<>
<Box
position={{ sm: isOpen ? 'absolute' : 'relative', md: 'relative' }}
top={{ sm: '0', md: 'unset' }}
left={{ sm: '0', md: 'unset' }}
width={{ sm: isOpen ? 'viewWidth' : 'auto', md: 'auto' }}
position={{ sm: isOpen ? 'absolute' : 'relative', lg: 'relative' }}
top={{ sm: '0', lg: 'unset' }}
left={{ sm: '0', lg: 'unset' }}
width={{ sm: isOpen ? 'viewWidth' : 'auto', lg: 'auto' }}
ref={searchRef}
style={{ zIndex: '1000' }}
>
@ -335,16 +331,16 @@ export const SearchBar = () => {
borderRadius={isOpen ? undefined : '12'}
borderTopRightRadius={isOpen && !isMobile ? '12' : undefined}
borderTopLeftRadius={isOpen && !isMobile ? '12' : undefined}
display={{ sm: isOpen ? 'flex' : 'none', md: 'flex' }}
display={{ sm: isOpen ? 'flex' : 'none', lg: 'flex' }}
justifyContent={isOpen || phase1Flag === NftVariant.Enabled ? 'flex-start' : 'center'}
onFocus={() => !isOpen && toggleOpen()}
onClick={() => !isOpen && toggleOpen()}
gap="12"
>
<Box display={{ sm: 'none', md: 'flex' }}>
<Box display={{ sm: 'none', lg: 'flex' }}>
<MagnifyingGlassIcon />
</Box>
<Box display={{ sm: 'flex', md: 'none' }} color="placeholder" onClick={toggleOpen}>
<Box display={{ sm: 'flex', lg: 'none' }} color="placeholder" onClick={toggleOpen}>
<ChevronLeftIcon />
</Box>
<Box
@ -359,7 +355,7 @@ export const SearchBar = () => {
value={searchValue}
/>
</Row>
<Box display={{ sm: isOpen ? 'none' : 'flex', md: 'none' }}>
<Box display={{ sm: isOpen ? 'none' : 'flex', lg: 'none' }}>
<NavIcon onClick={toggleOpen}>
<NavMagnifyingGlassIcon width={28} height={28} />
</NavIcon>

@ -20,6 +20,10 @@ const WalletWrapper = styled.div`
border: ${({ theme }) => `1px solid ${theme.backgroundOutline}`};
box-shadow: ${({ theme }) => theme.deepShadow};
padding: 16px 0;
@media only screen and (max-width: ${({ theme }) => `${theme.breakpoint.sm}px`}) {
width: 100%;
}
`
export enum MenuState {
@ -33,11 +37,12 @@ const WalletDropdownWrapper = styled.div`
top: 65px;
right: 20px;
@media only screen and (max-width: ${({ theme }) => `${theme.breakpoint.xl}px`}) {
@media only screen and (max-width: ${({ theme }) => `${theme.breakpoint.sm}px`}) {
top: unset;
right: 50%;
bottom: 45px;
transform: translateX(50%);
left: 0;
right: 0;
bottom: 56px;
z-index: 1;
}
`

@ -6,6 +6,8 @@ import { TraceEvent } from 'components/AmplitudeAnalytics/TraceEvent'
import WalletDropdown from 'components/WalletDropdown'
import { getConnection } from 'connection/utils'
import { NavBarVariant, useNavBarFlag } from 'featureFlags/flags/navBar'
import { Portal } from 'nft/components/common/Portal'
import { useIsMobile } from 'nft/hooks'
import { getIsValidSwapQuote } from 'pages/Swap'
import { darken } from 'polished'
import { useMemo, useRef } from 'react'
@ -285,6 +287,7 @@ export default function Web3Status() {
const ref = useRef<HTMLDivElement>(null)
const closeModal = useCloseModal(ApplicationModal.WALLET_DROPDOWN)
const isOpen = useIsOpen()
const isMobile = useIsMobile()
useOnClickOutside(ref, isOpen ? closeModal : undefined)
@ -300,7 +303,13 @@ export default function Web3Status() {
<span ref={ref}>
<Web3StatusInner />
<WalletModal ENSName={ENSName ?? undefined} pendingTransactions={pending} confirmedTransactions={confirmed} />
<WalletDropdown />
{isMobile ? (
<Portal>
<WalletDropdown />
</Portal>
) : (
<WalletDropdown />
)}
</span>
)
}