Tabs
A set of layered panels where only the selected one is shown at a time.
Usage
Tabs lets a single region host several panels and shows one at a time. Each TabsTrigger is matched to a TabsContent by its value; selecting a trigger reveals its panel and slides the active indicator across the list. Drive it uncontrolled with defaultValue, or controlled with value + onValueChange.
The visual style is set once on the root and flows down through context: variant (pill or line), size (sm/md/lg), and orientation (horizontal or vertical). Override any single part by passing the same prop directly to a TabsList or TabsTrigger.
Reach for Tabs to switch between alternate views of the same area. For navigating between pages or routes, use Navigation or a Breadcrumb instead — tabs are for in-place content, not page navigation.
Examples
Default
The pill variant: a filled track with a sliding white pill behind the active tab. Set the starting tab with defaultValue and pair every TabsTrigger with a TabsContent of the same value.
Variants
pill rides on a filled track; line drops the track for a minimal underline that slides under the active tab. Pick line for dense layouts or when the tabs sit directly above their content.
Sizes
Three sizes scale the triggers' padding and text together: sm, md (default), and lg. Set size on the root and it flows to every trigger.
Vertical
Set orientation="vertical" to stack the triggers in a column beside their panels — handy for settings screens. The arrow keys follow the axis (↑/↓), and the active indicator runs vertically.
With icons & badges
Drop an icon marked data-icon="start" before a trigger's label and it's sized and spaced automatically. The data-icon attribute also tells the trigger to tighten its padding on that side. Triggers accept any children, so a trailing Badge — say a count — sits inline after the label.
Icon-only
Give each trigger an icon-* size (icon-sm/icon-md/icon-lg) for square, label-less tabs — a compact view switcher, for instance. Pass an aria-label so each tab still has an accessible name.
Controlled
Hold the active tab in state with value + onValueChange to drive it from elsewhere — here Back/Next buttons step through a wizard while the tabs reflect the current step.
Disabled
Add disabled to a TabsTrigger to make it non-interactive; arrow-key navigation skips over it.
RTL
Every Appica UI component supports right-to-left layouts out of the box. Set the dir attribute on a container (commonly your <html> element) so CSS logical properties resolve correctly, and wrap your tree in DirectionProvider so direction-aware behavior — roving focus, indicator placement, and the like — follows the same direction.
The tabs flow from the right, the active indicator slides along the resolved direction, and ←/→ arrow keys swap roles. For setup details and caveats, see the RTL guide.
API reference
Tabs wraps Base UI's Tabs. The root provides the variant/size/orientation context; each part forwards ref and its remaining native attributes to the underlying element.
Tabs
The root. Owns the selected value and renders a <div>.
TabsList
The row (or column) of triggers, with the sliding active indicator built in. Renders a <div role="tablist">.
TabsTrigger
One tab button. Renders a <button role="tab">.
TabsContent
The panel revealed by its matching trigger. Renders a <div role="tabpanel">.
Accessibility
- The parts map to the WAI-ARIA tabs pattern:
TabsListis arole="tablist", eachTabsTriggerarole="tab", and eachTabsContentarole="tabpanel"wired together witharia-controls/aria-labelledby. - The list is a single tab stop: Tab moves focus into the active trigger, and the arrow keys move focus between triggers — ←/→ when horizontal, ↑/↓ when vertical — wrapping unless
loopFocusisfalse. - By default a tab activates on Enter/Space; set
activateOnFocusto switch panels as focus moves instead. disabledtriggers are removed from the tab order and skipped by arrow navigation.- An icon-only
TabsTriggerhas no visible text, so give it anaria-label. - The indicator and panel transitions honour
prefers-reduced-motion.