Tabs
A set of layered panels where only one panel is displayed at a time, triggered by corresponding tab buttons.
Examples
Primary
Manage your account settings and preferences.
Secondary
Showing all items.
Animated indicator
Dashboard overview with key metrics.
Disabled
This tab is active.
Vertical
General settings.
Controlled
Content for the first tab.
Overview
Tabs organize content into switchable panels. Two visual variants, optional animated indicator, vertical orientation, controlled or uncontrolled state. Built on Base UI Tabs.
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@rogo-technologies/ui/tabs";
<Tabs defaultValue="account">
<TabsList variant="primary">
<TabsTrigger variant="primary" value="account">
Account
</TabsTrigger>
<TabsTrigger variant="primary" value="security">
Security
</TabsTrigger>
</TabsList>
<TabsContent value="account">Account settings here.</TabsContent>
<TabsContent value="security">Security settings here.</TabsContent>
</Tabs>;Usage
Primary
Underline-style tab bar with a bottom border. Active tabs get the brand color border.
<Tabs defaultValue="account">
<TabsList variant="primary">
<TabsTrigger variant="primary" value="account">Account</TabsTrigger>
<TabsTrigger variant="primary" value="security">Security</TabsTrigger>
</TabsList>
<TabsContent value="account">…</TabsContent>
</Tabs>Secondary
Pill-style tabs inside a rounded container. Active tabs get a raised background.
<TabsList variant="secondary">
<TabsTrigger variant="secondary" value="all">All</TabsTrigger>
<TabsTrigger variant="secondary" value="active">Active</TabsTrigger>
</TabsList>Animated indicator
Pass the same activeLayoutId string to each trigger to get a smooth underline that slides between tabs via framer-motion layoutId.
<TabsTrigger variant="primary" value="overview" activeLayoutId="settings-tabs">
Overview
</TabsTrigger>
<TabsTrigger variant="primary" value="analytics" activeLayoutId="settings-tabs">
Analytics
</TabsTrigger>Disabled
<TabsTrigger variant="primary" value="archive" disabled>
Archive
</TabsTrigger>Vertical
Use orientation="vertical" and override layout classes on TabsList / TabsTrigger to switch the border from bottom to right.
<Tabs defaultValue="general" orientation="vertical">
<TabsList
variant="primary"
className="flex-col border-b-0 border-r border-primary h-auto w-48 gap-0"
>
<TabsTrigger
variant="primary"
value="general"
className="w-full justify-start border-b-0 border-r-2 px-4 py-2"
>
General
</TabsTrigger>
</TabsList>
<TabsContent value="general" className="mt-0">
…
</TabsContent>
</Tabs>Controlled
const [activeTab, setActiveTab] = useState("tab1");
<Tabs value={activeTab} onValueChange={setActiveTab}>
<TabsList variant="primary">
<TabsTrigger variant="primary" value="tab1">First</TabsTrigger>
<TabsTrigger variant="primary" value="tab2">Second</TabsTrigger>
</TabsList>
<TabsContent value="tab1">…</TabsContent>
<TabsContent value="tab2">…</TabsContent>
</Tabs>;API
Tabs
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | Controlled active tab value. |
defaultValue | string | — | Uncontrolled initial active tab. |
onValueChange | (value: string) => void | — | Callback when the active tab changes. |
orientation | "horizontal" | "vertical" | "horizontal" | Layout direction. |
className | string | — | Additional CSS classes. |
TabsList
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "primary" | "secondary" | "primary" | Visual style variant. |
className | string | — | Additional CSS classes. |
TabsTrigger
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | Unique tab identifier (required). |
variant | "primary" | "secondary" | "primary" | Visual style variant. |
activeLayoutId | string | — | Renders an animated indicator via framer-motion layoutId. Primary variant. |
disabled | boolean | false | Disables the tab. |
className | string | — | Additional CSS classes. |
TabsContent
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | Value matching a TabsTrigger (required). |
keepMounted | boolean | false | Keep DOM element when panel is hidden. |
className | string | — | Additional CSS classes. |
Guidelines
Do
- Match
variantonTabsListandTabsTriggerfor consistent styling - Use
activeLayoutIdwith the same string on all triggers when you want a sliding indicator - Use
orientation="vertical"for settings sidebars and navigation panels - Keep tab labels short — one or two words
Don't
- Don't nest tabs inside tabs — it creates confusing navigation
- Don't use tabs for sequential steps — use a stepper or wizard instead
- Don't use more than 5–6 tabs — group or collapse content if needed
- Don't mix variants within the same tab group