codefast/ui

Command Palette

Search for a command to run...

Source
Navigation

Tabs

Accessible tabbed interface. Automatic or manual activation via activationMode.

Examples

Line variant

An underline style for content-level navigation.

13 lines
import { Tabs, TabsList, TabsTrigger } from "@codefast/ui/tabs";

export 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>
    </Tabs>
  );
}

Disabled

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

14 lines
import { Tabs, TabsList, TabsTrigger } from "@codefast/ui/tabs";

export function TabsDisabled() {
  return (
    <Tabs defaultValue="home">
      <TabsList>
        <TabsTrigger value="home">Home</TabsTrigger>
        <TabsTrigger value="settings" disabled>
          Disabled
        </TabsTrigger>
      </TabsList>
    </Tabs>
  );
}

Icons

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

19 lines
import { Tabs, TabsList, TabsTrigger } from "@codefast/ui/tabs";
import { AppWindowIcon, CodeIcon } from "lucide-react";

export function TabsIcons() {
  return (
    <Tabs defaultValue="preview">
      <TabsList>
        <TabsTrigger value="preview">
          <AppWindowIcon />
          Preview
        </TabsTrigger>
        <TabsTrigger value="code">
          <CodeIcon />
          Code
        </TabsTrigger>
      </TabsList>
    </Tabs>
  );
}

RTL

Right-to-left layout support for languages such as Arabic and Hebrew.

Translations are AI-generated for demonstration and may be imperfect.

نظرة عامة
عرض مقاييسك الرئيسية وأنشطة المشروع الأخيرة. تتبع التقدم عبر جميع مشاريعك النشطة.
لديك ١٢ مشروعًا نشطًا و٣ مهام معلقة.
123 lines
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@codefast/ui/card";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@codefast/ui/tabs";

import type { Translations } from "#/features/components-catalog/components/detail/language";
import { useTranslation } from "#/features/components-catalog/components/detail/language-context";

const translations: Translations = {
  en: {
    dir: "ltr",
    values: {
      overview: "Overview",
      analytics: "Analytics",
      reports: "Reports",
      settings: "Settings",
      overviewTitle: "Overview",
      overviewDesc:
        "View your key metrics and recent project activity. Track progress across all your active projects.",
      overviewContent: "You have 12 active projects and 3 pending tasks.",
      analyticsTitle: "Analytics",
      analyticsDesc: "Track performance and user engagement metrics. Monitor trends and identify growth opportunities.",
      analyticsContent: "Page views are up 25% compared to last month.",
      reportsTitle: "Reports",
      reportsDesc: "Generate and download your detailed reports. Export data in multiple formats for analysis.",
      reportsContent: "You have 5 reports ready and available to export.",
      settingsTitle: "Settings",
      settingsDesc: "Manage your account preferences and options. Customize your experience to fit your needs.",
      settingsContent: "Configure notifications, security, and themes.",
    },
  },
  ar: {
    dir: "rtl",
    values: {
      overview: "نظرة عامة",
      analytics: "التحليلات",
      reports: "التقارير",
      settings: "الإعدادات",
      overviewTitle: "نظرة عامة",
      overviewDesc: "عرض مقاييسك الرئيسية وأنشطة المشروع الأخيرة. تتبع التقدم عبر جميع مشاريعك النشطة.",
      overviewContent: "لديك ١٢ مشروعًا نشطًا و٣ مهام معلقة.",
      analyticsTitle: "التحليلات",
      analyticsDesc: "تتبع مقاييس الأداء ومشاركة المستخدمين. راقب الاتجاهات وحدد فرص النمو.",
      analyticsContent: "زادت مشاهدات الصفحة بنسبة ٢٥٪ مقارنة بالشهر الماضي.",
      reportsTitle: "التقارير",
      reportsDesc: "إنشاء وتنزيل تقاريرك التفصيلية. تصدير البيانات بتنسيقات متعددة للتحليل.",
      reportsContent: "لديك ٥ تقارير جاهزة ومتاحة للتصدير.",
      settingsTitle: "الإعدادات",
      settingsDesc: "إدارة تفضيلات حسابك وخياراته. تخصيص تجربتك لتناسب احتياجاتك.",
      settingsContent: "تكوين الإشعارات والأمان والسمات.",
    },
  },
  he: {
    dir: "rtl",
    values: {
      overview: "סקירה כללית",
      analytics: "אנליטיקה",
      reports: "דוחות",
      settings: "הגדרות",
      overviewTitle: "סקירה כללית",
      overviewDesc: "הצג את המדדים העיקריים שלך ופעילות הפרויקט האחרונה. עקוב אחר התקדמות בכל הפרויקטים הפעילים שלך.",
      overviewContent: "יש לך 12 פרויקטים פעילים ו-3 משימות ממתינות.",
      analyticsTitle: "אנליטיקה",
      analyticsDesc: "עקוב אחר ביצועים ומדדי מעורבות משתמשים. עקוב אחר מגמות וזהה הזדמנויות צמיחה.",
      analyticsContent: "צפיות בדף עלו ב-25% בהשוואה לחודש שעבר.",
      reportsTitle: "דוחות",
      reportsDesc: "צור והורד את הדוחות המפורטים שלך. ייצא נתונים בפורמטים מרובים לניתוח.",
      reportsContent: "יש לך 5 דוחות מוכנים וזמינים לייצוא.",
      settingsTitle: "הגדרות",
      settingsDesc: "נהל את העדפות החשבון והאפשרויות שלך. התאם אישית את החוויה שלך כך שתתאים לצרכים שלך.",
      settingsContent: "הגדר התראות, אבטחה וערכות נושא.",
    },
  },
};

