Tabs

Sectioned panels for switching between related views.

Installation

npx shadcn@latest add @iconiq/tabs

File Structure

Usage

"use client";

import { useState } from "react";
import {
  Tabs,
  TabsContent,
  TabsList,
  TabsTrigger,
} from "@/components/ui/tabs";

export function TabsPreview() {
  const [value, setValue] = useState("overview");

  return (
    <Tabs
      className="w-full max-w-2xl"
      animateContent
      value={value}
      onValueChange={setValue}
    >
      <TabsList>
        <TabsTrigger value="overview">
          Overview
        </TabsTrigger>
        <TabsTrigger value="activity">
          Activity
        </TabsTrigger>
        <TabsTrigger value="files">
          Files
        </TabsTrigger>
      </TabsList>

        <TabsContent key="overview" value="overview">
          <div className="space-y-3 p-4">
            <p className="font-medium text-[15px] text-foreground tracking-[-0.02em]">
              Product workspace
            </p>
            <p className="text-[14px] text-secondary leading-6">
              Keep the main summary visible while switching between planning, delivery, and support details without leaving the current surface.
            </p>
          </div>
        </TabsContent>
        <TabsContent key="activity" value="activity">
          <div className="space-y-3 p-4">
            <p className="font-medium text-[15px] text-foreground tracking-[-0.02em]">
              Recent handoff
            </p>
            <p className="text-[14px] text-secondary leading-6">
              Review the last design review, implementation notes, and timeline updates in a compact panel that still feels grounded.
            </p>
          </div>
        </TabsContent>
        <TabsContent key="files" value="files">
          <div className="space-y-3 p-4">
            <p className="font-medium text-[15px] text-foreground tracking-[-0.02em]">
              Shared assets
            </p>
            <p className="text-[14px] text-secondary leading-6">
              Attach decks, mockups, and implementation references while preserving a clear transition between each content block.
            </p>
          </div>
        </TabsContent>
    </Tabs>
  );
}

Props

Props
Description

Tabs

children

Compose TabsList, TabsTrigger, and TabsContent inside the root.

Type ReactNode

defaultValue

Initial active tab for uncontrolled usage. Falls back to the first TabsContent value when omitted or invalid.

Type string

value

Controlled active tab value. Invalid values fall back to the first TabsContent value in development with a console warning.

Type string

onValueChange

Called when a trigger activates a different tab through click or keyboard interaction.

Type (value: string) => void

variant

Switches between the segmented pill rail and the underline indicator treatment.

Type "pill" | "underline"·Default "pill"

animateContent

Applies a short fade-and-rise transition to the active panel body. Respects reduced-motion preferences.

Type boolean·Default false

orientation

Radix orientation forwarded to the list and content layout. Vertical roots render as a flex row with the list beside the panel.

Type "horizontal" | "vertical"·Default "horizontal"

activationMode

Radix activation mode. Manual keeps focus and selection separate until Enter or Space.

Type "automatic" | "manual"·Default "automatic"

dir

Radix text direction for keyboard navigation order.

Type "ltr" | "rtl"

className

Merged onto the Radix tabs root wrapper.

Type string

TabsList

children

Usually a row of TabsTrigger elements.

Type ReactNode

fullWidth

Stretches the list to the container width instead of fitting the trigger row.

Type boolean·Default false

loop

Radix loop behavior for keyboard navigation across the first and last triggers.

Type boolean·Default true

className

Merged onto the trigger rail element.

Type string

TabsTrigger

value

Unique tab identifier used for active state and content matching.

Type string

children

Label content rendered inside the trigger button.

Type ReactNode

icon

Optional leading icon rendered before the label with consistent sizing.

Type ReactNode

badge

Optional trailing badge such as a count or status chip.

Type ReactNode

className

Merged onto the trigger button for local spacing, typography, or state overrides.

Type string

disabled

Prevents the trigger from receiving focus or changing the active tab.

Type boolean

TabsContent

value

Matches the corresponding TabsTrigger value.

Type string

children

Panel body shown when the content value is active.

Type ReactNode

className

Merged onto the rendered content panel element.

Type string

forceMount

Keeps the panel mounted while inactive. Useful for preserving form state or SSR-friendly markup.

Type boolean

Registry bundle

Install the exact registry entry shown on the right when you want the component file and its declared runtime dependencies together.

Dependencies: @radix-ui/react-tabs, motion.

Contact

Additionally, if you find any bug or issue, feel free to raise an issue.

Product workspace

Keep the main summary visible while switching between planning, delivery, and support details without leaving the current surface.