How to set selected and hover color of ListItem in MUI?
Solution 1
Below is the portion of the default ListItem styles that deals with the background color:
export const styles = (theme) => ({
/* Styles applied to the (normally root) `component` element. May be wrapped by a `container`. */
root: {
'&$focusVisible': {
backgroundColor: theme.palette.action.selected,
},
'&$selected, &$selected:hover': {
backgroundColor: theme.palette.action.selected,
},
'&$disabled': {
opacity: 0.5,
},
},
/* Pseudo-class applied to the `component`'s `focusVisibleClassName` prop if `button={true}`. */
focusVisible: {},
/* Styles applied to the inner `component` element if `button={true}`. */
button: {
transition: theme.transitions.create('background-color', {
duration: theme.transitions.duration.shortest,
}),
'&:hover': {
textDecoration: 'none',
backgroundColor: theme.palette.action.hover,
// Reset on touch devices, it doesn't add specificity
'@media (hover: none)': {
backgroundColor: 'transparent',
},
},
},
/* Pseudo-class applied to the root element if `selected={true}`. */
selected: {},
});
The important thing to notice is that the selected styling is done via a combination of two classes (root
and selected
), so if you try to override it using a single class you will not have sufficient specificity.
Below is an example showing one way to override the selected and hover states:
import React from "react";
import { makeStyles, withStyles } from "@material-ui/core/styles";
import List from "@material-ui/core/List";
import MuiListItem from "@material-ui/core/ListItem";
import ListItemIcon from "@material-ui/core/ListItemIcon";
import ListItemText from "@material-ui/core/ListItemText";
import Divider from "@material-ui/core/Divider";
import InboxIcon from "@material-ui/icons/Inbox";
import DraftsIcon from "@material-ui/icons/Drafts";
const useStyles = makeStyles((theme) => ({
root: {
width: "100%",
maxWidth: 360,
backgroundColor: theme.palette.background.paper
}
}));
const ListItem = withStyles({
root: {
"&$selected": {
backgroundColor: "red",
color: "white",
"& .MuiListItemIcon-root": {
color: "white"
}
},
"&$selected:hover": {
backgroundColor: "purple",
color: "white",
"& .MuiListItemIcon-root": {
color: "white"
}
},
"&:hover": {
backgroundColor: "blue",
color: "white",
"& .MuiListItemIcon-root": {
color: "white"
}
}
},
selected: {}
})(MuiListItem);
export default function SelectedListItem() {
const classes = useStyles();
const [selectedIndex, setSelectedIndex] = React.useState(1);
const handleListItemClick = (event, index) => {
setSelectedIndex(index);
};
return (
<div className={classes.root}>
<List component="nav" aria-label="main mailbox folders">
<ListItem
button
selected={selectedIndex === 0}
onClick={(event) => handleListItemClick(event, 0)}
>
<ListItemIcon>
<InboxIcon />
</ListItemIcon>
<ListItemText primary="Inbox" />
</ListItem>
<ListItem
button
selected={selectedIndex === 1}
onClick={(event) => handleListItemClick(event, 1)}
>
<ListItemIcon>
<DraftsIcon />
</ListItemIcon>
<ListItemText primary="Drafts" />
</ListItem>
</List>
<Divider />
<List component="nav" aria-label="secondary mailbox folder">
<ListItem
button
selected={selectedIndex === 2}
onClick={(event) => handleListItemClick(event, 2)}
>
<ListItemText primary="Trash" />
</ListItem>
<ListItem
button
selected={selectedIndex === 3}
onClick={(event) => handleListItemClick(event, 3)}
>
<ListItemText primary="Spam" />
</ListItem>
</List>
</div>
);
}
Related answers:
- How to overried the selected classes in menuItem in material ui REACTjs?
- How to change the styles of ListItem element with the "onclick" event?
Solution 2
You can use the sx
prop in MUI v5:
<List
sx={{
// selected and (selected + hover) states
'&& .Mui-selected, && .Mui-selected:hover': {
bgcolor: 'red',
'&, & .MuiListItemIcon-root': {
color: 'pink',
},
},
// hover states
'& .MuiListItemButton-root:hover': {
bgcolor: 'orange',
'&, & .MuiListItemIcon-root': {
color: 'yellow',
},
},
}}
>
Or styled
to create a styled component that can be reused multiple times:
import MuiList from '@mui/material/List';
const List = styled(MuiList)({
// selected and (selected + hover) states
'&& .Mui-selected, && .Mui-selected:hover': {
backgroundColor: 'red',
'&, & .MuiListItemIcon-root': {
color: 'pink',
},
},
// hover states
'& .MuiListItemButton-root:hover': {
backgroundColor: 'orange',
'&, & .MuiListItemIcon-root': {
color: 'yellow',
},
},
});
Live Demo
Related videos on Youtube

realtimez
Updated on June 16, 2022Comments
-
realtimez 11 months
Can't get 'selected' or 'hover colors to work for
ListItem
. For selected tried setting its classes like:<ListItem selected button key="home" classes={{ selected: classes.listItemSelected }}> <ListItemText primary="Hi"/> </ListItem>
and then setting the style like:
const useStyles = makeStyles((theme) => ({ listItemSelected:{ backgroundColor: "#ff0000", }, }));
But it doesn't do anything, the 'selected' is described in the
ListItem
component API here.How do you get to set the color of both the selected and hover for
ListItem
? -
blah about 2 yearsHow about the ListItemIcon? I noticed that it doesn't change color with the text. How would I go about changing the ListItemIcon color as well?
-
Ryan Cogswell about 2 years@blah I've updated my example to change the icon color as well.
-
Eric Liprandi almost 2 years@RyanCogswell super useful example. Can you point to an explanation? I had originally missed the
selected: {}
and it didn't work. Fairly new to React and Mui, but very curious how that works... or where it's documented. -
Reza over 1 yearThe great solution, thanks.
-
thedanotto over 1 year
"&:hover":
oh duh, so obvious.... /s thanks for the tip