当使用水平MUI折叠组件和过渡组转换时,如何使Flexbox与子级一起工作



我正在使用MUI,很难使用Collapse+TransitionGroup组件并使用flex box扩展容器。

<Box sx={{display: 'flex', height: '100vh', width: '100vw'}}>
<Box sx={{flex: 1}}>Content-A</Box>
<Box sx={{flex: 1}}>Content-B</Box>
</Box>

这是我想要的一个简单的例子。两个方框相邻,并将整个页面分为左侧和右侧。然而,当你引入崩溃组件时,它会崩溃:

<TransitionGroup sx={{display: 'flex', height: '100vh', width: '100vw}}>
<Collapse orientation='horizontal'>
<Box sx={{flex: 1}}>Content-A</Box>
</Collapse>
<Collapse orientation='horizontal'>
<Box sx={{flex: 1}}>Content-B</Box>
</Collapse>
</TransitionGroup>

折叠组件现在直接干扰Flexbox父子关系。如果我查看DOM,我会注意到Collapse组件围绕子组件插入了3个包装器(根包装器、外部包装器、内部包装器(。如何将flexbox属性传递给原始子项
我试图覆盖主题中每个包装组件的样式,并给它们display: flex, flex: 1,以迫使它沿着链一直到子组件,但这打破了过渡,看起来非常不稳定。

编辑:澄清:我需要转换组,因为我希望发生特定的转换。基本上我把页面分为左(A(和右(B(。在一个事件中,我希望(A(转换出屏幕(向左,因此是水平的(。(B( 应该转换到(A(所在的位置,并且一个新元素(C(从右边进入并转换到(B(所在的地方。想象一下,它就像一个滑动队列。然后冲洗并重复(B出->C转到B所在的位置->D转换到C所在的位置(。问题是使用"水平折叠"不会调整剩余空间。

我认为cssflex<Collapse />不应该以这种方式使用。<Collapse />本身将设置类似width:0px的css,而display:flex将忽略这些css。

使用CSSTransition

作为替代方案,您可以使用<CSSTransition />组件自己创建和设置转换规则。<Collapse/>内部也会使用此选项。

这些文档应该很有用。

示例

有一个沙箱的例子

const useStyles = makeStyles({
"slide-enter": {
flexGrow: 0,
width: 0,
overflow: "hidden",
whiteSpace: "nowrap",
transition: "all 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms"
},
"slide-active-enter": {
flexGrow: 1,
width: "auto",
overflow: "hidden",
whiteSpace: "nowrap",
transition: "all 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms"
},
"slide-done-enter": {
flexGrow: 1,
width: "auto",
overflow: "hidden",
whiteSpace: "nowrap"
},
"slide-exit": {
flexGrow: 1,
width: "auto",
transition: "all 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms"
},
"slide-active-exit": {
flexGrow: 0,
width: 0,
overflow: "hidden",
whiteSpace: "nowrap",
paddingLeft: 0,
paddingRight: 0,
transition: "all 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms"
},
"slide-done-exit": {
flexGrow: 0,
width: 0,
overflow: "hidden",
whiteSpace: "nowrap",
paddingLeft: 0,
paddingRight: 0
}
});
.......
<TransitionGroup style={{ display: "flex" }}>
{columns.map((_, i) =>
i >= columns.length - 2 ? (
<CSSTransition
key={i}
timeout={300}
classNames={{
appear: classes["slide-enter"],
appearActive: classes["slide-active-enter"],
appearDone: classes["slide-done-enter"],
enter: classes["slide-enter"],
enterActive: classes["slide-active-enter"],
enterDone: classes["slide-done-enter"],
exit: classes["slide-exit"],
exitActive: classes["slide-active-exit"],
exitDone: classes["slide-done-exit"]
}}
>
<ColoredBox>Content-{i}</ColoredBox>
</CSSTransition>
) : null
)}
</TransitionGroup>

旧答案

OP澄清之前的旧答案:
有点不清楚你实际上想要实现什么。

为什么要使用过渡组

通常,<TransistionGroup />用于自动设置<Collapse/>上的in属性。例如,在列表中添加一堆项目时。

如果只想渲染2列,则不需要<TransistionGroup />
您可以手动传递in布尔值。

设计塌陷的样式

您可以将样式传递给collapse包装器,并设置所需的任何css。IE:

<Collapse
in={isOn}
orientation="horizontal"
style={{ flex: "1", display: "inline-block" }}
>

示例

看看这个代码沙盒

它有两个例子:

  • 版本1,只打开/关闭列
  • 版本2,添加列并使用transitiongroup展开它们

我认为版本1才是您真正想要的:

const Example1 = () => {
const [isOn, setIsOn] = React.useState(false);
const toggle = () => {
setIsOn((prev) => !prev);
};
return (
<>
<Button variant="contained" onClick={toggle}>
{isOn ? "collapse" : "expand"}
</Button>
<Box display="flex">
<Collapse
in={isOn}
orientation="horizontal"
style={{ flex: "1", display: "inline-block" }}
>
<Box>Content-A</Box>
</Collapse>
<Collapse
in={isOn}
orientation="horizontal"
style={{ flex: "1", display: "inline-block" }}
>
<Box>Content-B</Box>
</Collapse>
</Box>
</>
);
};

最新更新