Tabs
A tabbed interface component for organizing content into separate panels with line-style navigation.
Usage
Basic Tabs
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@prisma-docs/eclipse";
export function BasicTabs() {
return (
<Tabs defaultValue="account">
<TabsList>
<TabsTrigger value="account">Account</TabsTrigger>
<TabsTrigger value="password">Password</TabsTrigger>
</TabsList>
<TabsContent value="account">
Account settings content
</TabsContent>
<TabsContent value="password">
Password settings content
</TabsContent>
</Tabs>
);
}Live Example:
Account settings content
Password settings content
Controlled Tabs
You can control the active tab programmatically:
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@prisma-docs/eclipse";
import { useState } from "react";
export function ControlledTabs() {
const [activeTab, setActiveTab] = useState("tab1");
return (
<>
<button onClick={() => setActiveTab("tab2")}>
Switch to Tab 2
</button>
<Tabs value={activeTab} onValueChange={setActiveTab}>
<TabsList>
<TabsTrigger value="tab1">Tab 1</TabsTrigger>
<TabsTrigger value="tab2">Tab 2</TabsTrigger>
<TabsTrigger value="tab3">Tab 3</TabsTrigger>
</TabsList>
<TabsContent value="tab1">Content 1</TabsContent>
<TabsContent value="tab2">Content 2</TabsContent>
<TabsContent value="tab3">Content 3</TabsContent>
</Tabs>
</>
);
}With Disabled Tabs
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@prisma-docs/eclipse";
export function DisabledTabs() {
return (
<Tabs defaultValue="available">
<TabsList>
<TabsTrigger value="available">Available</TabsTrigger>
<TabsTrigger value="locked" disabled>Locked</TabsTrigger>
<TabsTrigger value="premium" disabled>Premium</TabsTrigger>
</TabsList>
<TabsContent value="available">
This content is available to all users.
</TabsContent>
<TabsContent value="locked">
This content is locked.
</TabsContent>
<TabsContent value="premium">
This content requires a premium subscription.
</TabsContent>
</Tabs>
);
}Live Example:
This content is available to all users.
This content is locked.
Colored Tabs
Use the color prop on the Tabs component to apply brand-specific colors to all tab triggers:
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@prisma-docs/eclipse";
export function ColoredTabs() {
return (
<Tabs defaultValue="orm" color="orm">
<TabsList>
<TabsTrigger value="orm">Prisma ORM</TabsTrigger>
<TabsTrigger value="migrate">Migrate</TabsTrigger>
<TabsTrigger value="studio">Studio</TabsTrigger>
</TabsList>
<TabsContent value="orm">
Content about Prisma ORM
</TabsContent>
<TabsContent value="migrate">
Content about Prisma Migrate
</TabsContent>
<TabsContent value="studio">
Content about Prisma Studio
</TabsContent>
</Tabs>
);
}You can also override the color on individual triggers if needed:
<Tabs defaultValue="orm" color="orm">
<TabsList>
<TabsTrigger value="orm">Prisma ORM</TabsTrigger>
<TabsTrigger value="ppg" color="ppg">Prisma Postgres</TabsTrigger>
</TabsList>
{/* Content */}
</Tabs>Live Example:
Prisma ORM
Next-generation ORM for Node.js and TypeScript.
Prisma Migrate
Declarative data modeling and schema migrations.
Prisma Studio
Visual database browser and editor.
API Reference
Tabs
The root tabs container component.
Props:
defaultValue- The default active tab (string, optional)value- The controlled active tab value (string, optional)onValueChange- Callback when active tab changes ((value: string) => void, optional)color- Color variant for all tab triggers:"default","orm", or"ppg"(default:"default")orientation- Tab orientation:"horizontal"or"vertical"(default:"horizontal")dir- Text direction:"ltr"or"rtl"(optional)activationMode- How tabs are activated:"automatic"or"manual"(default:"automatic")className- Additional CSS classes (optional)
TabsList
The container for tab triggers with an underline indicator.
Props:
className- Additional CSS classes (optional)- All standard HTML
<div>attributes
TabsTrigger
Individual tab button/trigger.
Props:
value- The unique value for this tab (string, required)color- Color variant override for this specific trigger:"default","orm", or"ppg"(optional, inherits fromTabsif not set)disabled- Whether the tab is disabled (boolean, default: false)className- Additional CSS classes (optional)- All standard HTML
<button>attributes
TabsContent
The content panel for a tab.
Props:
value- The tab value this content corresponds to (string, required)forceMount- Force content to always be mounted (boolean, optional)className- Additional CSS classes (optional)- All standard HTML
<div>attributes
Features
- ✅ Clean underline indicator design (line variant)
- ✅ Smooth transitions and animations
- ✅ Keyboard navigation support
- ✅ Controlled and uncontrolled modes
- ✅ Disabled tab support
- ✅ Horizontal and vertical orientations
- ✅ Brand color variants (ORM, Postgres, Default)
- ✅ Accessible with ARIA attributes
- ✅ Eclipse design system styling
- ✅ Built on Radix UI primitives
Best Practices
- Use tabs for organizing related content into separate views
- Provide clear, concise labels for each tab
- Keep the number of tabs reasonable (3-7 tabs maximum)
- Use
defaultValueto set a sensible default active tab - Don't nest tabs within tabs - use a different pattern instead
- Ensure tab content is meaningful and substantial
- Use disabled state sparingly and provide context when tabs are disabled
- Consider using a different pattern for large amounts of navigation
- Place tabs near the content they control
- Maintain consistent tab ordering across similar interfaces
Keyboard Navigation
The Tabs component supports full keyboard navigation:
| Key | Action |
|---|---|
Tab | Move focus to the active tab or into tab content |
ArrowLeft / ArrowRight | Navigate between tabs (horizontal) |
ArrowUp / ArrowDown | Navigate between tabs (vertical) |
Home | Move to first tab |
End | Move to last tab |
Enter / Space | Activate focused tab (in manual mode) |
Accessibility
- Uses proper ARIA roles (
tablist,tab,tabpanel) - Active tab is indicated with
aria-selected="true" - Tab panels are associated with their triggers via
aria-controlsandaria-labelledby - Keyboard navigation follows ARIA authoring practices
- Disabled tabs are properly marked and not focusable
- Screen readers announce tab states and content
Common Use Cases
Settings Panels
<Tabs defaultValue="profile">
<TabsList>
<TabsTrigger value="profile">Profile</TabsTrigger>
<TabsTrigger value="account">Account</TabsTrigger>
<TabsTrigger value="notifications">Notifications</TabsTrigger>
</TabsList>
{/* Content for each tab */}
</Tabs>Documentation Examples
<Tabs defaultValue="preview">
<TabsList>
<TabsTrigger value="preview">Preview</TabsTrigger>
<TabsTrigger value="code">Code</TabsTrigger>
</TabsList>
{/* Preview and code content */}
</Tabs>Feature Comparison
<Tabs defaultValue="features">
<TabsList>
<TabsTrigger value="features">Features</TabsTrigger>
<TabsTrigger value="pricing">Pricing</TabsTrigger>
<TabsTrigger value="faq">FAQ</TabsTrigger>
</TabsList>
{/* Comparison content */}
</Tabs>Dashboard Views
<Tabs defaultValue="overview">
<TabsList>
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="analytics">Analytics</TabsTrigger>
<TabsTrigger value="reports">Reports</TabsTrigger>
</TabsList>
{/* Dashboard content */}
</Tabs>Integration with Fumadocs
You can use Tabs in your documentation pages for code examples:
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@prisma-docs/eclipse";
export default function Page() {
return (
<article>
<h1>API Documentation</h1>
<Tabs defaultValue="curl">
<TabsList>
<TabsTrigger value="curl">cURL</TabsTrigger>
<TabsTrigger value="javascript">JavaScript</TabsTrigger>
<TabsTrigger value="python">Python</TabsTrigger>
</TabsList>
<TabsContent value="curl">
<pre><code>curl https://api.example.com/data</code></pre>
</TabsContent>
<TabsContent value="javascript">
<pre><code>fetch('https://api.example.com/data')</code></pre>
</TabsContent>
<TabsContent value="python">
<pre><code>requests.get('https://api.example.com/data')</code></pre>
</TabsContent>
</Tabs>
</article>
);
}