---
layout: ~/layouts/MdxDocLayout.astro
title: "Tabs"
description: "A set of layered sections of content, known as tab panels, displayed one at a time."
sourceFile: "components/tabs"
---

import ComponentExample from "~/components/docs/ComponentExample.astro";
import ComponentSection from "~/components/docs/ComponentSection.astro";
import Heading from "~/components/docs/Heading.astro";
import PropsTable from "~/components/docs/PropsTable.astro";
import {
  TabsDefaultDemo,
  TabsSegmentedDemo,
  TabsUnderlineDemo,
  TabsControlledDemo,
  TabsManyDemo,
} from "~/components/demos/TabsDemo";

{/* Hero Demo */}

<ComponentSection>
  <ComponentExample demo="TabsDefaultDemo">
    <TabsDefaultDemo client:visible />
  </ComponentExample>
</ComponentSection>

{/* Installation */}

<ComponentSection>
  <Heading level={2}>Installation</Heading>
  <Heading level={3}>Barrel</Heading>

```tsx
import { Tabs } from "@cloudflare/kumo";
```

<Heading level={3}>Granular</Heading>

```tsx
import { Tabs } from "@cloudflare/kumo/components/tabs";
```

</ComponentSection>

{/* Usage */}

<ComponentSection>
  <Heading level={2}>Usage</Heading>

```tsx
import { Tabs } from "@cloudflare/kumo";

export default function Example() {
  return (
    <Tabs
      tabs={[
        { value: "overview", label: "Overview" },
        { value: "settings", label: "Settings" },
      ]}
      selectedValue="overview"
    />
  );
}
```

</ComponentSection>

{/* Examples */}

<ComponentSection>
  <Heading level={2}>Examples</Heading>

<Heading level={3}>Variants</Heading>

<h4 class="mb-3 text-base font-medium">Segmented (Default)</h4>
<p>A pill-shaped indicator slides between tabs on a subtle background.</p>
<ComponentExample demo="TabsSegmentedDemo">
  <TabsSegmentedDemo client:visible />
</ComponentExample>

<h4 class="mb-3 text-base font-medium">Underline</h4>
<p>
  A bottom border with a primary-colored indicator. The active tab has bolder
  text for emphasis.
</p>
<ComponentExample demo="TabsUnderlineDemo">
  <TabsUnderlineDemo client:visible />
</ComponentExample>

<Heading level={3}>Controlled</Heading>
<p>Use the `value` and `onValueChange` props for controlled state.</p>
<ComponentExample demo="TabsControlledDemo">
  <TabsControlledDemo client:visible />
</ComponentExample>

<Heading level={3}>Many Tabs</Heading>
<p>Tabs automatically scroll horizontally when there are many items.</p>
<ComponentExample demo="TabsManyDemo">
  <TabsManyDemo client:visible />
</ComponentExample>

</ComponentSection>

{/* API Reference */}

<ComponentSection>
  <Heading level={2}>API Reference</Heading>
  <PropsTable component="Tabs" />

<Heading level={3}>TabsItem</Heading>
<div class="overflow-x-auto">
  <table class="w-full text-sm">
    <thead>
      <tr class="border-b border-kumo-line">
        <th class="px-4 py-3 text-left font-semibold">Property</th>
        <th class="px-4 py-3 text-left font-semibold">Type</th>
        <th class="px-4 py-3 text-left font-semibold">Required</th>
      </tr>
    </thead>
    <tbody class="text-kumo-subtle">
      <tr class="border-b border-kumo-line">
        <td class="px-4 py-3 font-mono text-xs">value</td>
        <td class="px-4 py-3 font-mono text-xs">string</td>
        <td class="px-4 py-3 font-mono text-xs">Yes</td>
      </tr>
      <tr class="border-b border-kumo-line">
        <td class="px-4 py-3 font-mono text-xs">label</td>
        <td class="px-4 py-3 font-mono text-xs">ReactNode</td>
        <td class="px-4 py-3 font-mono text-xs">Yes</td>
      </tr>
      <tr class="border-b border-kumo-line">
        <td class="px-4 py-3 font-mono text-xs">className</td>
        <td class="px-4 py-3 font-mono text-xs">string</td>
        <td class="px-4 py-3 font-mono text-xs">No</td>
      </tr>
    </tbody>
  </table>
</div>

</ComponentSection>
