Add this component

npx zentauri-ui add tabs

Accessibility notes

Disclosure and tab patterns expose keyboard navigation and state. Keep headings, labels, and panel content meaningful for screen readers.

Dependency notes

Static imports do not pull framer-motion. Use the animated entry only when you want motion and have framer-motion installed.

Navigation

Tabs for related views

Tabs switch between related panels without full route changes—settings categories, chart ranges, or docs sections. Works in React layouts and shallow Next.js client navigations when needed.

High-level metrics and health for this service.

Examples

Underline list styling with small density, then vertical orientation with slide-in panels.


Workspace name, timezone, and defaults.

Avatar, display name, and locale.

Tabs variants playground

Pick a list variant, size, and appearance to preview the tabs live. Toggle Show output / Show code and the snippet updates to match the selected variant. List chrome and density come from tabsListVariants and tabsTriggerVariants; panel motion is set per TabsContent.


List variant: pills | Size: md | Appearance: default

First panel content.

All appearances

Every shipped appearance token at a glance. Click any swatch to load it into the playground above.

default
Sample panel.
sky
Sample panel.
rose
Sample panel.
purple
Sample panel.
pink
Sample panel.
orange
Sample panel.
yellow
Sample panel.
teal
Sample panel.
indigo
Sample panel.
emerald
Sample panel.
gray
Sample panel.
gradient-blue
Sample panel.
gradient-green
Sample panel.
gradient-red
Sample panel.
gradient-yellow
Sample panel.
gradient-purple
Sample panel.
gradient-teal
Sample panel.
gradient-indigo
Sample panel.
gradient-pink
Sample panel.
gradient-orange
Sample panel.
blue
Sample panel.
cyan
Sample panel.
green
Sample panel.
lime
Sample panel.
mint
Sample panel.
ocean
Sample panel.
sapphire
Sample panel.
lavender
Sample panel.
ruby
Sample panel.
red
Sample panel.
slate
Sample panel.
zinc
Sample panel.
stone
Sample panel.
royal
Sample panel.
electric
Sample panel.
forest
Sample panel.
sunset
Sample panel.
magenta
Sample panel.
crimson
Sample panel.
aqua
Sample panel.
plum
Sample panel.

Tabs API

Generated from the package prop types and variant definitions.

Tabs

TabsProps

Variants

PropTypeDefault
orientation
horizontalvertical
horizontal
size
lgmdsm
md
variant
defaultpillsunderline
pills

State

PropTypeDefault
defaultValuestring | undefinednone
onValueChange((value: TabsValue) => void) | undefinednone
valuestring | undefinednone

Behavior

PropTypeDefault
appearance'default' | 'blue' | 'cyan' | 'green' | 'lime' | 'mint' | 'ocean' | 'sapphire' | 'lavender' | 'ruby' | 'red' | 'slate' | 'zinc' | 'stone' | 'royal' | 'electric' | 'forest' | 'sunset' | 'magenta' | 'crimson' | 'aqua' | 'plum' | 'sky' | 'rose' | 'purple' | 'pink' | 'orange' | 'yellow' | 'teal' | 'indigo' | 'emerald' | 'gradient-blue' | 'gradient-green' | 'gradient-red' | 'gradient-yellow' | 'gradient-purple' | 'gradient-teal' | 'gradient-indigo' | 'gradient-pink' | 'gradient-orange' | 'gray' | undefinednone

Content

PropTypeDefault
children*ReactNodenone
Inherited HTML props
PropTypeDefault
classNamestring | undefinednone

TabsContent

TabsContentProps

State

PropTypeDefault
value*stringnone

Behavior

PropTypeDefault
asElementType | undefinednone

Content

PropTypeDefault
children*ReactNodenone
Inherited HTML props
PropTypeDefault
classNamestring | undefinednone
onClickMouseEventHandler<HTMLDivElement> | undefinednone
styleCSSProperties | undefinednone
titlestring | undefinednone

TabsList

TabsListProps

Content

PropTypeDefault
children*ReactNodenone
Inherited HTML props
PropTypeDefault
classNamestring | undefinednone

TabsTrigger

TabsTriggerProps

State

PropTypeDefault
value*stringnone

Behavior

PropTypeDefault
disabledboolean | undefinednone

Content

PropTypeDefault
children*ReactNodenone
Inherited HTML props
PropTypeDefault
classNamestring | undefinednone

TabsContentAnimated

TabsContentAnimatedProps

animated

State

PropTypeDefault
value*stringnone

Behavior

PropTypeDefault
animationTabsAnimation | undefinednone

