Overview
The Tabs component provides an accessible, keyboard-navigable tab interface built on Radix UI. It includes Tabs, TabsList, TabsTrigger, and TabsContent subcomponents with two visual variants.
Components
Tabs
Root container component for the tab interface.
variant
'underline' | 'solid'
default:"'solid'"
Visual style variant for the tabs
underline: Tabs with bottom border indicator
solid: Tabs with solid background for active state
The value of the tab that should be active by default
The controlled value of the active tab (use with onValueChange)
Callback when the active tab changes
orientation
'horizontal' | 'vertical'
default:"'horizontal'"
Orientation of the tabs
Reading direction for the tabs
activationMode
'automatic' | 'manual'
default:"'automatic'"
Whether tabs activate automatically on focus or require selection
TabsList
Container for tab triggers.
Additional CSS classes to apply to the list
ref
React.Ref<HTMLDivElement>
Ref to the underlying element
TabsTrigger
Individual tab button.
Unique identifier for this tab
Whether the tab is disabled
Additional CSS classes to apply to the trigger
ref
React.Ref<HTMLButtonElement>
Ref to the underlying button element
Content to display in the tab button
TabsContent
Content panel for each tab.
Identifier matching the associated TabsTrigger value
Force mount the content (useful for animations)
Additional CSS classes to apply to the content
ref
React.Ref<HTMLDivElement>
Ref to the underlying element
Content to display when tab is active
Usage
import { Tabs, TabsList, TabsTrigger, TabsContent } from '@repo/ui'
export function Example() {
return (
<Tabs defaultValue="account" variant="underline">
<TabsList>
<TabsTrigger value="account">Account</TabsTrigger>
<TabsTrigger value="password">Password</TabsTrigger>
</TabsList>
<TabsContent value="account">
Account settings content
</TabsContent>
<TabsContent value="password">
Password settings content
</TabsContent>
</Tabs>
)
}
Examples
Underline Variant
<Tabs defaultValue="tab1" variant="underline">
<TabsList>
<TabsTrigger value="tab1">Tab 1</TabsTrigger>
<TabsTrigger value="tab2">Tab 2</TabsTrigger>
<TabsTrigger value="tab3">Tab 3</TabsTrigger>
</TabsList>
<TabsContent value="tab1">Content 1</TabsContent>
<TabsContent value="tab2">Content 2</TabsContent>
<TabsContent value="tab3">Content 3</TabsContent>
</Tabs>
Solid Variant (Default)
<Tabs defaultValue="overview" variant="solid">
<TabsList>
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="analytics">Analytics</TabsTrigger>
<TabsTrigger value="reports">Reports</TabsTrigger>
</TabsList>
<TabsContent value="overview">
Overview dashboard
</TabsContent>
<TabsContent value="analytics">
Analytics data
</TabsContent>
<TabsContent value="reports">
Reports section
</TabsContent>
</Tabs>
Controlled Tabs
function ControlledTabs() {
const [activeTab, setActiveTab] = useState('home')
return (
<Tabs value={activeTab} onValueChange={setActiveTab}>
<TabsList>
<TabsTrigger value="home">Home</TabsTrigger>
<TabsTrigger value="profile">Profile</TabsTrigger>
</TabsList>
<TabsContent value="home">Home content</TabsContent>
<TabsContent value="profile">Profile content</TabsContent>
</Tabs>
)
}
With Disabled Tab
<Tabs defaultValue="available">
<TabsList>
<TabsTrigger value="available">Available</TabsTrigger>
<TabsTrigger value="disabled" disabled>Coming Soon</TabsTrigger>
</TabsList>
<TabsContent value="available">
Available features
</TabsContent>
</Tabs>
Accessibility
- Follows WAI-ARIA tabs pattern
- Keyboard navigation with arrow keys
- Automatic or manual activation modes
- Proper ARIA labels and roles
- Focus management
Implementation
Source: /home/daytona/workspace/source/packages/ui/src/tabs/tabs.tsx
Built with: @radix-ui/react-tabs