如何使用样式组件覆盖 ExpansionPanelSummary 深层元素?

IT技术 javascript css reactjs material-ui styled-components
2021-03-24 06:48:10

使用的文档/例子的覆盖材料UI造型与风格的成分,我已经成功地风格内的根源,“更深层次的元素”ExpansionPanelExpansionPanelDetails

但是,当我使用相同的技术ExpansionPanelSummary从传递给 的函数返回重写时,DOM 中styled()ExpansionPanelSummary移动和整体ExpansionPanel不再正确呈现。

有问题的技术,适用于ExpansionPanel(这在容器上按预期工作ExpansionPanel):

import MUIExpansionPanel from '@material-ui/core/ExpansionPanel';

export const ExpansionPanel = styled(props => (
  <MUIExpansionPanel
    classes={{expanded: 'expanded'}}
    {...props}
  />
))`
  && {
    ...root style overrides
  }
  &&.expanded {
    ...expanded style overrides
  }
`;

ExpansionPanel和朋友的典型 DOM(类名缩写)

<div class="MuiExpansionPanel...">
  <div class="MuiExpansionPanelSummary..." />
  <div class="MuiCollapse-container...>
    <div class="MuiCollapse-wrapper...>
      <div class="MuiCollapse-wrapperInner...>
        <div class="MuiExpansionPanelDetails..." />
      </div>
    </div>
  </div>
</div>

当我将上述技术应用于 DOM 时ExpansionPanelSummary

<div class="MuiExpansionPanel...">
  <div class="MuiCollapse-container...>
    <div class="MuiCollapse-wrapper...>
      <div class="MuiCollapse-wrapperInner...>
        <div class="MuiExpansionPanelSummary..." />
        <div class="MuiExpansionPanelDetails..." />
      </div>
    </div>
  </div>
</div>

为了完整起见,这是我正在做的事情的最小再现ExpansionPanelSummary,它触发了 DOM 切换:

export const ExpansionPanelSummary = styled(props => (
  <MUIExpansionPanelSummary
    {...props}
  />
))``;

我的 JSX 是标准ExpansionPanel设置:

<ExpansionPanel>
  <ExpansionPanelSummary>
    Summary Label
  </ExpansionPanelSummary>
  <ExpansionPanelDetails>
    <div>Some Content</div>
  </ExpansionPanelDetails>
</ExpansionPanel>
1个回答

这个困难与使用样式组件无关,只与包装ExpansionPanelSummary在另一个组件中有关。

您可以使用以下包装类似地重现这一点ExpansionPanelSummary

const MyCustomSummary = props => {
  return (
    <ExpansionPanelSummary {...props} expandIcon={<ExpandMoreIcon />}>
      <Typography>{props.text}</Typography>
    </ExpansionPanelSummary>
  );
};

有几个像这样的组件组,其中 Material-UI 父组件查找特定类型的子组件并特别对待该子组件。例如,您可以在以下代码块中找到ExpansionPanel

      if (isMuiElement(child, ['ExpansionPanelSummary'])) {
        summary = React.cloneElement(child, {
          disabled,
          expanded,
          onChange: this.handleChange,
        });
        return null;
      }

幸运的是,Material-UI 有一个简单的方法告诉它你的自定义组件应该通过muiName属性被视为一个特定的 Material-UI 组件

MyCustomSummary.muiName = "ExpansionPanelSummary";

或者在您的情况下,它看起来像:

export const ExpansionPanelSummary = styled(props => (
  <MUIExpansionPanelSummary
    {...props}
  />
))``;

ExpansionPanelSummary.muiName = "ExpansionPanelSummary";

编辑自定义 ExpansionPanelSummary

我正在使用 TypeScript,所以我发现我需要这样做,(MyCustomSummary as any).muiName = "ExpansionPanelSummary";因为出来的类型withSyles(...styles)(ExpansionPanelSummary)似乎不包含muiName,但在那之后它可以工作!
2021-05-31 06:48:10
该死的,它有效。我的下一步是开始在源代码中四处寻找……但那是周五下午 5 点。谢谢你为我做侦探工作!
2021-06-20 06:48:10