【问题标题】:Styling Material-UI Drawer component with Styled Components样式化 Material-UI Drawer 组件与 Styled Components
【发布时间】:2018-09-14 08:11:56
【问题描述】:

我正在尝试将下面 Drawer 组件的样式移植到 Styled Components 中。

    <Drawer
      variant="permanent"
      classes={{
        paper: classes.drawerPaper
      }}
    >

,其中paper 的样式如下:

const styles = theme => ({
  drawerPaper: {
    position: "relative",
    width: 240px
  }
});

我不知道如何通过 Styled Components 自定义 paper 属性。以下样式化组件语法不起作用:

export const StyledDrawer = styled(Drawer)`
    position: "relative";
    width: 240px;
`;

该组件的source-code 表示这是作为PaperProps 的props 传递的,但我仍然找不到覆盖它的方法。

【问题讨论】:

    标签: reactjs material-ui styled-components


    【解决方案1】:

    我最近在https://codesandbox.io/s/material-demo-k9l9h中给出了一个例子

    希望对你有帮助:

    import React, { useState } from "react";
    import Drawer from "@material-ui/core/Drawer";
    import styled from "styled-components";
    
    const drawerWidth = 240;
    
    const styles = theme => ({
      drawer: {
        position: "absolute",
        overflowX: "hidden",
        zIndex: theme.zIndex.drawer + 2,
        [theme.breakpoints.up("sm")]: {
          position: "relative",
          width: drawerWidth,
          flexShrink: 0,
          zIndex: theme.zIndex.drawer
        },
        whiteSpace: "nowrap"
      },
      drawerOpen: {
        width: drawerWidth,
        transition: theme.transitions.create("width", {
          easing: theme.transitions.easing.sharp,
          duration: theme.transitions.duration.enteringScreen
        })
      },
      drawerClose: {
        transition: theme.transitions.create("width", {
          easing: theme.transitions.easing.sharp,
          duration: theme.transitions.duration.leavingScreen
        }),
        overflowX: "hidden",
        width: 0,
        [theme.breakpoints.up("sm")]: {
          width: theme.spacing.unit * 9 + 1
        }
      }
    });
    
    const StyledDrawer = styled(Drawer)`
      ${({ theme, open }) => {
        const classes = styles(theme);
        return {
          ...classes.drawer,
          ...(open ? classes.drawerOpen : classes.drawerClose)
        };
      }}
    
      .MuiDrawer-paper {
        ${({ theme, open }) => {
          const classes = styles(theme);
          return open ? classes.drawerOpen : classes.drawerClose;
        }}
    
        &::-webkit-scrollbar {
          width: 2px;
        }
        &:hover {
          &::-webkit-scrollbar-thumb {
            display: none;
          }
        }
        &::-webkit-scrollbar-thumb {
          display: none;
        }
        &::-webkit-scrollbar-track {
          display: none;
        }
      }
    `;
    
    const PersistentDrawerLeft = () => {
      const [isOpen, setIsOpen] = useState(false);
    
      const handleDrawerOpen = () => {
        setIsOpen(true);
      };
    
      const handleDrawerClose = () => {
        setIsOpen(false);
      };
    
      return (
        <div>
          <StyledDrawer variant="permanent" open={isOpen}>
            <span>sidebar</span>
            <button onClick={handleDrawerClose}>close</button>
          </StyledDrawer>
          <span>Content</span>
          <button onClick={handleDrawerOpen}>open</button>
        </div>
      );
    };
    
    export default PersistentDrawerLeft;
    

    【讨论】:

    • 我们不能只通过样式组件传递&lt;StyledDrawer variant="permanent" classes={{ paper: { width: '200'px } }} 吗?
    【解决方案2】:

    我会在评论中给出我的答案,但由于我没有足够的声誉,我无法发表评论。不管怎样,看看样式化的组件documentation。它说:

    如果您尝试使用永久变体来设置抽屉的样式,您将 可能需要影响抽屉的底层纸张样式。然而, 这不是 Drawer 的根元素,因此不是 styled-components 如上所述的自定义将不起作用。您可以通过使用解决此问题 稳定的 JSS 类名,但最可靠的方法是使用 classes 属性引入覆盖样式,然后对其进行样式设置 通过 & 具有更高的特异性。

    还请查看给出的按钮示例。如果您仍然无法在此处发表评论,我会尽力提供帮助。

    【讨论】:

      【解决方案3】:

      这实际上相当容易。您可以传递纸张对象将使用的您自己的组件,从而让您轻松地传递自己的样式。

      import styled from "styled-components";
      const StyledPaper = styled.div`
         // my styles
      `;
      
      function MyComponent() {
        return (
          <Drawer
             // normal props
             PaperProps={{ component : StyledPaper }}
          >
            // drawer content
          </Drawer>
        )
      }
      

      另一种选择是让抽屉的第一个孩子也赋予样式。由于纸上有display: flex,您只需将flex: 1 放在您的孩子身上,它就会长到纸的全尺寸。

      function MyComponent() {
        return (
          <Drawer
             // normal props
          >
            <StyledDiv>
              My Content
            </StyledDiv>
          </Drawer>
        )
      }
      

      【讨论】:

      • 这是一个很好的解决方案,谢谢分享!
      猜你喜欢
      • 2020-11-16
      • 2020-06-28
      • 2019-06-27
      • 2019-08-02
      • 2020-05-06
      • 2020-01-16
      • 2020-03-01
      • 2023-03-26
      • 1970-01-01
      相关资源
      最近更新 更多