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.
Analytics
Deep dive into your data with detailed analytics and insights.
Reports
Generate and view comprehensive reports for your business.
Settings
Configure your preferences and account settings.
Minimal (Vertical)
Home content goes here.
Profile content goes here.
Messages content goes here.
With Icons
With Badges
You have 12 new messages in your inbox.
You have 3 draft messages.
View your sent messages.
Horizontal Layout
Team Management
Manage your team members, roles, and permissions. Add new members or update existing ones.
Team Analytics
View team performance metrics, activity logs, and productivity insights.
Team Settings
Configure team-wide settings, notifications, and integrations.
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.
| Prop | Type | Default | Description |
|---|---|---|---|
defaultValue | string | - | Initially active tab (required) |
variant | 'default', 'minimal' | 'default' | Visual style variant |
direction | 'vertical', 'horizontal' | 'vertical' | Layout direction |
className | string | - | Additional CSS classes |
children | React.ReactNode | - | Tab components |
TabList
Container for tab triggers. Extends div element props.
| Prop | Type | Description |
|---|---|---|
className | string | Additional CSS classes |
children | React.ReactNode | TabTrigger components |
TabTrigger
Individual tab button. Extends button element props.
| Prop | Type | Description |
|---|---|---|
value | string | Unique tab identifier (required) |
icon | React.ReactNode | Optional icon before text |
badge | string | number | Optional badge after text |
className | string | Additional CSS classes |
children | React.ReactNode | Tab label content |
TabContent
Content panel for each tab. Extends div element props.
| Prop | Type | Description |
|---|---|---|
value | string | Tab identifier matching trigger (required) |
className | string | Additional CSS classes |
children | React.ReactNode | Panel 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
hiddenattribute for screen readers - Auto-generated unique IDs ensure proper associations
Notes
- Only one tab panel is visible at a time
- The
defaultValueprop 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