Navigation
Tabs
Switches between related panels of content in the same place.
Installation
npx sinaui add tabsCopy the src/lib/ui/tabs/ folder and tokens.css. No dependencies.
Examples
Basic
Click a tab and the indicator slides; use the arrow keys and it snaps. Disabled tabs are skipped.
The Canon of Medicine, taught in Europe's medical schools for centuries.
Al-Jabr gave algebra its name, solving problems like
x² + 10x = 39.Measured the radius of the Earth from a mountaintop.
Founded al-Qarawiyyin in Fez in 859, still teaching today.
<script lang="ts">
import * as Tabs from '#lib/ui/tabs/index.js';
let scholar = $state('ibn-sina');
</script>
<Tabs.Root bind:value={scholar}>
<Tabs.List label="Scholars">
<Tabs.Tab value="ibn-sina">Ibn Sina</Tabs.Tab>
<Tabs.Tab value="khwarizmi">Al-Khwarizmi</Tabs.Tab>
<Tabs.Tab value="biruni" disabled>Al-Biruni</Tabs.Tab>
<Tabs.Tab value="fihri">Fatima al-Fihri</Tabs.Tab>
</Tabs.List>
<Tabs.Panel value="ibn-sina">
The Canon of Medicine, taught in Europe's medical schools for centuries.
</Tabs.Panel>
<Tabs.Panel value="khwarizmi">
Al-Jabr gave algebra its name, solving problems like <code>x² + 10x = 39</code>.
</Tabs.Panel>
<Tabs.Panel value="biruni">Measured the radius of the Earth from a mountaintop.</Tabs.Panel>
<Tabs.Panel value="fihri">Founded al-Qarawiyyin in Fez in 859, still teaching today.</Tabs.Panel>
</Tabs.Root>Vertical, manual activation
Arrows move focus without switching; Enter or Space opens the tab. Use manual activation when panels are slow to render.
Light travels in straight lines, shown by experiment rather than argument alone.
We see because light enters the eye, not because the eye sends out rays.
A dark room with a small hole projects an inverted image of the world outside.
<script lang="ts">
import * as Tabs from '#lib/ui/tabs/index.js';
</script>
<!-- No value: the first enabled tab is selected, already in the server-rendered HTML. -->
<Tabs.Root orientation="vertical" activation="manual">
<Tabs.List label="Ibn al-Haytham's Book of Optics">
<Tabs.Tab value="light">Light</Tabs.Tab>
<Tabs.Tab value="vision">Vision</Tabs.Tab>
<Tabs.Tab value="camera">Camera obscura</Tabs.Tab>
</Tabs.List>
<Tabs.Panel value="light">
Light travels in straight lines, shown by experiment rather than argument alone.
</Tabs.Panel>
<Tabs.Panel value="vision">
We see because light enters the eye, not because the eye sends out rays.
</Tabs.Panel>
<Tabs.Panel value="camera">
A dark room with a small hole projects an inverted image of the world outside.
</Tabs.Panel>
</Tabs.Root>Props
Tabs.Root
| Prop | Type | Default |
|---|---|---|
value | string, bindable | first enabled tab |
orientation | 'horizontal' | 'vertical' | 'horizontal' |
activation | 'automatic' | 'manual' | 'automatic' |
Tabs.List, Tabs.Tab, Tabs.Panel
| Part | Props |
|---|---|
Tabs.List | label: names the tab set |
Tabs.Tab | value (required), disabled |
Tabs.Panel | value (required), matching its tab |
Accessibility
- Follows the WAI-ARIA tabs pattern with a roving tab stop: Tab enters at the selected tab, arrows move within the list.
- Left and right arrows follow reading direction in right-to-left pages.
- Hidden panels stay in the page, so each tab's
aria-controlsalways points at something that exists. - The indicator only moves with transforms, and snaps for keyboard moves and reduced motion.
| Key | Action |
|---|---|
| → / ← (↓ / ↑ vertical) | Next / previous tab, wrapping and skipping disabled tabs. |
| Home / End | First / last tab. |
| Enter / Space | Selects the focused tab (manual activation). |