<div id="root"></div>
.tab-control-wrap {
display: flex;
flex: 0 0 auto;
.tab-control {
width: 100%;
background: transparent;
padding: 8px;
font-size: 20px;
border: none;
&[aria-selected=true]{
background: #333;
color: #fff;
}
}
}
.tab-panel-wrap {
background: #eee;
.tab-panel {
padding: 50px;
font-size: 50px;
text-align: center;
}
}
View Compiled
import * as React from "https://cdn.skypack.dev/react@17.0.1";
import * as ReactDOM from "https://cdn.skypack.dev/react-dom@17.0.1";
const tabControlArray = [
'Tab Control1',
'Tab Control2',
'Tab Control3'
]
const TabWrap = ({id, active, children}) => {
const {cloneElement} = React;
const tabChildren = children.map( (el, index) => {
return cloneElement(el, {
key: `tab-default0${index+1}`,
id,
active
})
})
return (
<div className="tab-wrap">
{tabChildren}
</div>
)
}
const TabControlWrap = ({id, active, onClick, data}) => {
return (
<div className="tab-control-wrap">
{
data.map( (controlEl, index) => {
return (
<TabControl
key={`tab-control0${index}`}
id={`${id}-control-0${index+1}`}
ariaControls={`${id}-panel-0${index+1}`}
activeStatus={active === index}
tabControl={controlEl}
onClick={() => onClick(index)}/>
)
})
}
</div>
)
}
const TabControl = ({id, ariaControls, activeStatus, tabControl, onClick}) => {
return (
<button
type="button"
id={id}
role="tab"
aria-selected={activeStatus}
aria-controls={ariaControls}
className="tab-control"
onClick={onClick}>
{tabControl}
</button>
)
}
const TabPanelWrap = ({id, active, children}) => {
const {cloneElement} = React;
const panel = children.map( (el, index) => {
return cloneElement(el, {
key: index,
id: `${id}-panel-0${index+1}`,
label: `${id}-control-0${index+1}`,
activeStatus: active === index,
})
})
return (
<div className="tab-panel-wrap">
{panel}
</div>
)
}
const TabPanel = ({id, label, activeStatus, children}) => {
return (
<div className="tab-panel"
role="tabpanel"
id={id}
aria-labelledby={label}
hidden={!activeStatus}>
{children}
</div>
)
}
const App = () => {
const {useState, useCallback} = React;
const [activeIndex, setActiveIndex] = useState(0);
const onClickTabControl = useCallback((changeIndex) => {
setActiveIndex(changeIndex);
}, [activeIndex]);
return (
<div>
<TabWrap id="tab-default" active={activeIndex}>
<TabControlWrap data={tabControlArray} onClick={onClickTabControl} />
<TabPanelWrap>
<TabPanel>
tab Panel 1 content
</TabPanel>
<TabPanel>
tab Panel 2 content
</TabPanel>
<TabPanel>
tab Panel 3 content
</TabPanel>
</TabPanelWrap>
</TabWrap>
</div>
)
};
ReactDOM.render(<App />, document.getElementById("root"));
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.