Tabs
Material 3 styled tab navigation with optional counts, content slots, and animated active indicators.
Installation
typescript
import { Tabs } from '@happyvertical/smrt-svelte';Basic Usage
Simple tab navigation with controlled active state.
svelte
<script lang="ts">
import { Tabs } from '@happyvertical/smrt-svelte';
const tabs = [
{ id: 'overview', label: 'Overview' },
{ id: 'details', label: 'Details' },
{ id: 'settings', label: 'Settings' }
];
let active = $state('overview');
</script>
<Tabs
tabs={tabs}
active={active}
onchange={(id) => active = id}
/>With Counts
Display counts next to tab labels.
typescript
const tabs = [
{ id: 'all', label: 'All', count: 42 },
{ id: 'active', label: 'Active', count: 28 },
{ id: 'pending', label: 'Pending', count: 14 }
];With Content Slot
Render tab content using the children snippet.
svelte
<Tabs tabs={tabs} {active} onchange={(id) => active = id}>
{#if active === 'overview'}
<p>Overview content</p>
{:else if active === 'details'}
<p>Details content</p>
{:else}
<p>Settings content</p>
{/if}
</Tabs>Size Variants
Three sizes available: small, medium (default), and large.
svelte
<Tabs tabs={tabs} {active} size="sm" />
<Tabs tabs={tabs} {active} size="md" />
<Tabs tabs={tabs} {active} size="lg" />Variants
Primary (centered indicator) or secondary (full-width indicator).
svelte
<Tabs tabs={tabs} {active} variant="primary" />
<Tabs tabs={tabs} {active} variant="secondary" />Disabled Tabs
Mark individual tabs as disabled.
typescript
const tabs = [
{ id: 'active', label: 'Active' },
{ id: 'disabled', label: 'Disabled', disabled: true }
];Props
| Prop | Type | Default | Description |
|---|---|---|---|
tabs * | Tab[] | - | Array of tab definitions |
active * | string | - | ID of the currently active tab |
onchange | (id: string) => void | undefined | Callback when tab changes |
size | 'sm' | 'md' | 'lg' | 'md' | Tab size variant |
variant | 'primary' | 'secondary' | 'primary' | Visual style variant |
children | Snippet | undefined | Content slot for tab panels |
TypeScript
typescript
import { Tabs } from '@happyvertical/smrt-svelte';
interface Tab {
id: string;
label: string;
count?: number;
disabled?: boolean;
}
interface Props {
tabs: Tab[];
active: string;
onchange?: (id: string) => void;
size?: 'sm' | 'md' | 'lg';
variant?: 'primary' | 'secondary';
children?: Snippet;
}Accessibility
- Uses
role="tablist"androle="tab" - Supports
aria-selectedfor active state - Tab panels linked via
aria-controls - Keyboard navigation supported