Tabs

An animated tab switcher with two visual variants. Both share the same controlled / uncontrolled API — only the appearance changes. Content rendering is left to the caller.

Underline (default)

The default underline variant: a sliding bottom indicator under the active tab.

Controlled

Active: activity

Count badges

Add count to any tab to show a pill badge. Badge opacity and background respond to active and hover state.

Small size

Use size="sm" for a compact 12px tab bar.

Segment variant

A classic segmented control: tinted container background, active tab gets a raised pill matching the page background. label accepts any ReactNode — pass icons or text.

Props

PropTypeDefaultDescription
tabsTab[]Array of tab descriptors.
variant'underline' | 'segment''underline'Visual style.
valuestringControlled active tab value.
defaultValuestringtabs[0]Initial tab in uncontrolled mode.
onChange(value: string) => voidCalled when the user clicks a tab.
onValueChange(value: string) => voidAlias for onChange.
size'xs' | 'sm' | 'md' | 'lg''md'Controls text size and button dimensions across all variants.
indicatorHeightnumber4Indicator thickness in px. underline variant only.
classNamestringExtra classes on the container.

Tab

FieldTypeDescription
valuestringUnique identifier for the tab.
labelReactNodeContent rendered inside the tab — string, icon, or any element.
countnumberCount badge shown next to the label. underline variant only.
titlestringTooltip text. Useful for icon-only segment tabs.

Compound API

Instead of the data-driven tabs prop, you can compose the tab bar and its panels from sub-components. Pass value / defaultValue and onValueChange (or onChange) to Tabs, then place TabsList / TabsTrigger / TabsContent as children. Each TabsContent renders only when its value matches the active tab.

tsx
<Tabs defaultValue="overview" onValueChange={setTab}>
  <TabsList>
    <TabsTrigger value="overview">Overview</TabsTrigger>
    <TabsTrigger value="activity">Activity</TabsTrigger>
  </TabsList>
  <TabsContent value="overview">…</TabsContent>
  <TabsContent value="activity">…</TabsContent>
</Tabs>

TabsList

Row container for the triggers. Accepts any <div> props plus className.

TabsTrigger

PropTypeDefaultDescription
valuestringIdentifier this trigger activates. Required.
classNamestringExtra classes on the button.

Also forwards native <button> attributes (onClick, disabled, …).

TabsContent

PropTypeDefaultDescription
valuestringPanel is shown only when this matches the active tab. Required.
classNamestringExtra classes on the panel.