Tabs
An accessible tabbed interface with default and line variants, disabled tabs, and keyboard navigation.
Installation
bunx shadcn@latest add https://ui.razeev.com/r/tabs.jsonUsage
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/hangry-ui/components/tabs";
<Tabs defaultValue="overview"> <TabsList aria-label="Project sections"> <TabsTrigger value="overview">Overview</TabsTrigger> <TabsTrigger value="settings">Settings</TabsTrigger> </TabsList> <TabsContent value="overview">Your project overview.</TabsContent> <TabsContent value="settings">Your project settings.</TabsContent></Tabs>Variants
Set variant="default" or variant="line" on TabsList. Give each TabsTrigger a unique value and use the same value on its TabsContent. Set disabled on a trigger to prevent selection. Set orientation="vertical" on Tabs for a vertical list.
Keyboard navigation
Use Left and Right Arrow for horizontal tabs, or Up and Down Arrow for vertical tabs, to move between enabled tabs; Home for the first tab, and End for the last. Moving focus selects the tab automatically. Tab moves from the selected tab into its panel.
Controlled selection
Pass value and update it through onValueChange to control the selected tab. Use defaultValue for an initial selection managed by the component. Panels stay mounted when hidden.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
Tabs.value | string | — | Controlled selected tab value. |
Tabs.defaultValue | string | — | Initial selected tab for uncontrolled usage. |
Tabs.onValueChange | (value: string) => void | — | Called when a tab is selected. |
Tabs.orientation | "horizontal" | "vertical" | "horizontal" | List direction and arrow key behavior. |
TabsList.variant | "default" | "line" | "default" | Muted background or an active underline. |
TabsList.aria-label | string | — | Accessible name for the tab list. |
TabsTrigger.value (required) | string | — | Unique tab value, matching a panel value. |
TabsTrigger.disabled | boolean | false | Prevents selection and skips this tab during arrow navigation. |
TabsContent.value (required) | string | — | Value of the trigger associated with this panel. |
children | ReactNode | — | Compose tab lists, triggers, and panel content. |
className | string | — | Additional classes on each part. |
Native props | ComponentProps<"div"> / ComponentProps<"button"> | — | Root, list, and content accept div props; triggers accept button props. Roles, IDs, and selection attributes are managed internally. |
Setup notes
Use Tailwind CSS v4 and the global theme tokens. Borders use border-border; no rounded classes or additional packages are required.