Skip to content

Tabs

Multipart component providing a way of navigating between multiple panels and their contents.

Tabs is based on the Chakra UI Component Tabs. It is a multipart component that consists of:

  • Tabs: Provides tab context and state for all tab-related components within
  • TabList: Wrapper for the Tab components
  • Tab: Clickable label which will trigger the display of the corresponding tab panel (matched by value)
  • TabPanels: Wrapper for the TabPanel components
  • TabPanel: Element that contains the content associated with a tab

You can render any element within <Tabs>, but it expects <TabList> and <TabPanels> as children. Order doesn’t matter, you can have <TabList> at the top, at the bottom, or both.

<TabList> should only have <Tab> as children. And <TabPanels> should have <TabPanel> as children.

import { Tab, TabList, TabPanel, TabPanels, Tabs, Text } from "@caspeco/casper-ui-library";
export default function Demo() {
return (
<Tabs defaultValue="one" onValueChange={(value) => console.log("New selected tab value is: ", value)}>
<TabList>
<Tab value="one">One</Tab>
<Tab value="two">Two</Tab>
<Tab value="three">Three</Tab>
</TabList>
<TabPanels>
<TabPanel value="one">
<Text>Content for tab one</Text>
</TabPanel>
<TabPanel value="two">
<Text>Content for tab two</Text>
</TabPanel>
<TabPanel value="three">
<Text>Content for tab three</Text>
</TabPanel>
</TabPanels>
</Tabs>
);
}
import { Tab, TabList, TabPanel, TabPanels, Tabs, Text } from "@caspeco/casper-ui-library";
export default function Demo() {
return (
<Tabs
variant="line"
defaultValue="one"
onValueChange={(value) => console.log("New selected tab value is: ", value)}
>
<TabList>
<Tab value="one">One</Tab>
<Tab value="two">Two</Tab>
<Tab value="three">Three</Tab>
</TabList>
<TabPanels>
<TabPanel value="one">
<Text>Content for tab one</Text>
</TabPanel>
<TabPanel value="two">
<Text>Content for tab two</Text>
</TabPanel>
<TabPanel value="three">
<Text>Content for tab three</Text>
</TabPanel>
</TabPanels>
</Tabs>
);
}
import { Tab, TabList, TabPanel, TabPanels, Tabs } from "@caspeco/casper-ui-library";
export default function Demo() {
const tabData = [
{
value: "one",
label: "One",
content: "Content for tab one",
},
{
value: "two",
label: "Two",
content: "Content for tab two",
},
];
return (
<Tabs
defaultValue={tabData[0].value}
onValueChange={({ value }) =>
console.log(
"New selected tab is: ",
tabData.find((t) => t.value === value),
)
}
>
<TabList>
{tabData.map((tab) => (
<Tab key={tab.value} value={tab.value}>
{tab.label}
</Tab>
))}
</TabList>
<TabPanels>
{tabData.map((tab) => (
<TabPanel key={tab.value} value={tab.value}>
{tab.content}
</TabPanel>
))}
</TabPanels>
</Tabs>
);
}

By default, the Tabs component renders all tabs content to the DOM, meaning that invisible tabs are still rendered but are hidden by styles.

If you want to defer rendering of each tab until that tab is selected, you can use the isLazy prop. This is useful if your tabs require heavy performance, or make network calls on mount that should only happen when the component is displayed.

<Tabs isLazy defaultValue="one">
<TabList>
<Tab value="one">One</Tab>
<Tab value="two">Two</Tab>
</TabList>
<TabPanels>
{/* initially mounted */}
<TabPanel value="one">
<Text>Content for tab one</Text>
</TabPanel>
{/* initially not mounted */}
<TabPanel value="two">
<Text>Content for tab two</Text>
</TabPanel>
</TabPanels>
</Tabs>

A tab can be shown with an image above the label text. Provide the image src with the imgSrc-property and the alt text for the image with imgAlt (required).

import { Tab, TabList, TabPanel, TabPanels, Tabs, Text } from "@caspeco/casper-ui-library";
export default function Demo() {
return (
<Tabs defaultValue="dev">
<TabList>
<Tab
value="dev"
imgAlt="Caspeco Logo (Dev)"
imgSrc="https://cdn4.caspeco.se/sso/favicon/development/icon.svg"
>
Dev
</Tab>
<Tab
value="stage"
imgAlt="Caspeco Logo (Stage)"
imgSrc="https://cdn4.caspeco.se/sso/favicon/staging/icon.svg"
>
Stage
</Tab>
<Tab
value="prod"
imgAlt="Caspeco Logo (Prod)"
imgSrc="https://cdn4.caspeco.se/sso/favicon/production/icon.svg"
>
Prod
</Tab>
</TabList>
<TabPanels>
<TabPanel value="dev">
<Text>Dev content</Text>
</TabPanel>
<TabPanel value="stage">
<Text>Stage content</Text>
</TabPanel>
<TabPanel value="prod">
<Text>Prod content</Text>
</TabPanel>
</TabPanels>
</Tabs>
);
}