Content

PropTypeDefault
children*ReactNodenone
Inherited HTML props
PropTypeDefault
classNamestring | undefinednone
onClickMouseEventHandler<HTMLDivElement> | undefinednone
style The React DOM `style` prop, enhanced with support for `MotionValue`s and separate `transform` values. ```jsx export const MyComponent = () => { const x = useMotionValue(0) return <motion.div style={{ x, opacity: 1, scale: 0.5 }} /> } ```MotionStyle | undefinednone
titlestring | undefinednone
CSS variable overrides

Tabs CSS variables

Override these tabs variables on :root, a theme selector, or a component wrapper.

366 variables

Pattern: --zui-<component>-<slot?>-<variant?>-<property>-<state?>-dark?

:root {
  --zui-tabs-list-default-bg: transparent;
  --zui-tabs-list-underline-border: transparent;
  --zui-tabs-trigger-default-bg: transparent;
  --zui-tabs-trigger-default-fg: oklch(20.8% 0.042 265.755);
  --zui-tabs-trigger-sky-bg: oklch(82.8% 0.111 230.318);
  --zui-tabs-trigger-sky-fg: oklch(39.1% 0.09 240.876);
  --zui-tabs-trigger-sky-bg-active: oklch(39.1% 0.09 240.876);
  --zui-tabs-trigger-sky-fg-active: oklch(97.7% 0.013 236.62);
  --zui-tabs-trigger-rose-bg: oklch(81% 0.117 11.638);
  --zui-tabs-trigger-rose-fg: oklch(41% 0.159 10.272);
  --zui-tabs-trigger-rose-bg-active: oklch(41% 0.159 10.272);
  --zui-tabs-trigger-rose-fg-active: oklch(96.9% 0.015 12.422);
  --zui-tabs-trigger-purple-bg: oklch(82.7% 0.119 306.383);
  --zui-tabs-trigger-purple-fg: oklch(38.1% 0.176 304.987);
  --zui-tabs-trigger-purple-bg-active: oklch(38.1% 0.176 304.987);
  --zui-tabs-trigger-purple-fg-active: oklch(97.7% 0.014 308.299);
  --zui-tabs-trigger-pink-bg: oklch(82.3% 0.12 346.018);
  --zui-tabs-trigger-pink-fg: oklch(40.8% 0.153 2.432);
  --zui-tabs-trigger-pink-bg-active: oklch(40.8% 0.153 2.432);
  --zui-tabs-trigger-pink-fg-active: oklch(97.1% 0.014 343.198);
  --zui-tabs-trigger-orange-bg: oklch(83.7% 0.128 66.29);
  --zui-tabs-trigger-orange-fg: oklch(40.8% 0.123 38.172);
  --zui-tabs-trigger-orange-bg-active: oklch(40.8% 0.123 38.172);
  --zui-tabs-trigger-orange-fg-active: oklch(98% 0.016 73.684);
  --zui-tabs-trigger-yellow-bg: oklch(90.5% 0.182 98.111);
  --zui-tabs-trigger-yellow-fg: oklch(42.1% 0.095 57.708);
  --zui-tabs-trigger-yellow-bg-active: oklch(42.1% 0.095 57.708);
  --zui-tabs-trigger-yellow-fg-active: oklch(98.7% 0.026 102.212);
  --zui-tabs-trigger-teal-bg: oklch(85.5% 0.138 181.071);
  --zui-tabs-trigger-teal-fg: oklch(38.6% 0.063 188.416);
  --zui-tabs-trigger-teal-bg-active: oklch(38.6% 0.063 188.416);
  --zui-tabs-trigger-teal-fg-active: oklch(98.4% 0.014 180.72);
  --zui-tabs-trigger-indigo-bg: oklch(78.5% 0.115 274.713);
  --zui-tabs-trigger-indigo-fg: oklch(35.9% 0.144 278.697);
  --zui-tabs-trigger-indigo-bg-active: oklch(35.9% 0.144 278.697);
  --zui-tabs-trigger-indigo-fg-active: oklch(96.2% 0.018 272.314);
  --zui-tabs-trigger-emerald-bg: oklch(84.5% 0.143 164.978);
  --zui-tabs-trigger-emerald-fg: oklch(37.8% 0.077 168.94);
  --zui-tabs-trigger-emerald-bg-active: oklch(37.8% 0.077 168.94);
  --zui-tabs-trigger-emerald-fg-active: oklch(97.9% 0.021 166.113);
  --zui-tabs-trigger-gray-bg: oklch(87.2% 0.01 258.338);
  --zui-tabs-trigger-gray-fg: oklch(21% 0.034 264.665);
  --zui-tabs-trigger-gray-bg-active: oklch(21% 0.034 264.665);
  --zui-tabs-trigger-gray-fg-active: oklch(98.5% 0.002 247.839);
  --zui-tabs-trigger-gradient-blue-from: oklch(42.4% 0.199 265.638);
  --zui-tabs-trigger-gradient-blue-to: oklch(43.8% 0.218 303.724);
  --zui-tabs-trigger-gradient-blue-fg: oklch(93.2% 0.032 255.585);
  --zui-tabs-trigger-gradient-blue-from-active: oklch(54.6% 0.245 262.881);
  --zui-tabs-trigger-gradient-blue-to-active: oklch(55.8% 0.288 302.321);
  --zui-tabs-trigger-gradient-blue-fg-active: oklch(93.2% 0.032 255.585);
  --zui-tabs-trigger-gradient-green-from: oklch(44.8% 0.119 151.328);
  --zui-tabs-trigger-gradient-green-to: oklch(45.3% 0.124 130.933);
  --zui-tabs-trigger-gradient-green-fg: oklch(96.2% 0.044 156.743);
  --zui-tabs-trigger-gradient-green-from-active: oklch(62.7% 0.194 149.214);
  --zui-tabs-trigger-gradient-green-to-active: oklch(64.8% 0.2 131.684);
  --zui-tabs-trigger-gradient-green-fg-active: oklch(96.2% 0.044 156.743);
  --zui-tabs-trigger-gradient-red-from: oklch(44.4% 0.177 26.899);
  --zui-tabs-trigger-gradient-red-to: oklch(45.9% 0.187 3.815);
  --zui-tabs-trigger-gradient-red-fg: oklch(93.6% 0.032 17.717);
  --zui-tabs-trigger-gradient-red-from-active: oklch(57.7% 0.245 27.325);
  --zui-tabs-trigger-gradient-red-to-active: oklch(59.2% 0.249 0.584);
  --zui-tabs-trigger-gradient-red-fg-active: oklch(93.6% 0.032 17.717);
  --zui-tabs-trigger-gradient-yellow-from: oklch(47.6% 0.114 61.907);
  --zui-tabs-trigger-gradient-yellow-to: oklch(47% 0.157 37.304);
  --zui-tabs-trigger-gradient-yellow-fg: oklch(97.3% 0.071 103.193);
  --zui-tabs-trigger-gradient-yellow-from-active: oklch(68.1% 0.162 75.834);
  --zui-tabs-trigger-gradient-yellow-to-active: oklch(64.6% 0.222 41.116);
  --zui-tabs-trigger-gradient-yellow-fg-active: oklch(97.3% 0.071 103.193);
  --zui-tabs-trigger-gradient-purple-from: oklch(43.8% 0.218 303.724);
  --zui-tabs-trigger-gradient-purple-to: oklch(45.9% 0.187 3.815);
  --zui-tabs-trigger-gradient-purple-fg: oklch(94.6% 0.033 307.174);
  --zui-tabs-trigger-gradient-purple-from-active: oklch(55.8% 0.288 302.321);
  --zui-tabs-trigger-gradient-purple-to-active: oklch(59.2% 0.249 0.584);
  --zui-tabs-trigger-gradient-purple-fg-active: oklch(94.6% 0.033 307.174);
  --zui-tabs-trigger-gradient-teal-from: oklch(43.7% 0.078 188.216);
  --zui-tabs-trigger-gradient-teal-to: oklch(45% 0.085 224.283);
  --zui-tabs-trigger-gradient-teal-fg: oklch(95.3% 0.051 180.801);
  --zui-tabs-trigger-gradient-teal-from-active: oklch(60% 0.118 184.704);
  --zui-tabs-trigger-gradient-teal-to-active: oklch(60.9% 0.126 221.723);
  --zui-tabs-trigger-gradient-teal-fg-active: oklch(95.3% 0.051 180.801);
  --zui-tabs-trigger-gradient-indigo-from: oklch(39.8% 0.195 277.366);
  --zui-tabs-trigger-gradient-indigo-to: oklch(43.8% 0.218 303.724);
  --zui-tabs-trigger-gradient-indigo-fg: oklch(93% 0.034 272.788);
  --zui-tabs-trigger-gradient-indigo-from-active: oklch(51.1% 0.262 276.966);
  --zui-tabs-trigger-gradient-indigo-to-active: oklch(55.8% 0.288 302.321);
  --zui-tabs-trigger-gradient-indigo-fg-active: oklch(93% 0.034 272.788);
  --zui-tabs-trigger-gradient-pink-from: oklch(45.9% 0.187 3.815);
  --zui-tabs-trigger-gradient-pink-to: oklch(45.5% 0.188 13.697);
  --zui-tabs-trigger-gradient-pink-fg: oklch(94.8% 0.028 342.258);
  --zui-tabs-trigger-gradient-pink-from-active: oklch(59.2% 0.249 0.584);
  --zui-tabs-trigger-gradient-pink-to-active: oklch(58.6% 0.253 17.585);
  --zui-tabs-trigger-gradient-pink-fg-active: oklch(94.8% 0.028 342.258);
  --zui-tabs-trigger-gradient-orange-from: oklch(47% 0.157 37.304);
  --zui-tabs-trigger-gradient-orange-to: oklch(44.4% 0.177 26.899);
  --zui-tabs-trigger-gradient-orange-fg: oklch(95.4% 0.038 75.164);
  --zui-tabs-trigger-gradient-orange-from-active: oklch(64.6% 0.222 41.116);
  --zui-tabs-trigger-gradient-orange-to-active: oklch(57.7% 0.245 27.325);
  --zui-tabs-trigger-gradient-orange-fg-active: oklch(95.4% 0.038 75.164);
  --zui-tabs-trigger-blue-bg-hover: #2563eb18;
  --zui-tabs-trigger-blue-fg-hover: #2563eb;
  --zui-tabs-trigger-blue-bg: #2563eb10;
  --zui-tabs-trigger-blue-fg: #2563eb;
  --zui-tabs-trigger-cyan-bg-hover: #0891b218;
  --zui-tabs-trigger-cyan-fg-hover: #0891b2;
  --zui-tabs-trigger-cyan-bg: #0891b210;
  --zui-tabs-trigger-cyan-fg: #0891b2;
  --zui-tabs-trigger-green-bg-hover: #16a34a18;
  --zui-tabs-trigger-green-fg-hover: #16a34a;
  --zui-tabs-trigger-green-bg: #16a34a10;
  --zui-tabs-trigger-green-fg: #16a34a;
  --zui-tabs-trigger-lime-bg-hover: #65a30d18;
  --zui-tabs-trigger-lime-fg-hover: #65a30d;
  --zui-tabs-trigger-lime-bg: #65a30d10;
  --zui-tabs-trigger-lime-fg: #65a30d;
  --zui-tabs-trigger-mint-bg-hover: #10b98118;
  --zui-tabs-trigger-mint-fg-hover: #10b981;
  --zui-tabs-trigger-mint-bg: #10b98110;
  --zui-tabs-trigger-mint-fg: #10b981;
  --zui-tabs-trigger-ocean-bg-hover: #0284c718;
  --zui-tabs-trigger-ocean-fg-hover: #0284c7;
  --zui-tabs-trigger-ocean-bg: #0284c710;
  --zui-tabs-trigger-ocean-fg: #0284c7;
  --zui-tabs-trigger-sapphire-bg-hover: #1d4ed818;
  --zui-tabs-trigger-sapphire-fg-hover: #1d4ed8;
  --zui-tabs-trigger-sapphire-bg: #1d4ed810;
  --zui-tabs-trigger-sapphire-fg: #1d4ed8;
  --zui-tabs-trigger-lavender-bg-hover: #8b5cf618;
  --zui-tabs-trigger-lavender-fg-hover: #8b5cf6;
  --zui-tabs-trigger-lavender-bg: #8b5cf610;
  --zui-tabs-trigger-lavender-fg: #8b5cf6;
  --zui-tabs-trigger-ruby-bg-hover: #be123c18;
  --zui-tabs-trigger-ruby-fg-hover: #be123c;
  --zui-tabs-trigger-ruby-bg: #be123c10;
  --zui-tabs-trigger-ruby-fg: #be123c;
  --zui-tabs-trigger-red-bg-hover: #dc262618;
  --zui-tabs-trigger-red-fg-hover: #dc2626;
  --zui-tabs-trigger-red-bg: #dc262610;
  --zui-tabs-trigger-red-fg: #dc2626;
  --zui-tabs-trigger-slate-bg-hover: #47556918;
  --zui-tabs-trigger-slate-fg-hover: #475569;
  --zui-tabs-trigger-slate-bg: #47556910;
  --zui-tabs-trigger-slate-fg: #475569;
  --zui-tabs-trigger-zinc-bg-hover: #52525b18;
  --zui-tabs-trigger-zinc-fg-hover: #52525b;
  --zui-tabs-trigger-zinc-bg: #52525b10;
  --zui-tabs-trigger-zinc-fg: #52525b;
  --zui-tabs-trigger-stone-bg-hover: #57534e18;
  --zui-tabs-trigger-stone-fg-hover: #57534e;
  --zui-tabs-trigger-stone-bg: #57534e10;
  --zui-tabs-trigger-stone-fg: #57534e;
  --zui-tabs-trigger-royal-bg-hover: #4338ca18;
  --zui-tabs-trigger-royal-fg-hover: #4338ca;
  --zui-tabs-trigger-royal-bg: #4338ca10;
  --zui-tabs-trigger-royal-fg: #4338ca;
  --zui-tabs-trigger-electric-bg-hover: #0ea5e918;
  --zui-tabs-trigger-electric-fg-hover: #0ea5e9;
  --zui-tabs-trigger-electric-bg: #0ea5e910;
  --zui-tabs-trigger-electric-fg: #0ea5e9;
  --zui-tabs-trigger-forest-bg-hover: #16653418;
  --zui-tabs-trigger-forest-fg-hover: #166534;
  --zui-tabs-trigger-forest-bg: #16653410;
  --zui-tabs-trigger-forest-fg: #166534;
  --zui-tabs-trigger-sunset-bg-hover: #ea580c18;
  --zui-tabs-trigger-sunset-fg-hover: #ea580c;
  --zui-tabs-trigger-sunset-bg: #ea580c10;
  --zui-tabs-trigger-sunset-fg: #ea580c;
  --zui-tabs-trigger-magenta-bg-hover: #c026d318;
  --zui-tabs-trigger-magenta-fg-hover: #c026d3;
  --zui-tabs-trigger-magenta-bg: #c026d310;
  --zui-tabs-trigger-magenta-fg: #c026d3;
  --zui-tabs-trigger-crimson-bg-hover: #b91c1c18;
  --zui-tabs-trigger-crimson-fg-hover: #b91c1c;
  --zui-tabs-trigger-crimson-bg: #b91c1c10;
  --zui-tabs-trigger-crimson-fg: #b91c1c;
  --zui-tabs-trigger-aqua-bg-hover: #0f766e18;
  --zui-tabs-trigger-aqua-fg-hover: #0f766e;
  --zui-tabs-trigger-aqua-bg: #0f766e10;
  --zui-tabs-trigger-aqua-fg: #0f766e;
  --zui-tabs-trigger-plum-bg-hover: #7e22ce18;
  --zui-tabs-trigger-plum-fg-hover: #7e22ce;
  --zui-tabs-trigger-plum-bg: #7e22ce10;
  --zui-tabs-trigger-plum-fg: #7e22ce;
  --zui-tabs-trigger-underline-border: transparent;
}

