Components

Tabs

Organize content into multiple panels with accessible tab navigation and multiple style variants.

Default (Vertical)

Overview

Get a high-level view of your dashboard metrics and key performance indicators.

Minimal (Vertical)

Home content goes here.

With Icons

Home content with icon

With Badges

You have 12 new messages in your inbox.

Horizontal Layout

Team Management

Manage your team members, roles, and permissions. Add new members or update existing ones.

Installation

Anatomy

Import the components and piece them together.

import { TabRoot, TabList, TabTrigger, TabContent } from "@/registry/core/tabs";

export default () => (
  <TabRoot defaultValue="tab1">
    <TabList>
      <TabTrigger value="tab1" />
      <TabTrigger value="tab2" />
    </TabList>
    <TabContent value="tab1" />
    <TabContent value="tab2" />
  </TabRoot>
);

Usage

import { TabRoot, TabList, TabTrigger, TabContent } from "@/registry/core/tabs";

export default () => (
  <TabRoot defaultValue="overview">
    <TabList>
      <TabTrigger value="overview">Overview</TabTrigger>
      <TabTrigger value="analytics">Analytics</TabTrigger>
      <TabTrigger value="reports">Reports</TabTrigger>
    </TabList>
    <TabContent value="overview">
      <p>Overview content goes here.</p>
    </TabContent>
    <TabContent value="analytics">
      <p>Analytics content goes here.</p>
    </TabContent>
    <TabContent value="reports">
      <p>Reports content goes here.</p>
    </TabContent>
  </TabRoot>
);

Examples

Variants

{
  /* Default */
}
<TabRoot defaultValue="tab1" variant="default">
  <TabList>
    <TabTrigger value="tab1">Tab 1</TabTrigger>
    <TabTrigger value="tab2">Tab 2</TabTrigger>
  </TabList>
  <TabContent value="tab1">Content 1</TabContent>
  <TabContent value="tab2">Content 2</TabContent>
</TabRoot>;

{
  /* Minimal */
}
<TabRoot defaultValue="tab1" variant="minimal">
  <TabList>
    <TabTrigger value="tab1">Tab 1</TabTrigger>
    <TabTrigger value="tab2">Tab 2</TabTrigger>
  </TabList>
  <TabContent value="tab1">Content 1</TabContent>
  <TabContent value="tab2">Content 2</TabContent>
</TabRoot>;

With Icons

import { Home, BarChart, FileText } from "lucide-react";

<TabRoot defaultValue="home">
  <TabList>
    <TabTrigger value="home" icon={<Home />}>
      Home
    </TabTrigger>
    <TabTrigger value="analytics" icon={<BarChart />}>
      Analytics
    </TabTrigger>
    <TabTrigger value="reports" icon={<FileText />}>
      Reports
    </TabTrigger>
  </TabList>
  <TabContent value="home">Home content</TabContent>
  <TabContent value="analytics">Analytics content</TabContent>
  <TabContent value="reports">Reports content</TabContent>
</TabRoot>;

With Badges

<TabRoot defaultValue="inbox">
  <TabList>
    <TabTrigger value="inbox" badge={12}>
      Inbox
    </TabTrigger>
    <TabTrigger value="drafts" badge={3}>
      Drafts
    </TabTrigger>
    <TabTrigger value="sent">Sent</TabTrigger>
  </TabList>
  <TabContent value="inbox">Inbox content</TabContent>
  <TabContent value="drafts">Drafts content</TabContent>
  <TabContent value="sent">Sent content</TabContent>
</TabRoot>

Horizontal Direction

<TabRoot defaultValue="tab1" direction="horizontal">
  <TabList>
    <TabTrigger value="tab1">Tab 1</TabTrigger>
    <TabTrigger value="tab2">Tab 2</TabTrigger>
    <TabTrigger value="tab3">Tab 3</TabTrigger>
  </TabList>
  <TabContent value="tab1">Content 1</TabContent>
  <TabContent value="tab2">Content 2</TabContent>
  <TabContent value="tab3">Content 3</TabContent>
</TabRoot>

API Reference

TabRoot

The root container for tabs. Extends div element props.

PropTypeDefaultDescription
defaultValuestring-Initially active tab (required)
variant'default', 'minimal''default'Visual style variant
direction'vertical', 'horizontal''vertical'Layout direction
classNamestring-Additional CSS classes
childrenReact.ReactNode-Tab components

TabList

Container for tab triggers. Extends div element props.

PropTypeDescription
classNamestringAdditional CSS classes
childrenReact.ReactNodeTabTrigger components

TabTrigger

Individual tab button. Extends button element props.

PropTypeDescription
valuestringUnique tab identifier (required)
iconReact.ReactNodeOptional icon before text
badgestring | numberOptional badge after text
classNamestringAdditional CSS classes
childrenReact.ReactNodeTab label content

TabContent

Content panel for each tab. Extends div element props.

PropTypeDescription
valuestringTab identifier matching trigger (required)
classNamestringAdditional CSS classes
childrenReact.ReactNodePanel content

Accessibility

  • Uses proper ARIA attributes (role="tab", role="tabpanel", aria-selected, aria-controls, aria-labelledby)
  • Keyboard accessible with standard tab navigation
  • Active tab is clearly indicated with visual styling
  • Content panels are properly associated with their triggers
  • Hidden content uses hidden attribute for screen readers
  • Auto-generated unique IDs ensure proper associations

Notes

  • Only one tab panel is visible at a time
  • The defaultValue prop sets the initially active tab
  • Icons are automatically sized to 20px (1.25rem)
  • Badges use the Badge component with primary color
  • Horizontal direction is responsive and wraps on small screens
  • Tab list scrolls horizontally if tabs overflow
  • State is managed internally with React context