How to Add a Clear Button to the MUI Select Component

The Material-UI Select component is a great user input component with a list of options. However, it is a bad experience to require a user to click into the component and press “backspace” to clear it. In this tutorial I will show how to add a clear button inside the Select.

The biggest challenge is removing the arrow icon and replacing it with a clear icon. I only want the clear icon when the Select has a value, and I still want the arrow icon when no value is selected:

The arrow icon is rendered by default in the Material-UI Select and there are no props to disable it, so I had to get clever with styling.

Full code is in the Resources section.

Here’s a YouTube video version of this post or watch below:

How to Clear the MUI Select

The easiest way to clear the MUI Select component is to use a state value and then set this value as the value prop in the Select component:

<const [score, setScore] = useState('');

//JSX
<Select value={score} />

The score state value can be set to an empty string by a button inside the Select or by an external button. Here’s what the click handler looks like for either an internal or external button:

const handleClearClick = () => {
  setScore('');
};

How to Add a Clear Button to the MUI Select

The Select component appears to me to render the same as a TextField (in fact, the TextField has a select prop that converts it to a Select component).

MUI Select DOM with Clear Icon
MUI Select DOM with Clear Icon

However, the props for adding a clear button are a little bit different. Instead of setting InputProps.endAdornment, we can directly set the endAdornment prop:

endAdornment={<IconButton sx={{display: score? "": "none"}} onClick={handleClearClick}><ClearIcon/></IconButton>}

Notice how I make it display or not display based on the score state prop. This allows the clear button to be visible only when there is a value to clear.

Remember, a display: none component is not rendered. It is best to not render a component when possible to keep the DOM light. I did not see any jumping or strange render effects with display: none.

I also made the IconButton primary.blue on focus with the below nested selector, just like the Select outline does by default:

//Select level sx:
"&.Mui-focused .MuiIconButton-root": {color: 'primary.main'}

The Autocomplete component has a clear button by default.

How to Remove the MUI Select Dropdown Arrow

I decided that I wanted the dropdown arrow to be visible only if no option is chosen.

//Select level sx:
"& .MuiSelect-iconOutlined": {display: score? 'none': ''}

This nested selector finds the .MuiSelect-iconOutlined class in the DOM, which wraps the dropdown arrow by default.

Using a state value for the Select allows us to manage all these styles that depend on whether the Select has been populated.

Resources

Here’s a great Material-UI Select component styling tutorial.

MUI Select Component Docs

import React, { useState } from 'react';
import InputLabel from '@mui/material/InputLabel';
import MenuItem from '@mui/material/MenuItem';
import FormControl from '@mui/material/FormControl';
import Select, { SelectChangeEvent } from '@mui/material/Select';
import ClearIcon from "@mui/icons-material/Clear";
import IconButton from "@mui/material/IconButton";

export default function ClearSelect() {
  const [score, setScore] = useState('');
  const handleClearClick = () => {
    setScore('');
  };

  const scoreData = ["100", "90", "80", "70", "60", "50", "40", "30"];

  const handleChange = (event: SelectChangeEvent<string>) => {
    setScore(event.target.value);
  };

  return (
      <FormControl sx={{width: 200}}>
        {score.length ? <InputLabel id="custom-select-label">Score</InputLabel>: ''}
        <Select
          labelId="clearable-select-label"
          label={score.length ? "Score": ""}
          id="clearable-select"
          value={score}
          onChange={handleChange}
          displayEmpty
          sx={{"& .MuiSelect-iconOutlined": {display: score? 'none': ''}, "&.Mui-focused .MuiIconButton-root": {color: 'primary.main'}}}
          renderValue={(value) => value ? value : <em>Nothing Selected</em>}
          endAdornment={<IconButton sx={{visibility: score? "visible": "hidden"}} onClick={handleClearClick}><ClearIcon/></IconButton>}
        >
          {scoreData.map((scoreValue) => {
            return <MenuItem value={scoreValue}>{scoreValue}</MenuItem>
          })}
        </Select>
      </FormControl>
  );
}
Share this post:

2 thoughts on “How to Add a Clear Button to the MUI Select Component”

  1. There is an uninteded sideeffect with your code, when you add the endAdornment attribute to the Select component mui makes room for the content by adding padding to the MuiSelect component.

    That removes the ablilty to click on the right part of the select to open the popout

    To fix this make the content of endAdornment conditionally and only return the element if score is true like this

    endAdornment={
    score ? (

    ) : (
    false
    )
    }
    this makes it so you can click the entire select box to trigger the popout with options 🙂

    other than that great work 🙂

    Reply

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.