Tabs
Organise content into switchable panels with animated indicators, four variants, five sizes, five intents, icon/badge/closable support, vertical orientation, and full RTL/keyboard navigation.
Playground
Installation
pnpm add @tessinaui/uiUsage
import { Tabs, TabsList, Tab, TabsPanel } from "@tessinaui/ui";<Tabs defaultValue="account">
<TabsList>
<Tab value="account">Account</Tab>
<Tab value="password">Password</Tab>
<Tab value="notifications">Notifications</Tab>
</TabsList>
<TabsPanel value="account">
Manage your account settings and preferences.
</TabsPanel>
<TabsPanel value="password">
Change your password and enable two-factor authentication.
</TabsPanel>
<TabsPanel value="notifications">
Configure which notifications you receive.
</TabsPanel>
</Tabs>Examples
Default
A basic set of tabs with the default line variant and switchable panels.
Variants
Four visual styles — line, enclosed, pill, and soft.
Sizes
Five sizes from xs to xl.
Intents
Colour the active indicator and text with none, error, warning, success, or info.
Icons & Badges
Tabs with leading icons, count and dot badges, plus a disabled tab.
Vertical
A vertical tab list with panels rendered alongside.
API Reference
Tabs (Root) props
| Prop | Type | Default | Description |
|---|---|---|---|
value | any | — | Controlled active tab value |
defaultValue | any | 0 | Default active tab (uncontrolled) |
onValueChange | (value: any) => void | — | Callback when active tab changes |
variant | "line" | "enclosed" | "pill" | "soft" | "line" | Visual style of the tab bar |
size | "xs" | "sm" | "md" | "lg" | "xl" | "md" | Size of all tabs |
rounded | "none" | "sm" | "md" | "lg" | "xl" | "full" | "full" | Corner rounding for pill/soft/enclosed variants |
intent | "none" | "error" | "warning" | "success" | "info" | "none" | Colour intent for active indicator/text |
fullWidth | boolean | false | Tabs stretch to fill container width |
orientation | "horizontal" | "vertical" | "horizontal" | Layout direction of tabs |
dir | "ltr" | "rtl" | — | Text/layout direction |
TabsList props
| Prop | Type | Default | Description |
|---|---|---|---|
activateOnFocus | boolean | false | Activate tab on arrow-key focus (vs Enter/Space) |
loopFocus | boolean | true | Loop keyboard focus at list edges |
Tab props
| Prop | Type | Default | Description |
|---|---|---|---|
value | any | required | Unique tab identifier |
disabled | boolean | false | Disable this tab |
icon | ReactNode | — | Leading icon element |
badge | number | boolean | — | Count badge (number) or dot indicator (true) |
closable | boolean | false | Show close button |
onClose | () => void | — | Close button callback |
TabsPanel props
| Prop | Type | Default | Description |
|---|---|---|---|
value | any | required | Must match a Tab value |
keepMounted | boolean | false | Keep panel in DOM when hidden |
Variants
Line (default)
Bottom underline indicator that slides between tabs. The most common pattern.
Enclosed
Card-style tabs where the active tab connects visually to the content panel with matching borders.
Pill
Active tab highlighted with a rounded pill background. Indicator slides with animation.
Soft
Subtle rounded-rectangle background on the active tab.
Keyboard Navigation
| Key | Action |
|---|---|
Tab | Move focus to the tab list, then to the active panel |
ArrowLeft / ArrowRight | Move between tabs (horizontal) |
ArrowUp / ArrowDown | Move between tabs (vertical) |
Home / End | Jump to first/last tab |
Enter / Space | Activate focused tab (when activateOnFocus is false) |
Accessibility
- Uses
role="tablist",role="tab", androle="tabpanel"via Base UI primitives aria-selectedset on active tabaria-controls/aria-labelledbylink tabs to panels- Disabled tabs are skipped during keyboard navigation
- Closable tab close button is separately focusable with
role="button" - Focus ring visible on keyboard navigation (
focus-visible:ring-2)
Table
A complete primitive set for tabular data — header, body, footer, sortable columns, sticky header, row states, plus cell helpers for avatars, status, currency amounts, and actions. Designed in the Wise / PrimeReact tradition.
Textarea
Multi-line text input with intent variants, sizes, label positions, character counter, auto-resize, and LTR/RTL support.