Segments and audience rules.
Installation
$Terminal
npx shadcn@latest add https://sdk-components.thesqd.com/r/tabs.jsonUsage
Import from the master file and pair `TabsTrigger` values with `TabsContent` values.
TSImport
import { Tabs } from "@/components/ui/tabs";TSExample
import { Tabs } from "@/components/ui/tabs";
export function Example() {
return (
<Tabs
defaultValue="account"
items={[
{ value: "account", label: "Account", content: "Make changes to your account." },
{ value: "password", label: "Password", content: "Change your password." },
]}
/>
);
}Composition
Anatomy of the Tabs primitive.
Tabs (single component — pass items as data)
├── variant="default" | "segment"
├── size="default" | "sm" (sm = h-8, compact)
├── items={[
│ { value, label, icon?, content?, disabled?, triggerClassName?, contentClassName? },
│ …
│ ]}
└── ...rest (defaultValue / value / onValueChange / orientation)
Auto-emits TabsList + TabsTrigger per item; TabsContent per item that has
`content`. Items without `content` render a trigger only — useful for
toolbar-style segmented controls (e.g. a theme switcher).
Need a custom panel layout, asynchronous content loading, or a TabsList
sandwiched between hand-written rows? The slot exports — TabsList,
TabsTrigger, TabsContent — remain available as the escape hatch.Default
Rounded pill container with a primary-colored active label and a soft shadow.
Segments and audience rules.
Small
`size="sm"` shrinks the tab list to `h-8` for compact, inline filter rows.
Theme switcher
Compact segmented control with colored icons — drop-in for a light/dark/system toggle.
Underline
Plain text labels with an animated underline that slides between active tabs. Use for page-level section navigation where the segmented look is too heavy.
Segments and audience rules.
Underline (large)
Pass `size="lg"` with the underline variant for prominent, nav-style tabs — a larger label and bigger icons. Great as the primary section nav at the top of a page.
Everything queued for this project.
Rounded
`variant="rounded"` is a Notion-style icon nav — tabs collapse to their icon and the active one expands into a labelled rounded-full pill (the label's grid column animates from `0fr` to `1fr`). No container surface; each tab is its own pill.
Conversations and threads.
API Reference
Props exposed by the Tabs component.
Tabs
| Prop | Type | Default | Description |
|---|---|---|---|
items | TabsItem[] | — | List of tab specs. Without this prop, Tabs stays compound (drop in TabsList + TabsTrigger + TabsContent children). |
variant | "default" | "segment" | "underline" | "rounded" | "default" | Pill container, compact segmented control, sliding underline nav, or Notion-style rounded icon tabs that expand the active label. |
size | "default" | "sm" | "default" | Tab list height. `sm` shrinks to `h-8` for compact, inline filter rows. |
fluid | boolean | false | Fill the available width with content-proportional tabs — each trigger grows/shrinks from its natural label width (flex-auto), so long labels keep more room than short ones when space is tight. Great for full-width tab rows on mobile. Applies to `default` and `segment` variants. |
defaultValue | string | — | Uncontrolled initial active tab. |
value | string | — | Controlled active tab value. |
onValueChange | (value: string) => void | — | Fires when the active tab changes. |
orientation | "horizontal" | "vertical" | "horizontal" | Drives flex direction and arrow-key navigation. |
listClassName | string | — | Class names applied to the auto-emitted `TabsList`. |
TabsItem
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | Identifier matching a `TabsContent` panel. |
label | ReactNode | — | Trigger label. |
icon | ReactNode | — | Leading icon rendered before the label. |
content | ReactNode | — | Panel content. Omit to render a trigger-only tab (e.g. for segmented control patterns). |
disabled | boolean | — | Skip this tab in keyboard navigation. |
triggerClassName | string | — | Per-tab trigger class names. |
contentClassName | string | — | Per-tab panel class names. |