ReactJS Material UI Drawer Display Issue - reactjs

I used the Material UI API for Drawer (found here) to create a sidebar component. However, when I render this component on a screen along with other components, it is displayed under the other components as shown below :
I tried to add an elevation property, hoping it would resolve the issue, but that didn't work. Is there a way to overcome this? Here is the code:
const drawerWidth = '224px';
interface propsDashBoard {
itemsBeforeDivider: ItemData[];
}
interface ItemData {
name: string;
Icon: OverridableComponent<SvgIconTypeMap<{}, "svg">>;
routeAddress: string;
}
const history = createBrowserHistory();
const useStyles = makeStyles((theme) => ({
root: {
display: 'flex',
position: 'relative',
backgroundColor: COLOR.NEUTRAL.WHITE,
},
drawer: {
[theme.breakpoints.up('sm')]: {
width: drawerWidth,
flexShrink: 0,
position: 'absolute',
zIndex: -1,
boxShadow: '0px 1px 1px red',
},
},
appBar: {
[theme.breakpoints.up('sm')]: {
//width: `calc(100% - ${drawerWidth}px)`,
margin: '0px',
backgroundColor: COLOR.NEUTRAL.WHITE,
// position: 'absolute',
boxShadow:'0px 1px 0px #DBE1E7',
},
},
menuButton: {
marginRight: theme.spacing(2),
[theme.breakpoints.up('sm')]: {
display: 'none',
backgroundColor: COLOR.NEUTRAL.WHITE,
},
},
// necessary for content to be below app bar
toolbar: theme.mixins.toolbar,
drawerPaper: {
width: drawerWidth,
paddingLeft: '33px',
},
content: {
flexGrow: 1,
},
cssBaseline: {
boxShadow:'none',
},
navBar: {
backgroundColor: COLOR.NEUTRAL.WHITE,
},
}));
const MyDrawer =(props: propsDashBoard) => {
const {
itemsBeforeDivider,
} = props;
const classes = useStyles();
const theme = useTheme();
const [mobileOpen, setMobileOpen] = React.useState(false);
const handleDrawerToggle = () => {
setMobileOpen(!mobileOpen);
};
return (
<Router history={history}>
<nav className={classes.drawer} aria-label="mailbox folders">
<Drawer
variant="temporary"
anchor ={theme.direction === 'rtl' ? 'right' : 'left'}
open={mobileOpen}
onClose={handleDrawerToggle}
classes={{
paper: classes.drawerPaper
}}
ModalProps={{
keepMounted: true, // Better open performance on mobile.
}}
>
<div>
<div className={classes.toolbar} />
<Divider />
<List>
{itemsBeforeDivider.map(({name, Icon, routeAddress}) => (
<ListItem button key={name} component={Link} to={routeAddress}>
<ListItemIcon><Icon /></ListItemIcon>
<ListItemText primary={name} />
</ListItem>
))}
</List>
<Divider />
</div>
</Drawer>
<Hidden xsDown implementation="css">
<Drawer
classes={{
paper: classes.drawerPaper,
}}
variant="permanent"
open
>
<div>
<div className={classes.toolbar} />
<Divider />
<List>
{itemsBeforeDivider.map(({name, Icon, routeAddress}) => (
<ListItem button key={name} component={Link} to={routeAddress}>
<ListItemIcon><Icon /></ListItemIcon>
<ListItemText primary={name} />
</ListItem>
))}
</List>
<Divider />
</div>
</Drawer>
</Hidden>
</nav>
</Router>
);
}
const WhiteTypography = withStyles({
root: {
backgroundColor: COLOR.NEUTRAL.WHITE,
variant:"h6",
noWrap:"true",
}
})(Typography);
function DashBoard (props: propsDashBoard) {
const {
itemsBeforeDivider,
} = props;
const classes = useStyles();
const theme = useTheme();
const [mobileOpen, setMobileOpen] = React.useState(false);
const handleDrawerToggle = () => {
setMobileOpen(!mobileOpen);
};
return (
<div className={classes.root}>
<CssBaseline classes={classes.cssBaseline} />
<AppBar position="fixed" className={classes.appBar}>
<Toolbar>
<IconButton
color="inherit"
aria-label="open drawer"
edge="start"
onClick={handleDrawerToggle}
className={classes.menuButton}
>
<MenuIcon />
</IconButton>
</Toolbar>
</AppBar>
<MyDrawer itemsBeforeDivider={itemsBeforeDivider}/>
</div>
);
}

