This is my old implementation of the Tabs component in Ant Design.
const tabList = [
{
key: "tab1",
label: "Tab1",
children: <Tab1 />,
},
{
key: "tab2",
label: "Tab2",
children: <Tab2 />,
},
];
<Tabs onChange={onTabChange} activeKey={selectedTab}>
{tabList.map((tab) => {
const { key, label, children } = tab;
return (
<Tabs.TabPane
key={key}
tab={label}
style={{ margin: "1.5rem auto 1.5rem" }}
>
{children}
</Tabs.TabPane>
);
})}
</Tabs>;
In the new version ( > 4.23.0 ) the boilerplate got reduced.
I can simply pass my tabList to my Tabs as a prop items
.
The new code looks something like this.
<Tabs items={tabList} />
But I had an issue with styling.
I am adding top and bottom margins to all of my TabPane components.
To get that margin in the new implementation. I had to do something like this.
{
key: "tab1",
label: "Tab1",
children: <Tab1 style={{margin: "1.5rem 0 1.5rem"}} />,
},
Here I am facing two issues.
function Tab1(props) {
return <div {...props}>JSX for original Tab1</div>;
}
Is there a better way to do this?
Use a higher Order component like <TabPaneWrapper>
or <TabChildrenWrapper>
. This component does nothing but to wrap your children (<TabPane>
) with a div and give the styles you require.
Component:
export function TabPaneWrapper({
children,
...props
}){
return (
<div style={{ margin: "1.5rem auto 1.5rem" }} {...props}>
{children}
</div>
);
}
Usage:
const tabList = [
{
key: "tab1",
label: "Tab1",
children: <TabPaneWrapper> <Tab1 /> </TabPaneWrapper>,
},
{
key: "tab2",
label: "Tab2",
children: <TabPaneWrapper> <Tab2 /> </TabPaneWrapper>,
},
];
If you have more tabs or use this tabs component in multiple places. You will find TabPaneWrapper to be repetitive. In such case,
<CustomTabs/>
which takes the tabList mentioned in the question.<TabPaneWrapper/>
. You can loop this list inside the <CustomTabs/>
component to generate the tabList mentioned above and then pass it to the Ant Desing <Tabs/>
component.