【问题标题】:How to set selected and hover color of ListItem in MUI?如何在 MUI 中设置 ListItem 的选定和悬停颜色?
【发布时间】:2020-04-28 17:17:42
【问题描述】:

无法让 ListItem 使用“已选择”或“悬停颜色”。对于选定的尝试设置其类,如:

<ListItem selected button key="home" classes={{ selected: classes.listItemSelected }}>
  <ListItemText primary="Hi"/>
</ListItem>

然后设置样式如下:

const useStyles = makeStyles((theme) => ({
  listItemSelected:{
    backgroundColor: "#ff0000",
  },
}));

但它什么也没做,'selected'在ListItem组件APIhere中有描述。

如何为ListItem 设置selectedhover 的颜色?

【问题讨论】:

    标签: css reactjs material-ui


    【解决方案1】:

    下面是default ListItem styles 中处理背景颜色的部分:

    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: {},
    });
    

    需要注意的重要一点是,所选样式是通过两个类(rootselected)的组合完成的,因此如果您尝试使用单个类覆盖它,您将没有足够的 specificity .

    下面是一个示例,展示了一种覆盖选定和悬停状态的方法:

    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>
      );
    }
    

    相关答案:

    【讨论】:

    • ListItemIcon 怎么样?我注意到它不会随文本改变颜色。我将如何更改 ListItemIcon 颜色?
    • @blah 我已经更新了我的示例以更改图标颜色。
    • @RyanCogswell 超级有用的例子。你能指出一个解释吗?我最初错过了selected: {},但它没有用。对 React 和 Mui 来说相当新,但很好奇它是如何工作的......或者它在哪里被记录。
    • "&amp;:hover": 哦,太明显了.... /s 谢谢你的提示
    【解决方案2】:

    您可以在 MUI v5 中使用 sx 属性:

    <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',
          },
        },
      }}
    >
    

    或者styled创建一个可以多次重复使用的样式化组件:

    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',
        },
      },
    });
    

    现场演示

    【讨论】:

    • 很好的解决方案,谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-10-08
    • 1970-01-01
    • 1970-01-01
    • 2015-06-11
    • 2022-06-19
    • 1970-01-01
    • 2022-01-23
    相关资源
    最近更新 更多