You can trying giving drawerWidth value like 150 or so and don't give value in pixel.

Related

Each child in a list should have a unique "key" prop Error for custom component

I am mapping over an array and rendering a custom card component for each index in the array. However, I am receiving the error "Each child in a list should have a unique "key" prop" 1. Although, I am passing the index as the key. I have tried with a React.fragment and passing the index down to the card component and adding the key there. Both methods are still throwing the same error.
Main Component
import React from "react";
import { useRouter } from "next/router";
import { Button, Container } from "#mui/material";
import { makeStyles } from "#mui/styles";
import { InstructionsCard } from "../layout/directory";
import {
RiNumber1 as OneIcon,
RiNumber2 as TwoIcon,
RiNumber3 as ThreeIcon,
} from "react-icons/ri";
function InstructionSection() {
const router = useRouter();
const classes = useStyles();
const instructions = [
{
id: 1,
icon: OneIcon,
title: "step one",
text: [
"Navigate to the",
<Button
onClick={() => router.push("/requirements")}
size="small"
style={{ margin: "5px" }}
variant="outlined"
color="inherit"
>
requirements
</Button>,
"page for our most frequently asked questions and specific requirements before booking any activity. ",
],
},
{
id: 2,
icon: TwoIcon,
title: "step two",
text: [
"Find the activity you are interested in and read through the information carefully. Be sure to fully understand the,",
<Button
onClick={() => router.push("/#upgrades")}
size="small"
style={{ margin: "5px" }}
variant="outlined"
color="inherit"
>
entry fee
</Button>,
" and",
<Button
onClick={() => router.push("/#upgrades")}
size="small"
style={{ margin: "5px" }}
variant="outlined"
color="inherit"
>
upgrade
</Button>,
" packages",
],
},
{
id: 3,
icon: ThreeIcon,
title: "step three",
text: [
"Please, be sure to verify we are ",
<Button
onClick={() => router.push("/locations")}
size="small"
style={{ margin: "5px" }}
variant="outlined"
color="inherit"
>
located
</Button>,
" in your area. Select an experience, date, time-slot, toggle any upgrades, and continue through checkout.",
],
},
];
return (
<Container className={classes.root}>
{/* instructions iteration */}
{instructions.map((_instruction, index) => {
return (
<React.Fragment key={index}>
<InstructionsCard item={_instruction} />
</React.Fragment>
);
})}
</Container>
);
}
// custom styles
const useStyles = makeStyles((theme) => ({
root: {
[theme.breakpoints.down("md")]: {
flexDirection: "column",
},
width: "100%",
display: "flex",
justifyContent: "space-evenly",
},
}));
export default InstructionSection;
Card Component
import { makeStyles } from "#mui/styles";
import { Card, CardContent, Typography, Divider } from "#mui/material";
const InstructionsCard = ({ item }) => {
const classes = useStyles();
const Icon = item.icon;
return (
<Card className={classes.root}>
<CardContent>
<Icon className={classes.icon} />
<Typography className={classes.title} variant="h5" component="h6">
{item.title.toUpperCase()}
</Typography>
<Divider className={classes.divider} />
<Typography
variant="subtitle1"
component="p"
sx={{ mb: 1.5 }}
color="text.secondary"
>
{item.text}
</Typography>
</CardContent>
</Card>
);
};
const useStyles = makeStyles((theme) => ({
root: {
[theme.breakpoints.down("md")]: {
margin: theme.spacing(4, 0, 4, 0),
},
background: theme.palette.primary.main,
borderRadius: theme.spacing(5),
padding: theme.spacing(2),
margin: theme.spacing(5),
width: "100%",
textAlign: "center",
boxShadow: `0px 0px 10px 10px ${theme.palette.offset.main}`,
},
icon: {
background: theme.palette.secondary.dark,
width: "50px",
height: "50px",
padding: "15px",
borderRadius: theme.spacing(5),
},
divider: {
background: theme.palette.secondary.dark,
padding: "2px",
width: "20%",
margin: theme.spacing(1, "auto", 1, "auto"),
},
title: {
fontWeight: 800,
},
}));
export default InstructionsCard;
Change like this in your main component
React.Fragment we need to use One time it can't use multiple time
return (
<Container className={classes.root}>
<React.Fragment>
{instructions.map((_instruction, index) => {
<InstructionsCard key={index} item={_instruction} />;
})}
</React.Fragment>
</Container>
);
Thank You

