VayuUI

Tabs

A set of layered sections of content, known as tab panels, displayed one at a time.

Installation

npx vayu-ui init
npx vayu-ui add tabs
npx vayu-ui add -t tabs

Usage

Tabs Example

Account

Make changes to your account here. Click save when you're done.

Vertical Tabs

Profile Settings

Manage your personal information and preferences.

Disabled Tab

This tab is active and can be selected.

Tabs with Actions

Overview Section

Get a quick summary of your content and recent activity.

<h2 id="account-label">Account Settings</h2>
<Tabs defaultValue="account" className="mb-8">
  <Tabs.List aria-labelledby="account-label" className="grid w-full grid-cols-2">
    <Tabs.Trigger value="account">Account</Tabs.Trigger>
    <Tabs.Trigger value="password">Password</Tabs.Trigger>
  </Tabs.List>
  <Tabs.Content value="account">
    <p>Manage your account settings and preferences.</p>
  </Tabs.Content>
  <Tabs.Content value="password">
    <p>Change your password and security settings.</p>
  </Tabs.Content>
</Tabs>

<h3>Vertical</h3>
<Tabs defaultValue="profile" orientation="vertical" className="mb-8">
  <Tabs.List aria-label="Settings navigation" className="min-w-50">
    <Tabs.Trigger value="profile">Profile</Tabs.Trigger>
    <Tabs.Trigger value="settings">Settings</Tabs.Trigger>
    <Tabs.Trigger value="notifications">Notifications</Tabs.Trigger>
  </Tabs.List>
  <Tabs.Content value="profile" className="pl-4">
    <p>Manage your personal information and preferences.</p>
  </Tabs.Content>
  <Tabs.Content value="settings" className="pl-4">
    <p>Configure your application preferences and options.</p>
  </Tabs.Content>
  <Tabs.Content value="notifications" className="pl-4">
    <p>Choose which notifications you want to receive.</p>
  </Tabs.Content>
</Tabs>

<h3>With disabled tab</h3>
<Tabs defaultValue="enabled">
  <Tabs.List aria-label="Tab options" className="grid w-full grid-cols-2">
    <Tabs.Trigger value="enabled">Enabled Tab</Tabs.Trigger>
    <Tabs.Trigger value="disabled" disabled>Disabled Tab</Tabs.Trigger>
  </Tabs.List>
  <Tabs.Content value="enabled">
    <p>This tab is active and can be selected.</p>
  </Tabs.Content>
</Tabs>

Anatomy

<Tabs defaultValue="tab1">
  <Tabs.List aria-label="Example tabs">
    <Tabs.Trigger value="tab1">Tab 1</Tabs.Trigger>
    <Tabs.Trigger value="tab2">Tab 2</Tabs.Trigger>
  </Tabs.List>
  <Tabs.Content value="tab1">Content 1</Tabs.Content>
  <Tabs.Content value="tab2">Content 2</Tabs.Content>
</Tabs>

Accessibility

  • Keyboard navigation: Arrow keys move focus between tabs (left/right for horizontal, up/down for vertical). Home jumps to the first tab, End jumps to the last.
  • Roving tabindex: Only the active tab has tabIndex={0}; all others are -1. Arrow keys move focus and activate the tab simultaneously.
  • Activation: Pressing Enter or Space on a focused trigger activates the associated tab panel.
  • Disabled tabs: Skipped during keyboard navigation and marked with aria-disabled="true".
  • Auto-focus: When autoFocus is set on Tabs, focus moves to the tab panel when it becomes active.

ARIA attributes

ElementAttributeValue
Tabs.Listroletablist
Tabs.Listaria-orientation"horizontal" or "vertical"
Tabs.Listaria-label / aria-labelledbyAccessible name for the tab list
Tabs.Triggerroletab
Tabs.Triggeraria-selectedtrue or false
Tabs.Triggeraria-controlsID of the associated tab panel
Tabs.Triggeraria-disabledtrue when disabled
Tabs.Contentroletabpanel
Tabs.Contentaria-labelledbyID of the associated tab trigger

Screen reader behavior

  • Screen readers announce Tabs.List as a "tab list" using the provided aria-label or aria-labelledby.
  • Each trigger is announced as a "tab" with its label text and selection state (e.g., "Account, tab, selected" or "Password, tab").
  • When a tab is activated, the associated panel is announced as a "tab panel" linked to the trigger via aria-labelledby.
  • Disabled triggers are announced as unavailable and are not included in the tab navigation sequence.
  • Switching tabs moves the reading cursor to the new panel content automatically.

Component Folder Structure

Tab/
├── Tab.tsx           # Context provider + compound component wiring
├── TabsList.tsx      # Tablist container with keyboard navigation
├── TabsTrigger.tsx   # Tab trigger button
├── TabsContent.tsx   # Tab panel content
├── hooks.ts          # TabsContext + useTabsContext hook
├── types.ts          # All interfaces and type exports
├── index.ts          # Public API
└── README.md         # Internal documentation

Props

Tabs

PropTypeDefaultDescription
defaultValuestring-The value of the tab to activate by default (uncontrolled).
valuestring-The controlled value of the active tab.
onValueChange(value: string) => void-Called when the active tab changes.
orientation"horizontal" | "vertical""horizontal"Layout direction of the tab list.
autoFocusbooleanfalseMove focus to the tab panel when activated.
classNamestring-Additional CSS classes.
childrenReactNode-Tabs.List and Tabs.Content components.

Tabs.List

PropTypeDefaultDescription
aria-labelstring-Accessible name for the tab list.
aria-labelledbystring-ID of an element that labels the tab list.
classNamestring-Additional CSS classes.
childrenReactNode-Tabs.Trigger components.

Tabs.Trigger

PropTypeDefaultDescription
valuestring-Unique value matching a Tabs.Content.
disabledbooleanfalsePrevents the tab from being activated.
classNamestring-Additional CSS classes.
childrenReactNode-Label content.

Tabs.Content

PropTypeDefaultDescription
valuestring-Unique value matching a Tabs.Trigger.
forceMountbooleanfalseKeep the panel mounted when inactive (hidden with hidden attribute).
classNamestring-Additional CSS classes.
childrenReactNode-Panel content.

On this page