user11399997
user11399997

Reputation:

I wish to seperate Appbar and Drawer into two components - Material UI

I would like to seperate AppBar and Drawer into two different components. But because of open-drawer icon and state i couldn't do this. Can any one help me out? This is sample layout from https://material-ui.com/components/drawers/ (Mini Variant drawer) The look and feel should not change!!

Tried to keep and in two different components but failed to do because of open drawer icon

class Header extends React.Component { state = { open: false, };

handleDrawerOpen = () => {
    this.setState({ open: true });
};

handleDrawerClose = () => {
    this.setState({ open: false });
};

render() {
    const { classes, theme, userProfile } = this.props;

    return (
    <React.Fragment>
        <AppBar
            position="absolute"
            className={classNames(classes.appBar, this.state.open && classes.appBarShift)}>
            <Toolbar disableGutters={!this.state.open}>
                <IconButton
                    color="inherit"
                    aria-label="Open drawer"
                    onClick={this.handleDrawerOpen}
                    className={classNames(classes.menuButton, this.state.open && classes.hide)}>
                    <MenuIcon />
                </IconButton>
                <Typography variant="title" color="inherit" noWrap className={classes.grow}>
                    Configuration Repository
                </Typography>
                <UserProfile userProfile={userProfile} />
            </Toolbar>
        </AppBar>
        <Drawer
            variant="permanent"
            classes={{
                paper: classNames(classes.drawerPaper, !this.state.open && classes.drawerPaperClose),
            }}
            open={this.state.open}>
            <div className={classes.toolbar}>
                <IconButton onClick={this.handleDrawerClose}>
                    {theme.direction === 'rtl' ? <ChevronRightIcon /> : <ChevronLeftIcon />}
                </IconButton>
            </div>
            <Divider />
               <List>{mailFolderListItems}</List>
            <Divider />
            <List>{otherMailFolderListItems}</List>
        </Drawer>
    </React.Fragment>
    );
}

}

Upvotes: 1

Views: 3267

Answers (1)

Monika Mangal
Monika Mangal

Reputation: 1760

You can create one component consisting of AppBar with a DrawerWrapper as a component and pass drawerOpen state to that component as a prop -

<div>
  <AppBar>
    <IconButton
      onClick={handleDrawerOpen}
     >
     </IconButton>
  </AppBar>
  <DrawerWrapper drawerOpen={this.state.drawerOpen} />
</div>

with handleDrawerOpen changing the state as -

handleDrawerOpen = () => {
    this.setState({
      drawerOpen: true
    })
  }

And in the DrawerWrapper component -

<Drawer open={this.props.drawerOpen} />

From your code -

AppBar component -

class AppBar extends Component {
    state = {
        open: false
    };

    handleDrawerOpen = () => {
        this.setState({ open: true });
    };

    handleDrawerClose = () => {
        this.setState({ open: false });
    };

    render() {
        const { classes, theme, userProfile } = this.props;

        return (
            <React.Fragment>
                <AppBar
                    position="absolute"
                    className={classNames(classes.appBar, this.state.open && classes.appBarShift)}>
                    <Toolbar disableGutters={!this.state.open}>
                        <IconButton
                            color="inherit"
                            aria-label="Open drawer"
                            onClick={this.handleDrawerOpen}
                            className={classNames(classes.menuButton, this.state.open && classes.hide)}>
                            <MenuIcon />
                        </IconButton>
                        <Typography variant="title" color="inherit" noWrap className={classes.grow}>
                            Configuration Repository
                        </Typography>
                        <UserProfile userProfile={userProfile} />
                    </Toolbar>
                </AppBar>
                <DrawerWrapper open={this.state.open} classes={classes} theme={theme} handleDrawerClose={this.handleDrawerClose}/>
            </React.Fragment>
        );
    }
}

DrawerWrapper component -

class DrawerWrapper extends Component {
    render() {
        const { classes, theme, open, handleDrawerClose } = this.props;

        return (
            <Drawer
                variant="permanent"
                classes={{
                    paper: classNames(classes.drawerPaper, !open && classes.drawerPaperClose),
                }}
                open={open}>
                <div className={classes.toolbar}>
                    <IconButton onClick={handleDrawerClose}>
                        {theme.direction === 'rtl' ? <ChevronRightIcon /> : <ChevronLeftIcon />}
                    </IconButton>
                </div>
                <Divider />
                <List>{mailFolderListItems}</List>
                <Divider />
                <List>{otherMailFolderListItems}</List>
            </Drawer>
        );
    }
}

Upvotes: 1

Related Questions