Compositereadycomponentready
Tabs
A tablist, trigger, and panel set for switching between related sections of content.
Import
import { Tabs, TabsContent, TabsList, TabsTrigger } from 'radcn/tabs'Live package example
The upstream Account and Password card form composition ported to RadCN Tabs.
Tabs Demo
The upstream Account and Password card form composition ported to RadCN Tabs.
Account
Make changes to your account here. Click save when you're done.
Password
Change your password here. After saving, you'll be logged out.
import { Button } from 'radcn/button'
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'radcn/card'
import { Input } from 'radcn/input'
import { Label } from 'radcn/label'
import { Tabs, TabsContent, TabsList, TabsTrigger } from 'radcn/tabs'
export function TabsDemo() {
return (
<div class="flex w-full max-w-sm flex-col gap-6" style="display:flex;width:100%;max-width:24rem;flex-direction:column;gap:1.5rem;">
<Tabs defaultValue="account">
<TabsList>
<TabsTrigger value="account">Account</TabsTrigger>
<TabsTrigger value="password">Password</TabsTrigger>
</TabsList>
<TabsContent value="account">
<Card>
<CardHeader>
<CardTitle>Account</CardTitle>
<CardDescription>Make changes to your account here. Click save when you're done.</CardDescription>
</CardHeader>
<CardContent class="grid gap-6" style="display:grid;gap:1.5rem;">
<div class="grid gap-3" style="display:grid;gap:0.75rem;">
<Label for="tabs-demo-name">Name</Label>
<Input id="tabs-demo-name" value="Pedro Duarte" />
</div>
<div class="grid gap-3" style="display:grid;gap:0.75rem;">
<Label for="tabs-demo-username">Username</Label>
<Input id="tabs-demo-username" value="@peduarte" />
</div>
</CardContent>
<CardFooter>
<Button>Save changes</Button>
</CardFooter>
</Card>
</TabsContent>
<TabsContent value="password">
<Card>
<CardHeader>
<CardTitle>Password</CardTitle>
<CardDescription>Change your password here. After saving, you'll be logged out.</CardDescription>
</CardHeader>
<CardContent class="grid gap-6" style="display:grid;gap:1.5rem;">
<div class="grid gap-3" style="display:grid;gap:0.75rem;">
<Label for="tabs-demo-current">Current password</Label>
<Input id="tabs-demo-current" type="password" />
</div>
<div class="grid gap-3" style="display:grid;gap:0.75rem;">
<Label for="tabs-demo-new">New password</Label>
<Input id="tabs-demo-new" type="password" />
</div>
</CardContent>
<CardFooter>
<Button>Save password</Button>
</CardFooter>
</Card>
</TabsContent>
</Tabs>
</div>
)
}Installation
Intended future install command. RadCN is private and not published to npm yet, so this snippet documents the target user-facing API rather than something external consumers can run today.
pnpm add radcn # intended future package
import { Tabs, TabsContent, TabsList, TabsTrigger } from 'radcn/tabs'Theming
RadCN tokens read the resolved theme from the document. Store the user's preference separately, then resolve system preferences to a concrete light or dark theme before setting package tokens.
<html data-radcn-theme-mode="system" data-radcn-theme="dark">
...
</html>Accessibility
- Enhanced tabs apply tab, tabpanel, aria-selected, aria-controls, and keyboard roving focus behavior.
- Triggers are native buttons and panels are real content regions.
- Supports horizontal and vertical orientation plus automatic or manual activation modes.
Customization
- List, trigger, and content parts expose stable RadCN classes and data-state values.
- Orientation and active state can be styled through public data attributes and tokens.
- The Account/Password demo composes Tabs with Card, Label, Input, and Button; defaultValue="account" maps to server markup plus browser-enhanced data-value state.
- Upstream wrapper utilities flex, w-full, max-w-sm, flex-col, and gap-6 map to class plus explicit style evidence in RadCN docs.
Remix 3 Notes
- RadCN tabs use browser enhancement for selection and keyboard behavior instead of React component state.
- Server markup remains readable and package-owned, while interactive selection is attached explicitly by enhanceTabs.
- use client, React component props, and Radix TabsPrimitive.Root/List/Trigger/Content map to server-rendered RadCN parts with scoped enhanceTabs behavior.
- cva, VariantProps, tabsListVariants, className, Tailwind utilities, cn, data-slot, data-orientation, data-variant, and data-state map to RadCN props, class, public data-radcn hooks, data-orientation, and data-state.
- AppWindowIcon and CodeIcon are unused upstream lucide-react imports and are not RadCN package dependencies.
- Upstream Input defaultValue maps to RadCN Input value for static server-rendered demo defaults.
- Vendor source remains read-only evidence and is not imported by RadCN.
