Tabs · animated
An indicator that slides between tabs, panels that ease in from the side you picked, three looks, and full keyboard support.
Line
Panels are built once and toggled with CSS — state is preserved across switches. The indicator slides; the panel eases in from the side you picked.
Arrow keys, Home and End move between tabs once one has focus.
A longer label — the indicator animates its width as well as its position.
Pills
Panels are built once and toggled with CSS — state is preserved across switches. The indicator slides; the panel eases in from the side you picked.
Arrow keys, Home and End move between tabs once one has focus.
A longer label — the indicator animates its width as well as its position.
Enclosed
Panels are built once and toggled with CSS — state is preserved across switches. The indicator slides; the panel eases in from the side you picked.
Arrow keys, Home and End move between tabs once one has focus.
A longer label — the indicator animates its width as well as its position.
Usage
import { signal } from "./index.js";import { Tabs } from "./components/tabs.js"; // panels are built once and toggled with CSS, so their state survives switches.// The indicator slides to the active tab; the panel eases in from that side.Tabs({ tabs: [ { id: "a", label: "Overview", content: () => html`<p>First panel</p>` }, { id: "b", label: "Activity", content: () => html`<p>Second panel</p>` },] }) Tabs({ variant: "pills", tabs }) // "line" (default) · "pills" · "enclosed"Tabs({ stretch: true, tabs }) // tabs share the full width const tab = signal("b"); // control / read the active tabTabs({ value: tab, tabs, onChange: (id) => console.log(id), ariaLabel: "Account" })