【问题标题】:Change Material-UI ListItem children on hover/active在悬停/活动时更改 Material-UI ListItem 子项
【发布时间】:2018-11-25 13:35:08
【问题描述】:

考虑以下侧边栏导航的组件结构:

<ListItem button dense component={CustomNavLink} to="/dashboard">
    <ListItemIcon>
        <DashboardIcon />
    </ListItemIcon>
    <ListItemText primary="Dashboard" />
</ListItem>

任务是在悬停或CustomNavLink 变为活动状态时更改ListItemIconListItemText 的外观。

注意CustomNavLink 是一个扩展的 React Router 的 NavLink 组件 当它与当前路由匹配时,它会得到一个 active 类。

以下有点老套的方法通过classes 属性实现了这一点(为清楚起见进行了简化和简化):

const styles =  {
    root: {
        ...
        '&.active, &:hover, &.active:hover': {
            '& path': {
                fill: 'red'
            },
            '& span': {
                color: 'red'
            }
        }
    }
};

(然后将classes 应用于ListItem 组件)

这似乎是一种极其糟糕的做法,因为嵌套组件的结构会泄漏到父级的样式中......这类似于在“旧”CSS 中这样做:

div:hover > ul > li > a {
    color: red;
}

解决此问题的惯用 Material-UI 方法是什么?

作为参考,这是styled-components中的做法:

const CustomNavLink = styled(NavLink)`
    ...
    &:hover {
        ${ListItemIcon} {
            path: {
                fill: red;
            }
        }

        ${ListItemText} {
            color: red;
        }
    }
`;

【问题讨论】:

    标签: reactjs material-ui


    【解决方案1】:

    请尝试以下示例以更改悬停/活动时的材质 UI ListItem 子项

    const wrapperStyles = {
      parent: {
        backgroundColor: 'yellow',
        '&:hover $child': {
          color: 'red'
        }
    
      },
      child: {
        fontSize: '2em',
        padding: 24
      }
    }
    

    【讨论】:

    • 您能否提供一个更完整的答案,例如如何将这些样式注入到 jsx 中?
    【解决方案2】:

    @Patel Charul 的扩展答案。如果您想在悬停时更改多个子项的样式。

    const wrapperStyles = {
      parent: {
        backgroundColor: 'yellow',
        '&:hover': {
          '& $child1': {
            color: 'red'
          },
          '& $child2': {
            color: 'blue'
          }
      },
      child1: {
        fontSize: '2em',
        padding: 24
      },
      child2: {
        fontSize: '4em',
        padding: 28
      }
    }
    

    【讨论】:

      【解决方案3】:

      这是MUI v5中的一种方法,首先导入以下组件:

      import ListItem, { listItemClasses } from "@mui/material/ListItem";
      import ListItemButton from "@mui/material/ListItemButton";
      import ListItemIcon from "@mui/material/ListItemIcon";
      import ListItemText from "@mui/material/ListItemText";
      

      然后定义你自定义的NavLink,这个NavLink会在匹配当前路由时添加active className:

      function MyNavLink(props) {
        return <NavLink {...props} activeClassName="active" />;
      }
      

      然后在List 组件中,添加以下样式来设置ListItem 处于活动和悬停状态的样式:

      <List
        sx={{
          [`& .active, & .${listItemClasses.root}:hover`]: {
            color: "red",
            fontWeight: "bold",
            "& svg": {
              fill: "red"
            }
          }
        }}
      >
        <ListItem component={MyNavLink} to="/" exact>
          <ListItemButton>
            <ListItemIcon>
              <InboxIcon />
            </ListItemIcon>
            <ListItemText primary="Home" />
          </ListItemButton>
        </ListItem>
        {/* other NavLink component */}
      </List>
      

      现场演示

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-06-27
        • 2018-03-26
        • 2021-01-28
        • 2019-12-14
        • 1970-01-01
        • 1970-01-01
        • 2018-06-02
        • 1970-01-01
        相关资源
        最近更新 更多