Skip to content

Tabs

Tabs

Basic (Uncontrolled)

Controlled

import { Tabs, TabList, Tab, TabPanel } from "@f0rbit/ui";
<Tabs defaultValue="overview">
<TabList>
<Tab value="overview">Overview</Tab>
<Tab value="features">Features</Tab>
</TabList>
<TabPanel value="overview">
<p>Overview content here.</p>
</TabPanel>
<TabPanel value="features">
<p>Features content here.</p>
</TabPanel>
</Tabs>

Use defaultValue to set the initially active tab:

<Tabs defaultValue="first">
<TabList>
<Tab value="first">First</Tab>
<Tab value="second">Second</Tab>
</TabList>
<TabPanel value="first">First panel content</TabPanel>
<TabPanel value="second">Second panel content</TabPanel>
</Tabs>

For full control, use value and onValueChange:

const [activeTab, setActiveTab] = createSignal("tab1");
<Tabs value={activeTab()} onValueChange={setActiveTab}>
<TabList>
<Tab value="tab1">Tab 1</Tab>
<Tab value="tab2">Tab 2</Tab>
</TabList>
<TabPanel value="tab1">Controlled content 1</TabPanel>
<TabPanel value="tab2">Controlled content 2</TabPanel>
</Tabs>

The Tabs component supports keyboard interaction following WAI-ARIA patterns:

KeyAction
TabMoves focus into the tab list, landing on the active tab
Enter / SpaceActivates the focused tab (if not already active)
Tab (from tab list)Moves focus to the active panel content

Note: Arrow key navigation between tabs is not currently implemented. Users can navigate between tabs using Tab to move focus out and back into the tab list, or by clicking directly on tabs.

The Tabs component implements proper ARIA attributes for screen reader support:

  • TabList: role="tablist" - identifies the container as a tab list
  • Tab: role="tab" with aria-selected - indicates the tab’s selection state
  • TabPanel: role="tabpanel" with hidden - associates content with its tab
  • Active tab has tabindex="0" (focusable in normal tab order)
  • Inactive tabs have tabindex="-1" (focusable only programmatically)
  • Only the active panel is visible; others are hidden from the DOM

Screen readers will announce:

  • The tab role and its label
  • Whether the tab is selected
  • The position in the tab list (e.g., “tab 1 of 3”)
PropTypeDefaultDescription
defaultValuestringInitial active tab (uncontrolled)
valuestringControlled active tab value
onValueChange(value: string) => voidCallback when active tab changes
PropTypeDefaultDescription
valuestringUnique identifier for this tab
childrenJSX.ElementTab label content
PropTypeDefaultDescription
valuestringMust match a Tab value to associate content
childrenJSX.ElementPanel content