Skip to content
CodeAtlas UI

Navigation

Tabs

Keyboard-navigable tab panels backed by Bits UI, controlled or uncontrolled.

<script>
  import { Tabs, TabsList, TabsTrigger, TabsContent } from "@codeatlasdev/ui";
</script>

<Tabs value="overview">
  <TabsList>
    <TabsTrigger value="overview">Overview</TabsTrigger>
    <TabsTrigger value="props">Props</TabsTrigger>
  </TabsList>
  <TabsContent value="overview">...</TabsContent>
  <TabsContent value="props">...</TabsContent>
</Tabs>

Arrow keys move between tabs, Home and End jump to the first and last, and the panels use the tabpanel role. Each TabsTrigger and TabsContent pair must share a value.

Default

Three tabs with content panels.

The Tabs component uses Bits UI's accessible tab primitives. Arrow keys cycle through tabs, Home and End jump to the first and last.

Code
svelte
<script lang="ts">
  import { Tabs, TabsList, TabsTrigger, TabsContent } from '@codeatlasdev/ui';
</script>

<div class="wrap">
  <Tabs value="overview">
    <TabsList>
      <TabsTrigger value="overview">Overview</TabsTrigger>
      <TabsTrigger value="props">Props</TabsTrigger>
      <TabsTrigger value="examples">Examples</TabsTrigger>
    </TabsList>
    <TabsContent value="overview">
      <div class="panel">
        <p>The <strong>Tabs</strong> component uses Bits UI's accessible tab primitives. Arrow keys cycle through tabs, Home and End jump to the first and last.</p>
      </div>
    </TabsContent>
    <TabsContent value="props">
      <div class="panel">
        <p>Tabs accepts a <code>value</code> prop for controlled mode and <code>onchange</code> for change notifications. Uncontrolled mode works too.</p>
      </div>
    </TabsContent>
    <TabsContent value="examples">
      <div class="panel">
        <p>Common uses: settings pages, detail views with several data categories, code and preview panes, and stepped forms.</p>
      </div>
    </TabsContent>
  </Tabs>
</div>

<style>
  .wrap { width: 100%; max-width: 560px; }
  .panel { padding: 20px 0 8px; font-size: var(--ca-font-size-body2); color: var(--ca-text-secondary); line-height: 1.6; }
  .panel p { margin: 0; }
  .panel strong { color: var(--ca-text-primary); }
  .panel code {
    font-family: var(--ca-font-mono);
    font-size: 0.9em;
    color: var(--ca-brand-text);
    background: color-mix(in oklch, var(--ca-brand-main) 10%, transparent);
    padding: 1px 5px;
    border-radius: var(--ca-radius-xs);
  }
</style>

Controlled

The parent owns the active tab with bind:value.

Overview panel.

Active tab: overview

Code
svelte
<script lang="ts">
  import { Tabs, TabsList, TabsTrigger, TabsContent } from '@codeatlasdev/ui';

  let active = $state('overview');
</script>

<div class="wrap">
  <Tabs bind:value={active}>
    <TabsList>
      <TabsTrigger value="overview">Overview</TabsTrigger>
      <TabsTrigger value="props">Props</TabsTrigger>
      <TabsTrigger value="examples">Examples</TabsTrigger>
    </TabsList>
    <TabsContent value="overview"><div class="panel">Overview panel.</div></TabsContent>
    <TabsContent value="props"><div class="panel">Props panel.</div></TabsContent>
    <TabsContent value="examples"><div class="panel">Examples panel.</div></TabsContent>
  </Tabs>
  <p class="state">Active tab: <code>{active}</code></p>
</div>

<style>
  .wrap { width: 100%; max-width: 480px; }
  .panel { padding: 20px 0 8px; font-size: var(--ca-font-size-body2); color: var(--ca-text-secondary); }
  .state { font-size: var(--ca-font-size-caption); color: var(--ca-text-secondary); margin: 12px 0 0; }
  .state code { font-family: var(--ca-font-mono); color: var(--ca-brand-text); }
</style>

Tabs

PropTypeDefaultDescription
valuestring–Bindable active tab value.
onchange(v: string) => void–Fires when the active tab changes.
childrenSnippet–TabsList and TabsContent children.
classstring''Extra classes on the root.

TabsTrigger

PropTypeDefaultDescription
valuestring–Required. Links the trigger to its TabsContent.
disabledbooleanfalsePrevents selecting the tab.
childrenSnippet–Trigger label.
classstring''Extra CSS classes.

TabsContent

PropTypeDefaultDescription
valuestring–Required. Shown while the matching trigger is active.
childrenSnippet–Panel content.
classstring''Extra CSS classes.