Skip to content
Esc
navigateopen⌘Jpreview
On this page

Tabs

A set of layered sections of content displayed one at a time.

Make changes to your account here.
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

npx shadcn@latest add @madeui/tabs

Usage

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

Composition

<Tabs>
  <TabsList>
    <TabsTrigger />
  </TabsList>
  <TabsContent />
</Tabs>

Line variant

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

Overview of your project.
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

The other tab is disabled.
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.

Update your name and photo.
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

Update your account settings.
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. 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 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.

Was this page helpful?