Search code examples
reactjsmaterial-uistyled-components

How to apply styles to MUI MenuList with styled compoents


I'm trying to apply background-color when MenuItem component has the selected={true}

also I'd like to apply a style when MenuItem component hovered.

How can I do that?

import * as React from "react";
import Paper from "@mui/material/Paper";
import MenuList from "@mui/material/MenuList";
import Stack from "@mui/material/Stack";
import { MenuItem } from "./styles";

export default function MenuListComposition() {
  return (
    <Stack direction="row" spacing={2}>
      <Paper>
        <MenuList>
          <MenuItem selected={true}>Profile</MenuItem>
          <MenuItem>My account</MenuItem>
          <MenuItem>Logout</MenuItem>
        </MenuList>
      </Paper>
    </Stack>
  );
}

styles.js

import styled from "styled-components";

import { default as MuiMenuItem } from "@mui/material/MenuItem";

export const MenuItem = styled(MuiMenuItem)`
  .MuiMenuItem-root {
    color: blue;
    padding: 10px 0;
    & .Mui-selected {
      background-color: red;
    }
    &:hover {
      background-color: green;
    }
  }
`;

Solution with styled-components

If you need to use styled-components instead of styled from Mui, you can do it.

export const MenuItem = styled(MuiMenuItem)`
  color: blue;
  padding: 20px;

  &.Mui-selected {
    background-color: red;
  }

  &:hover {
    background-color: green;
  }
`;


Solution

  • You can fix the problem by importing styled from material and adapt the format, like this:

    import { MenuItem as MuiMenuItem, styled } from "@mui/material";
    
    export const MenuItem = styled(MuiMenuItem)({
      "&.MuiMenuItem-root": {
        color: "blue",
        padding: "10px",
        "&.Mui-selected": {
          backgroundColor: "red"
        },
        "&:hover": {
          backgroundColor: "green"
        }
      }
    });
    

    and then I assume that what you want is to change the color only of the selected MenuItem and you can create the array of objects like in the code so you do not repeat to much code.

    import React, { useState } from "react";
    import Paper from "@mui/material/Paper";
    import MenuList from "@mui/material/MenuList";
    import Stack from "@mui/material/Stack";
    import { MenuItem } from "./styles";
    
    const ITEMS = [
      { index: 1, title: "Profile" },
      { index: 2, title: "My Account" },
      { index: 3, title: "Logout" }
    ];
    
    export default function MenuListComposition() {
      const [selectedIndex, setSelectedIndex] = useState(1);
    
      const handleListItemClick = (event, index) => {
        setSelectedIndex(index);
      };
    
      return (
        <Stack direction="row" spacing={2}>
          <Paper>
            <MenuList variant="menu">
              {ITEMS.map(({ index, title }) => (
                <MenuItem
                  key={index}
                  onClick={(event) => handleListItemClick(event, index)}
                  selected={selectedIndex === index}
                >
                  {title}
                </MenuItem>
              ))}
            </MenuList>
          </Paper>
        </Stack>
      );
    }