/* Dark theme variables follow the same names with -dark appended. */
.dark {
  --zui-tabs-list-default-bg-dark: transparent;
  --zui-tabs-list-underline-border-dark: transparent;
}

What it does

Roving tabindex keeps arrow keys predictable.

Lazy-mount heavy panels until first activation when performance matters.

Composition and API

Prefer compound subcomponents instead of one oversized prop bag. Export a small, documented API for your design system.

Avoid hiding critical errors inside inactive tabs without a summary indicator.

Common use cases

  • Organize dense settings without deep routes.
  • Compare datasets across time windows.
  • Split API reference examples by language.
  • Host onboarding steps with lightweight state.

Accessibility

Keyboard order, focus rings, and ARIA attributes should match production usage. Test with your supported browsers and assistive technologies when semantics are non-trivial.

This preview page exposes a single h1 in the hero for a clean outline.

Next.js integration notes

Colocate examples under the App Router, keep server and client boundaries explicit, and avoid pulling interactive overlays into unexpected server layouts.

Set NEXT_PUBLIC_SITE_URL so canonical and Open Graph URLs resolve on deploy.

FAQ

Does the Tabs component work with Next.js App Router?

Yes. Import it like any other React component; keep interactive subtrees in client components when you need hooks or browser APIs, and leave static structure in server components where possible.

Can I customize tabs with Tailwind CSS?

Zentauri UI exposes class-friendly variants and slots so you can extend styles with Tailwind utilities without fighting inline styles.

Is this Tabs implementation accessible by default?

Primitives follow sensible defaults, but accessibility depends on how you label controls, manage focus, and wire keyboard handlers in your app. Validate critical flows with keyboard-only use and screen readers.