refactor: move drawer to its own component file

This commit is contained in:
Jeremy Kahn 2022-09-15 21:16:41 -05:00
parent f2aeec5acb
commit 9b5551a4bd
3 changed files with 142 additions and 101 deletions

View File

@ -0,0 +1,116 @@
import { PropsWithChildren, useContext } from 'react'
import { Link } from 'react-router-dom'
import { Theme } from '@mui/material/styles'
import MuiDrawer from '@mui/material/Drawer'
import List from '@mui/material/List'
import Typography from '@mui/material/Typography'
import Divider from '@mui/material/Divider'
import IconButton from '@mui/material/IconButton'
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 Brightness4Icon from '@mui/icons-material/Brightness4'
import Brightness7Icon from '@mui/icons-material/Brightness7'
import { SettingsContext } from 'contexts/SettingsContext'
import { PeerNameDisplay } from 'components/PeerNameDisplay'
import { DrawerHeader } from './DrawerHeader'
export const drawerWidth = 240
export interface DrawerProps extends PropsWithChildren {
isDrawerOpen: boolean
onDrawerClose: () => void
onHomeLinkClick: () => void
theme: Theme
userPeerId: string
}
export const Drawer = ({
isDrawerOpen,
onDrawerClose,
onHomeLinkClick,
theme,
userPeerId,
}: DrawerProps) => {
const settingsContext = useContext(SettingsContext)
const colorMode = settingsContext.getUserSettings().colorMode
const handleColorModeToggleClick = () => {
const newMode = colorMode === 'light' ? 'dark' : 'light'
settingsContext.updateUserSettings({ colorMode: newMode })
}
return (
<MuiDrawer
sx={{
width: drawerWidth,
flexShrink: 0,
'& .MuiDrawer-paper': {
width: drawerWidth,
boxSizing: 'border-box',
},
}}
variant="persistent"
anchor="left"
open={isDrawerOpen}
>
<DrawerHeader>
<IconButton onClick={onDrawerClose} aria-label="Close menu">
{theme.direction === 'ltr' ? (
<ChevronLeftIcon />
) : (
<ChevronRightIcon />
)}
</IconButton>
</DrawerHeader>
<Divider />
<ListItem disablePadding>
<ListItemText
sx={{
padding: '1em 1.5em',
}}
primary={
<Typography>
Your user name:{' '}
<PeerNameDisplay sx={{ fontWeight: 'bold' }}>
{userPeerId}
</PeerNameDisplay>
</Typography>
}
/>
</ListItem>
<Divider />
<List role="navigation">
<Link to="/" onClick={onHomeLinkClick}>
<ListItem disablePadding>
<ListItemButton>
<ListItemIcon>
<Home />
</ListItemIcon>
<ListItemText primary="Home" />
</ListItemButton>
</ListItem>
</Link>
<ListItem disablePadding>
<ListItemButton onClick={handleColorModeToggleClick}>
<ListItemIcon>
{theme.palette.mode === 'dark' ? (
<Brightness7Icon />
) : (
<Brightness4Icon />
)}
</ListItemIcon>
<ListItemText primary="Change theme" />
</ListItemButton>
</ListItem>
</List>
<Divider />
</MuiDrawer>
)
}

View File

@ -0,0 +1,10 @@
import { styled } from '@mui/material/styles'
export 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',
}))

View File

