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.
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>Playground
Showcase
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)
Tooltip
Rich tooltip card for product tours, feature walkthroughs, and contextual help. Supports title, image, subtitle, description, keyboard shortcuts, step counter, navigation buttons, a close button, 5 intent colors, 6 rounded variants, and all 12 arrow positions.
Accordion
Vertically stacked expandable items with animated open/close transitions, two variants, five sizes, and full keyboard navigation.