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
npm install our-package
yarn add our-package
pnpm add our-package
Props
<Tabs />
Prop | Type | Default | Description |
---|---|---|---|
defaultTab | string | "" | The tab key to activate on load |
class | string | "" | Additional classes for the wrapper |
<TabButton />
Prop | Type | Default | Description |
---|---|---|---|
tab | string | required | Tab key that maps to a panel |
selected | boolean | false | Whether this tab is initially active |
id | string | tab-{tab} | Button ID for accessibility (auto-generated) |
controls | string | panel-{tab} | ID of the controlled panel (auto-generated) |
class | string | "" | Additional classes |
<TabPanel />
Prop | Type | Default | Description |
---|---|---|---|
tab | string | required | Key that matches the tab button |
class | string | "" | 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
Slot | Description |
---|---|
tabs | Where all <TabButton /> components go |
content | Where 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
, andcontrols