@ -8,16 +8,12 @@ import {
useMemo, useMemo,
useState, useState,
} from 'react' } from 'react'
import { Link } from 'react-router-dom'
import CssBaseline from '@mui/material/CssBaseline' import CssBaseline from '@mui/material/CssBaseline'
import MuiAppBar, { AppBarProps as MuiAppBarProps } from '@mui/material/AppBar' import MuiAppBar, { AppBarProps as MuiAppBarProps } from '@mui/material/AppBar'
import { ThemeProvider, createTheme, styled } from '@mui/material/styles' import { ThemeProvider, createTheme, styled } from '@mui/material/styles'
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'
@ -31,23 +27,14 @@ import DialogContentText from '@mui/material/DialogContentText'
import DialogTitle from '@mui/material/DialogTitle' import DialogTitle from '@mui/material/DialogTitle'
import MenuIcon from '@mui/icons-material/Menu' import MenuIcon from '@mui/icons-material/Menu'
import WarningIcon from '@mui/icons-material/Warning' import WarningIcon from '@mui/icons-material/Warning'
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 Brightness4Icon from '@mui/icons-material/Brightness4'
import Brightness7Icon from '@mui/icons-material/Brightness7'
import LinkIcon from '@mui/icons-material/Link' import LinkIcon from '@mui/icons-material/Link'
import { ShellContext } from 'contexts/ShellContext' import { ShellContext } from 'contexts/ShellContext'
import { SettingsContext } from 'contexts/SettingsContext' import { SettingsContext } from 'contexts/SettingsContext'
import { AlertOptions } from 'models/shell' import { AlertOptions } from 'models/shell'
import { PeerNameDisplay } from 'components/PeerNameDisplay'
const drawerWidth = 240 import { Drawer, drawerWidth } from './Drawer'
import { DrawerHeader } from './DrawerHeader'
const Alert = forwardRef<HTMLDivElement, AlertProps>(function Alert( const Alert = forwardRef<HTMLDivElement, AlertProps>(function Alert(
props, props,
@ -94,15 +81,6 @@ const AppBar = styled(MuiAppBar, {
}), }),
})) }))
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 interface ShellProps extends PropsWithChildren { export interface ShellProps extends PropsWithChildren {
userPeerId: string userPeerId: string
appNeedsUpdate: boolean appNeedsUpdate: boolean
@ -139,11 +117,6 @@ export const Shell = ({ appNeedsUpdate, children, userPeerId }: ShellProps) => {
const colorMode = settingsContext.getUserSettings().colorMode const colorMode = settingsContext.getUserSettings().colorMode
const handleColorModeToggleClick = () => {
const newMode = colorMode === 'light' ? 'dark' : 'light'
settingsContext.updateUserSettings({ colorMode: newMode })
}
const theme = useMemo( const theme = useMemo(
() => () =>
createTheme({ createTheme({
@ -173,14 +146,6 @@ export const Shell = ({ appNeedsUpdate, children, userPeerId }: ShellProps) => {
setIsDrawerOpen(true) setIsDrawerOpen(true)
} }
const handleDrawerClose = () => {
setIsDrawerOpen(false)
}
const handleHomeLinkClick = () => {
setIsDrawerOpen(false)
}
const handleLinkButtonClick = async () => { const handleLinkButtonClick = async () => {
await navigator.clipboard.writeText(window.location.href) await navigator.clipboard.writeText(window.location.href)
@ -193,6 +158,14 @@ export const Shell = ({ appNeedsUpdate, children, userPeerId }: ShellProps) => {
window.location.reload() window.location.reload()
} }
const handleDrawerClose = () => {
setIsDrawerOpen(false)
}
const handleHomeLinkClick = () => {
setIsDrawerOpen(false)
}
return ( return (
<ShellContext.Provider value={shellContextValue}> <ShellContext.Provider value={shellContextValue}>
<ThemeProvider theme={theme}> <ThemeProvider theme={theme}>
@ -295,70 +268,12 @@ export const Shell = ({ appNeedsUpdate, children, userPeerId }: ShellProps) => {
</Toolbar> </Toolbar>
</AppBar> </AppBar>
<Drawer <Drawer
sx={{ isDrawerOpen={isDrawerOpen}
width: drawerWidth, onDrawerClose={handleDrawerClose}
flexShrink: 0, onHomeLinkClick={handleHomeLinkClick}
'& .MuiDrawer-paper': { theme={theme}
width: drawerWidth, userPeerId={userPeerId}
boxSizing: 'border-box', />
},
}}
variant="persistent"
anchor="left"
open={isDrawerOpen}
>
<DrawerHeader>
<IconButton onClick={handleDrawerClose} aria-label="Close menu">
{theme.direction === 'ltr' ? (
<ChevronLeftIcon />
) : (
<ChevronRightIcon />
)}
</IconButton>
</DrawerHeader>
<Divider />
<ListItem disablePadding>
<ListItemText
sx={{
padding: '1em 1.5em',
}}
primary={
<Typography>
Your user name:{' '}
<PeerNameDisplay sx={{ fontWeight: 'bold' }}>
{userPeerId}
</PeerNameDisplay>
</Typography>
}
/>
</ListItem>
<Divider />
<List role="navigation">
<Link to="/" onClick={handleHomeLinkClick}>
<ListItem disablePadding>
<ListItemButton>
<ListItemIcon>
<Home />
</ListItemIcon>
<ListItemText primary="Home" />
</ListItemButton>
</ListItem>
</Link>
<ListItem disablePadding>
<ListItemButton onClick={handleColorModeToggleClick}>
<ListItemIcon>
{theme.palette.mode === 'dark' ? (
<Brightness7Icon />
) : (
<Brightness4Icon />
)}
</ListItemIcon>
<ListItemText primary="Change theme" />
</ListItemButton>
</ListItem>
</List>
<Divider />
</Drawer>
<Main <Main
open={isDrawerOpen} open={isDrawerOpen}
sx={{ sx={{