Tabs
Tab navigation with an optional animated active state, wrapping Radix Tabs.
Tabs wraps @radix-ui/react-tabs. The list uses bg-muted; the active
trigger lifts onto a surface. Set animation={true} on TabsList to
enable a sliding active-tab highlight. List animation defaults to false;
content changes cross-fade with
animate-fade-in.
Installation
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@iammikz/srui";
Usage
Props
Each part passes through Radix's own prop types:
| Export | Notes |
|---|---|
Tabs | Root; defaultValue or value/onValueChange |
TabsList | The tab strip (bg-muted); animation?: boolean defaults to false |
TabsTrigger | One tab button; data-[state=active] lifts onto surface |
TabsContent | Panel for one value; animate-fade-in on change |
Examples
Animated highlight
<Tabs defaultValue="account">
<TabsList animation={true}>
<TabsTrigger value="account">Account</TabsTrigger>
<TabsTrigger value="password">Password</TabsTrigger>
</TabsList>
<TabsContent value="account">Account settings…</TabsContent>
<TabsContent value="password">Password settings…</TabsContent>
</Tabs>
Omit animation or set animation={false} for a static highlight.
Reduced-motion preferences disable the sliding transition even when enabled.
This option controls the list highlight and trigger transitions; TabsContent
retains its existing content fade.
Full-width tabs
Controlled / vertical
Both need state or layout CSS, so snippets only. Controlled tabs hold the
value yourself — value + onValueChange instead of defaultValue:
const [tab, setTab] = useState("account");
<Tabs value={tab} onValueChange={setTab}>
<TabsList>
<TabsTrigger value="account">Account</TabsTrigger>
<TabsTrigger value="password">Password</TabsTrigger>
</TabsList>
<TabsContent value="account">Account settings…</TabsContent>
<TabsContent value="password">Password settings…</TabsContent>
</Tabs>
Vertical tabs set orientation="vertical" on Tabs (arrow-key navigation
follows orientation) and stack the list with a flex-col className:
<Tabs orientation="vertical" defaultValue="account">
<TabsList className="flex h-fit flex-col">
<TabsTrigger value="account">Account</TabsTrigger>
<TabsTrigger value="password">Password</TabsTrigger>
</TabsList>
<TabsContent value="account">Account settings…</TabsContent>
<TabsContent value="password">Password settings…</TabsContent>
</Tabs>
Accessibility
Radix wires the tablist/tab/tabpanel ARIA pattern: arrow keys move
between triggers, Home/End jump to the edges, the active tab gets
aria-selected, and panels are labelled by their triggers. Content fade
is motion-safe:-gated.