Skip to main content

Installation

npx shadcn@latest add tabs

Usage

import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
<Tabs defaultValue="account" className="w-[400px]">
  <TabsList>
    <TabsTrigger value="account">Account</TabsTrigger>
    <TabsTrigger value="password">Password</TabsTrigger>
  </TabsList>
  <TabsContent value="account">Make changes to your account here.</TabsContent>
  <TabsContent value="password">Change your password here.</TabsContent>
</Tabs>

Component API

Tabs

Root tabs component. Built on Radix UI Tabs.
function Tabs({
  className,
  orientation = "horizontal",
  ...props
}: React.ComponentProps<typeof TabsPrimitive.Root>)
Props:
  • defaultValue - Default active tab
  • value - Controlled active tab
  • onValueChange - Callback when active tab changes
  • orientation - Layout direction ("horizontal" | "vertical")

TabsList

Container for tab triggers.
function TabsList({
  className,
  variant = "default",
  ...props
}: React.ComponentProps<typeof TabsPrimitive.List> & {
  variant?: "default" | "line"
})
Props:
  • variant - Visual style ("default" | "line")

TabsTrigger

Clickable tab button.
function TabsTrigger({
  className,
  ...props
}: React.ComponentProps<typeof TabsPrimitive.Trigger>)
Props:
  • value - Unique value for this tab
  • disabled - Disables this tab

TabsContent

Tab panel content.
function TabsContent({
  className,
  ...props
}: React.ComponentProps<typeof TabsPrimitive.Content>)
Props:
  • value - Value that matches the trigger

Examples

Basic Tabs

<Tabs defaultValue="tab1">
  <TabsList>
    <TabsTrigger value="tab1">Tab 1</TabsTrigger>
    <TabsTrigger value="tab2">Tab 2</TabsTrigger>
    <TabsTrigger value="tab3">Tab 3</TabsTrigger>
  </TabsList>
  <TabsContent value="tab1">
    <p>Content for Tab 1</p>
  </TabsContent>
  <TabsContent value="tab2">
    <p>Content for Tab 2</p>
  </TabsContent>
  <TabsContent value="tab3">
    <p>Content for Tab 3</p>
  </TabsContent>
</Tabs>

Line Variant

Underline style tabs:
<Tabs defaultValue="account">
  <TabsList variant="line">
    <TabsTrigger value="account">Account</TabsTrigger>
    <TabsTrigger value="password">Password</TabsTrigger>
    <TabsTrigger value="settings">Settings</TabsTrigger>
  </TabsList>
  <TabsContent value="account">{/* Content */}</TabsContent>
  <TabsContent value="password">{/* Content */}</TabsContent>
  <TabsContent value="settings">{/* Content */}</TabsContent>
</Tabs>

Vertical Tabs

Vertical orientation:
<Tabs defaultValue="account" orientation="vertical" className="flex gap-4">
  <TabsList variant="line">
    <TabsTrigger value="account">Account</TabsTrigger>
    <TabsTrigger value="password">Password</TabsTrigger>
    <TabsTrigger value="settings">Settings</TabsTrigger>
  </TabsList>
  <div className="flex-1">
    <TabsContent value="account">{/* Content */}</TabsContent>
    <TabsContent value="password">{/* Content */}</TabsContent>
    <TabsContent value="settings">{/* Content */}</TabsContent>
  </div>
</Tabs>

Disabled Tab

<Tabs defaultValue="tab1">
  <TabsList>
    <TabsTrigger value="tab1">Active</TabsTrigger>
    <TabsTrigger value="tab2" disabled>
      Disabled
    </TabsTrigger>
    <TabsTrigger value="tab3">Active</TabsTrigger>
  </TabsList>
  <TabsContent value="tab1">{/* Content */}</TabsContent>
  <TabsContent value="tab3">{/* Content */}</TabsContent>
</Tabs>

With Icons

Tabs with icons:
import { Home, Settings, User } from "lucide-react"

<Tabs defaultValue="home">
  <TabsList>
    <TabsTrigger value="home">
      <Home className="mr-2 h-4 w-4" />
      Home
    </TabsTrigger>
    <TabsTrigger value="profile">
      <User className="mr-2 h-4 w-4" />
      Profile
    </TabsTrigger>
    <TabsTrigger value="settings">
      <Settings className="mr-2 h-4 w-4" />
      Settings
    </TabsTrigger>
  </TabsList>
  <TabsContent value="home">{/* Content */}</TabsContent>
  <TabsContent value="profile">{/* Content */}</TabsContent>
  <TabsContent value="settings">{/* Content */}</TabsContent>
</Tabs>

Controlled Tabs

function ControlledTabs() {
  const [value, setValue] = React.useState("tab1")

  return (
    <div className="space-y-4">
      <Tabs value={value} onValueChange={setValue}>
        <TabsList>
          <TabsTrigger value="tab1">Tab 1</TabsTrigger>
          <TabsTrigger value="tab2">Tab 2</TabsTrigger>
        </TabsList>
        <TabsContent value="tab1">Content 1</TabsContent>
        <TabsContent value="tab2">Content 2</TabsContent>
      </Tabs>
      <div className="flex gap-2">
        <Button onClick={() => setValue("tab1")}>Go to Tab 1</Button>
        <Button onClick={() => setValue("tab2")}>Go to Tab 2</Button>
      </div>
    </div>
  )
}

With Cards

Tab content in cards:
<Tabs defaultValue="overview" className="w-[500px]">
  <TabsList className="grid w-full grid-cols-2">
    <TabsTrigger value="overview">Overview</TabsTrigger>
    <TabsTrigger value="analytics">Analytics</TabsTrigger>
  </TabsList>
  <TabsContent value="overview">
    <Card>
      <CardHeader>
        <CardTitle>Overview</CardTitle>
        <CardDescription>View your overview here.</CardDescription>
      </CardHeader>
      <CardContent>{/* Content */}</CardContent>
    </Card>
  </TabsContent>
  <TabsContent value="analytics">
    <Card>
      <CardHeader>
        <CardTitle>Analytics</CardTitle>
        <CardDescription>View your analytics here.</CardDescription>
      </CardHeader>
      <CardContent>{/* Content */}</CardContent>
    </Card>
  </TabsContent>
</Tabs>

Form Sections

Organize form into tabs:
<Tabs defaultValue="personal">
  <TabsList>
    <TabsTrigger value="personal">Personal Info</TabsTrigger>
    <TabsTrigger value="account">Account</TabsTrigger>
    <TabsTrigger value="preferences">Preferences</TabsTrigger>
  </TabsList>
  <TabsContent value="personal">
    <div className="space-y-4">
      <div>
        <Label htmlFor="name">Name</Label>
        <Input id="name" />
      </div>
      <div>
        <Label htmlFor="email">Email</Label>
        <Input id="email" type="email" />
      </div>
    </div>
  </TabsContent>
  <TabsContent value="account">
    {/* Account settings */}
  </TabsContent>
  <TabsContent value="preferences">
    {/* Preferences */}
  </TabsContent>
</Tabs>

Accessibility

  • Full keyboard navigation (arrow keys, Home, End)
  • Automatic focus management
  • Proper ARIA attributes
  • Screen reader support
  • Roving tabindex

API Reference

See the Radix UI Tabs documentation for complete API reference.

Build docs developers (and LLMs) love