feat: add app drawer with home button

This commit is contained in:
Jeremy Kahn 2022-08-31 21:44:00 -05:00
parent bf4b6b18d6
commit 0468977072
2 changed files with 130 additions and 7 deletions

View File

@ -151,8 +151,6 @@ export function Room({
className="Room" className="Room"
sx={{ sx={{
height: '100%', height: '100%',
padding: 2,
paddingTop: 0,
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
}} }}

View File

@ -7,20 +7,37 @@ import {
useState, useState,
SyntheticEvent, SyntheticEvent,
} from 'react' } from 'react'
import AppBar from '@mui/material/AppBar' import { Link } from 'react-router-dom'
import CssBaseline from '@mui/material/CssBaseline'
import { styled, useTheme } from '@mui/material/styles'
import MuiAppBar, { AppBarProps as MuiAppBarProps } from '@mui/material/AppBar'
import Drawer from '@mui/material/Drawer'
import Toolbar from '@mui/material/Toolbar' import Toolbar from '@mui/material/Toolbar'
import Box from '@mui/material/Box' import Box from '@mui/material/Box'
import List from '@mui/material/List'
import Typography from '@mui/material/Typography' import Typography from '@mui/material/Typography'
import Divider from '@mui/material/Divider'
import StepIcon from '@mui/material/StepIcon' import StepIcon from '@mui/material/StepIcon'
import Tooltip from '@mui/material/Tooltip' import Tooltip from '@mui/material/Tooltip'
import Snackbar from '@mui/material/Snackbar' import Snackbar from '@mui/material/Snackbar'
import MuiAlert, { AlertProps, AlertColor } from '@mui/material/Alert' import MuiAlert, { AlertProps, AlertColor } from '@mui/material/Alert'
import IconButton from '@mui/material/IconButton'
import MenuIcon from '@mui/icons-material/Menu'
import ChevronLeftIcon from '@mui/icons-material/ChevronLeft'
import ChevronRightIcon from '@mui/icons-material/ChevronRight'
import ListItem from '@mui/material/ListItem'
import ListItemButton from '@mui/material/ListItemButton'
import ListItemIcon from '@mui/material/ListItemIcon'
import ListItemText from '@mui/material/ListItemText'
import Home from '@mui/icons-material/Home'
import { ShellContext } from 'ShellContext' import { ShellContext } from 'ShellContext'
import { AlertOptions } from 'models/shell' import { AlertOptions } from 'models/shell'
interface ShellProps extends PropsWithChildren {} interface ShellProps extends PropsWithChildren {}
const drawerWidth = 240
const Alert = forwardRef<HTMLDivElement, AlertProps>(function Alert( const Alert = forwardRef<HTMLDivElement, AlertProps>(function Alert(
props, props,
ref ref
@ -28,8 +45,59 @@ const Alert = forwardRef<HTMLDivElement, AlertProps>(function Alert(
return <MuiAlert elevation={6} ref={ref} variant="filled" {...props} /> return <MuiAlert elevation={6} ref={ref} variant="filled" {...props} />
}) })
const Main = styled('main', { shouldForwardProp: prop => prop !== 'open' })<{
open?: boolean
}>(({ theme, open }) => ({
flexGrow: 1,
padding: theme.spacing(3),
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
marginLeft: `-${drawerWidth}px`,
...(open && {
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
marginLeft: 0,
}),
}))
interface AppBarProps extends MuiAppBarProps {
open?: boolean
}
const AppBar = styled(MuiAppBar, {
shouldForwardProp: prop => prop !== 'open',
})<AppBarProps>(({ theme, open }) => ({
transition: theme.transitions.create(['margin', 'width'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
...(open && {
width: `calc(100% - ${drawerWidth}px)`,
marginLeft: `${drawerWidth}px`,
transition: theme.transitions.create(['margin', 'width'], {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
}),
}))
const DrawerHeader = styled('div')(({ theme }) => ({
display: 'flex',
alignItems: 'center',
padding: theme.spacing(0, 1),
// necessary for content to be below app bar
...theme.mixins.toolbar,
justifyContent: 'flex-end',
}))
export const Shell = ({ children }: ShellProps) => { export const Shell = ({ children }: ShellProps) => {
const theme = useTheme()
const [isAlertShowing, setIsAlertShowing] = useState(false) const [isAlertShowing, setIsAlertShowing] = useState(false)
const [isDrawerOpen, setIsDrawerOpen] = useState(false)
const [alertSeverity, setAlertSeverity] = useState<AlertColor>('info') const [alertSeverity, setAlertSeverity] = useState<AlertColor>('info')
const [title, setTitle] = useState('') const [title, setTitle] = useState('')
const [alertText, setAlertText] = useState('') const [alertText, setAlertText] = useState('')
@ -63,14 +131,22 @@ export const Shell = ({ children }: ShellProps) => {
document.title = title document.title = title
}, [title]) }, [title])
const handleDrawerOpen = () => {
setIsDrawerOpen(true)
}
const handleDrawerClose = () => {
setIsDrawerOpen(false)
}
return ( return (
<ShellContext.Provider value={shellContextValue}> <ShellContext.Provider value={shellContextValue}>
<CssBaseline />
<Box <Box
className="Chitchatter" className="Chitchatter"
sx={{ sx={{
height: '100vh', height: '100vh',
display: 'flex', display: 'flex',
flexDirection: 'column',
paddingTop: 8, paddingTop: 8,
}} }}
> >
@ -88,7 +164,7 @@ export const Shell = ({ children }: ShellProps) => {
{alertText} {alertText}
</Alert> </Alert>
</Snackbar> </Snackbar>
<AppBar position="fixed"> <AppBar position="fixed" open={isDrawerOpen}>
<Toolbar <Toolbar
variant="regular" variant="regular"
sx={{ sx={{
@ -97,13 +173,62 @@ export const Shell = ({ children }: ShellProps) => {
justifyContent: 'space-between', justifyContent: 'space-between',
}} }}
> >
<Typography variant="h6">{title}</Typography> <IconButton
size="large"
edge="start"
color="inherit"
aria-label="menu"
sx={{ mr: 2, ...(isDrawerOpen && { display: 'none' }) }}
onClick={handleDrawerOpen}
>
<MenuIcon />
</IconButton>
<Typography variant="h6" noWrap component="div">
{title}
</Typography>
<Tooltip title="Number of peers in the room"> <Tooltip title="Number of peers in the room">
<StepIcon icon={numberOfPeers} sx={{ marginLeft: 'auto' }} /> <StepIcon icon={numberOfPeers} sx={{ marginLeft: 'auto' }} />
</Tooltip> </Tooltip>
</Toolbar> </Toolbar>
</AppBar> </AppBar>
{children} <Drawer
sx={{
width: drawerWidth,
flexShrink: 0,
'& .MuiDrawer-paper': {
width: drawerWidth,
boxSizing: 'border-box',
},
}}
variant="persistent"
anchor="left"
open={isDrawerOpen}
>
<DrawerHeader>
<IconButton onClick={handleDrawerClose}>
{theme.direction === 'ltr' ? (
<ChevronLeftIcon />
) : (
<ChevronRightIcon />
)}
</IconButton>
</DrawerHeader>
<Divider />
<List>
<Link to="/">
<ListItem disablePadding>
<ListItemButton>
<ListItemIcon>
<Home />
</ListItemIcon>
<ListItemText primary="Home" />
</ListItemButton>
</ListItem>
</Link>
</List>
<Divider />
</Drawer>
<Main open={isDrawerOpen}>{children}</Main>
</Box> </Box>
</ShellContext.Provider> </ShellContext.Provider>
) )