选择 ListItemButton 时如何覆盖样式?

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

我正在尝试覆盖 MUI 中按钮的现有样式。这是我第一次使用 MUI,我使用默认的 emotion 作为样式引擎安装了我的项目。我尝试使用此处指定的 css() 方法:The css prop 但是它似乎不起作用,即使在提供的示例案例中也是如此。 我会尝试添加自定义 css 文件来处理 :select,但我在我的组件中使用状态从 selected 更改为未 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;

看起来 MUI 组件不使用标准 CSS 规则,而是定义了一组 CSS 规则,您可以修改 https://mui.com/material-ui/api/list-item/#props.

Code Sandbox 上的工作示例

我使用 Code Sandbox 制作了一个类似的示例,您可以在此处找到 https://codesandbox.io/s/amazing-gagarin-gvl66n。我使用以下方法展示了一个有效的实现:

  • css道具
  • sx道具

使用 css 道具

要使用 Emotion's css prop.

使代码正常工作,您需要做两件事
  1. 在您使用 css 属性的文件顶部添加以下行(示例中也有)。这将告诉您的应用程序如何处理 css 属性。
/* eslint-disable react/react-in-jsx-scope -- Unaware of jsxImportSource */
/** @jsxImportSource @emotion/react */
  1. 瞄准 classes Material UI provides for the List Item Button component。例如,如果我想在 selectedtrue 时设置列表项按钮的样式,我将针对 .Mui-selected class.

我假设您想设计列表项按钮的背景颜色而不是颜色。设置颜色样式会更改字体颜色。但是,如果您想更改字体颜色,只需将 background-color 的每个实例更改为 color.

总而言之:

/* 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;

备选方案:使用 SX 道具

sx prop 可用于覆盖所有 Material UI 组件的样式。您已经在示例中将其用于 AvatarListItemText 组件。

使用 sx 属性,等效代码为:

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;