Prevent auto focus of a material-ui popover element
The reason why this is happening is that you are calling this.showPopover(event)
every time the onChange={this.handleContactSearch.bind(this)}
event is fired in your <TextField>
.
In order to fix this, you'll need to find a way to call this.showPopover(event)
only once.
I was able to make it work using a combination of autoFocus={true}
and the onFocus={this.showPopover}
event on the <TextField/>
. The only issue with this is that the popover will show up empty when you first open the modal. I used a ref
on the textfield and a conditional to set the opacity of the popover so it only shows once there's a value in the textfield.
Maybe not the ultimate solution, but it works and should at least send you in the right direction.
<div className={classes.paper}>
<TextField
id="contact123"
label="Contact Name"
className={classes.textField}
margin="normal"
onChange={this.handleContactSearch.bind(this)}
value={this.state.contactSearch}
autoFocus={true}
onFocus={this.showPopover}
inputRef={input => (this.tf = input)}
/>
<Popover
open={Boolean(anchorEl)}
anchorEl={document.getElementById("contact123")}
onClick={this.closePopover}
anchorOrigin={{
vertical: "bottom",
horizontal: "center"
}}
transformOrigin={{
vertical: "top",
horizontal: "center"
}}
style={{ opacity: this.tf && !this.tf.value.length ? 0 : 1 }}
>
<List>{this.state.contactSearch}</List>
</Popover>
<div>
<Button color="primary" className={classes.saveButton}>
Save
</Button>
</div>
</div>
Sandbox: Working Demo
An alternative to this approach is to use Popper
, ClickAwayListener
and Backdrop
components. Using Popper
allows you to preserve focus on the input field and keep typing. The solution would look roughly like:
class Foo extends React.Component {
inputRef = React.createRef(),
render() {
const { open, searchValue } = this.state
<RootRef rootRef={this.inputRef}>
<div className={classes.container}>
// You may be able to use TextField as well
<FormControl
onKeyDown={//set open = false}
onClick={// set open = true (e.g. only when searchValue !== '' }
>
<InputBase
value={searchValue}
onChange={this.handleSearchValueChange}
inputRef={this.inputRef}
/>
</FormControl>
<Popper anchorEl={this.inputRef.current} open={open} >
<ClickAwayListener onClick={//set open = false} onClickAway={//set open = false}>
Popover content
</ClickAwayListener>
</Popper>
</div>
</RootRef>
}
}
Not a working example, but shows how to solve the problem of being able to type in an input while having popover/popper opened.
Pass 'disableAutoFocus', 'disableEnforceFocus' props to your popover. It worked for me!
<Popover
open={Boolean(anchorEl)}
// pass these props to the popover component
disableAutoFocus={true}
disableEnforceFocus={true}
>
https://material-ui.com/api/modal/