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

How can I override ExpansionPanelSummary deep elements with styled-components?

使用 the docs/examples 覆盖 Material UI 带有样式组件的样式,我设法在 ExpansionPanel 中设置了根和 "deeper elements" 的样式和 ExpansionPanelDetails.

但是,当我使用相同的技术 return 从传递给 styled() 的函数重写 ExpansionPanelSummary 时,ExpansionPanelSummary 在 DOM 并且整个 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(class 姓名缩写):

<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>

当我将上述技术应用到ExpansionPanelSummary时的DOM:

<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>

这个困难与使用样式组件无关,只与在另一个组件中包装 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 有一种直接的方式告诉它您的自定义组件应该与特定的 Material-UI 组件一样对待,通过muiName 属性:

MyCustomSummary.muiName = "ExpansionPanelSummary";

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

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

ExpansionPanelSummary.muiName = "ExpansionPanelSummary";