Tabs

An accessible tab interface with buttons and panels for switching between related content.

Last updated: July 1, 2025

Overview

The Tabs component provides a structured, accessible way to organize content in tabbed sections. It consists of three subcomponents:

  • <Tabs /> — wrapper for the entire tab interface
  • <TabButton /> — individual tab selector
  • <TabPanel /> — content area corresponding to each tab

Supports keyboard navigation, ARIA roles, and optional icons.


Usage

<Tabs defaultTab="npm">
  <TabButton slot="tabs" tab="npm">npm</TabButton>
  <TabButton slot="tabs" tab="yarn">yarn</TabButton>
  <TabButton slot="tabs" tab="pnpm">pnpm</TabButton>

  <TabPanel slot="content" tab="npm">
    ```bash
    npm install our-package
    ```
  </TabPanel>
  <TabPanel slot="content" tab="yarn">
    ```bash
    yarn add our-package
    ```
  </TabPanel>
  <TabPanel slot="content" tab="pnpm">
    ```bash
    pnpm add our-package
    ```
  </TabPanel>
</Tabs>

Example


Props

<Tabs />

PropTypeDefaultDescription
defaultTabstring""The tab key to activate on load
classstring""Additional classes for the wrapper

<TabButton />

PropTypeDefaultDescription
tabstringrequiredTab key that maps to a panel
selectedbooleanfalseWhether this tab is initially active
idstringtab-{tab}Button ID for accessibility (auto-generated)
controlsstringpanel-{tab}ID of the controlled panel (auto-generated)
classstring""Additional classes

<TabPanel />

PropTypeDefaultDescription
tabstringrequiredKey that matches the tab button
classstring""Additional classes

Accessibility

Each TabButton uses role="tab" and each TabPanel uses role="tabpanel", with aria-selected, aria-controls, and tabindex for full keyboard support.

Keyboard navigation

  • ←/→ keys to switch between tabs
  • Tab to move focus into panels
  • ARIA roles enable screen reader support

Icons in Tab Buttons

You can pass icons using slots:

<TabButton tab="docs">
  <BookIcon slot="left-icon" />
  Documentation
</TabButton>

<TabButton tab="code">
  Source
  <CodeIcon slot="right-icon" />
</TabButton>

Icons are optional and work on both sides of the label.


Styling and State

The active tab button is visually distinguished via class toggling in the included JavaScript. Panels show/hide automatically.

/* Active classes (JS toggled) */
.text-sky-600
.border-sky-600
/* In dark mode */
.dark\:text-sky-300
.dark\:border-sky-400

Slot

SlotDescription
tabsWhere all <TabButton /> components go
contentWhere all <TabPanel /> components go

Best Practices

  • Use defaultTab to control which tab is shown first
  • Make sure tab values match between buttons and panels
  • Include icons only when they add useful context
  • Use consistent naming for tab, id, and controls
Edit on GitHub
Was this helpful?