Tabs
Segmented navigation component for switching between related views.
The Tabs component lets users switch between related views without leaving the page. It is built on Radix UI Tabs and styled with PyColors tokens for consistent theming.
Use Tabs for:
- Settings sections (Profile / Billing / Security)
- Dashboards (Overview / Activity / Logs)
- Compact UIs (filters, panels, segmented content)
Import
import {
Tabs,
TabsList,
TabsTrigger,
TabsContent,
} from "@/components/ui/tabs";Usage
Account settings content
<Tabs defaultValue="account">
<TabsList aria-label="Settings tabs">
<TabsTrigger value="account">Account</TabsTrigger>
<TabsTrigger value="password">Password</TabsTrigger>
</TabsList>
<TabsContent value="account">...</TabsContent>
<TabsContent value="password">...</TabsContent>
</Tabs>import {
Tabs,
TabsList,
TabsTrigger,
TabsContent,
} from "@/components/ui/tabs";
export function SettingsTabs() {
return (
<Tabs defaultValue="account" className="w-full max-w-xl">
<TabsList aria-label="Settings tabs">
<TabsTrigger value="account">Account</TabsTrigger>
<TabsTrigger value="password">Password</TabsTrigger>
</TabsList>
<TabsContent value="account">
<div className="rounded-md border bg-card p-4 text-sm">
Account settings content
</div>
</TabsContent>
<TabsContent value="password">
<div className="rounded-md border bg-card p-4 text-sm">
Password settings content
</div>
</TabsContent>
</Tabs>
);
}Sizes
TabsList and TabsTrigger accept a size prop to adapt density.
Small tabs content
Medium tabs content
Large tabs content
<TabsList size="sm">...</TabsList>
<TabsTrigger size="sm" value="...">...</TabsTrigger>import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
export function SizedTabsList() {
return (
<Tabs defaultValue="one">
<TabsList size="sm" aria-label="Small tabs">
<TabsTrigger size="sm" value="one">One</TabsTrigger>
<TabsTrigger size="sm" value="two">Two</TabsTrigger>
</TabsList>
</Tabs>
);
}Available sizes
| Size | Description |
|---|---|
sm | Dense UIs (filters, toolbars) |
md | Default density |
lg | Comfortable spacing (marketing / onboarding) |
API
Components
| Component | Description |
|---|---|
Tabs | Root container (Radix TabsPrimitive.Root) |
TabsList | Trigger list (supports size) |
TabsTrigger | Individual trigger (supports size) |
TabsContent | Content panel |
Props
TabsextendsTabsPrimitive.TabsPropsTabsListextendsTabsPrimitive.TabsListProps+{ size?: "sm" | "md" | "lg" }TabsTriggerextendsTabsPrimitive.TabsTriggerProps+{ size?: "sm" | "md" | "lg" }TabsContentextendsTabsPrimitive.TabsContentProps
TypeScript types
export type TabsSize = "sm" | "md" | "lg";Accessibility
- Always provide an
aria-labelonTabsList(or associate with a visible heading). - Ensure each
TabsTriggerhas clear text (avoid icon-only triggers). - Keyboard support is built-in via Radix (Arrow keys to navigate triggers).
- Keep tab labels short and descriptive.
Design guidelines
- Use Tabs when the views are peers (same hierarchy).
- Don’t hide critical actions behind tabs; keep actions visible in the page header.
- Prefer 2–5 tabs; more than that usually becomes a navigation problem.
- Keep content height stable when possible to reduce layout shift.