javascriptreactjsmaterial-ui

React Material UI - Autocomplete Component button after clear field button


I am trying to add a search button my Autocomplete Component on Material UI. So far I have been able to add the button however, it always appears before the clear button like below:

enter image description here

How can I set the InputProps such that the button will appear after the X.

So far I have:

<Autocomplete
    id="search-input"
    freeSolo                                   
    renderInput={(params) => (                    
        <TextField
            {...params} 
            placeholder={`...`} 
            margin="normal" 
            variant="outlined" 
            size="medium"
            InputProps={{
                ...params.InputProps,
                endAdornment: (
                <React.Fragment>                          
                    <IconButton size="small">
                        <SearchIcon />
                    </IconButton>    
                    {params.InputProps.endAdornment}               
                </React.Fragment>
                ),
            }}
        />  
    )}
/>

I have tried replacing the order of ...params.InputProps and the endAdornment but nothing changes.


Solution

  • When you inspect the elements within the Autocomplete in the dev tools, you'll see the following: an input representing the search area, the end adornment of the TextField which in your case is a button with a SearchIcon and a div with the class MuiAutocomplete-endAdornment which holds the clear icon. These appear on the screen in that order from left to right. These are all siblings within a div that has the CSS property: display: inline-flex. This means the siblings can be re-ordered using order. We want to show the elements in the following order from left to right: input, clear icon and search icon.

    How

    We can achieve this by overriding existing styles. Since the div which houses these three elements is a child of the root of the TextField component, we can apply the styling to the root class of the TextField.

    1. Create class called textFieldRoot - you can call it whatever you want.
    import { makeStyles } from "@material-ui/core/styles";
    
    const useStyles = makeStyles({
      textFieldRoot: {
        "& > div.MuiAutocomplete-inputRoot[class*='MuiOutlinedInput-root']": {
          // default paddingRight was 39px since clear icon was positioned absolute
          paddingRight: "9px", 
          
          // Search icon
          "& button": {
            order: 3, // order 3 means the search icon will appear after the clear icon which has an order of 2
          },
    
          // Clear icon
          "& > div.MuiAutocomplete-endAdornment": {
            position: "relative", // default was absolute. we make it relative so that it is now within the flow of the other two elements
            order: 2,
          },
        },
      },
    });
    
    1. Apply the class to the root of the TextField
    const classes = useStyles();
    
    <Autocomplete
      id="search-input"
      freeSolo
      options={[]}
      renderInput={(params) => (
        <TextField
          {...params}
          classes={{
            root: classes.textFieldRoot, // apply class here
          }}
          placeholder={`...`}
          margin="normal"
          variant="outlined"
          size="medium"
          InputProps={{
            ...params.InputProps,
            endAdornment: (
              <React.Fragment>
                <IconButton size="small">
                  <SearchIcon />
                </IconButton>
                {params.InputProps.endAdornment}
              </React.Fragment>
            ),
          }}
        />
      )}
    />
    

    Result Autocomplete with Search Icon at end after clear icon

    Alternative

    As you can see, it is a bit of work. I would consider using startAdornment instead of endAdornment in your InputProps to place the search icon at the front of the search bar.