Skip to content

Tabs

Switches between views of related content in the same place.

  • Navigating between pages: use links or a nav.
  • Steps in a sequence: use a Stepper (Wave 3).

Install

Terminal
pnpm dlx shadcn@latest add @acme/tabs

Or import from the package: import { Tabs } from '@acme/react'

Examples

Basic

Revenue this month: $48,210, up 12% from August.
tabs-basic.tsx
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'

export default function TabsBasic() {
  return (
    <Tabs defaultValue="overview" className="w-full max-w-lg">
      <TabsList>
        <TabsTrigger value="overview">Overview</TabsTrigger>
        <TabsTrigger value="invoices">Invoices</TabsTrigger>
        <TabsTrigger value="settings">Settings</TabsTrigger>
      </TabsList>
      <TabsContent value="overview" className="text-body-sm">
        Revenue this month: $48,210, up 12% from August.
      </TabsContent>
      <TabsContent value="invoices" className="text-body-sm">
        3 invoices are overdue. The oldest is 18 days late.
      </TabsContent>
      <TabsContent value="settings" className="text-body-sm">
        Invoices are sent from billing@northwind.example.
      </TabsContent>
    </Tabs>
  )
}

Props

Tabs props
PropTypeDefaultDescription
value / defaultValuestring—The active tab.
onValueChange(value) => void—Called when the tab changes.
TabsTrigger.value (required)string—Matches a TabsContent value.

Accessibility

Keyboard
KeyAction
TabMoves into the tab list, then into the active panel
Arrow Left / RightMoves between tabs
Home / EndFirst / last tab
Role
tablist / tab / tabpanel
You provide
  • Short, distinct tab labels.
Built in
  • The active tab is marked by an underline as well as color.
  • The indicator animation is removed under reduced motion.
WCAG 2.2 criteria
1.3.1, 1.4.1, 2.1.1, 4.1.2

Don’t

  • Use more than about 6 tabs; wrap or rethink.
  • Put unrelated content in tabs.

Tokens

  • color.primary
  • color.muted-foreground
  • color.border
  • color.ring