apps/eclipse/content/design-system/components/tabs.mdx
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@prisma/eclipse";
Basic Tabs
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@prisma/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:
<div className="not-prose"> <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> </div>Controlled Tabs
You can control the active tab programmatically:
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@prisma/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/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:
<div className="not-prose"> <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"> <div className="p-4 border rounded-lg"> <span className="text-sm text-muted-foreground"> This content is available to all users. </span> </div> </TabsContent> <TabsContent value="locked"> <div className="p-4 border rounded-lg"> <span className="text-sm text-muted-foreground"> This content is locked. </span> </div> </TabsContent> <TabsContent value="premium"> <div className="p-4 border rounded-lg"> <span className="text-sm text-muted-foreground"> This content requires a premium subscription. </span> </div> </TabsContent> </Tabs> </div>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/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>
</Tabs>
Live Example:
<div className="not-prose"> <Tabs defaultValue="orm" color="orm"> <TabsList> <TabsTrigger value="orm">Prisma ORM</TabsTrigger> <TabsTrigger value="migrate" color="ppg">Migrate</TabsTrigger> <TabsTrigger value="studio">Studio</TabsTrigger> </TabsList> <TabsContent value="orm"> <div className="p-4 border rounded-lg"> <h3 className="font-semibold mb-2">Prisma ORM</h3> <span className="text-sm text-muted-foreground"> Next-generation ORM for Node.js and TypeScript. </span> </div> </TabsContent> <TabsContent value="migrate"> <div className="p-4 border rounded-lg"> <h3 className="font-semibold mb-2">Prisma Migrate</h3> <span className="text-sm text-muted-foreground"> Declarative data modeling and schema migrations. </span> </div> </TabsContent> <TabsContent value="studio"> <div className="p-4 border rounded-lg"> <h3 className="font-semibold mb-2">Prisma Studio</h3> <span className="text-sm text-muted-foreground"> Visual database browser and editor. </span> </div> </TabsContent> </Tabs> </div>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)The container for tab triggers with an underline indicator.
Props:
className - Additional CSS classes (optional)<div> attributesIndividual 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 from Tabs if not set)disabled - Whether the tab is disabled (boolean, default: false)className - Additional CSS classes (optional)<button> attributesThe 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)<div> attributesdefaultValue to set a sensible default active tabThe 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) |
tablist, tab, tabpanel)aria-selected="true"aria-controls and aria-labelledbySettings Panels
<Tabs defaultValue="profile">
<TabsList>
<TabsTrigger value="profile">Profile</TabsTrigger>
<TabsTrigger value="account">Account</TabsTrigger>
<TabsTrigger value="notifications">Notifications</TabsTrigger>
</TabsList>
</Tabs>
Documentation Examples
<Tabs defaultValue="preview">
<TabsList>
<TabsTrigger value="preview">Preview</TabsTrigger>
<TabsTrigger value="code">Code</TabsTrigger>
</TabsList>
</Tabs>
Feature Comparison
<Tabs defaultValue="features">
<TabsList>
<TabsTrigger value="features">Features</TabsTrigger>
<TabsTrigger value="pricing">Pricing</TabsTrigger>
<TabsTrigger value="faq">FAQ</TabsTrigger>
</TabsList>
</Tabs>
Dashboard Views
<Tabs defaultValue="overview">
<TabsList>
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="analytics">Analytics</TabsTrigger>
<TabsTrigger value="reports">Reports</TabsTrigger>
</TabsList>
</Tabs>
You can use Tabs in your documentation pages for code examples:
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@prisma/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>
);
}