Tabs organise related content across screens, data sets, or other groupings. Use TabHolder with TabContent for
content-panel tabs, or with href on each item for navigation tabs.
The Tabs family implements the Material Design 3 Tabs pattern, including the sliding active indicator underneath the tab row.
import { TabHolder, Tab, TabContent } from '@noxlovette/material'; TabHolder The container. Renders the tab row from an items array and the sliding active-state indicator.
Tab A single trigger — rendered internally by TabHolder for each item. Renders as <a> when href is set, otherwise <button>.
TabContent A content panel matched to a Tab by value. Only used for content-panel (non-href) tabs.
See it live, with Controls, in Storybook rather than a hand-rolled preview here.
Give each item a value and pair it with a matching TabContent:
<script lang="ts">
import { TabHolder, TabContent } from '@noxlovette/material';
let value = $state('flights');
</script>
<TabHolder
bind:value
items={[
{ value: 'flights', name: 'Flights', iconProps: { name: 'flight' } },
{ value: 'trips', name: 'Trips', iconProps: { name: 'luggage' } },
{ value: 'explore', name: 'Explore', iconProps: { name: 'explore' } }
]}
/>
<TabContent value="flights">Flights panel</TabContent>
<TabContent value="trips">Trips panel</TabContent>
<TabContent value="explore">Explore panel</TabContent> | Prop | Type | Default | Description |
|---|---|---|---|
items required | TabProps[] | — | Tab items to render. Each is passed to an internal Tab component. |
value | string | items[0]?.value | The currently active tab value. Bindable. |
onValueChange | (value: string) => void | — | Callback fired when the active tab changes. |
variant | "primary" | "secondary" | "primary" | Primary tabs show icon + label (h-16). Secondary tabs show label only (h-12). |
activationMode | "automatic" | "manual" | "automatic" | Automatic activates a tab on arrow-key focus; manual requires Enter/Space. |
| Prop | Type | Default | Description |
|---|---|---|---|
name required | string | — | The tab label. |
value | string | — | Unique identifier — required for content-panel tabs (paired with TabContent). Omit for href-based navigation tabs. |
href | string | — | Renders the tab as an <a> for route navigation instead of a content-panel <button>. |
iconProps | IconProps | — | Icon shown above the label. Only rendered when variant is "primary". |
disabled | boolean | false | Disables the tab trigger. |
Keyboard navigation
Arrow keys move focus between tabs; automatic activationMode selects on focus, manual requires Enter/Space.
Active state
The active Tab.Trigger sets aria-selected via Bits UI Tabs, and the sliding indicator is purely visual.
Disabled tabs
Disabled tabs are removed from the arrow-key focus order.