Reputation: 2015
I am trying to use Drawer component
in Material UI React. I want that state inside the Drawer component
should not lost on closing of Drawer component, hence I'm passing variant="persistent"
in Drawer component.
Now, the problem is that the Persistent Drawer
does not provide backdrop functionality
by default unlike temporary
drawers hence I'm unable to close it on outside click.
I tried {{ModalProps={{ onBackdropClick: this.toggleDrawer }} }}
also but still it is not working.
Is there any workaround for this?
Material UI Version: 1.0.0
Upvotes: 30
Views: 51352
Reputation: 632
If you want to use the "temporary" variant and retain state when opening and closing the drawer, you can pass the keepMounted: true
prop to ModalProps of the drawer.
<Drawer
variant="temporary"
ModalProps={{
keepMounted: true,
}}
>
{children}
</Drawer>
Upvotes: 2
Reputation: 551
For searchers how have problem with closing the drawer when clicking outside, you can simply detect outside click in onClose
prop. it takes a function and runs it when you click outside of the drawer.
<Drawer open={state} onClose={() => setState(false)} >
</Drawer>
Upvotes: 1
Reputation: 1
You can use in Drawer's open attribute a useState and set to false in the onClose property:
onClose={() => setOpen(false)}
in this example, the useState name is ** open ** and ** setOpen **
Upvotes: 0
Reputation: 81270
Working solution in MUI v5:
Drawer
Use ClickAwayListener
to know when the user clicks outside the Drawer
. You also need to set mouseEvent="onMouseDown"
, otherwise the onClickAway
callback is fired after the user clicks the open button and make the Drawer
close immediately before it can be opened.
<ClickAwayListener
mouseEvent="onMouseDown"
touchEvent="onTouchStart"
open={open}
onClickAway={() => open && setOpen(false)}
>
<Drawer variant="persistent" {...props} />
</ClickAwayListener>
Drawer
<Drawer
variant="temporary"
open={open}
onClose={(_, reason) =>
reason === 'backdropClick' && setOpen(false)
}
>
Upvotes: 12
Reputation: 3219
For the sake of searchers landing on this question. If you are having trouble with ClickAwayListener
and are not using variant='persistent'
. Try this instead: Providing a toggle function to ModalProps
onBackdropClick
<Drawer
open={drawerIsOpen}
ModalProps={{ onBackdropClick: this.toggleDrawer }}
>
<MenuItem>drawer item 1</MenuItem>
</Drawer>
UPDATE July 2021:
I recently updated material-ui/core
to version 4.12.1
and noticed that onBackdropClick
is being deprecated. Instead they have added native support for this functionality, the onClose
function will be called automatically when clicking outside the drawer, and it now gives a reason
for why it was called:
Signature:
function(event: object, reason: string) => void
event
: The event source of the callback.
reason
: Can be: "escapeKeyDown", "backdropClick"
See example here: https://material-ui.com/api/modal/ scroll down to onBackDropClicked - it works the same for the drawer as it does for the
Do this instead:
<Drawer
open={drawerIsOpen}
onClose={{ (ev, reason) => this.setState({ drawerIsOpen: false }) }}
>
<MenuItem>drawer item 1</MenuItem>
</Drawer>
Upvotes: 40
Reputation: 31
Recently found out about this neat useOnClickOutside hook => CodeSandBox and replaced all my with it. Much more elegant than adding an element to the dom and really easy to use with Mui now that you can pass a ref prop to any Material-ui component.
Upvotes: 0
Reputation: 11
I am not sure if it works with 1.0.0 version but this approach works for me noting that i am using the drawer from "material-ui/core @4.10"
<Drawer ... open={this.state.open} onClose={() => this.handleDrawerClose()}>
....
</Drawer>
Upvotes: 0
Reputation: 181
I spend some time training to fix this, but I found a really a useful solution and is to change the variant to Temporary and use de onEscapeKeyDown and the onBackdropClick as follow:
<Drawer
variant="temporary"
onEscapeKeyDown={handleDrawerClose}
onBackdropClick={handleDrawerClose}
open={open}
...rest of your code...
Upvotes: 18
Reputation: 852
You can use the ClickAwayListener
component for this.
https://material-ui.com/api/click-away-listener/
import ClickAwayListener from '@material-ui/core/ClickAwayListener';
const drawer = (
<ClickAwayListener onClickAway={this.handleDrawerClose}>
<Drawer
variant="persistent"
anchor={anchor}
open={open}
classes={{
paper: classes.drawerPaper
}}
>
<div className={classes.drawerHeader}>
<IconButton onClick={this.handleDrawerClose}>
{theme.direction === "rtl" ? (
<ChevronRightIcon />
) : (
<ChevronLeftIcon />
)}
</IconButton>
</div>
<Divider />
<List>a asdasd</List>
<Divider />
<List>asdasd</List>
</Drawer>
</ClickAwayListener>
);
https://codesandbox.io/s/072ny1rjw
Upvotes: 21
Reputation: 976
You can implement this yourself by adding a div in your appFrame
which has an onClick
that closes the drawer like this:
<div className={classes.appFrame}>
{this.state.open ?
<div style={{ position: "fixed", zIndex: 1, left: 0, right: 0, top: 0, bottom: 0 }}
onClick={() => this.handleDrawerClose()} />
: null
}
// rest of your code
Upvotes: 4