This is best explained using code.
The following example is constructed by copy/pasting code form the docs and combining ClickAwayListener
and Select
.
When an option in Select
is chosen the ClickAwayListener
triggers the callback, despite Select
being its descendant.
<ClickAwayListener onClickAway={this.handleClickAway}>
<Paper className={classes.paper}>
<Select
multiple
value={this.state.selected}
onChange={this.handleChange}
input={<Input id="select-multiple" />}
MenuProps={MenuProps}>
{names.map(name => (
<MenuItem key={name} value={name}>
{name}
</MenuItem>
))}
</Select>
</Paper>
</ClickAwayListener>
Select
should normally close with the chosen value being the current in the Select
and the click-away trigger shouldn't fire.
When an option in Select
is chosen the ClickAwayListener
triggers the callback, despite Select
being its descendant.
Note that this doesn't happen if select is in
native
mode withoptions
instead ofMenuItems
. The same behaviour is exhibited in both multi- and regularSelects
.
See codesandbox: https://codesandbox.io/s/3qq7l6478m, forked from the one in docs: https://codesandbox.io/s/6llvjywwq3
I have a Select
in a Drawer
that contains a form. The Drawer
has ClickAwayListener
enveloping its content, including Select
.
When a value is chosen in Select
, the click-away trigger is executed (and it closes the Drawer
in my app).
| Tech | Version |
|--------------|---------|
| Material-UI | v1.?.? |
| React | 16.4.1 |
| browser | Chrome |
| etc | |
@dnutels The Select portals the options to the end of the body element. You can't use the ClickAwayListener
this way. I see two alternatives:
@oliviertassinari So... custom Select
or native select
then? Alright.
custom Select
@dnutels There is a container
property. We could also think of disabling the Portal behavior. I'm wondering how this would behave.
Yeah, I don't think that we can do anything at the ClickAwayListener
component level, this component works with native DOM events, not the simulated ones by React.
I'm having the same kind of problem: click on a Select option triggers ClickAwayListener and closes my Collapse, even though Select is a descendant of ClickAwayListener (not a direct child though).
I saw the PR fixing the problem but I can't understand how it applies to Select component: I only see disablePortal prop in Modal and Popper components.
Easy enough to work around this
Add an id or some other identifier to the MenuItem
component thats falsley triggering the ClickAwayListener
component.
On the ClickAwayListener.onClickAway
event, check that the e.target
doesn't match the pattern before triggering whatever action you're taking on the onClickAway
event (such as closing the Popover)
https://github.com/mui-org/material-ui/issues/13216#issuecomment-429527839
This works for me.
Also, if you are using TextField
<TextField
select
label={"Name"}
value={value}
onChange={selectValue}
SelectProps={{
MenuProps: { disablePortal: true }
}}
>
{[1, 2, 3].map((value, index) =>
<MenuItem key={index} value={value}>
{value}
</MenuItem>
)}
</TextField>
Note that #18586 has a proposed solution to a builtin solution to the problem, it's up for a pull request :).
Most helpful comment
Easy enough to work around this
Add an id or some other identifier to the
MenuItem
component thats falsley triggering theClickAwayListener
component.On the
ClickAwayListener.onClickAway
event, check that thee.target
doesn't match the pattern before triggering whatever action you're taking on theonClickAway
event (such as closing the Popover)