---
title: Tabs
description: "A set of layered sections of content displayed one at a time."
---

```tsx
import * as stylex from '@stylexjs/stylex';

import { container } from '@/lib/constants.stylex';

import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';

export default function TabsDemo() {
  return (
    <Tabs defaultValue="account" style={styles.tabs}>
      <TabsList>
        <TabsTrigger value="account">Account</TabsTrigger>
        <TabsTrigger value="password">Password</TabsTrigger>
      </TabsList>
      <TabsContent value="account">
        Make changes to your account here.
      </TabsContent>
      <TabsContent value="password">Change your password here.</TabsContent>
    </Tabs>
  );
}

const styles = stylex.create({
  tabs: {
    width: container.lg,
  },
});
```

## Install

```bash
npx shadcn@latest add @madeui/tabs
```

## Usage

```tsx
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
```

## Composition

```tsx
<Tabs>
  <TabsList>
    <TabsTrigger />
  </TabsList>
  <TabsContent />
</Tabs>
```

## Line variant

Underline-style tabs: `variant="line"` on `TabsList`.

```tsx
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';

export default function TabsLine() {
  return (
    <Tabs defaultValue="overview">
      <TabsList variant="line">
        <TabsTrigger value="overview">Overview</TabsTrigger>
        <TabsTrigger value="analytics">Analytics</TabsTrigger>
        <TabsTrigger value="reports">Reports</TabsTrigger>
      </TabsList>
      <TabsContent value="overview">Overview of your project.</TabsContent>
      <TabsContent value="analytics">Traffic and usage.</TabsContent>
      <TabsContent value="reports">Exportable reports.</TabsContent>
    </Tabs>
  );
}
```

## Disabled tab

```tsx
import * as stylex from '@stylexjs/stylex';

import { container } from '@/lib/constants.stylex';

import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';

export default function TabsDisabled() {
  return (
    <Tabs defaultValue="active" style={styles.tabs}>
      <TabsList>
        <TabsTrigger value="active">Active</TabsTrigger>
        <TabsTrigger value="disabled" disabled>
          Disabled
        </TabsTrigger>
      </TabsList>
      <TabsContent value="active">The other tab is disabled.</TabsContent>
    </Tabs>
  );
}

const styles = stylex.create({
  tabs: {
    width: container.lg,
  },
});
```

## Vertical

Use `orientation="vertical"` for vertical tabs.

```tsx
import * as stylex from '@stylexjs/stylex';

import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { container } from '@/lib/constants.stylex';

export default function TabsVertical() {
  return (
    <Tabs defaultValue="profile" orientation="vertical" style={styles.tabs}>
      <TabsList>
        <TabsTrigger value="profile">Profile</TabsTrigger>
        <TabsTrigger value="account">Account</TabsTrigger>
        <TabsTrigger value="notifications">Notifications</TabsTrigger>
      </TabsList>
      <TabsContent value="profile">Update your name and photo.</TabsContent>
      <TabsContent value="account">Manage your account details.</TabsContent>
      <TabsContent value="notifications">Choose what you're notified about.</TabsContent>
    </Tabs>
  );
}

const styles = stylex.create({
  tabs: {
    width: container.lg,
  },
});
```

## Icons

```tsx
import * as stylex from '@stylexjs/stylex';

import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { space, container } from '@/lib/constants.stylex';

function UserIcon() {
  return (
    <svg width="16" height="16" viewBox={`0 0 16 16`} fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden>
      <circle cx="8" cy="5" r="2.5" />
      <path d={`M3 13.5c0-2.5 2.2-4 5-4s5 1.5 5 4`} />
    </svg>
  );
}

function BellIcon() {
  return (
    <svg width="16" height="16" viewBox={`0 0 16 16`} fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden>
      <path d={`M4 6.5a4 4 0 0 1 8 0c0 3 1 4 1 4H3s1-1 1-4Z`} />
      <path d={`M6.5 12.5a1.5 1.5 0 0 0 3 0`} />
    </svg>
  );
}

export default function TabsIcons() {
  return (
    <Tabs defaultValue="account" style={styles.tabs}>
      <TabsList>
        <TabsTrigger value="account" style={styles.trigger}>
          <UserIcon />
          Account
        </TabsTrigger>
        <TabsTrigger value="notifications" style={styles.trigger}>
          <BellIcon />
          Notifications
        </TabsTrigger>
      </TabsList>
      <TabsContent value="account">Update your account settings.</TabsContent>
      <TabsContent value="notifications">Manage notification preferences.</TabsContent>
    </Tabs>
  );
}

const styles = stylex.create({
  tabs: {
    width: container.lg,
  },
  trigger: {
    alignItems: 'center',
    display: 'inline-flex',
    gap: space.s15,
  },
});
```

## API reference

Built on [Base UI Tabs](https://base-ui.com/react/components/tabs). The tables below cover the props this library adds or changes — every other prop is forwarded to the underlying Base UI part; see the [Base UI Tabs API reference](https://base-ui.com/react/components/tabs#api-reference) for the full list.

### Tabs (Root)

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `value` | `any` | — | Controlled selected tab value. |
| `defaultValue` | `any` | — |  |
| `onValueChange` | `(value: any) => void` | — |  |
| `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` |  |
| `style` | `StyleXStyles` | — | StyleX styles merged last — always win over the component's own styles. |

`TabsList` accepts `variant`: `'default'` (filled pill list) or `'line'` (underline). `Tabs` accepts `orientation`: `'horizontal' | 'vertical'` (Base UI keyboard behavior follows).

### TabsTrigger

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `value` *(required)* | `any` | — |  |
| `disabled` | `boolean` | `false` |  |
| `style` | `StyleXStyles` | — | StyleX styles merged last — always win over the component's own styles. |

### TabsContent

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `value` *(required)* | `any` | — |  |
| `style` | `StyleXStyles` | — | StyleX styles merged last — always win over the component's own styles. |

### Styling

`TabsList` accept `style` (`StyleXStyles`, merged last so caller overrides always win) plus all native props of the element they render.

`TabsTrigger` must be inside `TabsList`.
