Morph Tabs
Fluid tabs with a shared-layout active pill that morphs between items, plus optional layered glow polish.
No glow
Large tabs with team roster dummy content
Team members
8 online, 3 pending invites
no-glow-example.tsx
1import { MorphTabs } from "@/registry/ui";23export function MorphTabsNoGlowExample() {4 return (5 <div className="mx-auto w-full max-w-2xl">6 <MorphTabs7 tabs={["Activity", "Team", "Billing"]}8 defaultActive="Team"9 size="lg"10 glow={false}11 panels={{12 Activity: (13 <div className="space-y-1">14 <p className="text-sm font-medium">Recent activity</p>15 <p className="text-xs text-muted-foreground">16 24 events in the last hour across deploy, auth, and logs.17 </p>18 </div>19 ),20 Team: (21 <div className="space-y-1">22 <p className="text-sm font-medium">Team members</p>23 <p className="text-xs text-muted-foreground">24 8 online, 3 pending invites25 </p>26 </div>27 ),28 Billing: (29 <div className="space-y-1">30 <p className="text-sm font-medium">Billing snapshot</p>31 <p className="text-xs text-muted-foreground">32 Current plan: Growth. Next invoice: $1,240 on Apr 25.33 </p>34 </div>35 ),36 }}37 />38 </div>39 );40}
Subtle glow
Subtle glow with default color
MRR
$42,380
Active users
12,481
Churn
1.8%
subtle-glow-example.tsx
1import { Card } from "@/components/ui/card";2import { MorphTabs } from "@/registry/ui";34export function MorphTabsSubtleGlowExample() {5 return (6 <div className="mx-auto w-full max-w-2xl">7 <MorphTabs8 tabs={["Overview", "Analytics", "Settings"]}9 glowIntensity="subtle"10 defaultActive="Overview"11 panels={{12 Overview: (13 <div className="grid gap-3 sm:grid-cols-3">14 <Card className="gap-2 p-3">15 <p className="text-xs text-muted-foreground">MRR</p>16 <p className="text-xl font-semibold">$42,380</p>17 </Card>18 <Card className="gap-2 p-3">19 <p className="text-xs text-muted-foreground">Active users</p>20 <p className="text-xl font-semibold">12,481</p>21 </Card>22 <Card className="gap-2 p-3">23 <p className="text-xs text-muted-foreground">Churn</p>24 <p className="text-xl font-semibold">1.8%</p>25 </Card>26 </div>27 ),28 Analytics: (29 <div className="grid gap-3 sm:grid-cols-2">30 <Card className="gap-2 p-4">31 <p className="text-xs text-muted-foreground">32 Weekly conversion33 </p>34 <p className="text-xl font-semibold">4.9%</p>35 </Card>36 <Card className="gap-2 p-4">37 <p className="text-xs text-muted-foreground">Retention (30d)</p>38 <p className="text-xl font-semibold">87.4%</p>39 </Card>40 </div>41 ),42 Settings: (43 <div className="space-y-2">44 <p className="text-sm font-medium">Workspace defaults</p>45 <p className="text-xs text-muted-foreground">46 Notifications: Daily digest, Billing alerts: Enabled, SSO:47 Required48 </p>49 </div>50 ),51 }}52 />53 </div>54 );55}
Strong glow
Stronger glow with a custom accent color
Engineering progress
Sprint velocity: 92 points, 3 blockers under review.
strong-glow-example.tsx
1import { MorphTabs } from "@/registry/ui";23export function MorphTabsStrongGlowExample() {4 return (5 <div className="mx-auto w-full max-w-2xl">6 <MorphTabs7 tabs={["Design", "Build", "Ship"]}8 defaultActive="Build"9 glow10 glowIntensity="strong"11 glowColor="rgb(129 50 50)"12 panels={{13 Design: (14 <div className="space-y-1">15 <p className="text-sm font-medium">Planning board</p>16 <p className="text-xs text-muted-foreground">17 Specs, wireframes, and approval notes are ready for handoff.18 </p>19 </div>20 ),21 Build: (22 <div className="space-y-1">23 <p className="text-sm font-medium">Engineering progress</p>24 <p className="text-xs text-muted-foreground">25 Sprint velocity: 92 points, 3 blockers under review.26 </p>27 </div>28 ),29 Ship: (30 <div className="space-y-1">31 <p className="text-sm font-medium">Release status</p>32 <p className="text-xs text-muted-foreground">33 Release train is on schedule with staged rollout enabled.34 </p>35 </div>36 ),37 }}38 />39 </div>40 );41}
Installation & source
Install via the shadcn CLI or copy the registry files manually.
bash
npx shadcn@latest add @tt-ui/morph-tabs
Props
| Name | Type | Default | Description |
|---|---|---|---|
| tabs | string[] | required | Ordered list of tab labels |
| active / onActiveChange | string / (value: string) => void | uncontrolled if omitted | Controlled mode support for selected tab state |
| defaultActive | string | first tab | Initial active tab in uncontrolled mode |
| panels / panelClassName | Record<string, ReactNode> / string | undefined | Optional tab-specific content panel rendered under tabs |
| glow | boolean | true | Toggles decorative glow layers on the active pill |
| glowIntensity | "subtle" | "default" | "strong" | "default" | Controls glow spread and opacity when glow is enabled |
| glowColor | string | "hsl(var(--primary))" | CSS color value used for active pill glow layers |
| size (CVA) | "sm" | "default" | "lg" | "default" | Adjusts wrapper and trigger sizing |