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:

ExportNotes
TabsRoot; defaultValue or value/onValueChange
TabsListThe tab strip (bg-muted); animation?: boolean defaults to false
TabsTriggerOne tab button; data-[state=active] lifts onto surface
TabsContentPanel 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.