Skip to Content
Puzzle
UI ComponentsNavigation

Tabs

Switch between related panels of content.

Organize related content into panels, with a single selected tab at a time. Compose Tabs with direct Tabs.Tab children, each with a unique id.

Import

import { Tabs } from "@puzzle-ui/ui";

Basic usage

tab supplies the trigger label, and children supplies the panel content. initialActiveId chooses the initial panel; otherwise the first enabled tab is selected.

390 × 240

Tab bar position

tabBarPosition supports top, bottom, left, and right. Left and right positions use vertical keyboard navigation.

390 × 540

Controlled selection

Use activeId with onActivate to own the selected tab. Do not combine controlled selection with initialActiveId.

390 × 240

Preserve panel state

Inactive panel contents are unmounted by default. forceMountContent keeps them mounted but hidden, preserving local state and uncontrolled form values. Type a note, switch tabs, then return to see it preserved.

390 × 300

Disabled tabs and RTL

Set disabled on a tab to prevent selection and skip it during keyboard navigation. Provide dir="rtl" on Tabs for right-to-left horizontal arrow-key behavior.

390 × 280

API

Tabs

PropTypeDefaultDescription
childrenReactNodeRequiredDirect Tabs.Tab children.
tabBarPosition"top" | "bottom" | "left" | "right""top"Position and orientation of the tab bar.
initialActiveIdstringFirst enabled tabInitial uncontrolled selection.
activeIdstring-Controlled selection. Invalid or disabled IDs fall back to the first enabled tab.
onActivate(tabId: string) => void-Called when a tab is activated.
forceMountContentbooleanfalseKeeps inactive panel contents mounted and hidden.
classNamestring-Additional class on the root div.
dir"ltr" | "rtl" | "auto"-Root text direction; use explicit rtl for RTL keyboard navigation.

Other native div attributes are forwarded to the root, except onChange.

Tabs.Tab

TabsTab is also exported as a named alias of Tabs.Tab, with the same props and direct-child requirement.

PropTypeDefaultDescription
idstringRequiredUnique tab identifier.
tabReactNodeRequiredContent of the tab button.
childrenReactNodeRequiredPanel content.
disabledbooleanfalsePrevents focus and selection.

Accessibility

Tabs use automatic activation: arrow-key focus changes the selected panel. Horizontal tabs use Left/Right; vertical tabs use Up/Down. Home and End move to the first and last enabled tab. Tab buttons expose aria-selected and aria-controls, and each panel is labelled by its trigger.

;