Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | import {BorderBox, Flex, Link, Text} from '@primer/components'
import {ChevronDownIcon, ChevronUpIcon, XIcon} from '@primer/octicons-react'
import {Link as GatsbyLink} from 'gatsby'
import debounce from 'lodash.debounce'
import React from 'react'
import navItems from '../nav.yml'
import primerNavItems from '../primer-nav.yml'
import useSiteMetadata from '../use-site-metadata'
import DarkButton from './dark-button'
import Details from './details'
import Drawer from './drawer'
import NavItems from './nav-items'
export function useNavDrawerState(breakpoint) {
// Handle string values from themes with units at the end
if (typeof breakpoint === 'string') {
breakpoint = parseInt(breakpoint, 10)
}
const [isOpen, setOpen] = React.useState(false)
const onResize = React.useCallback(() => {
if (window.innerWidth >= breakpoint) {
setOpen(false)
}
}, [setOpen])
const debouncedOnResize = React.useCallback(debounce(onResize, 250), [
onResize,
])
React.useEffect(() => {
if (isOpen) {
window.addEventListener('resize', debouncedOnResize)
return () => {
// cancel any debounced invocation of the resize handler
debouncedOnResize.cancel()
window.removeEventListener('resize', debouncedOnResize)
}
}
}, [isOpen, debouncedOnResize])
return [isOpen, setOpen]
}
function NavDrawer({isOpen, onDismiss}) {
const siteMetadata = useSiteMetadata()
return (
<Drawer isOpen={isOpen} onDismiss={onDismiss}>
<Flex
flexDirection="column"
height="100%"
bg="gray.0"
style={{overflow: 'auto', WebkitOverflowScrolling: 'touch'}}
>
<Flex flexDirection="column" flex="1 0 auto" color="gray.7" bg="gray.0">
<BorderBox
borderWidth={0}
borderRadius={0}
borderBottomWidth={1}
borderColor="gray.7"
>
<Flex
py={3}
pl={4}
pr={3}
alignItems="center"
justifyContent="space-between"
color="gray.1"
bg="gray.9"
>
<Link
as={GatsbyLink}
to="/"
display="inline-block"
color="inherit"
>
{siteMetadata.title}
</Link>
<DarkButton aria-label="Close" onClick={onDismiss}>
<XIcon />
</DarkButton>
</Flex>
</BorderBox>
{navItems.length > 0 ? (
<Flex flexDirection="column">
<NavItems items={navItems} editOnGitHub={false} />
</Flex>
) : null}
</Flex>
{primerNavItems.length > 0 ? (
<Flex
flexDirection="column"
flex="1 0 auto"
color="gray.1"
bg="gray.9"
>
<PrimerNavItems items={primerNavItems} />
</Flex>
) : null}
</Flex>
</Drawer>
)
}
function PrimerNavItems({items}) {
return items.map((item, index) => {
return (
<BorderBox
key={item.title}
borderWidth={0}
borderRadius={0}
borderTopWidth={index !== 0 ? 1 : 0}
borderColor="gray.7"
p={4}
>
{item.children ? (
<Details key={index}>
{({open, toggle}) => (
<>
<summary onClick={toggle} style={{cursor: 'pointer'}}>
<Flex alignItems="center" justifyContent="space-between">
<Text>{item.title}</Text>
{open ? <ChevronUpIcon /> : <ChevronDownIcon />}
</Flex>
</summary>
<Flex flexDirection="column" mt={2}>
{item.children.map((child) => (
<Link
key={child.title}
href={child.url}
py={1}
mt={2}
fontSize={1}
color="inherit"
>
{child.title}
</Link>
))}
</Flex>
</>
)}
</Details>
) : (
<Link key={index} href={item.url} color="inherit" display="block">
{item.title}
</Link>
)}
</BorderBox>
)
})
}
export default NavDrawer
|