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' const StyledLink = styled('a')({ display: 'block', textDecoration: 'none', marginTop: '3rem', marginBottom: '3rem', }) const Container = styled('span')({ display: 'flex', alignItems: 'center', padding: '0 1rem', height: '2rem', margin: '0 0 0 auto', boxSizing: 'border-box', '@media (min-width: 720px)': { maxWidth: 'var(--max-width)', }, }) 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', transitionTimingFunction: 'ease', transitionDuration: '350ms', '@media (min-width: 720px)': { left: 0, width: `${100 / 4}%`, maxWidth: 'none', height: '100%', '+ *': { paddingLeft: `${100 / 4}%`, boxSizing: 'border-box', }, }, }) const Actions = styled('div')({ marginBottom: '4rem', display: 'flex', gap: '1rem', alignItems: 'center', }) const ToggleWrapper = styled('label')({ cursor: 'pointer', color: 'var(--color-accent)', display: 'inline-block', }) const ToggleIcon = styled('span')({ }) const ToggleInput = styled('input')({ position: 'absolute', left: -999999, }) const NavWrapper = styled('nav')({ '--size-link': '3rem', }) const RepoLink = styled('a')({ display: 'inline-grid', width: '1.5rem', height: '1.5rem', placeContent: 'center', }) const Sidebar = ({ data, brand: Brand, initialTheme = 'Dark', }) => { const [theme, setTheme] = React.useState(initialTheme) const toggleDarkMode = (b: string) => () => { setTheme(b) } React.useEffect(() => { let storageTheme = window.localStorage.getItem('tesseract-theme') || ( window.matchMedia('(prefers-color-scheme: dark)').matches ? 'Dark' : 'Light' ) window.localStorage.setItem('tesseract-theme', storageTheme) setTimeout(() => { setTheme(storageTheme) }) }, []) React.useEffect(() => { window.localStorage.setItem('tesseract-theme', theme) }, [theme]) React.useEffect(() => { const stylesheets = Array.from(window.document.querySelectorAll('link[title]')) as HTMLLinkElement[] stylesheets.forEach(s => { const enabled = s.title === theme s.setAttribute('rel', enabled ? 'stylesheet' : 'alternate stylesheet') if (enabled) { s.removeAttribute('disabled') } else { s.setAttribute('disabled', 'disabled') } }) }, [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> ) } export default Sidebar