Playground
A segmented tab bar with keyboard support. Labels come from a JSON attribute. Each panel is a slotted element whose slot is the label in kebab-case.
Examples
With panels
A light, fast shuttle built for orbital hops.
Payload 4t · Δv 9.4 km/s · 2 engines
Commander, pilot and one very good dog.
<sb-tabs labels='["Overview","Specs","Crew"]' style="inline-size: 100%">
<p slot="overview">A light, fast shuttle built for orbital hops.</p>
<p slot="specs">Payload 4t · Δv 9.4 km/s · 2 engines</p>
<p slot="crew">Commander, pilot and one very good dog.</p>
</sb-tabs>
Follow the selection
<div data-signals:_tab="'Home'">
<sb-tabs labels='["Home","Docs","API"]' data-on:sb-tab-change="$_tab = evt.detail.label"></sb-tabs>
<p data-text="'Current: ' + $_tab"></p>
</div>
Accessibility
It follows the WAI-ARIA tabs pattern: role="tablist", tab and tabpanel, a roving tabindex, and arrow keys, Home and End for navigation.
Installation
Add Datastar with Rocket and the Starbase autoloader once per page, then use the tag. The autoloader imports each component the first time its tag appears, including tags added later by a Datastar morph.
<!-- Once per page: Datastar with Rocket, and the Starbase autoloader.
It loads every <sb-…> component the first time its tag appears. -->
<script type="importmap">
{ "imports": { "datastar": "https://cdn.jsdelivr.net/gh/starfederation/datastar@v1.0.4/bundles/datastar-rocket.js" } }
</script>
<script type="module" src="https://rocket.libretto.ch/c/autoloader.js"></script>
<!-- Optional, no flash of undefined elements: class="sb-cloak" on <html>, and -->
<style>.sb-cloak :not(:defined) { visibility: hidden }</style>
<sb-tabs labels='["Home","Docs","API"]'></sb-tabs>
<!-- Or skip the autoloader and load just this component: -->
<!-- <script type="module" src="https://rocket.libretto.ch/c/tabs/tabs.js"></script> -->API reference
Props
| Attribute | Type | Default | Description |
|---|---|---|---|
labels | array | [
"Home",
"Docs",
"API"
] | Tab labels, as a JSON array. |
selected | number | 0 | Index of the initially selected tab. |
Slots
| Name | Description |
|---|---|
<label-slug> | Panel content per tab, e.g. slot="docs" for a tab labelled "Docs". |
Events
| Name | Description |
|---|---|
sb-tab-change | detail: { index, label }. |