Tabs

A tabbed content switcher with keyboard navigation and multiple variants.

uiinteractivenavigation

Installation

Copy the component file into your project's src/lib/components/ directory.

templates/Tabs.svelte

Usage

<script>
  import Tabs from '$lib/components/Tabs.svelte';

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

<!-- Default variant -->
<Tabs
  bind:value={activeTab}
  tabs={[
    { value: 'account', label: 'Account' },
    { value: 'password', label: 'Password' },
    { value: 'notifications', label: 'Notifications' }
  ]}
  label="Settings tabs"
>
  <svelte:fragment slot="account">
    <div class="text-neutral-300">
      <h3 class="text-lg font-semibold text-white mb-2">Account Settings</h3>
      <p>Manage your account information and preferences.</p>
    </div>
  </svelte:fragment>

  <svelte:fragment slot="password">
    <div class="text-neutral-300">
      <h3 class="text-lg font-semibold text-white mb-2">Password Settings</h3>
      <p>Update your password and security settings.</p>
    </div>
  </svelte:fragment>

  <svelte:fragment slot="notifications">
    <div class="text-neutral-300">
      <h3 class="text-lg font-semibold text-white mb-2">Notification Settings</h3>
      <p>Control your notification preferences.</p>
    </div>
  </svelte:fragment>
</Tabs>

<!-- Underline variant -->
<Tabs
  variant="underline"
  defaultValue="overview"
  tabs={[
    { value: 'overview', label: 'Overview' },
    { value: 'analytics', label: 'Analytics' },
    { value: 'reports', label: 'Reports' },
    { value: 'settings', label: 'Settings', disabled: true }
  ]}
  label="Dashboard tabs"
>
  <svelte:fragment slot="overview">
    <div class="text-neutral-300">Dashboard overview content</div>
  </svelte:fragment>

  <svelte:fragment slot="analytics">
    <div class="text-neutral-300">Analytics content</div>
  </svelte:fragment>

  <svelte:fragment slot="reports">
    <div class="text-neutral-300">Reports content</div>
  </svelte:fragment>

  <svelte:fragment slot="settings">
    <div class="text-neutral-300">Settings content</div>
  </svelte:fragment>
</Tabs>

Props

PropTypeDefaultDescription
valuestring''The currently active tab value (bindable)
defaultValuestring''Default tab to show if value is not provided
variant'default' | 'underline''default'Visual variant of the tabs
labelstring'Tabs'Accessible label for the tabs
tabsArray<{value: string, label: string, disabled?: boolean}>[]Array of tab items with value, label, and optional disabled state

Slots

SlotDescription
[tab.value]Named slot for each tab panel (slot name matches the tab value)

Files