feat: mobile network switcher (#4486)
* feat: mobile network switcher * adjust bottom border radius on mobile Co-authored-by: Charlie <charlie@uniswap.org>
This commit is contained in:
parent
33c73f4dc8
commit
fdbe4b8f5e
@ -1,7 +1,7 @@
|
|||||||
import { style } from '@vanilla-extract/css'
|
import { style } from '@vanilla-extract/css'
|
||||||
import { lightGrayOverlayOnHover } from 'nft/css/common.css'
|
import { lightGrayOverlayOnHover } from 'nft/css/common.css'
|
||||||
|
|
||||||
import { sprinkles } from '../../nft/css/sprinkles.css'
|
import { breakpoints, sprinkles } from '../../nft/css/sprinkles.css'
|
||||||
|
|
||||||
export const ChainSwitcher = style([
|
export const ChainSwitcher = style([
|
||||||
lightGrayOverlayOnHover,
|
lightGrayOverlayOnHover,
|
||||||
@ -26,11 +26,16 @@ export const ChainSwitcherRow = style([
|
|||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
color: 'blackBlue',
|
color: 'blackBlue',
|
||||||
borderRadius: '12',
|
borderRadius: '12',
|
||||||
|
width: { sm: 'full' },
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
lineHeight: '24px',
|
lineHeight: '24px',
|
||||||
|
'@media': {
|
||||||
|
[`screen and (min-width: ${breakpoints.sm}px)`]: {
|
||||||
width: '204px',
|
width: '204px',
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
export const Image = style([
|
export const Image = style([
|
||||||
|
@ -5,10 +5,12 @@ import { useOnClickOutside } from 'hooks/useOnClickOutside'
|
|||||||
import useSelectChain from 'hooks/useSelectChain'
|
import useSelectChain from 'hooks/useSelectChain'
|
||||||
import useSyncChainQuery from 'hooks/useSyncChainQuery'
|
import useSyncChainQuery from 'hooks/useSyncChainQuery'
|
||||||
import { Box } from 'nft/components/Box'
|
import { Box } from 'nft/components/Box'
|
||||||
|
import { Portal } from 'nft/components/common/Portal'
|
||||||
import { Column, Row } from 'nft/components/Flex'
|
import { Column, Row } from 'nft/components/Flex'
|
||||||
import { CheckMarkIcon, NewChevronDownIcon, NewChevronUpIcon, TokenWarningRedIcon } from 'nft/components/icons'
|
import { CheckMarkIcon, NewChevronDownIcon, NewChevronUpIcon, TokenWarningRedIcon } from 'nft/components/icons'
|
||||||
import { subhead } from 'nft/css/common.css'
|
import { subhead } from 'nft/css/common.css'
|
||||||
import { themeVars, vars } from 'nft/css/sprinkles.css'
|
import { themeVars, vars } from 'nft/css/sprinkles.css'
|
||||||
|
import { useIsMobile } from 'nft/hooks'
|
||||||
import { ReactNode, useReducer, useRef } from 'react'
|
import { ReactNode, useReducer, useRef } from 'react'
|
||||||
import { isChainAllowed } from 'utils/switchChain'
|
import { isChainAllowed } from 'utils/switchChain'
|
||||||
|
|
||||||
@ -55,12 +57,13 @@ const NETWORK_SELECTOR_CHAINS = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
interface ChainSwitcherProps {
|
interface ChainSwitcherProps {
|
||||||
isMobile?: boolean
|
leftAlign?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ChainSwitcher = ({ isMobile }: ChainSwitcherProps) => {
|
export const ChainSwitcher = ({ leftAlign }: ChainSwitcherProps) => {
|
||||||
const { chainId } = useWeb3React()
|
const { chainId } = useWeb3React()
|
||||||
const [isOpen, toggleOpen] = useReducer((s) => !s, false)
|
const [isOpen, toggleOpen] = useReducer((s) => !s, false)
|
||||||
|
const isMobile = useIsMobile()
|
||||||
|
|
||||||
const ref = useRef<HTMLDivElement>(null)
|
const ref = useRef<HTMLDivElement>(null)
|
||||||
useOnClickOutside(ref, isOpen ? toggleOpen : undefined)
|
useOnClickOutside(ref, isOpen ? toggleOpen : undefined)
|
||||||
@ -76,38 +79,8 @@ export const ChainSwitcher = ({ isMobile }: ChainSwitcherProps) => {
|
|||||||
|
|
||||||
const isSupported = isChainAllowed(chainId)
|
const isSupported = isChainAllowed(chainId)
|
||||||
|
|
||||||
return (
|
const dropdown = (
|
||||||
<Box position="relative" ref={ref}>
|
<NavDropdown top={54} leftAligned={leftAlign} paddingBottom={8} paddingTop={8}>
|
||||||
<Row
|
|
||||||
as="button"
|
|
||||||
gap="8"
|
|
||||||
className={styles.ChainSwitcher}
|
|
||||||
background={isOpen ? 'accentActiveSoft' : 'none'}
|
|
||||||
onClick={toggleOpen}
|
|
||||||
>
|
|
||||||
{!isSupported ? (
|
|
||||||
<>
|
|
||||||
<TokenWarningRedIcon fill={themeVars.colors.darkGray} width={24} height={24} />
|
|
||||||
<Box as="span" className={subhead} style={{ lineHeight: '20px' }}>
|
|
||||||
{info?.label ?? 'Unsupported'}
|
|
||||||
</Box>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<img src={info.logoUrl} alt={info.label} className={styles.Image} />
|
|
||||||
<Box as="span" className={subhead} style={{ lineHeight: '20px' }}>
|
|
||||||
{info.label}
|
|
||||||
</Box>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{isOpen ? (
|
|
||||||
<NewChevronUpIcon width={16} height={16} color="blackBlue" />
|
|
||||||
) : (
|
|
||||||
<NewChevronDownIcon width={16} height={16} color="blackBlue" />
|
|
||||||
)}
|
|
||||||
</Row>
|
|
||||||
{isOpen && (
|
|
||||||
<NavDropdown top={60} leftAligned={isMobile} paddingBottom={8} paddingTop={8}>
|
|
||||||
<Column marginX="8">
|
<Column marginX="8">
|
||||||
{NETWORK_SELECTOR_CHAINS.map((chainId: SupportedChainId) =>
|
{NETWORK_SELECTOR_CHAINS.map((chainId: SupportedChainId) =>
|
||||||
isSupported ? (
|
isSupported ? (
|
||||||
@ -123,7 +96,39 @@ export const ChainSwitcher = ({ isMobile }: ChainSwitcherProps) => {
|
|||||||
)}
|
)}
|
||||||
</Column>
|
</Column>
|
||||||
</NavDropdown>
|
</NavDropdown>
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box position="relative" ref={ref}>
|
||||||
|
<Row
|
||||||
|
as="button"
|
||||||
|
gap="8"
|
||||||
|
className={styles.ChainSwitcher}
|
||||||
|
background={isOpen ? 'accentActiveSoft' : 'none'}
|
||||||
|
onClick={toggleOpen}
|
||||||
|
>
|
||||||
|
{!isSupported ? (
|
||||||
|
<>
|
||||||
|
<TokenWarningRedIcon fill={themeVars.colors.darkGray} width={24} height={24} />
|
||||||
|
<Box as="span" className={subhead} display={{ sm: 'none', xl: 'flex' }} style={{ lineHeight: '20px' }}>
|
||||||
|
{info?.label ?? 'Unsupported'}
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<img src={info.logoUrl} alt={info.label} className={styles.Image} />
|
||||||
|
<Box as="span" className={subhead} display={{ sm: 'none', xl: 'flex' }} style={{ lineHeight: '20px' }}>
|
||||||
|
{info.label}
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
|
{isOpen ? (
|
||||||
|
<NewChevronUpIcon width={16} height={16} color="blackBlue" />
|
||||||
|
) : (
|
||||||
|
<NewChevronDownIcon width={16} height={16} color="blackBlue" />
|
||||||
|
)}
|
||||||
|
</Row>
|
||||||
|
{isOpen && (isMobile ? <Portal>{dropdown}</Portal> : <>{dropdown}</>)}
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,25 @@
|
|||||||
import { style } from '@vanilla-extract/css'
|
import { style } from '@vanilla-extract/css'
|
||||||
|
|
||||||
import { sprinkles } from '../../nft/css/sprinkles.css'
|
import { breakpoints, sprinkles } from '../../nft/css/sprinkles.css'
|
||||||
|
|
||||||
export const NavDropdown = style([
|
export const NavDropdown = style([
|
||||||
sprinkles({
|
sprinkles({
|
||||||
position: 'absolute',
|
position: { sm: 'fixed', md: 'absolute' },
|
||||||
background: 'lightGray',
|
background: 'lightGray',
|
||||||
borderRadius: '12',
|
borderRadius: '12',
|
||||||
borderStyle: 'solid',
|
borderStyle: 'solid',
|
||||||
borderColor: 'medGray',
|
borderColor: 'medGray',
|
||||||
borderWidth: '1px',
|
borderWidth: '1px',
|
||||||
|
bottom: { sm: '56', md: 'unset' },
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
boxShadow: '0px 4px 12px 0px #00000026',
|
boxShadow: '0px 4px 12px 0px #00000026',
|
||||||
zIndex: 10,
|
zIndex: 10,
|
||||||
|
'@media': {
|
||||||
|
[`screen and (max-width: ${breakpoints.sm}px)`]: {
|
||||||
|
borderBottomLeftRadius: '0',
|
||||||
|
borderBottomRightRadius: '0',
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { Box } from 'nft/components/Box'
|
import { Box } from 'nft/components/Box'
|
||||||
|
import { useIsMobile } from 'nft/hooks'
|
||||||
import { ReactNode } from 'react'
|
import { ReactNode } from 'react'
|
||||||
|
|
||||||
import * as styles from './NavDropdown.css'
|
import * as styles from './NavDropdown.css'
|
||||||
@ -23,13 +24,14 @@ export const NavDropdown = ({
|
|||||||
paddingTop,
|
paddingTop,
|
||||||
children,
|
children,
|
||||||
}: NavDropdownProps) => {
|
}: NavDropdownProps) => {
|
||||||
|
const isMobile = useIsMobile()
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
paddingX={horizontalPadding ? '16' : undefined}
|
paddingX={horizontalPadding ? '16' : undefined}
|
||||||
style={{
|
style={{
|
||||||
top: `${top}px`,
|
top: isMobile ? 'unset' : `${top}px`,
|
||||||
left: centerHorizontally ? '50%' : leftAligned ? '0px' : 'auto',
|
left: isMobile ? 0 : centerHorizontally ? '50%' : leftAligned ? '0px' : 'auto',
|
||||||
right: centerHorizontally || leftAligned ? 'auto' : '0px',
|
right: isMobile ? 0 : centerHorizontally || leftAligned ? 'auto' : '0px',
|
||||||
transform: centerHorizontally ? 'translateX(-50%)' : 'unset',
|
transform: centerHorizontally ? 'translateX(-50%)' : 'unset',
|
||||||
paddingBottom: paddingBottom ?? '24px',
|
paddingBottom: paddingBottom ?? '24px',
|
||||||
paddingTop: paddingTop ?? '24px',
|
paddingTop: paddingTop ?? '24px',
|
||||||
|
@ -43,7 +43,7 @@ const MobileNavbar = () => {
|
|||||||
<Box as="a" href="#/swap" className={styles.logoContainer}>
|
<Box as="a" href="#/swap" className={styles.logoContainer}>
|
||||||
<UniIconMobile width="44" height="44" className={styles.logo} />
|
<UniIconMobile width="44" height="44" className={styles.logo} />
|
||||||
</Box>
|
</Box>
|
||||||
<ChainSwitcher isMobile={true} />
|
<ChainSwitcher leftAlign={true} />
|
||||||
</Box>
|
</Box>
|
||||||
<Box className={styles.rightSideMobileContainer}>
|
<Box className={styles.rightSideMobileContainer}>
|
||||||
<Row gap="16">
|
<Row gap="16">
|
||||||
|
@ -4,7 +4,6 @@ import { Box } from 'nft/components/Box'
|
|||||||
import { Column, Row } from 'nft/components/Flex'
|
import { Column, Row } from 'nft/components/Flex'
|
||||||
import { vars } from 'nft/css/sprinkles.css'
|
import { vars } from 'nft/css/sprinkles.css'
|
||||||
import { useSearchHistory } from 'nft/hooks'
|
import { useSearchHistory } from 'nft/hooks'
|
||||||
// import { fetchSearchCollections, fetchTrendingCollections } from 'nft/queries'
|
|
||||||
import { FungibleToken, GenieCollection } from 'nft/types'
|
import { FungibleToken, GenieCollection } from 'nft/types'
|
||||||
import { ethNumberStandardFormatter } from 'nft/utils/currency'
|
import { ethNumberStandardFormatter } from 'nft/utils/currency'
|
||||||
import { putCommas } from 'nft/utils/putCommas'
|
import { putCommas } from 'nft/utils/putCommas'
|
||||||
|
@ -112,6 +112,7 @@ const spacing = {
|
|||||||
'48': '48px',
|
'48': '48px',
|
||||||
'50': '50px',
|
'50': '50px',
|
||||||
'52': '52px',
|
'52': '52px',
|
||||||
|
'56': '56px',
|
||||||
'60': '60px',
|
'60': '60px',
|
||||||
'64': '64px',
|
'64': '64px',
|
||||||
'82': '82px',
|
'82': '82px',
|
||||||
|
Loading…
Reference in New Issue
Block a user