样式化 Material-UI Drawer 组件与 Styled Components

Posted

技术标签:

【中文标题】样式化 Material-UI Drawer 组件与 Styled Components【英文标题】:Styling Material-UI Drawer component with 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 传递的,但我仍然找不到覆盖它的方法。

【问题讨论】:

【参考方案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>
  )

【讨论】:

这是一个很好的解决方案,谢谢分享!

以上是关于样式化 Material-UI Drawer 组件与 Styled Components的主要内容,如果未能解决你的问题,请参考以下文章

在样式化组件中使用 Material-ui 主题

如何在样式化组件中访问 Material-ui 的主题

Material-UI Drawer 组件的单独触发器

使用 React.js 和 Material-UI 简化样式化的组件媒体查询

如何使用 react-testing-library 测试包装在 withStyles 中的样式化 Material-UI 组件?

在样式化组件中设置 React 组件道具