export function TabsRtl() {
  const { dir, t } = useTranslation(translations, "ar");

  return (
    <Tabs defaultValue="overview" className="w-full max-w-sm" dir={dir}>
      <TabsList dir={dir}>
        <TabsTrigger value="overview">{t.overview}</TabsTrigger>
        <TabsTrigger value="analytics">{t.analytics}</TabsTrigger>
        <TabsTrigger value="reports">{t.reports}</TabsTrigger>
        <TabsTrigger value="settings">{t.settings}</TabsTrigger>
      </TabsList>
      <TabsContent value="overview">
        <Card dir={dir}>
          <CardHeader>
            <CardTitle>{t.overviewTitle}</CardTitle>
            <CardDescription>{t.overviewDesc}</CardDescription>
          </CardHeader>
          <CardContent className="text-sm text-muted-foreground">{t.overviewContent}</CardContent>
        </Card>
      </TabsContent>
      <TabsContent value="analytics">
        <Card dir={dir}>
          <CardHeader>
            <CardTitle>{t.analyticsTitle}</CardTitle>
            <CardDescription>{t.analyticsDesc}</CardDescription>
          </CardHeader>
          <CardContent className="text-sm text-muted-foreground">{t.analyticsContent}</CardContent>
        </Card>
      </TabsContent>
      <TabsContent value="reports">
        <Card dir={dir}>
          <CardHeader>
            <CardTitle>{t.reportsTitle}</CardTitle>
            <CardDescription>{t.reportsDesc}</CardDescription>
          </CardHeader>
          <CardContent className="text-sm text-muted-foreground">{t.reportsContent}</CardContent>
        </Card>
      </TabsContent>
      <TabsContent value="settings">
        <Card dir={dir}>
          <CardHeader>
            <CardTitle>{t.settingsTitle}</CardTitle>
            <CardDescription>{t.settingsDesc}</CardDescription>
          </CardHeader>
          <CardContent className="text-sm text-muted-foreground">{t.settingsContent}</CardContent>
        </Card>
      </TabsContent>
    </Tabs>
  );
}

Vertical

Use orientation='vertical' for vertical tabs.

13 lines
import { Tabs, TabsList, TabsTrigger } from "@codefast/ui/tabs";

export function TabsVertical() {
  return (
    <Tabs defaultValue="account" orientation="vertical">
      <TabsList>
        <TabsTrigger value="account">Account</TabsTrigger>
        <TabsTrigger value="password">Password</TabsTrigger>
        <TabsTrigger value="notifications">Notifications</TabsTrigger>
      </TabsList>
    </Tabs>
  );
}

Usage

The minimal import and composition — see Examples below for styled, real-world variants.

14 lines
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@codefast/ui/tabs";

export function TabsUsage() {
  return (
    <Tabs className="w-full max-w-xs" defaultValue="account">
      <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>
  );
}

Anatomy

How the parts nest — every slot the component exposes, in composition order.

Tabs
├── TabsList
│ └── TabsTrigger
└── TabsContent

Features

  • Two TabsList variants — default (solid pill) and line (underline) — set independently of the Tabs root.
  • orientation="vertical" stacks the list and switches keyboard nav to Up/Down.
  • activationMode="manual" requires Enter/Space to activate a focused tab instead of switching on arrow-key focus alone.

API reference

Props for each part of the component. All native element props are also forwarded.

Tabs

Root. Controls which panel is active.

valuestring

The controlled active tab.

defaultValuestring

The active tab when initially rendered (uncontrolled).

onValueChange(value: string) => void

Called when the active tab changes.

activationMode"automatic" | "manual"

Whether focusing a tab activates it, or only on click/Enter.

Default"automatic"

TabsList

variant"default" | "line"

Solid pill list, or an underline list.

Default"default"

Accessibility

Built to be keyboard-navigable and screen-reader friendly out of the box.

KeyFunction
TabMoves focus into the active tab, then to the panel.
Arrow+LeftMoves to the previous tab.
Arrow+RightMoves to the next tab.
HomeMoves to the first tab.
EndMoves to the last tab.
  • Implements the WAI-ARIA Tabs pattern with roving tabindex.
  • Each TabsTrigger is wired to its TabsContent via aria-controls automatically.

Guidelines

Conventions that keep usage consistent across an app.

Do

  • Keep tab labels to one or two words.
  • Use tabs for peer views of the same context, not for a multi-step flow.

Don’t

  • Don’t nest tabs more than one level deep.
  • Don’t hide critical actions behind a non-default tab.

Explore further

Ready to integrate?

Follow the Getting Started guide to install @codefast/ui, or browse the full component gallery.