The function name and argument were wrong, probably remains of some old version. If you update this code also on the CodePen project, it will print to the console, like intended
2.5 KiB
2.5 KiB
title, tags, firstSeen, lastUpdated
| title | tags | firstSeen | lastUpdated |
|---|---|---|---|
| Tabs | components,state,children,intermediate | 2019-01-27T11:59:52+02:00 | 2020-11-25T20:46:35+02:00 |
Renders a tabbed menu and view component.
- Define a
Tabscomponent that uses theuseState()hook to initialize the value of thebindIndexstate variable todefaultIndex. - Define a
TabItemcomponent and filterchildrenpassed to theTabscomponent to remove unnecessary nodes except forTabItemby identifying the function's name. - Define
changeTab, which will be executed when clicking a<button>from the menu. changeTabexecutes the passed callback,onTabClick, and updatesbindIndexbased on the clicked element.- Use
Array.prototype.map()on the collected nodes to render the menu and view of the tabs, using the value ofbinIndexto determine the active tab and apply the correctclassName.
.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')
);