Navigation

Tabs

Organize content into tabbed sections. Supports pill and link variants, icons, vertical layout, controlled state, and custom content rendering.

Playground

Experiment with different props in real-time.

Manage your account settings and preferences.

Basic Usage

Pass an array of items with label, value, and content.

Manage your account settings and preferences.
<script lang="ts">
  import { Tabs } from 'sv5ui';

  const items = [
    { label: 'Account', value: 'account', content: 'Manage your account settings and preferences.' },
    { label: 'Settings', value: 'settings', content: 'Configure application settings and themes.' },
    { label: 'Notifications', value: 'notifications', content: 'Control your notification preferences.' }
  ];
</script>

<Tabs {items} />

Variants

2 visual styles.

Pill

Manage your account settings and preferences.

Link

Manage your account settings and preferences.
<!-- Pill variant (default) -->
<Tabs variant="pill" {items} />

<!-- Link variant -->
<Tabs variant="link" {items} />

Sizes

4 sizes.

xs

Manage your account settings and preferences.

sm

Manage your account settings and preferences.

md

Manage your account settings and preferences.

lg

Manage your account settings and preferences.
<Tabs size="xs" {items} />
<Tabs size="sm" {items} />
<Tabs size="md" {items} />
<Tabs size="lg" {items} />

Colors

Semantic color schemes.

primary

Manage your account settings and preferences.

secondary

Manage your account settings and preferences.

success

Manage your account settings and preferences.

error

Manage your account settings and preferences.
<Tabs color="primary" {items} />
<Tabs color="secondary" {items} />
<Tabs color="success" {items} />
<Tabs color="error" {items} />

With Icons

Add leading icons to tab triggers.

Manage your account settings.
<Tabs items={[
  { label: 'Account', icon: 'lucide:user', value: 'account', content: 'Manage your account.' },
  { label: 'Settings', icon: 'lucide:settings', value: 'settings', content: 'Configure preferences.' },
  { label: 'Notifications', icon: 'lucide:bell', value: 'notifications', content: 'Control alerts.' }
]} />

Vertical

Set orientation="vertical" for side-by-side layout.

View and edit your profile details.
<Tabs orientation="vertical" items={[
  { label: 'Profile', value: 'profile', content: 'View and edit your profile details.' },
  { label: 'Security', value: 'security', content: 'Update password and 2FA settings.' },
  { label: 'Billing', value: 'billing', content: 'Manage subscription and payments.' }
]} />

Disabled Items

Disable individual tabs.

This tab is clickable.
<Tabs items={[
  { label: 'Active', value: 'active', content: 'This tab is clickable.' },
  { label: 'Disabled', value: 'disabled', content: 'Cannot view.', disabled: true },
  { label: 'Also Active', value: 'also-active', content: 'This tab works normally.' }
]} />

Without Content Panels

Set content={false} to use tabs as a selector only, rendering your own content.

Active tab: account

<script lang="ts">
  import { Tabs } from 'sv5ui';

  let value = $state('account');
</script>

<!-- Tabs without content panels -->
<Tabs
  bind:value
  content={false}
  items={[
    { label: 'Account', value: 'account' },
    { label: 'Settings', value: 'settings' },
    { label: 'Billing', value: 'billing' }
  ]}
/>

<!-- Render your own content based on active tab -->
<p>Active tab: {value}</p>

Controlled

Use bind:value for programmatic control.

Manage your account settings and preferences.
<script lang="ts">
  import { Tabs, Button } from 'sv5ui';

  let value = $state('account');
</script>

<div class="flex gap-2 mb-4">
  <Button label="Go to Account" size="sm" variant="outline" onclick={() => value = 'account'} />
  <Button label="Go to Settings" size="sm" variant="outline" onclick={() => value = 'settings'} />
</div>

<Tabs bind:value {items} />

Custom Body

Use the body snippet for fully custom panel content.

account Details

Custom rendered content for Account.

<Tabs items={[
  { label: 'Account', value: 'account' },
  { label: 'Settings', value: 'settings' },
  { label: 'Notifications', value: 'notifications' }
]}>
  {#snippet body({ item, active })}
    {#if active}
      <div class="space-y-2">
        <h3 class="font-semibold capitalize">{item.value} Details</h3>
        <p class="text-sm text-on-surface/60">Custom rendered content for {item.label}.</p>
      </div>
    {/if}
  {/snippet}
</Tabs>

UI Slots

Use the ui prop to override classes on internal elements.

SlotDescription
rootRoot tabs container
listTab list wrapper
indicatorActive tab indicator (animated)
triggerIndividual tab trigger button
leadingIconIcon before tab label
labelTab label text
contentTab panel content wrapper

Snippets

Each snippet receives item, index, and active as props.

SnippetPropsDescription
leadingitem, index, activeCustom leading section (replaces icon)
labelitem, index, activeCustom label section
trailingitem, index, activeCustom trailing section
bodyitem, index, activeCustom content for tab panel

Props

PropTypeDefault
itemsTabsItem[][]
valuestring-
defaultValuestring-
variant'pill' | 'link''pill'
colorColorType'primary'
size'xs' | 'sm' | 'md' | 'lg''md'
orientation'horizontal' | 'vertical''horizontal'
contentbooleantrue
activationMode'automatic' | 'manual''automatic'
disabledbooleanfalse
loopbooleantrue
onValueChange(value) => void-
refHTMLElement | nullnull
classstring-
uiRecord<Slot, Class>-

Item Props

PropTypeDefault
labelstring-
iconstring-
valuestringindex
contentstring-
disabledbooleanfalse
slotstring-
classstring-
uiRecord<Slot, Class>-