Home > OS >  How can I override styling for ListItemButton when it's selected?
How can I override styling for ListItemButton when it's selected?

Time:04-25

I'm trying to override the existing styling for a button in MUI. This is my first time using MUI, and I installed my project with the default emotion as a styling engine. I tried to use the css() method as specified here : The css prop however it doesn't seem to be working, even on the example case provided. I would have tried to add a custom css file to handle :select, but I'm using state in my component to change from selected to not selected.

import * as React from "react";
import Avatar from "@mui/material/Avatar";
import ListItemText from "@mui/material/ListItemText";
import ListItemButton from "@mui/material/ListItemButton";
import { useState } from "react";
import { css } from "@emotion/react";


const ProfileInfo = ({ userCredentials, userPicture }) => {
  const [selected, setSelected] = useState(false);

  return (
    <ListItemButton
      selected={selected}
      onClick={() => setSelected((prev) => !prev)}
      css={css`

        ::selection {
          color: #2e8b57;
        }
        :focus {
          color:#2e8b57;
        }
        :active {
          color:#2e8b57
        }
      `}
    >
      <Avatar
        alt={userCredentials}
        src={userPicture}
        sx={{ width: 24, height: 24 }}
      />
      <ListItemText primary={userCredentials} sx={{ marginLeft: 3 }} />
    </ListItemButton>
  );
};

export default ProfileInfo;

CodePudding user response:

Working examples on Code Sandbox

I have made a similar example using Code Sandbox, which you can find here https://codesandbox.io/s/amazing-gagarin-gvl66n. I show a working implementation using:

  • The css prop
  • The sx prop

Using the css prop

There's two things you need to do to make your code work using Emotion's css prop.

  1. Add the following lines, which is also in the example, at the top of the file where you are using the css prop. This will tell your app how to handle the css prop.
/* eslint-disable react/react-in-jsx-scope -- Unaware of jsxImportSource */
/** @jsxImportSource @emotion/react */
  1. Target the classes Material UI provides for the List Item Button component. For example, if I want to style the List Item Button when selected is true, I would target the .Mui-selected class.

I am assuming you wanted to style the background color of the List Item Button rather than the color. Styling the color changes the font color. However, if you wanted to change the font color, you can just change each instance of background-color to color.

Putting it altogether:

/* eslint-disable react/react-in-jsx-scope -- Unaware of jsxImportSource */
/** @jsxImportSource @emotion/react */
import * as React from "react";
import Avatar from "@mui/material/Avatar";
import ListItemText from "@mui/material/ListItemText";
import ListItemButton from "@mui/material/ListItemButton";
import { useState } from "react";
import { css } from "@emotion/react";

const ProfileInfo = ({ userCredentials, userPicture }) => {
  const [selected, setSelected] = useState(false);

  return (
    <ListItemButton
      selected={selected}
      onClick={() => setSelected((prev) => !prev)}
      css={css`
        &.Mui-selected {
          background-color: #2e8b57;
        }
        &.Mui-focusVisible {
          background-color: #2e8b57;
        }
        :hover {
          background-color: #2e8b57;
        }
      `}
    >
      <Avatar
        alt={userCredentials}
        src={userPicture}
        sx={{ width: 24, height: 24 }}
      />
      <ListItemText primary={userCredentials} sx={{ marginLeft: 3 }} />
    </ListItemButton>
  );
};

export default ProfileInfo;

Alternative: Using the SX prop

The sx prop can be used to override styles with all Material UI components. You are already using this for the Avatar and ListItemText components in your example.

Using the sx prop, the equivalent code would be:

import * as React from "react";
import Avatar from "@mui/material/Avatar";
import ListItemText from "@mui/material/ListItemText";
import ListItemButton from "@mui/material/ListItemButton";
import { useState } from "react";

const ProfileInfo = ({ userCredentials, userPicture }) => {
  const [selected, setSelected] = useState(false);

  return (
    <ListItemButton
      selected={selected}
      onClick={() => setSelected((prev) => !prev)}
      sx={{
        "&.Mui-selected": {
          backgroundColor: "#2e8b57"
        },
        "&.Mui-focusVisible": {
          backgroundColor: "#2e8b57"
        },
        ":hover": {
          backgroundColor: "#2e8b57"
        }
      }}
    >
      <Avatar
        alt={userCredentials}
        src={userPicture}
        sx={{ width: 24, height: 24 }}
      />
      <ListItemText primary={userCredentials} sx={{ marginLeft: 3 }} />
    </ListItemButton>
  );
};

export default ProfileInfo;

CodePudding user response:

It looks like MUI components doesn't use standard CSS rules but instead has a defined set of CSS rules you can modify https://mui.com/material-ui/api/list-item/#props.

  • Related