Tabs
Switch between related content in the same context.
pnpm dlx shadcn@latest add @uiarc/tabs- Peer views of the same object, such as Overview, Activity, and Settings.
- Panels with different heights, where the container should spring between them.
- Long tab sets that need to scroll horizontally with edge buttons.
- Use segmented-control for a compact value toggle not tied to panels.
- Use accordion for stacked sections people read in order.
- Use liquid-tab-bar or morph-nav for app-level navigation between routes.
Installation
Add Tabs with the shadcn CLI, or copy the source by hand.
pnpm dlx shadcn@latest add @uiarc/tabsAdds the component and its local dependencies, and installs @radix-ui/react-tabs, motion, lucide-react. First time? Add the @uiarc registry to components.json, or use the full URL:
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/registry/components/tabs/tabs"; export function ProjectTabs() { return ( <Tabs defaultValue="overview"> <TabsList aria-label="Project"> <TabsTrigger value="overview">Overview</TabsTrigger> <TabsTrigger value="activity">Activity</TabsTrigger> </TabsList> <TabsContent value="overview">Summary and stats</TabsContent> <TabsContent value="activity">Recent events</TabsContent> </Tabs> );}API reference
4 parts. The first is the root.
Tabs
Radix Tabs root that tracks direction so panels slide the way the selection moved.
valuestring–Controlled active tab value.defaultValuestring–Initial active tab when uncontrolled.onValueChange(value: string) => void–Called when the active tab changes....propsComponentPropsWithoutRef<typeof TabsPrimitive.Root>–Other Radix root props such as activationMode and className.TabsList
Scrollable tab strip. Shows edge scroll buttons when triggers overflow and keeps the active tab in view.
...propsComponentPropsWithoutRef<typeof TabsPrimitive.List>–Radix list props, including aria-label and loop.TabsTrigger
A tab with a shared selection pill that glides between triggers.
valueRequiredstring–Matches a TabsContent value....propsComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>–Radix trigger props such as disabled.TabsContent
Panel that slides in and morphs its height from the previous panel.
valueRequiredstring–Matches a TabsTrigger value.forceMounttrue–Keeps the panel mounted and skips the enter and exit animation....propsComponentPropsWithoutRef<typeof TabsPrimitive.Content>–Radix content props such as className.- ArrowLeftorArrowRight
- Moves between tabs and activates them.
- HomeorEnd
- Jumps to the first or last tab.
- Tab
- Moves focus from the tab list into the active panel.
- Radix provides role="tablist", role="tab", role="tabpanel", aria-selected, and aria-controls.
- The outgoing panel is made inert while it fades so it cannot take focus.
- Overflow scroll buttons are labelled "Scroll tabs left" and "Scroll tabs right"; give TabsList an aria-label.
- The selection pill glides between triggers on a morph spring, scoped to one Tabs instance.
- Panels slide 8px in the direction of travel while the height springs from the previous panel.
- Reduced motion swaps the pill instantly and crossfades panels in place without height animation.
- The tab list keeps max-width 100% and scrolls horizontally when triggers overflow, with scroll buttons at the edges.
- Focusing a tab scrolls it into view, so keyboard navigation works on narrow screens.
- Triggers keep a 5.5rem minimum width, so many tabs overflow sooner on mobile.
- ResizeObservers track list overflow and the active panel height; one per Tabs instance is cheap.
- The selection pill is a shared layout animation scoped to one Tabs; avoid dozens of tab sets on one screen.
Notes for AI
Give your coding assistant the Markdown reference instead of screenshots.
- Use for peer views of the same object. Use segmented-control for a compact value toggle that is not tied to panels, and accordion for stacked sections.
- Every TabsTrigger value needs a matching TabsContent. Long lists scroll horizontally on their own.
The full library index for assistants is at /llms.txt.