Skip to main content

tabs

A set of layered sections of content - known as tab panels - that are displayed one at a time.

Philosophy

Tabs organize content into parallel views - only one is visible at a time, but all are equally important. We keep the component controlled-optional (works with or without state management) because simple use cases shouldn't pay the complexity tax. The TabsList/TabsTrigger/TabsContent split keeps styling separate from behavior.

How It's Built

Loading diagram...

Installation


npx @gentleduck/cli add tabs

npx @gentleduck/cli add tabs

Usage

import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
<Tabs
  defaultValue="account"
  className="w-[400px]"
>
  <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>
<Tabs
  defaultValue="account"
  className="w-[400px]"
>
  <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>

Component Composition

Loading diagram...

RTL Support

Direction is resolved through the shared primitives direction module. Use a local dir="rtl" override when the component exposes it, or set DirectionProvider at app/root level for global RTL/LTR behavior.

Motion

Use MotionTabs, MotionTabsList, MotionTabsTrigger, and MotionTabsContent for a sliding active indicator and direction-aware content crossfade powered by motion. The indicator slides between tabs via layoutId and content panels fade with a directional shift.

Segmented Control

A pill-shaped segmented control with a sliding indicator and disabled tab support.

API Reference

Tabs

PropTypeDefaultDescription
valuestring-Controlled active tab value. Must be used alongside onValueChange
defaultValuestring-Uncontrolled initial tab value
onValueChange(value: string) => void-Callback fired when the active tab changes
dir'ltr' | 'rtl'-Text direction override. Resolved via useDirection (dir prop -> DirectionProvider -> 'ltr').
...propsOmit<React.HTMLProps<HTMLDivElement>, 'defaultValue'>-Additional props to spread to the content div

TabsList

PropTypeDefaultDescription
classNamestring-Additional CSS class names
childrenReact.ReactNode-TabsTrigger elements
...propsReact.HTMLProps<HTMLDivElement>-Additional props to spread to the container div (renders with role="tablist")

TabsTrigger

PropTypeDefaultDescription
valuestring(required)A unique value that identifies this tab trigger
defaultCheckedboolean-If true, sets this tab as the default active tab on first render
disabledboolean-Disables the tab trigger from user interaction
classNamestring-Additional CSS class names
childrenReact.ReactNode-Label or node to render inside the tab
...propsReact.HTMLProps<HTMLButtonElement>-Additional props to spread to the button element

TabsContent

PropTypeDefaultDescription
valuestring(required)The associated value that matches a TabsTrigger
forceMountbooleanfalseIf true, the content stays mounted in the DOM even when hidden
classNamestring-Additional CSS class names
childrenReact.ReactNode-Tab panel content
...propsReact.HTMLProps<HTMLDivElement>-Additional props to spread to the content div

MotionTabs

Replaces Tabs. Tracks tab order for directional content animation. Uses domMax for layout animations. Requires the motion package.

PropTypeDefaultDescription
...propsTabsProps-All props from Tabs are supported

MotionTabsList

Replaces TabsList. Wraps with LayoutGroup for shared layoutId indicator animation. Requires the motion package.

PropTypeDefaultDescription
...propsTabsListProps-All props from TabsList are supported

MotionTabsTrigger

Replaces TabsTrigger. Adds sliding layoutId indicator and disabled tab shake feedback. Requires the motion package.

PropTypeDefaultDescription
...propsOmit<TabsTriggerProps, 'onDrag' | 'onDragStart' | 'onDragEnd' | 'onAnimationStart'>-All props from TabsTrigger except motion event handlers

MotionTabsContents

Wrapper around all MotionTabsContent panels. Provides a single AnimatePresence with overflow-hidden for directional slide animation. Requires the motion package.

PropTypeDefaultDescription
classNamestring-Additional CSS class names
childrenReact.ReactNode-MotionTabsContent elements
...propsReact.HTMLProps<HTMLDivElement>-Additional props to spread to the container div

MotionTabsContent

Individual tab panel inside MotionTabsContents. Renders content with proper ARIA attributes. Requires the motion package.

PropTypeDefaultDescription
valuestring(required)The associated value that matches a MotionTabsTrigger
classNamestring-Additional CSS class names
childrenReact.ReactNode-Tab panel content
...propsReact.HTMLProps<HTMLDivElement>-Additional props to spread to the content div