Tabs
Navigate between different sections of content.
- Documentation
- React Aria
- Pattern
- W3C ARIA
- Source
- GitHub
- Issues
- Report
- Install
pnpm dlx @kkga/shim add tabs
Home
Profile
Settings
Welcome to the home tab!
import {
GearSixIcon,
HouseIcon,
UserIcon,
} from "@phosphor-icons/react/dist/ssr";
import { Tab, TabList, TabPanel, Tabs } from "@/shim-ui/tabs";
export default () => (
<Tabs>
<TabList>
<Tab id="home">
<HouseIcon size={16} weight="duotone" />
Home
</Tab>
<Tab id="profile">
<UserIcon size={16} weight="duotone" />
Profile
</Tab>
<Tab id="settings">
<GearSixIcon size={16} weight="duotone" />
Settings
</Tab>
</TabList>
<TabPanel className="py-4" id="home">
Welcome to the home tab!
</TabPanel>
<TabPanel className="py-4" id="profile">
Your profile information.
</TabPanel>
<TabPanel className="py-4" id="settings">
Change your settings.
</TabPanel>
</Tabs>
);Install
Use the CLI or copy the source code manually.
Command
Source code
pnpm dlx @kkga/shim add tabsVariant
Set the variant prop on <TabList> to adjust tab styling.
Home
Profile
Settings
Home
Profile
Settings
import { Tab, TabList, Tabs } from "@/shim-ui/tabs";
export default () => (
<>
<Tabs>
<TabList variant="soft">
<Tab id="home">Home</Tab>
<Tab id="profile">Profile</Tab>
<Tab id="settings">Settings</Tab>
</TabList>
</Tabs>
<Tabs>
<TabList variant="underline">
<Tab id="home">Home</Tab>
<Tab id="profile">Profile</Tab>
<Tab id="settings">Settings</Tab>
</TabList>
</Tabs>
</>
);Size
Use the size prop on <TabList> to control tab spacing and typography.
Home
Profile
Settings
Home
Profile
Settings
Home
Profile
Settings
Home
Profile
Settings
import { Tab, TabList, Tabs } from "@/shim-ui/tabs";
export default () =>
([1, 2, 3, 4] as const).map((size) => (
<Tabs key={size}>
<TabList size={size} variant="soft">
<Tab id="home">Home</Tab>
<Tab id="profile">Profile</Tab>
<Tab id="settings">Settings</Tab>
</TabList>
</Tabs>
));Orientation
Switch between horizontal and vertical layouts via the orientation prop.
Home
Profile
Settings
Welcome to the home tab!
import {
GearSixIcon,
HouseIcon,
UserIcon,
} from "@phosphor-icons/react/dist/ssr";
import { Tab, TabList, TabPanel, Tabs } from "@/shim-ui/tabs";
export default () => (
<Tabs orientation="vertical">
<TabList className="w-[120px]" variant="underline">
<Tab id="home">
<HouseIcon size={16} weight="duotone" />
Home
</Tab>
<Tab id="profile">
<UserIcon size={16} weight="duotone" />
Profile
</Tab>
<Tab id="settings">
<GearSixIcon size={16} weight="duotone" />
Settings
</Tab>
</TabList>
<TabPanel className="px-4 py-2" id="home">
Welcome to the home tab!
</TabPanel>
<TabPanel className="px-4 py-2" id="profile">
Your profile.
</TabPanel>
<TabPanel className="px-4 py-2" id="settings">
Your settings.
</TabPanel>
</Tabs>
);Controlled
Manage tab selection with selectedKey and onSelectionChange.
Selected tab: favorites
Recent
Favorites
"use client";
import { useState } from "react";
import type { Key } from "react-aria-components";
import { Tab, TabList, Tabs } from "@/shim-ui/tabs";
export default () => {
const [tabId, setTabId] = useState<Key>("favorites");
return (
<>
<p>Selected tab: {tabId}</p>
<Tabs onSelectionChange={setTabId} selectedKey={tabId}>
<TabList>
<Tab id="recent">Recent</Tab>
<Tab id="favorites">Favorites</Tab>
</TabList>
</Tabs>
</>
);
};Dynamic content
Render tabs from dynamic data by passing an items iterable and a render function as children.
Your profile information.
"use client";
import { GearSixIcon, UserIcon, XSquareIcon } from "@phosphor-icons/react";
import { useState } from "react";
import { Collection, type Key } from "react-aria-components";
import { Tab, TabList, TabPanel, Tabs } from "@/shim-ui/tabs";
export default () => {
const [tabId, setTabId] = useState<Key>("profile");
const items = [
{
id: "profile",
label: "Profile",
icon: UserIcon,
content: "Your profile information.",
disabled: false,
},
{
id: "settings",
label: "Settings",
icon: GearSixIcon,
content: "Change your settings here.",
disabled: false,
},
{
id: "disabled",
label: "Disabled",
icon: XSquareIcon,
content: "You can't see this.",
disabled: true,
},
];
return (
<Tabs
disabledKeys={items
.filter((item) => item.disabled)
.map((item) => item.id)}
onSelectionChange={setTabId}
selectedKey={tabId}
>
<TabList items={items}>
{({ id, icon: Icon, label }) => (
<Tab aria-label={label} id={id}>
<Icon size={16} weight="duotone" />
</Tab>
)}
</TabList>
<Collection items={items}>
{({ content }) => <TabPanel className="py-4">{content}</TabPanel>}
</Collection>
</Tabs>
);
};