Tessera UI

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/ui

Usage

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

Preview

Showcase

Preview

API Reference

Tabs (Root) props

PropTypeDefaultDescription
valueanyControlled active tab value
defaultValueany0Default active tab (uncontrolled)
onValueChange(value: any) => voidCallback 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
fullWidthbooleanfalseTabs stretch to fill container width
orientation"horizontal" | "vertical""horizontal"Layout direction of tabs
dir"ltr" | "rtl"Text/layout direction

TabsList props

PropTypeDefaultDescription
activateOnFocusbooleanfalseActivate tab on arrow-key focus (vs Enter/Space)
loopFocusbooleantrueLoop keyboard focus at list edges

Tab props

PropTypeDefaultDescription
valueanyrequiredUnique tab identifier
disabledbooleanfalseDisable this tab
iconReactNodeLeading icon element
badgenumber | booleanCount badge (number) or dot indicator (true)
closablebooleanfalseShow close button
onClose() => voidClose button callback

TabsPanel props

PropTypeDefaultDescription
valueanyrequiredMust match a Tab value
keepMountedbooleanfalseKeep 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

KeyAction
TabMove focus to the tab list, then to the active panel
ArrowLeft / ArrowRightMove between tabs (horizontal)
ArrowUp / ArrowDownMove between tabs (vertical)
Home / EndJump to first/last tab
Enter / SpaceActivate focused tab (when activateOnFocus is false)

Accessibility

  • Uses role="tablist", role="tab", and role="tabpanel" via Base UI primitives
  • aria-selected set on active tab
  • aria-controls / aria-labelledby link 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)

On this page