如何使用样式组件覆盖 ExpansionPanelSummary 深层元素?
Posted
技术标签:
【中文标题】如何使用样式组件覆盖 ExpansionPanelSummary 深层元素?【英文标题】:How can I override ExpansionPanelSummary deep elements with styled-components? 【发布时间】:2019-08-20 22:48:27 【问题描述】:使用the docs/examples 来覆盖带有样式组件的Material UI 样式,我设法在ExpansionPanel
和ExpansionPanelDetails
中设置了根和“更深层元素”的样式。
但是,当我使用相同的技术从传递给 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(类名缩写):
<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>
【问题讨论】:
【参考方案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";
【讨论】:
该死的,它有效。我的下一步是开始在源头中四处寻找……但那是星期五下午 5 点。感谢您为我做侦探工作! 我使用的是TypeScript,所以我发现我需要做(MyCustomSummary as any).muiName = "ExpansionPanelSummary";
,因为来自withSyles(...styles)(ExpansionPanelSummary)
的类型似乎不包括muiName
,但在那之后它就可以工作了!以上是关于如何使用样式组件覆盖 ExpansionPanelSummary 深层元素?的主要内容,如果未能解决你的问题,请参考以下文章
如何在scoped不污染组件样式的前提下,实现el-input组件样式覆盖?