Connect React Material UI: Mini Variant + Responsive drawer

I am new to React and Material UI and I've been trying really hard to connect Mini Variant Drawer that I have now with Responsive drawer, so when you use it on phone it changes to Responsive drawer. If anyone could help me it would mean a lot to me, I tried but I always failed.
It would also help me get the knowledge for further connections with drawers.
Here is my code that I use for Mini Variant Drawer:
import React, {useState} from 'react';
import clsx from 'clsx';
import { makeStyles } from '#material-ui/core/styles';
import CssBaseline from '#material-ui/core/CssBaseline';
import Drawer from '#material-ui/core/Drawer';
import AppBar from '#material-ui/core/AppBar';
import Toolbar from '#material-ui/core/Toolbar';
import List from '#material-ui/core/List';
import Typography from '#material-ui/core/Typography';
import Divider from '#material-ui/core/Divider';
import IconButton from '#material-ui/core/IconButton';
import MenuIcon from '#material-ui/icons/Menu';
import MenuOpenIcon from '#material-ui/icons/MenuOpen';
import { MainListItems } from './listItems';
import AccountMenu from '../../components/AccountMenu'
import ChangePasswordDialog from './ChangePasswordDialog';
const drawerWidth = 240;
const useStyles = makeStyles((theme) => ({
root: {
display: 'flex',
},
toolbar: {
paddingRight: 60,
},
toolbarIcon: {
display: 'flex',
alignItems: 'center',
justifyContent: 'flex-end',
padding: '0 8px',
...theme.mixins.toolbar,
},
appBar: {
zIndex: theme.zIndex.drawer + 1,
transition: theme.transitions.create(['width', 'margin'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
},
appBarShift: {
marginLeft: drawerWidth,
width: `calc(100% - ${drawerWidth}px)`,
transition: theme.transitions.create(['width', 'margin'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen,
}),
},
menuButton: {
marginRight: 36,
},
menuButtonHidden: {
display: 'none',
},
mainTitle: {
flexGrow: 1,
marginLeft: 12
},
title: {
flexGrow: 1,
},
drawerPaper: {
position: 'relative',
whiteSpace: 'nowrap',
width: drawerWidth,
transition: theme.transitions.create('width', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen,
}),
},
drawerPaperClose: {
overflowX: 'hidden',
transition: theme.transitions.create('width', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
width: theme.spacing.unit * 7,
[theme.breakpoints.up('sm')]: {
width: theme.spacing.unit * 9,
},
},
appBarSpacer: theme.mixins.toolbar,
content: {
flexGrow: 1,
height: '100vh',
overflow: 'auto',
},
container: {
paddingTop: theme.spacing(4),
paddingBottom: theme.spacing(4),
},
paper: {
padding: theme.spacing(2),
display: 'flex',
overflow: 'auto',
flexDirection: 'column',
},
fixedHeight: {
height: 240,
},
}));
export default function SideMenuLayout({
drawerOpen,
setDrawerOpen,
children,
title
}) {
const classes = useStyles();
const handleDrawerOpen = () => {
setDrawerOpen(true);
};
const handleDrawerClose = () => {
setDrawerOpen(false);
};
const [changePasswordDialogOpen, setChangePasswordDialogOpen] = useState(false)
return (
<div className={classes.root}>
<CssBaseline />
<AppBar position="absolute" className={clsx(classes.appBar, drawerOpen && classes.appBarShift)}>
<Toolbar className={classes.toolbar}>
<IconButton
edge="start"
color="inherit"
aria-label="open drawer"
onClick={handleDrawerOpen}
className={clsx(classes.menuButton, drawerOpen && classes.menuButtonHidden)}
>
<MenuIcon />
</IconButton>
<Typography component="h1" variant="h6" color="inherit" noWrap className={classes.title}>
{drawerOpen ? title : `MyTitle - ${title}`}
</Typography>
<AccountMenu onChangePassword={() => setChangePasswordDialogOpen(true)} />
</Toolbar>
</AppBar>
<Drawer
variant="permanent"
classes={{
paper: clsx(classes.drawerPaper, !drawerOpen && classes.drawerPaperClose),
}}
open={drawerOpen}
>
<div className={classes.toolbarIcon}>
<Typography component="h1" variant="h6" color="inherit" noWrap className={classes.mainTitle}>
MyTitle
</Typography>
<IconButton onClick={handleDrawerClose}>
<MenuOpenIcon />
</IconButton>
</div>
<Divider />
<List><MainListItems /></List>
</Drawer>
<main className={classes.content}>
<div className={classes.appBarSpacer} />
{children}
</main>
<ChangePasswordDialog
isOpen={changePasswordDialogOpen}
setOpen={setChangePasswordDialogOpen}
/>
</div>
);
}
I too have stumbled upon some issue trying to mix together the two drawer variants, but after a couple of hours I've found a configuration that seems to work properly.
NOTE: I'm absolutely no expert in JS/CSS/HTML, I'm way more a backend guy, so this solution can certainly be optimized and modified to fit your needs.
In my case the drawer is used to select the "page" to display. So I'll start from there.
The "page" component simply contains a Router. Its contents are put inside a Box with display: flex:
const HomePage = () => {
return (
<Router>
<Box sx={{display: 'flex'}}>
<HomePageInner />
<Switch>
<Route path="/">
<p>Example</p>
</Route>
</Switch>
</Box>
</Router>
);
}
The HomePageInner is the component that renders the "menu" and appbar.
It keeps tracks of the open/closed status:
const drawerWidth = 240;
const HomePageInner = () => {
const [open, setOpen] = useState(true);
const toggleDrawer = () => setOpen(!open);
const drawer = <DrawerContents onClick={toggleDrawer} />;
return (
<>
<MainAppBar open={open} onClick={toggleDrawer}/>
<Box
component="nav"
aria-label="menu items"
>
<MobileDrawer open={open} onClose={toggleDrawer} drawer={drawer}/>
<DesktopDrawer open={open} drawer={drawer}/>
</Box>
</>
);
}
Here you can see that for clarity I have defined two distinct components for "mobile" and for "desktop". The contents of the drawer are shared and are defined in a separate DrawerContents component that is passed as a child.
There is an outer Box that wraps both Drawers. In the examples on this Box there is an sx property that specifies width: {sm: drawerWidth}, flexShrink: {sm :0}, the flexShrink should be removed, but trying to add/remove the width setting does not seem to do anything, but if something is broken for you try to set that property.
The DrawerContents is pretty simple. It places the "chevron" icon button on the top that can be used to toggle the state and shows the links:
const DrawerContents: FunctionComponent<{ onClick: () => void }> = (props) => {
return <>
<Toolbar
sx={{
display: "flex",
alignItems: "center",
justifyContent: "flex-end",
px: [1],
}}
>
<IconButton onClick={props.onClick}>
<ChevronLeftIcon/>
</IconButton>
</Toolbar>
<Divider/>
<List>
<ListItemLink primary="First" to="/first" icon={<DashboardIcon/>}/>
</List>
<List>
<ListItemLink primary="Second" to="/second" icon={<TodayIcon/>}/>
</List>
<Divider/>
<List>
<ListItemLink primary="Third" to="/third" icon={<SettingsIcon/>}/>
</List>
</>;
}
Now for the interesting part! The Drawers and the AppBar. So, the MobileDrawer is pretty much exactly the same as the temporary drawer in the "Responsive Drawer" example:
const MobileDrawer: FunctionComponent<{ container?: (() => any), open: boolean, onClose: () => void }> = (props) => {
return <Drawer
variant="temporary"
container={props.container}
open={props.open}
onClose={props.onClose}
ModalProps={{
keepMounted: true,
}}
sx={{
display: {xs: "block", sm: "none"},
"& .MuiDrawer-paper": {boxSizing: "border-box", width: drawerWidth},
}}
>
{props.children}
</Drawer>;
}
For the DesktopDrawer is mostly the same of the permanent drawer in th Responsive Drawer example however you have to modify the styling in the sx property so that it changes width when the status changes:
const DesktopDrawer: FunctionComponent<{ open: boolean }> = (props) => {
return <Drawer
variant="permanent"
sx={{
display: {xs: "none", sm: "block"},
"& .MuiDrawer-paper": {
position: "relative",
whiteSpace: "nowrap",
width: drawerWidth,
transition: theme => theme.transitions.create('width', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen,
}),
boxSizing: "border-box",
...(!props.open && {
overflowX: "hidden",
transition: theme => theme.transitions.create('width', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
width: theme => ({xs: theme.spacing(7), sm: theme.spacing(9)}),
})
},
}}
open={props.open}
>
{props.children}
</Drawer>;
}
Note that here I made ample use of the function form of the sx properties that gives you access to the theme. I derived the correct values by "mergin" the values I saw in the Mini-Variant example and the Responsive example.
And now the MainAppBar. This too is quite similar to the Responsive Drawer example, however again we have to modify the sx property:
const MainAppBar: FunctionComponent<{ open: boolean, onClick: () => void }> = (props) => {
const location = useLocation();
const headers: { [key: string]: string } = {
'/first': "First",
'/second': "Second",
'/third': "Third",
};
return <AppBar
position="fixed"
sx={{
zIndex: theme => theme.zIndex.drawer + 1,
transition: theme => theme.transitions.create(['width', 'margin'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
...(props.open && {
ml: {sm: `${drawerWidth}px`},
width: {sm: `calc(100% - ${drawerWidth}px)`},
transition: theme => theme.transitions.create(['width', 'margin'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen,
}),
})
}}
>
<Toolbar>
<IconButton
color="inherit"
aria-label="open drawer"
edge="start"
onClick={props.onClick}
sx={{mr: 2}}
>
<MenuIcon/>
</IconButton>
<Typography
component="h1"
variant="h6"
color="inherit"
noWrap
sx={{flexGrow: 1}}
>
{headers[location.pathname] || "Error"}
</Typography>
</Toolbar>
</AppBar>;
}
Note that here you want to:
remove the display: { sm: 'none' } in the sx of the IconButton to toggle the state
The width and ml settings must be included only in the open state
With all this configuration I get a drawer that for larger screen can be opened/closed like the mini variant:
But is also responsive:
PS: I didn't have the time to write a short answer, so I wrote a long one by copy&pasting my code and cutting away some stuff. If I find some time I might modify the sample code to be shorter and/or be self-contained.

How to make toolbar in material-ui transparent?

I am using material-ui. There are two toolbars where the second toolbar want to have transparent background
I followed this, Transparent AppBar in material-ui (React) but its for AppBar component and not working for Toolbar
My Code :
Theme Fie :
const MuiTheme = createMuiTheme({
palette: {
primary: {
main: purple[500],
},
secondary: {
main: green[500],
},
},
mixins: {
toolbar: {
backgroundColor: "transparent",
},
},
});
Toolbar File
const toolbarStyles = makeStyles((theme) => ({
toolbar: {
backgroundColor: theme.mixins.toolbar.backgroundColor,
},
}));
<AppBar position="static" style={{ boxShadow: "none" }}>
<Toolbar className="toptoolBar">
{/* */}
</Toolbar>
<div style={{ backgroundColor: "transparent" }}>
<Toolbar
style={{ backgroundColor: "transparent" }}
classes={{ root: toolbarSt.toolbar }}
>
{/* */}
</Toolbar>
</div>
</AppBar>
if you want to make only a certain number of toolbar style changes, then doing it in the theme file is not recommended. Instead, use the makeStyles
export default function App() {
const classes = useStyles();
return (
<AppBar position="static" style={{ boxShadow: "none" }}>
<Toolbar classes={{root:classes.greenToolbar}} className="toptoolBar" >
Green
</Toolbar>
<div style={{ backgroundColor: "transparent" }}>
<Toolbar
classes={{ root: classes.transparentToolbar }}>
transparent
</Toolbar>
</div>
</AppBar>
);
}
const useStyles = makeStyles((theme) => ({
transparentToolbar: {
backgroundColor: "transparent",
color: "red"
},
greenToolbar:{
backgroundColor:'green'
}
}));
Here is the working demo :

How to reduce Material Toolbar height Material-UI?

I want to change(reduce) the default height of the toolbar from Material-UI
I already referred How do I change the Material UI Toolbar height? still I'm facing the problem
The thing is when I am increasing beyond like 50 , I can see changes. But when I want to decrease the height I am unable to.
How can I achieve this?
My Code :
const useStyles = makeStyles((theme) => ({
root: {
position: "relative",
display: "flex",
alignItems: "center",
justifyContent: "flex-end",
},
minHeight: {
minHeight: "20px !important",
},
}));
const AppHeader = () => {
const toolbarSt = useStyles();
return (
<>
<AppBar position="static">
<Toolbar
className={toolbarSt.minHeight}
classes={{ regular: toolbarSt.regular, root: toolbarSt.root }}
>
<Typography> Home </Typography>
<Typography> About </Typography>
</Toolbar>
</AppBar>
</>
);
};
This is due to the font size of <Typography> Home </Typography> and
<Typography> About </Typography> for exemple if you add style class to both Typography like this:
const useStyles = makeStyles((theme) => ({
root: {
position: "relative",
display: "flex",
alignItems: "center",
justifyContent: "flex-end",
},
minHeight: {
minHeight: "5px !important",
},
smallTypo:{
fontSize:"5px"
}
}));
const AppHeader = () => {
const toolbarSt = useStyles();
return (
<>
<AppBar position="static">
<Toolbar
className={toolbarSt.minHeight}
classes={{ regular: toolbarSt.regular, root: toolbarSt.root }}
>
<Typography className={toolbarSt.smallTypo}> Home </Typography>
<Typography className={toolbarSt.smallTypo}> About </Typography>
</Toolbar>
</AppBar>
</>
);
};
you can make a really small AppBar.
here a codeSandeBox
You should set the minHeight property to the root element
const useStyles = makeStyles((theme) => ({
root: {
position: "relative",
display: "flex",
alignItems: "center",
justifyContent: "flex-end",
minHeight: "20px"
}
}));
const AppHeader = () => {
const toolbarSt = useStyles();
return (
<>
<AppBar position="static">
<Toolbar classes={{ root: toolbarSt.root }}>
<Typography> Home </Typography>
<Typography> About </Typography>
</Toolbar>
</AppBar>
</>
);
};
Please refer to the docs for more information https://material-ui.com/api/toolbar/#toolbar-api
just put sx={{ height : '70px }} in appbar for some reason it is not working in toolbar but works on appbar
return (
<AppBar position="static" sx={{ height: '70px' }} >
<Container >
<Toolbar disableGutters >
</Toolbar>
</Container>
</AppBar>
);
};

popper hiding the page components

I have a page with the sidebar as the main component and the rest of the components of the page as the children, I have a popper in the appbar for a button, I want to move my child components of the sidedrawer to shift to the left of popper when it appears
I already have all the components , I just have to shift the components to the left of the popper
const drawerWidth = 240;
const styles = theme => ({
root: {
display: 'flex',
},
flex: {
flexGrow: 1,
},
appBar: {
zIndex: theme.zIndex.drawer + 1,
transition: theme.transitions.create(['width', 'margin'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
},
appBarShift: {
marginLeft: drawerWidth,
width: `calc(100% - ${drawerWidth}px)`,
transition: theme.transitions.create(['width', 'margin'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen,
}),
},
menuButton: {
marginLeft: 12,
marginRight: 25,
},
hide: {
display: 'none',
},
drawer: {
width: drawerWidth,
flexShrink: 0,
whiteSpace: 'nowrap',
},
drawerOpen: {
width: drawerWidth,
transition: theme.transitions.create('width', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen,
}),
},
drawerClose: {
transition: theme.transitions.create('width', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
overflowX: 'hidden',
width: theme.spacing.unit * 7 + 1,
[theme.breakpoints.up('sm')]: {
width: theme.spacing.unit * 9 + 1,
},
},
toolbar: {
display: 'flex',
alignItems: 'center',
justifyContent: 'flex-end',
padding: '0 8px',
...theme.mixins.toolbar,
},
content: {
flexGrow: 1,
padding: theme.spacing.unit * 3,
},
});
class TaskListMain extends React.Component {
state = {
open: false,
popup:false,
anchorEl: null,
notifier:false
};
handleDrawerOpen = () => {
this.setState({ open: true });
};
handleDrawerClose = () => {
this.setState({ open: false });
};
handleToggle = event => {
const { currentTarget } = event;
this.setState(state => ({
anchorEl: currentTarget,
popup: !state.popup,
}));
}
handleIcon = event => {
const { currentTarget } = event;
this.setState(state => ({
anchorEl: currentTarget,
notifier: !state.notifier,
}));
}
render() {
const { classes, theme } = this.props;
const { anchorEl, popup, notifier } = this.state;
let otherTask;
let notify;
if(this.state.popup){
otherTask=<OtherTaskPaper/>
}
if(this.state.notifier){
notify=<NotificationPaper/>
}
return (
<div className={classes.root}>
<CssBaseline/>
<AppBar
position="fixed"
className={classNames(classes.appBar, {
[classes.appBarShift]: this.state.open,
})}style={{ background: '#00050f' }}
>
<Toolbar disableGutters={!this.state.open}>
<IconButton
color="inherit"
aria-label="Open drawer"
onClick={this.handleDrawerOpen}
className={classNames(classes.menuButton, {
[classes.hide]: this.state.open,
})}
>
<MenuIcon />
</IconButton>
<Typography variant="title" color="inherit" className={classes.flex}>
<img src="../../logo.jpg" alt="drawer" height="30px"/></Typography>
<Button color="inherit" onClick={this.handleToggle}>
Other Tasks
</Button>
<Popper open={popup} anchorEl={anchorEl}>
<Paper>
{otherTask}
</Paper>
</Popper>
<IconButton className={classes.menuButton} color="inherit" aria-label="Menu" onClick={this.handleIcon}>
<Badge badgeContent={2} style={{borderColor:""}}>
<NotificationsIcon />
</Badge>
</IconButton>
<Popper open={notifier} anchorEl={anchorEl}>
<Paper>
{notify}
</Paper>
</Popper>
</Toolbar>
</AppBar>
<Drawer
variant="permanent"
className={classNames(classes.drawer, {
[classes.drawerOpen]: this.state.open,
[classes.drawerClose]: !this.state.open,
})}
classes={{
paper: classNames({
[classes.drawerOpen]: this.state.open,
[classes.drawerClose]: !this.state.open,
}),
}}
open={this.state.open}
>
<div className={classes.toolbar}>
<IconButton onClick={this.handleDrawerClose}>
{theme.direction === 'rtl' ? <ChevronRightIcon /> : <ChevronLeftIcon />}
</IconButton>
</div>
<Divider />
<List>
<ListItem button>
<ListItemIcon>
<AssignmentTurnedIn />
</ListItemIcon>
<ListItemText primary="Tasks" />
</ListItem>
<ListItem button>
<ListItemIcon>
<DateRange/>
</ListItemIcon>
<ListItemText primary="TimeSheet" />
</ListItem>
<ListItem button>
<ListItemIcon>
<Receipt/>
</ListItemIcon>
<ListItemText primary="Reports" />
</ListItem>
</List>
</Drawer>
<main className={classes.content}>
<div className={classes.toolbar} />
{this.props.children}
</main>
</div>
);
}
}
TaskListMain.propTypes = {
classes: PropTypes.object.isRequired,
theme: PropTypes.object.isRequired,
};
//child components
import TaskCardComponent from './TaskCardComponent'
import TaskList from './TaskList'
const styles = theme => ({
root: {
...theme.mixins.gutters(),
paddingTop: theme.spacing.unit * 5,
paddingBottom: theme.spacing.unit * 5,
background: "grey"
},
});
function TaskListComponents(props) {
const { classes } = props;
return (
<div>
<Paper className={classes.root} elevation={1}>
<TaskCardComponent/>
<TaskList/>
</Paper>
</div>
);
}
TaskListComponents.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(TaskListComponents);
Write style for shifting the contents to one side like me did for the side drawer
contentShift: {
marginRight: popperwidth, width: `calc(100% - ${popperwidth}px)`, transition:
theme.transitions.create(['width', 'margin'], { easing:
theme.transitions.easing.sharp, duration: theme.transitions.duration.enteringScreen,
}),
},
state = {
open: false,
popup:false,
anchorEl: null,
notifier:false,
};
handleToggle =
event => {
const { currentTarget } = event; this.setState(state => ({ anchorEl:
currentTarget, popup: !state.popup, }));
}
------------------------------------------------------------------------

Resources