定制手风琴的设计
Design of a custom accordion
我正在尝试用这些连接 parent 和 children 的精美红线设计一个自定义手风琴(见图)。
我在这里使用 Grommet 组件,但总而言之,布局只是一堆 divs(Box 标签)和一个用于 children(Collapsible 标签)的可折叠面板组件. Children 面板可以打开并显示更多内容。
经过几次尝试,我连接 parent 和 children 的方法是用 left-border 包裹外框,然后使用它上面的一个白框(第二个示例代码的 Stack 标签)。连接卡片和 left-border 的水平线只是样式 div 放置在 Child 选项卡旁边(在 SubMenuElement 组件内)。
我认为这是一个相当复杂的解决方案(也是因为我需要使白框响应)但我想不出更简单的解决方案。
您对我如何改进或 re-do 红色连接有什么建议吗?
先谢谢您的帮助!
请注意,我知道所有面板在点击时都使用相同的变量
<MenuButton
open={openMenu}
label="PARENT TAB-XYZ"
onClick={() => {
const newOpenMenu = !openMenu;
setOpenMenu(newOpenMenu);
setOpenSubmenu1(!newOpenMenu ? false : openSubmenu1);
}}
/>
<Collapsible open={openMenu}>
<Box background="antiquewhite" margin={{ left: 'small' }} border={{ side: 'left', size: '2px', color: 'red' }}>
{Tabs.map(el => {
return (
<SubMenuElement
key={el.title}
open={openSubmenu1}
label={el.title}
onClick={() => setOpenSubmenu1(!openSubmenu1)}
/>
);
})}
</Box>
</Collapsible>
<MenuButton
open={openMenu}
label="PARENT TAB-POU"
onClick={() => {
const newOpenMenu = !openMenu;
setOpenMenu(newOpenMenu);
setOpenSubmenu1(!newOpenMenu ? false : openSubmenu1);
}}
/>
<Collapsible open={openMenu}>
<Stack anchor="bottom-left">
<Box
background="antiquewhite"
margin={{ left: 'small' }}
border={{ side: 'left', size: '2px', color: 'red' }}
>
{Tabs.map(el => {
return (
<SubMenuElement
key={el.title}
open={openSubmenu1}
label={el.title}
onClick={() => setOpenSubmenu1(!openSubmenu1)}
/>
);
})}
</Box>
<Box background="white" height="39px" width="35px"></Box>
</Stack>
</Collapsible>
</Box>
);
基于, I can propose you something like that: repro on Stackblitz
您会在第一个 link 上找到原始分频器代码。根据您的需要,我对其进行了一些修改,因此只需在内容左侧添加 link 即可。内容包装器上仍然有一个左边框,这对我来说似乎是最简单的解决方案。
您的主文件:
import React, { Component } from "react";
import { render } from "react-dom";
import Divider from "./divider";
import "./style.css";
const App = () => {
const toggleAccordion = e => {
e.target.classList.toggle("hidden");
};
return (
<>
<div className="accordion hidden" onClick={toggleAccordion}>
accordion header
<div className="accordion-content-wrapper">
<Divider>
<div>Content</div>
</Divider>
<Divider>
<div>Content</div>
</Divider>
<Divider>
<div>Content</div>
</Divider>
</div>
</div>
</>
);
};
render(<App />, document.getElementById("root"));
我的手风琴css(我猜你的组件已经有这个功能,我只是做了一个最小的复制):
.accordion.hidden {
height: 18px;
overflow: hidden;
}
.accordion-content-wrapper{
margin-left: 10px;
border-left: 1px solid black;
}
对于分隔符,与我原来的答案没有太大变化,这里是代码:
import React from 'react';
const Divider = ({ children }) => {
return (
<div className="divider-component">
<div className="container">
<div className="border" />
<span className="content">{children}</span>
</div>
</div>
);
};
export default Divider;
css:
.divider-component .container{
display: flex;
align-items: center;
}
.divider-component .border{
border-bottom: 1px solid black;
width: 15px;
}
.divider-component .content {
width: 100%;
}
即使您必须对其进行编辑以满足您的需要,我们的想法是添加一个 flex 容器,以便您可以在内容左侧添加小 link,与您的内容正确对齐.
对于遇到相同问题的人,我最终在 div 中使用了两个 50% 高度的 flexboxes 来替换水平线。这允许自动管理响应式调整大小,同时在最后一个项目边框上提供灵活性。
const SubMenuElement = ({ last, label, open, onClick }: { last?: boolean; label: string; open: any; onClick: any }) => {
return (
<Box direction="row">
<Line last={last} />
<Box width="100%" margin={{ vertical: 'small' }}>
<Card background="white" onClick={onClick}>
....
</Card>
</Box>
</Box>
);
};
线在哪里
const Line = ({ last }: { last?: boolean }) => (
<Box direction="column" width="20px" flex="grow">
<Box height="50%" style={{ borderLeft: '1px solid red', borderBottom: '1px solid red' }} />
<Box height="50%" style={last ? {} : { borderLeft: '1px solid red' }} />
</Box>
);
我正在尝试用这些连接 parent 和 children 的精美红线设计一个自定义手风琴(见图)。
我在这里使用 Grommet 组件,但总而言之,布局只是一堆 divs(Box 标签)和一个用于 children(Collapsible 标签)的可折叠面板组件. Children 面板可以打开并显示更多内容。
经过几次尝试,我连接 parent 和 children 的方法是用 left-border 包裹外框,然后使用它上面的一个白框(第二个示例代码的 Stack 标签)。连接卡片和 left-border 的水平线只是样式 div 放置在 Child 选项卡旁边(在 SubMenuElement 组件内)。
我认为这是一个相当复杂的解决方案(也是因为我需要使白框响应)但我想不出更简单的解决方案。 您对我如何改进或 re-do 红色连接有什么建议吗? 先谢谢您的帮助! 请注意,我知道所有面板在点击时都使用相同的变量
<MenuButton
open={openMenu}
label="PARENT TAB-XYZ"
onClick={() => {
const newOpenMenu = !openMenu;
setOpenMenu(newOpenMenu);
setOpenSubmenu1(!newOpenMenu ? false : openSubmenu1);
}}
/>
<Collapsible open={openMenu}>
<Box background="antiquewhite" margin={{ left: 'small' }} border={{ side: 'left', size: '2px', color: 'red' }}>
{Tabs.map(el => {
return (
<SubMenuElement
key={el.title}
open={openSubmenu1}
label={el.title}
onClick={() => setOpenSubmenu1(!openSubmenu1)}
/>
);
})}
</Box>
</Collapsible>
<MenuButton
open={openMenu}
label="PARENT TAB-POU"
onClick={() => {
const newOpenMenu = !openMenu;
setOpenMenu(newOpenMenu);
setOpenSubmenu1(!newOpenMenu ? false : openSubmenu1);
}}
/>
<Collapsible open={openMenu}>
<Stack anchor="bottom-left">
<Box
background="antiquewhite"
margin={{ left: 'small' }}
border={{ side: 'left', size: '2px', color: 'red' }}
>
{Tabs.map(el => {
return (
<SubMenuElement
key={el.title}
open={openSubmenu1}
label={el.title}
onClick={() => setOpenSubmenu1(!openSubmenu1)}
/>
);
})}
</Box>
<Box background="white" height="39px" width="35px"></Box>
</Stack>
</Collapsible>
</Box>
);
基于
您会在第一个 link 上找到原始分频器代码。根据您的需要,我对其进行了一些修改,因此只需在内容左侧添加 link 即可。内容包装器上仍然有一个左边框,这对我来说似乎是最简单的解决方案。
您的主文件:
import React, { Component } from "react";
import { render } from "react-dom";
import Divider from "./divider";
import "./style.css";
const App = () => {
const toggleAccordion = e => {
e.target.classList.toggle("hidden");
};
return (
<>
<div className="accordion hidden" onClick={toggleAccordion}>
accordion header
<div className="accordion-content-wrapper">
<Divider>
<div>Content</div>
</Divider>
<Divider>
<div>Content</div>
</Divider>
<Divider>
<div>Content</div>
</Divider>
</div>
</div>
</>
);
};
render(<App />, document.getElementById("root"));
我的手风琴css(我猜你的组件已经有这个功能,我只是做了一个最小的复制):
.accordion.hidden {
height: 18px;
overflow: hidden;
}
.accordion-content-wrapper{
margin-left: 10px;
border-left: 1px solid black;
}
对于分隔符,与我原来的答案没有太大变化,这里是代码:
import React from 'react';
const Divider = ({ children }) => {
return (
<div className="divider-component">
<div className="container">
<div className="border" />
<span className="content">{children}</span>
</div>
</div>
);
};
export default Divider;
css:
.divider-component .container{
display: flex;
align-items: center;
}
.divider-component .border{
border-bottom: 1px solid black;
width: 15px;
}
.divider-component .content {
width: 100%;
}
即使您必须对其进行编辑以满足您的需要,我们的想法是添加一个 flex 容器,以便您可以在内容左侧添加小 link,与您的内容正确对齐.
对于遇到相同问题的人,我最终在 div 中使用了两个 50% 高度的 flexboxes 来替换水平线。这允许自动管理响应式调整大小,同时在最后一个项目边框上提供灵活性。
const SubMenuElement = ({ last, label, open, onClick }: { last?: boolean; label: string; open: any; onClick: any }) => {
return (
<Box direction="row">
<Line last={last} />
<Box width="100%" margin={{ vertical: 'small' }}>
<Card background="white" onClick={onClick}>
....
</Card>
</Box>
</Box>
);
};
线在哪里
const Line = ({ last }: { last?: boolean }) => (
<Box direction="column" width="20px" flex="grow">
<Box height="50%" style={{ borderLeft: '1px solid red', borderBottom: '1px solid red' }} />
<Box height="50%" style={last ? {} : { borderLeft: '1px solid red' }} />
</Box>
);