Tabs
Tab navigation for switching between content panels, in underline and pill variants, built on Radix UI.
Installation
npx paubha@latest add tabsUsage
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
<Tabs defaultValue="account">
<TabsList aria-label="Settings">
<TabsTrigger value="account">Account</TabsTrigger>
<TabsTrigger value="billing">Billing</TabsTrigger>
</TabsList>
<TabsContent value="account">Account settings</TabsContent>
<TabsContent value="billing">Billing settings</TabsContent>
</Tabs>The underline variant renders a 2px bottom border on every trigger
(transparent when inactive, border-brand when active) rather than only on
the selected one. That keeps the tab bar's height constant when selection
changes, instead of jumping by 2px the way a literal reading of the static
mockup would.
Examples
Pill variant
Keep labels to one or two words, and use a single tab group per set of panels — don't nest tab groups inside a panel.
With icons
An optional leading Lucide icon is sized to 16px automatically. Mark it
aria-hidden so the label stays the accessible name.
Manual activation
Arrow keys select the focused tab by default. When a panel takes noticeable
time to render, pass activationMode="manual" to Tabs: arrows then only move
focus, and Enter or Space selects.
<Tabs defaultValue="overview" activationMode="manual">…</Tabs>API reference
Tabs and TabsContent are direct re-exports of Radix's Root/Content.
TabsList
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "underline" | "pill" | "underline" | Shared with child TabsTrigger elements via context. |
Accessibility
Accessibility
Roles.
role="tablist", each tabrole="tab", each panelrole="tabpanel".Keyboard. Left/Right Arrow move between tabs and, by default, select the newly focused tab; Home/End jump to the first/last enabled tab. Roving tabindex keeps only the selected tab in the Tab sequence, so the next Tab moves into the panel. With
activationMode="manual", arrows only move focus and Enter/Space select.Label. Give
TabsListanaria-labeloraria-labelledby.Motion. State changes use a 100ms ease-out transition, instant under
prefers-reduced-motion.ARIA.
aria-selectedon the active tab,aria-controlslinking each tab to its panel, andaria-labelledbylinking each panel back to its tab.