Tabs
A set of layered sections of content — known as tab panels — that are displayed one at a time.
Uses role="tablist" / role="tab" / role="tabpanel"; keyboard navigable with arrow keys; animated indicator via TabsIndicator.
Preview
tsx
import {
Tabs,
TabsContent,
TabsIndicator,
TabsList,
TabsTrigger,
} from '@arshad-shah/cynosure-react';
export default function Example() {
return (
<Tabs defaultValue="overview">
<TabsList>
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="analytics">Analytics</TabsTrigger>
<TabsTrigger value="settings">Settings</TabsTrigger>
<TabsIndicator />
</TabsList>
<TabsContent value="overview">
<p>Your project overview and summary will appear here.</p>
</TabsContent>
<TabsContent value="analytics">
<p>Analytics data and charts will appear here.</p>
</TabsContent>
<TabsContent value="settings">
<p>Project settings and configuration will appear here.</p>
</TabsContent>
</Tabs>
);
}
Variants
Section titled “Variants”Vertical
Section titled “Vertical”Use orientation="vertical" to stack the tab list along the side.
Preview
tsx
import {
Tabs,
TabsContent,
TabsIndicator,
TabsList,
TabsTrigger,
} from '@arshad-shah/cynosure-react';
export default function Example() {
return (
<Tabs defaultValue="profile" orientation="vertical">
<TabsList>
<TabsTrigger value="profile">Profile</TabsTrigger>
<TabsTrigger value="security">Security</TabsTrigger>
<TabsTrigger value="notifications">Notifications</TabsTrigger>
<TabsIndicator />
</TabsList>
<TabsContent value="profile">
<p>Manage your public profile information.</p>
</TabsContent>
<TabsContent value="security">
<p>Update your password and two-factor authentication settings.</p>
</TabsContent>
<TabsContent value="notifications">
<p>Choose what notifications you receive and how.</p>
</TabsContent>
</Tabs>
);
}
With icons
Section titled “With icons”Add icons alongside tab labels by rendering icon components directly inside TabsTrigger.
Preview
tsx
import {
Tabs,
TabsContent,
TabsIndicator,
TabsList,
TabsTrigger,
} from '@arshad-shah/cynosure-react';
import { BarChart3Icon, HomeIcon, SettingsIcon } from 'lucide-react';
export default function Example() {
return (
<Tabs defaultValue="home">
<TabsList>
<TabsTrigger value="home">
<HomeIcon size={14} />
Home
</TabsTrigger>
<TabsTrigger value="analytics">
<BarChart3Icon size={14} />
Analytics
</TabsTrigger>
<TabsTrigger value="settings">
<SettingsIcon size={14} />
Settings
</TabsTrigger>
<TabsIndicator />
</TabsList>
<TabsContent value="home">
<p>Welcome home! Here is your dashboard summary.</p>
</TabsContent>
<TabsContent value="analytics">
<p>View your performance metrics and trends.</p>
</TabsContent>
<TabsContent value="settings">
<p>Configure your preferences and integrations.</p>
</TabsContent>
</Tabs>
);
}
Disabled tab
Section titled “Disabled tab”Pass disabled to any TabsTrigger to prevent selection.
Preview
tsx
import {
Tabs,
TabsContent,
TabsIndicator,
TabsList,
TabsTrigger,
} from '@arshad-shah/cynosure-react';
export default function Example() {
return (
<Tabs defaultValue="active">
<TabsList>
<TabsTrigger value="active">Active</TabsTrigger>
<TabsTrigger value="pending">Pending</TabsTrigger>
<TabsTrigger value="archived" disabled>
Archived
</TabsTrigger>
<TabsIndicator />
</TabsList>
<TabsContent value="active">
<p>These are your active items.</p>
</TabsContent>
<TabsContent value="pending">
<p>These items are awaiting approval.</p>
</TabsContent>
<TabsContent value="archived">
<p>Archived items are read-only.</p>
</TabsContent>
</Tabs>
);
}
PropTypeDefaultDescription
value
string
—
Controlled active value.
defaultValue
string
—
Uncontrolled initial value.
onValueChange
((value: string) => void)
—
Fires with the next active value.
activationMode
"automatic"|"manual"
automatic
`automatic` activates each tab as soon as it receives keyboard focus;
`manual` requires a Space/Enter press. WAI-ARIA recommends `automatic`
for stable tab content, `manual` when activating a tab triggers a
costly transition.
variant
"line"|"solid"|"enclosed"|"soft"
line
Visual treatment for the trigger row. `line` underlines the active
tab; `solid` fills the active tab; `enclosed` draws a notched tab
sitting above a panel border; `soft` uses a tinted pill.
size
"sm"|"md"|"lg"
md
Size of the trigger row.
colorScheme
"accent"|"neutral"
accent
Active-state colour. `accent` uses the theme's accent ramp; `neutral`
stays in the neutral palette (useful for secondary tab strips).
orientation
"horizontal"|"vertical"
horizontal
Layout direction. Drives arrow-key navigation (←/→ for horizontal,
↑/↓ for vertical).
fullWidth
boolean
false
Make each trigger flex to fill the row evenly.
dir
"ltr"|"rtl"
—
Override the inherited locale direction.
Accessibility
Section titled “Accessibility”- The tab list carries
role="tablist"; each trigger carriesrole="tab"witharia-selectedandaria-controlswired by the component. - Arrow keys cycle between tabs within the list;
Home/Endjump to first / last tab. TabsContentcarriesrole="tabpanel"and is linked to its trigger viaaria-labelledby.TabsIndicatorisaria-hidden="true"— purely decorative.- The
disabledprop setsaria-disabled="true"on the trigger, preventing keyboard focus and interaction.
Recipes
Section titled “Recipes”- Use
variant="solid"orvariant="enclosed"for more prominent visual styling. - Use
colorScheme="neutral"to tone down accent colour on the active trigger. - Use
fullWidthto make all triggers share equal width. - Omit
<TabsIndicator />when you prefer a static active border instead of the animated underline. - Pair with
size="sm"orsize="lg"for dense or spacious UIs.