1 import React from 'react'
2 import {Button} from '@primer/react'
3 import {XIcon, ThreeBarsIcon} from '@primer/octicons-react'
4 import NavItems from './nav-items'
5 import {useIsMobile} from '../hooks/use-breakpoint'
6 import {DarkTheme, LightTheme} from '../theme'
7 import {AnimatePresence, motion} from 'framer-motion'
8 import {FocusOn} from 'react-focus-on'
9 import {HEADER_BAR, HEADER_HEIGHT} from '../constants'
10 import SiteTitle from './site-title'
11
12 import * as styles from './nav-drawer.module.css'
13
14 const Drawer = ({isOpen, onDismiss, children}) => (
15 <AnimatePresence>
16 {isOpen ? (
17 // These event handlers fix a bug that caused links below the fold
18 // to be unclickable in macOS Safari.
19 // Reference: https://github.com/theKashey/react-focus-lock/issues/79
20 <div
21 onMouseDown={event => event.preventDefault()}
22 onKeyDown={event => event.target.focus()}
23 onClick={event => event.target.focus()}
24 role="button"
25 tabIndex="0"
26 >
27 <FocusOn returnFocus={true} onEscapeKey={onDismiss}>
28 <motion.div
29 key="overlay"
30 initial={{opacity: 0}}
31 animate={{opacity: 1}}
32 exit={{opacity: 0}}
33 transition={{type: 'tween'}}
34 onClick={onDismiss}
35 className={styles.Box}
36 />
37 <motion.div
38 style={{top: `${HEADER_BAR}px`}}
39 key="drawer"
40 initial={{x: '100%'}}
41 animate={{x: 0}}
42 exit={{x: '100%'}}
43 transition={{type: 'tween', duration: 0.2}}
44 className={styles.Box_1}
45 >
46 {children}
47 </motion.div>
48 </FocusOn>
49 </div>
50 ) : null}
51 </AnimatePresence>
52 )
53
54 function NavDrawer() {
55 const isMobile = useIsMobile()
56 const [open, setOpen] = React.useState(false)
57
58 React.useEffect(() => {
59 if (!isMobile && open) {
60 setOpen(false)
61 }
62 }, [isMobile, open])
63
64 return (
65 <>
66 <Button aria-label="Menu" aria-expanded={open} onClick={() => setOpen(true)} className={styles.Button}>
67 <ThreeBarsIcon />
68 </Button>
69 <LightTheme as={Drawer} isOpen={open} onDismiss={() => setOpen(false)}>
70 <div style={{WebkitOverflowScrolling: 'touch'}} className={styles.Box_2}>
71 <div className={styles.Box_3}>
72 <DarkTheme style={{height: `${HEADER_HEIGHT}px`}} className={styles.DarkTheme}>
73 <SiteTitle />
74 <Button aria-label="Close" onClick={() => setOpen(false)}>
75 <XIcon />
76 </Button>
77 </DarkTheme>
78 <div className={styles.Box_4}>
79 <NavItems />
80 </div>
81 </div>
82 </div>
83 </LightTheme>
84 </>
85 )
86 }
87
88 export default NavDrawer