Glin UI
Signature / Molecule

Morphing Tabs

Tab component with a smoothly sliding indicator that morphs between items.

Revenue this month

+8%

$48,200 across 312 paid invoices, up 8 percent on last month.

Installation$

Install from
pnpm dlx @glinui/cli@latest add morphing-tabs

Prefer the package?

Usage$

MorphingTabs is a "use client" component. Pass an array of items with id and label. The active indicator smoothly slides between tabs.

Examples$

Underline Variant$

"use client"
import { MorphingTabs } from "@glinui/ui"
export function MorphingTabsUnderlineDemo() {
return (
<div className="flex items-center justify-center p-8">
<MorphingTabs
variant="underline"
items={[
{ id: "all", label: "All" },
{ id: "active", label: "Active" },
{ id: "archived", label: "Archived" }
]}
/>
</div>
)
}

Solid Variant$

"use client"
import { MorphingTabs } from "@glinui/ui"
export function MorphingTabsSolidDemo() {
return (
<div className="flex items-center justify-center p-8">
<MorphingTabs
variant="solid"
size="lg"
items={[
{ id: "daily", label: "Daily" },
{ id: "weekly", label: "Weekly" },
{ id: "monthly", label: "Monthly" }
]}
/>
</div>
)
}

Variants$

Omit variant to follow the ambient design style: glinr is the raised pill track with a sliding key, plain is the flat shadcn track. The indicator moves with transform only.

"use client"
import { MorphingTabs } from "@glinui/ui"
export function MorphingTabsVariantsDemo() {
return (
<div className="flex flex-col items-start gap-4">
<MorphingTabs variant="glinr" items={[
{ id: "a", label: "One" },
{ id: "b", label: "Two" },
{ id: "c", label: "Three" }
]} />
<MorphingTabs variant="plain" items={[
{ id: "a", label: "One" },
{ id: "b", label: "Two" },
{ id: "c", label: "Three" }
]} />
<MorphingTabs variant="soft" items={[
{ id: "a", label: "One" },
{ id: "b", label: "Two" },
{ id: "c", label: "Three" }
]} />
<MorphingTabs variant="outline" items={[
{ id: "a", label: "One" },
{ id: "b", label: "Two" },
{ id: "c", label: "Three" }
]} />
<MorphingTabs variant="ghost" items={[
{ id: "a", label: "One" },
{ id: "b", label: "Two" },
{ id: "c", label: "Three" }
]} />
</div>
)
}

Glass (opt-in)$

Glass needs a backdrop behind it: switch the stage backdrop to Photo or Vivid.

"use client"
import { MorphingTabs } from "@glinui/ui"
export function MorphingTabsGlassDemo() {
return (
<MorphingTabs variant="glass" items={[
{ id: "a", label: "One" },
{ id: "b", label: "Two" },
{ id: "c", label: "Three" }
]} />
)
}

Accessibility$

  • Renders with role="tablist" on the container and role="tab" on each button.
  • aria-selected is set on the active tab.
  • Disabled tabs receive disabled attribute and are visually marked.

Reduced Motion$

When prefers-reduced-motion: reduce is active, the indicator transition duration is set to 0 for instant position changes.

API Reference$

PropTypeRequiredDefaultDescription
activeIdstringNo-Active tab id
defaultActiveIdstringNo-Default active tab id
itemsMorphingTabItem[]Yes-Tab items
onTabChange(id: string) => voidNo-Callback when active tab changes
size"sm" | "md" | "lg"No"md"Size
variantControlVariantPropNo-Look. Omit to follow the ambient design style (glinr = raised pill track with a sliding key). Also: solid, plain, soft, outline, ghost, underline, glass (opt-in, needs a backdrop).

Source$

import { MorphingTabs } from "@glinui/ui"
packages/ui/src/components/morphing-tabs.tsx

Generated API Snapshot

Beta

Auto-extracted from TypeScript source in packages/ui/src/components/morphing-tabs.tsx. This section is in beta and may lag behind hand-curated docs. Regenerate with pnpm --filter @glinui/docs api:generate.

Generated: 2026-10-08T01:41:21.546Z · Full index: /docs/api-metadata

Primary Props Type

MorphingTabsProps

MorphingTabsProps

PropTypeRequiredDefaultDescription
activeIdstringNo-Active tab id
defaultActiveIdstringNo-Default active tab id
itemsMorphingTabItem[]Yes-Tab items
onTabChange(id: string) => voidNo-Callback when active tab changes
size"sm" | "md" | "lg"No"md"Size
variantControlVariantPropNo-Look. Omit to follow the ambient design style (glinr = raised pill track with a sliding key). Also: solid, plain, soft, outline, ghost, underline, glass (opt-in, needs a backdrop).