Tabs
Navigate between different sections of content.
- Documentation
- React Aria
- Pattern
- W3C ARIA
- Source
- GitHub
- Issues
- Report
Profile
Settings
Your profile information.
Tabs example
import { GearSix, User } from "@phosphor-icons/react/dist/ssr";
import { Tab, TabList, TabPanel, Tabs } from "@/shim-ui/tabs";
export default () => (
<Tabs>
<TabList>
<Tab id="profile">
<User size={16} weight="duotone" />
Profile
</Tab>
<Tab id="settings">
<GearSix size={16} weight="duotone" />
Settings
</Tab>
</TabList>
<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 tabs
Variant example
import { Tab, TabList, Tabs } from "@/shim-ui/tabs";
export default () => (
<>
<Tabs>
<TabList variant="soft">
<Tab id="profile">Profile</Tab>
<Tab id="settings">Settings</Tab>
</TabList>
</Tabs>
<Tabs>
<TabList variant="underline">
<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.
Profile
Settings
Profile
Settings
Profile
Settings
Profile
Settings
Size example
import { Tab, TabList, Tabs } from "@/shim-ui/tabs";
export default () => (
<>
<Tabs>
<TabList size={1}>
<Tab id="profile">Profile</Tab>
<Tab id="settings">Settings</Tab>
</TabList>
</Tabs>
<Tabs>
<TabList size={2}>
<Tab id="profile">Profile</Tab>
<Tab id="settings">Settings</Tab>
</TabList>
</Tabs>
<Tabs>
<TabList size={3}>
<Tab id="profile">Profile</Tab>
<Tab id="settings">Settings</Tab>
</TabList>
</Tabs>
<Tabs>
<TabList size={4}>
<Tab id="profile">Profile</Tab>
<Tab id="settings">Settings</Tab>
</TabList>
</Tabs>
</>
);
Orientation
Switch between horizontal and vertical layouts via theorientation
prop.
Profile
Settings
Your profile.
Orientation example
import { GearSixIcon, 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]">
<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="profile">
Your profile.
</TabPanel>
<TabPanel className="px-4 py-2" id="settings">
Your settings.
</TabPanel>
</Tabs>
);
Controlled
Manage tab selection with selectedKey
andonSelectionChange
.
Selected tab: favorites
Recent
Favorites
Controlled example
"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.
Dynamic content example
"use client";
import { GearSix, User, XSquare } 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: User,
content: "Your profile information.",
disabled: false,
},
{
id: "settings",
label: "Settings",
icon: GearSix,
content: "Change your settings here.",
disabled: false,
},
{
id: "disabled",
label: "Disabled",
icon: XSquare,
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>
);
};