Search code examples
reactjsdropdownmaterial-ui

How to detect if React Material UI Select Field is expanded?


I am trying to determine if SelectField is expanded or not, i.e. if the dropdown and it's MenuItems are visible.

Currently I use roughly following approach:

<SelectField onClick={() => this.setState({ isExpanded: true })} >
    <MenuItem primaryText={
      <MenuItemContent onHide={() => this.setState({ isExpanded: false })}} />
    }>
</SelectField>

and in MenuItemContent I implement

class MenuItemContent extends React.Component {
  componentWillUnmount = () => this.props.onHide()
}

This approach has a drawback, that when you click outside the menu, the componentWillUnmount call is not triggered immidiately, but cca after 200ms, despite the MenuItems are no longer visible.

The Select field menu can be expanded by clicking it, and when is expanded, it will hide either when some menu item is clicked, or user clicks outside the menu.

This is how the SelectField looks when is expanded:

enter image description here

And here is collapsed:

enter image description here


Solution

  • For the better handling of SelectField close event you can use property dropDownMenuProps:

    /**
     * Object that can handle and override any property of component DropDownMenu.
     */
    dropDownMenuProps: PropTypes.object,
    

    By using this prop we can pass to DropDownMenu component onClose prop with handler function, which will be fired instantly after DropDownMenu close (caused by ESC, outside click or item select). Unfortunately DropDownMenu component dont provide similar prop to determine the opening so the only way (without extending the component) is to follow your approach with onClick event handler. Here is my working test example:

      onSelectClose = () => {
        console.log("close")
      }
    
      onSelectOpen = () => {
        console.log("open")
      }
    
      render() {
        return (
          <MuiThemeProvider>
            <div className="App">
              <SelectField
                floatingLabelText="Frequency"
                onClick={this.onSelectOpen}
                dropDownMenuProps={{
                  onClose: this.onSelectClose
                }}
                value={this.state.value}
                onChange={this.handleChange}>
                  <MenuItem value={1} primaryText="Never" />
                  <MenuItem value={2} primaryText="Every Night" />
                  <MenuItem value={3} primaryText="Weeknights" />
                  <MenuItem value={4} primaryText="Weekends" />
                  <MenuItem value={5} primaryText="Weekly" />
              </SelectField>
            </div>
          </MuiThemeProvider>
        );
      }