Tabs
A set of panels that share one visible view at a time.
Overview
Tabs keeps one panel visible at a time. Triggers live in TabsList; each TabsContent matches a trigger value. Selection can be controlled or uncontrolled.
Preview
Manage your account details and preferences.
Customize
Installation
Add the component with the CLI. It copies the files in and installs anything they depend on.
npx vinyaas add tabsUsage
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
Tabs,
TabsContent,
TabsList,
TabsTrigger,
} from "@/components/ui/tabs";
export function AccountTabs() {
return (
<Card className="w-full max-w-md text-left">
<CardHeader>
<CardTitle>Account</CardTitle>
<CardDescription>Manage your public profile.</CardDescription>
</CardHeader>
<CardContent>
<Tabs defaultValue="profile">
<TabsList>
<TabsTrigger value="profile">Profile</TabsTrigger>
<TabsTrigger value="email">Email</TabsTrigger>
</TabsList>
<TabsContent value="profile" className="flex flex-col gap-3 pt-3">
<div className="flex flex-col gap-2">
<Label htmlFor="tabs-usage-name">Display name</Label>
<Input id="tabs-usage-name" defaultValue="Sarang Kumar" />
</div>
<Button size="sm" className="self-start">
Save profile
</Button>
</TabsContent>
<TabsContent value="email" className="flex flex-col gap-3 pt-3">
<div className="flex flex-col gap-2">
<Label htmlFor="tabs-usage-email">Email</Label>
<Input
id="tabs-usage-email"
type="email"
defaultValue="sarang@example.com"
/>
</div>
<Button size="sm" className="self-start" variant="outline">
Update email
</Button>
</TabsContent>
</Tabs>
</CardContent>
</Card>
);
}Examples
Basic
A Card holds profile and email panels. Activating a tab replaces the panel.
Manage your public profile.
Line
Use variant="line" on TabsList for an underline under the active tab.
Switch between product views.
Project overview
Richer panels can mix copy, status, and actions.
Design system
Source-installed primitives for product UI.
Last deployed 2 hours ago · 12 open issues
Disabled tab
A disabled trigger stays visible and cannot be activated.
With icons
Triggers can include decorative icons beside the label.
Compact
A denser list fits toolbars and side panels.
In practice
Settings live in a Card. Three tabs hold profile fields, notification switches, and security controls.
Manage your profile, notifications, and security.
API
Other attributes for the underlying element are passed through.
| Name | Type | Default | Description |
|---|---|---|---|
value | string | — | Controlled selected tab. Omit it for uncontrolled tabs. |
defaultValue | string | — | The tab selected on first render. |
onValueChange | (value: string) => void | — | Called with the next tab value after activation. |
orientation | "horizontal" | "vertical" | "horizontal" | Sets aria-orientation and the list layout direction. |
variant | "default" | "line" | "default" | On TabsList, line draws an underline under the active tab. |
disabled | boolean | — | Disables the whole set, or one TabsTrigger. |
forceMount | boolean | — | On TabsContent, keeps the panel mounted while it is hidden. |
className | string | — | Merged onto Tabs, TabsList, TabsTrigger, or TabsContent. |
Accessibility
TabsList is a tablist. Each TabsTrigger is a tab with aria-selected and aria-controls. The active TabsContent is a tabpanel labeled by its trigger.
Arrow keys move focus between enabled triggers. Home and End jump to the first and last enabled trigger. Click, Enter, or Space activates the focused tab. Disabled triggers are skipped.