Tabs

React Tabs components are used to organize related content into separate panels that share the same context. They are commonly used in dashboards, settings pages, profile views, and any interface where users need to switch between sections without leaving the page.

This Tabs component is built with React and styled using Tailwind CSS. It supports multiple visual variants, icons, badges, and vertical or horizontal layouts while keeping tab behavior accessible and predictable.

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 tab parts and compose them to build the layout.

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 the components and match each trigger with its content using the same value.

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

Use variants to change the visual style of the tab list.

{
  /* 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