Tabs
component. Use the useState()
hook to initialize the value of the bindIndex
state variable to defaultIndex
.TabItem
component and filter children
passed to the Tabs
component to remove unnecessary nodes except for TabItem
by identifying the function's name.changeTab
, which will be executed when clicking a <button>
from the menu.changeTab
executes the passed callback, onTabClick
, and updates bindIndex
based on the clicked element.Array.prototype.map()
on the collected nodes to render the menu and view of the tabs.bindIndex
to determine the active tab and apply the correct className
..tab-menu > button {
cursor: pointer;
padding: 8px 16px;
border: 0;
border-bottom: 2px solid transparent;
background: none;
}
.tab-menu > button.focus {
border-bottom: 2px solid #007bef;
}
.tab-menu > button:hover {
border-bottom: 2px solid #007bef;
}
.tab-content {
display: none;
}
.tab-content.selected {
display: block;
}
const TabItem = props => <div {...props} />;
const Tabs = ({ defaultIndex = 0, onTabClick, children }) => {
const [bindIndex, setBindIndex] = React.useState(defaultIndex);
const changeTab = newIndex => {
if (typeof onTabClick === 'function') onTabClick(newIndex);
setBindIndex(newIndex);
};
const items = children.filter(item => item.type.name === 'TabItem');
return (
<div className="wrapper">
<div className="tab-menu">
{items.map(({ props: { index, label } }) => (
<button
key={`tab-btn-${index}`}
onClick={() => changeTab(index)}
className={bindIndex === index ? 'focus' : ''}
>
{label}
</button>
))}
</div>
<div className="tab-view">
{items.map(({ props }) => (
<div
{...props}
className={`tab-content ${
bindIndex === props.index ? 'selected' : ''
}`}
key={`tab-content-${props.index}`}
/>
))}
</div>
</div>
);
};
ReactDOM.render( <Tabs defaultIndex="1" onTabClick={console.log}> <TabItem label="A" index="1"> Lorem ipsum </TabItem> <TabItem label="B" index="2"> Dolor sit amet </TabItem> </Tabs>, document.getElementById('root') );
Subscribe to get resources directly to your inbox. You won't receive any spam! ✌️