Reputation: 143
I'm trying to apply some basic styles to the options inside the Autocomplete component from MUI v5. I'm just trying to change the background color on hover, and based on whether or not it is selected. I've tried 2 approaches based on the documentation, using a theme, and applying the sx prop to Autocomplete.
Using Theme almost has me there, code below:
import { createTheme, ThemeProvider } from '@mui/material/styles';
const theme = createTheme({
components: {
MuiAutocomplete: {
styleOverrides: {
option: {
'&[aria-selected="true"]': {
backgroundColor: '#e3abed',
},
'&:hover': {
backgroundColor: '#9c27b0',
},
backgroundColor: '#fff',
},
},
},
},
})
I have the ThemeProvider wrapped around my entire app
and the component:
<Autocomplete
options={['1', '2', '3']}
renderInput={(params) => <TextField {...params} label="Priority" />}
onChange={(_e, val) => setPriority(val)}
/>
So, this almost works. However the [aria-selected="true"] styling is only being applied when I am also hovering over another option in the dropdown. Otherwise it's the default grey that comes with the component and I don't understand why.
The second path I have tried is to use the sx prop on the Autocomplete component. In the docs it says you can target child components by their class name: https://mui.com/material-ui/customization/how-to-customize/#overriding-styles-with-class-names
Here is my component:
<Autocomplete
options={['1', '2', '3']}
renderInput={(params) => <TextField {...params} label="Priority" />}
onChange={(_e, val) => setPriority(val)}
sx={{
'& .MuiAutocomplete-option': {
backgroundColor: '#000',
},
'& .Mui-focused': {
backgroundColor: 'red',
},
}}
open
/>
That doesn't appear to be having any effect. I've been working on this for almost 2 hours and can't seem to get to the finish line here. Any help would be greatly appreciated.
Upvotes: 8
Views: 24306
Reputation: 91
If you just need custom styling CustomPaper component might be an overkill (and I also faced some TypeScript issues trying that).
For simple styling you can use slotProps:
<Autocomplete
slotProps={{
paper: {
sx: {
'& .MuiAutocomplete-listbox': {
'& .MuiAutocomplete-option': {
display: 'flex',
flexDirection: 'column',
alignItems: 'flex-start',
},
},
},
},
}}
...
/>
Upvotes: 6
Reputation: 65
You can override the style of Autocomplete list items by using the makeStyle() in your functional component with these attributes:
'@global': {
'& .MuiAutocomplete-popper': {
'& .MuiPaper-root': {
'& .MuiAutocomplete-listbox': {
'& li': {
fontSize: '14px !important',
paddingTop: 0,
paddingBottom: 0
}
}
}
},
},
Because it's being created in the root element of DOM.
Upvotes: 1
Reputation: 91
function CustomPaper({ children }) {
return (
<Paper
sx={{
"& .MuiAutocomplete-listbox": {
"& .MuiAutocomplete-option[aria-selected='true']": {
bgcolor: "purple",
"&.Mui-focused": {
bgcolor: "purple",
}
}
},
"& .MuiAutocomplete-listbox .MuiAutocomplete-option.Mui-focused": {
bgcolor: "red",
}
}}
>
{children}
</Paper>
);
}
Following up on Lars' answer, here's an example using a custom Paper component. Just pass in the custom Paper component name to the PaperComponent prop on Autocomplete <Autocomplete PaperComponent={CustomPaper} {...blahBlahOtherProps} />
. This way is nice if you don't want to override the theme for all Autocomplete components.
Upvotes: 5
Reputation: 154
I too faced this issue and found a solution. You Can try this to set the css for options, single option and while hovered (focused) in the Autocomplete using 'sx' prop
Easy Way to customize your AutoComplete component which can be used in Mui V5
<Autocomplete
limitTags={1}
disablePortal
id="simple-search"
value={select.region}
onChange={handleChange("region")}
options={region}
sx={{
width: { sm: "100%", md: 340 },
"& + .MuiAutocomplete-popper .MuiAutocomplete-option":
{
backgroundColor: "#363636",
},
"& + .MuiAutocomplete-popper .MuiAutocomplete-option[aria-selected='true']":
{
backgroundColor: "#4396e6",
},
"& + .MuiAutocomplete-popper .MuiAutocomplete-option[aria-selected ='true'] .Mui-focused":
{
backgroundColor: "#3878b4",
},
}}
disableCloseOnSelect
multiple
renderInput={(params) => (
<TextField {...params} label="Region" color="info" />
)}
/>
Upvotes: 1
Reputation: 5674
I had the same problem; turns out I just needed to explore the Autocomplete
API docs' Props section a bit further. There are several customization possibilities if you don't want to deal with global theme customization:
PaperComponent
prop allows customization of "[t]he component used to render the body of the popup." Note that simply using sx
on Autocomplete
does not work here because (as @bnays-mhz pointed out) the PopperComponent
that the PaperComponent
is nested in lives outside the main DOM tree (for z-index/modal UX purposes).renderGroup
prop allows overriding the rendering of option group headers.renderOption
prop allows overriding the rendering of individual options.Upvotes: 4
Reputation: 503
You can override Autocomplete options css by targeting class
'.MuiAutocomplete-popper'
You will have to apply css globally because this node is created outside the root element in DOM.
Upvotes: 1