@@ -1,14 +1,15 @@
import * as React from 'react'
import { Icon } from '../../../../react-common/src'
import pkg from '../../../../../package.json'
import styled from 'styled-components'
import Link from 'next/link'
import * as React from 'react'
import Nav from '../Nav/Nav'
import { MouseEventHandler } from 'react'
const StyledLink = styled('a')({
display: 'block',
textDecoration: 'none',
marginTop: '3 rem',
marginTop: '4 rem',
marginBottom: '3rem',
})
@@ -28,16 +29,16 @@ const Base = styled('aside')({
'--max-width': 240,
position: 'fixed',
top: 0,
left: '-100%',
width: '100%',
height: '100%',
backgroundColor: 'var(--color-bg)',
zIndex: 4,
transitionProperty: 'color, background-color',
transitionProperty: 'color, background-color, left ',
transitionTimingFunction: 'ease',
transitionDuration: '350ms',
overflow: 'auto',
'@media (min-width: 720px)': {
left: 0,
left: ' 0 !important' ,
width: `${100 / 4}%`,
maxWidth: 'none',
height: '100%',
@@ -48,6 +49,31 @@ const Base = styled('aside')({
},
})
const SidebarToggle = styled('a')({
width: '4rem',
height: '4rem',
position: 'fixed',
top: 0,
left: 0,
display: 'grid',
placeContent: 'center',
zIndex: 5,
'@media (min-width: 720px)': {
display: 'none',
},
'::before': {
backgroundColor: 'var(--color-bg)',
content: "''",
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
opacity: 0.75,
zIndex: -1,
},
})
const Actions = styled('div')({
marginBottom: '4rem',
display: 'flex',
@@ -72,6 +98,7 @@ const ToggleInput = styled('input')({
const NavWrapper = styled('nav')({
'--size-link': '3rem',
marginBottom: '4rem',
})
const RepoLink = styled('a')({
@@ -87,10 +114,18 @@ const Sidebar = ({
initialTheme = 'Dark',
}) => {
const [theme, setTheme] = React.useState(initialTheme)
const [sidebar, setSidebar] = React.useState(false)
const navRef = React.useRef<HTMLDivElement>(null)
const toggleDarkMode = (b: string) => () => {
setTheme(b)
}
const toggleSidebar = (b: boolean) => (e) => {
e.preventDefault()
setSidebar(b)
}
React.useEffect(() => {
let storageTheme = window.localStorage.getItem('tesseract-theme')
|| (
@@ -104,6 +139,36 @@ const Sidebar = ({
})
}, [])
React.useEffect(() => {
const eventListener: MouseEventHandler = (e) => {
let currentElement = e.target as HTMLElement
while (currentElement !== e.currentTarget) {
if (currentElement.tagName === 'A') {
setSidebar(false)
break
}
const { parentElement } = currentElement
if (parentElement as HTMLElement === null) {
break
}
currentElement = parentElement as HTMLElement
}
}
if (navRef.current === null) {
return
}
navRef.current.addEventListener('click', eventListener, { capture: true })
return () => {
if (navRef.current === null) {
return
}
navRef.current.removeEventListener('click', eventListener, { capture: true })
}
}, [])
React.useEffect(() => {
window.localStorage.setItem('tesseract-theme', theme)
}, [theme])
@@ -122,64 +187,89 @@ const Sidebar = ({
}, [theme])
return (
<Base>
<NavWrapper>
<Link
href="/"
passHref
>
<StyledLink>
<Container>
<Brand />
</Container>
</StyledLink>
</Link>
<Container>
<Actions>
<ToggleWrapper>
<ToggleInput
type="checkbox"
defaultChecked={theme === 'Dark'}
onChange={toggleDarkMode(theme === 'Dark' ? 'Light' : 'Dark')}
/>
<ToggleIcon>
{
theme === 'Dark'
&& (
<Icon
label="Set Light Mode"
name="moon"
/>
)
}
{
theme === 'Light'
&& (
<Icon
label="Set Dark Mode"
name="sun"
/>
)
}
</ToggleIcon>
</ToggleWrapper>
<RepoLink
href={pkg.repository}
target="_blank"
rel="noopener noreferer"
>
<Icon
name="code"
label="Visit Repository"
/>
</RepoLink>
</Actions>
</Container>
<Nav
data={data.nav}
/>
</NavWrapper>
</Base>
<React.Fragment>
<SidebarToggle
onClick={toggleSidebar(!sidebar)}
>
{
!sidebar && (
<Icon
name="menu"
/>
)
}
{
sidebar && (
<Icon
name="x"
/>
)
}
</SidebarToggle>
<Base
ref={navRef}
style={{
left: sidebar ? 0 : '-100%',
}}
>
<NavWrapper>
<Link
href="/"
passHref
>
<StyledLink>
<Container>
<Brand />
</Container>
</StyledLink>
</Link>
<Container>
<Actions>
<ToggleWrapper>
<ToggleInput
type="checkbox"
defaultChecked={theme === 'Dark'}
onChange={toggleDarkMode(theme === 'Dark' ? 'Light' : 'Dark')}
/>
<ToggleIcon>
{
theme === 'Dark'
&& (
<Icon
label="Set Light Mode"
name="moon"
/>
)
}
{
theme === 'Light'
&& (
<Icon
label="Set Dark Mode"
name="sun"
/>
)
}
</ToggleIcon>
</ToggleWrapper>
<RepoLink
href={pkg.repository}
target="_blank"
rel="noopener noreferer"
>
<Icon
name="code"
label="Visit Repository"
/>
</RepoLink>
</Actions>
</Container>
<Nav
data={data.nav}
/>
</NavWrapper>
</Base>
</React.Fragment>
)
}