mirror of https://github.com/ethereum/go-ethereum
Mobile menu (#39)
* add MobileMenu component * implement MobileMenu via Header * close menu with links * move all menu logic to MobileMenu component * refactor MobileMenu to use Modals * remove unneeded motion params * remove animation on fixed modal * abstract out a HeaderButtons component * abstract out Search component * move BORDER_WIDTH to constants * hover fixes * change requests * fix: Link should wrap header buttons Co-authored-by: Corwin Smith <cssmittys@gmail.com> Co-authored-by: Nicolás Quiroz <nh.quiroz@gmail.com>pull/26459/head^2
parent
5364cb731e
commit
bd80434b83
@ -0,0 +1,48 @@ |
||||
import { FC, MouseEventHandler } from 'react'; |
||||
import { Flex, Link, Stack, Text } from '@chakra-ui/react'; |
||||
import NextLink from 'next/link'; |
||||
|
||||
import { BORDER_WIDTH, DOCS_PAGE, DOWNLOADS_PAGE } from '../../constants'; |
||||
|
||||
interface Props { |
||||
close?: MouseEventHandler<HTMLAnchorElement>; |
||||
} |
||||
|
||||
export const HeaderButtons: FC<Props> = ({ close }) => { |
||||
const menuItemStyles = { |
||||
p: { base: 8, md: 4 }, |
||||
borderBottom: { base: BORDER_WIDTH, md: 'none' }, |
||||
borderRight: { base: 'none', md: BORDER_WIDTH }, |
||||
borderColor: { base: 'bg', md: 'primary' }, |
||||
color: { base: 'bg', md: 'primary' }, |
||||
alignItems: 'center', |
||||
_hover: { |
||||
textDecoration: 'none', |
||||
bg: 'primary', |
||||
color: 'bg !important' |
||||
} |
||||
}; |
||||
return ( |
||||
<Flex direction={{ base: 'column', md: 'row' }}> |
||||
{/* DOWNLOADS */} |
||||
<NextLink href={DOWNLOADS_PAGE} passHref> |
||||
<Link _hover={{ textDecoration: 'none' }} onClick={close}> |
||||
<Stack {...menuItemStyles}> |
||||
<Text textStyle={{ base: 'header-mobile-button', md: 'header-button' }}>downloads</Text> |
||||
</Stack> |
||||
</Link> |
||||
</NextLink> |
||||
|
||||
{/* DOCUMENTATION */} |
||||
<NextLink href={DOCS_PAGE} passHref> |
||||
<Link _hover={{ textDecoration: 'none' }} onClick={close}> |
||||
<Stack {...menuItemStyles}> |
||||
<Text textStyle={{ base: 'header-mobile-button', md: 'header-button' }}> |
||||
documentation |
||||
</Text> |
||||
</Stack> |
||||
</Link> |
||||
</NextLink> |
||||
</Flex> |
||||
); |
||||
}; |
@ -1,4 +1,5 @@ |
||||
export * from './ButtonLinkSecondary'; |
||||
export * from './DataTable'; |
||||
export * from './Header'; |
||||
export * from './HeaderButtons'; |
||||
export * from './PageMetadata'; |
||||
|
@ -0,0 +1,30 @@ |
||||
import { FC } from 'react'; |
||||
import { Input, InputGroup, Stack } from '@chakra-ui/react' |
||||
|
||||
import { BORDER_WIDTH } from '../../../constants' |
||||
import { LensIcon } from '../icons'; |
||||
|
||||
export const Search: FC = () => { |
||||
return ( |
||||
<Stack |
||||
borderBottom={{ base: BORDER_WIDTH, md: 'none' }} |
||||
borderRight={{ base: 'none', md: BORDER_WIDTH }} |
||||
borderColor={{ base: 'bg', md: 'primary' }} |
||||
px={4} |
||||
py={{ base: 8, md: 4 }} |
||||
_hover={{ base: {bg: 'primary'}, md: {bg: 'none'}}} |
||||
> |
||||
<InputGroup> |
||||
<Input |
||||
variant='unstyled' |
||||
placeholder='search' |
||||
size='md' |
||||
_placeholder={{ color: {base: 'bg', md: 'primary'}, fontStyle: 'italic' }} |
||||
/> |
||||
<Stack pl={4} justifyContent='center' alignItems='center'> |
||||
<LensIcon color={{ base: 'bg', md: 'primary' }} fontSize={{ base: '3xl', md: 'md' }} /> |
||||
</Stack> |
||||
</InputGroup> |
||||
</Stack> |
||||
); |
||||
}; |
@ -0,0 +1 @@ |
||||
export * from './Search'; |
@ -0,0 +1,71 @@ |
||||
import { Box, Flex, Modal, ModalContent, ModalOverlay, useDisclosure } from '@chakra-ui/react'; |
||||
import { CloseIcon } from '@chakra-ui/icons'; |
||||
|
||||
import { HamburgerIcon } from '../UI/icons'; |
||||
import { Search } from '../UI/search'; |
||||
import { HeaderButtons } from '../UI'; |
||||
|
||||
import { BORDER_WIDTH } from '../../constants'; |
||||
|
||||
export const MobileMenu: React.FC = () => { |
||||
const { isOpen, onOpen, onClose } = useDisclosure(); |
||||
|
||||
return ( |
||||
<> |
||||
{/* HAMBURGER MENU ICON */} |
||||
<Box |
||||
as='button' |
||||
p={4} |
||||
display={{ base: 'block', md: 'none' }} |
||||
color='primary' |
||||
_hover={{ bg: 'primary', color: 'bg' }} |
||||
onClick={onOpen} |
||||
> |
||||
<HamburgerIcon /> |
||||
</Box> |
||||
|
||||
{/* MODAL */} |
||||
<Modal isOpen={isOpen} onClose={onClose} motionPreset='none'> |
||||
<ModalOverlay /> |
||||
<ModalContent> |
||||
{/* MOBILE MENU */} |
||||
<Flex |
||||
position='fixed' |
||||
maxW='min(calc(var(--chakra-sizes-container-sm) - 2rem), 100vw - 2rem)' |
||||
marginInline='auto' |
||||
inset='0' |
||||
top={4} |
||||
mb={4} |
||||
color='bg' |
||||
bg='secondary' |
||||
border={BORDER_WIDTH} |
||||
overflow='hidden' |
||||
direction='column' |
||||
> |
||||
<Flex borderBottom={BORDER_WIDTH} justify='flex-end'> |
||||
{/* CLOSE ICON */} |
||||
<Box |
||||
as='button' |
||||
p={4} |
||||
borderInlineStartWidth={BORDER_WIDTH} |
||||
borderColor='bg' |
||||
color='bg' |
||||
_hover={{ bg: 'primary' }} |
||||
onClick={onClose} |
||||
ms='auto' |
||||
> |
||||
<CloseIcon boxSize={5} /> |
||||
</Box> |
||||
</Flex> |
||||
|
||||
{/* HEADER BUTTONS */} |
||||
<HeaderButtons close={onClose} /> |
||||
|
||||
{/* SEARCH */} |
||||
<Search /> |
||||
</Flex> |
||||
</ModalContent> |
||||
</Modal> |
||||
</> |
||||
); |
||||
}; |
@ -1 +1,3 @@ |
||||
export { Layout } from './Layout'; |
||||
export { Footer } from './Footer'; |
||||
export { MobileMenu } from './MobileMenu'; |
||||
|
Loading…
Reference in new issue