Material-UI Select, how to apply :focus-within styling on the select when the input is clicked?

Viewed 2962

I'm using the Select inside a div component:

<div className="custom-filter custom-filter-data">
            <DateRangeIcon className="search-icon"/>
            <FormControl variant='standard' ref={addrRef} className= 
                {classes.formControl}>                
              <Select
                labelId="demo-simple-select-label"
                id="demo-simple-select"
                defaultValue=""
                onFocus={(e) => {addrRef.current.focus()}}
                displayEmpty
              >
                <MenuItem value="" disabled>
                  Seleziona data
                </MenuItem>
                <MenuItem value={10}>Ten</MenuItem>
                <MenuItem value={20}>Twenty</MenuItem>
                <MenuItem value={30}>Thirty</MenuItem>
              </Select>
            </FormControl>
              //other components
         </div>

css container

.custom-filter:focus-within{
  color: #495057;
  background-color: #fff;
  border-color: #80bdff;
  outline: 0;
  box-shadow: 0 0 0 0.2rem rgb(0 123 255 / 25%);
}

I need to trigger the focus on the select when the select input is clicked in order to leverage :focus-within styling of the parent container. Now the parent :focus-within is working just onChange event (when I select the MenuItem). as you can see, I've tried with useRef() but is not working... It seems that when a user clicks on the input of the select, it blocks all the other focus...

https://codesandbox.io/s/react-material-ui-select-forked-8msbu?file=/src/index.js

1 Answers

By default, Select opens the popup (implemented via the Menu component) of its options within a portal. This means that the menu items are not descendants of your div in the DOM, so when focus is on the menu or menu items then the :focus-within selector on your div is not matched.

You can change this behavior by adding MenuProps={{ disablePortal: true }} to the Select.

Relevant documentation:

Here's a modified version of your sandbox:

import React from "react";
import ReactDOM from "react-dom";
import Input from "@material-ui/core/Input";
import InputLabel from "@material-ui/core/InputLabel";
import MenuItem from "@material-ui/core/MenuItem";
import FormControl from "@material-ui/core/FormControl";
import Select from "@material-ui/core/Select";
import "./styles.css";

const App = () => {
  const [value, setValue] = React.useState("");
  return (
    <div className="custom-filter custom-filter-data">
      <FormControl>
        <InputLabel htmlFor="age-simple">Age</InputLabel>
        <Select
          style={{ minWidth: "100px" }}
          value={value}
          input={<Input id="age-simple" />}
          onChange={(event) => setValue(event.target.value)}
          MenuProps={{ disablePortal: true }}
        >
          <MenuItem value="">
            <em>None</em>
          </MenuItem>
          <MenuItem value={10}>Ten</MenuItem>
          <MenuItem value={20}>Twenty</MenuItem>
          <MenuItem value={30}>Thirty........</MenuItem>
        </Select>
      </FormControl>
    </div>
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Edit Select focus-within

Related