样式化 Material-UI 带有样式化组件的抽屉组件

Styling Material-UI Drawer component with 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 表明它作为 props 作为 PaperProps 传递,但我仍然找不到覆盖它的方法。

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

if you attempt to style a Drawer with variant permanent, you will likely need to affect the Drawer's underlying paper style. However, this is not the root element of Drawer and therefore styled-components customization as above will not work. You can workaround this by using stable JSS class names, but the most reliable approach is to use the classes property to introduce an override style, and then style it with higher specificity via &.

请同时查看按钮的示例。如果您仍然无法理解,请在此处发表评论,我会尽力提供进一步帮助。

我最近在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;

这其实很简单。您可以传递论文 object 将使用的您自己的组件,让您轻松地赋予自己的样式。

import styled from "styled-components";
const StyledPaper = styled.div`
   // my styles
`;

function MyComponent() {
  return (
    <Drawer
       // normal props
       PaperProps={{ component : StyledPaper }}
    >
      // drawer content
    </Drawer>
  )
}

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

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