Tabs

Tabs switch between related panels without leaving the current product context.

Overview and decision boundary

Use Tabs to switch between related panels within the same context.

Do not use Tabs for unrelated page destinations or a form selection value.

12 tasks are due this week.
import { ArrowRight, LayoutDashboard } from "@nerio-ui/adapters/icons";import { Badge } from "@nerio-ui/ui";import { Tabs, TabsContent, TabsIndicator, TabsList, TabsPanels, TabsTrigger } from "@nerio-ui/ui/client";<Tabs defaultValue="overview" variant="segmented" size="md">  <TabsList aria-label="Workspace sections">    <TabsTrigger value="overview" leadingIcon={LayoutDashboard} badge={<Badge size="sm">12</Badge>}>Overview</TabsTrigger>    <TabsTrigger value="activity" trailingIcon={ArrowRight}>Activity</TabsTrigger>    <TabsIndicator />  </TabsList>  <TabsPanels>    <TabsContent value="overview">Overview content</TabsContent>    <TabsContent value="activity">Activity content</TabsContent>  </TabsPanels></Tabs>

Installation and imports

Install the editable registry source, or use the matching package entrypoint when the product keeps Nerio as a workspace dependency.

pnpm dlx nerio add tabsimport { Badge } from "@nerio-ui/ui";import { Tabs, TabsContent, TabsIndicator, TabsList, TabsPanels, TabsTrigger } from "@nerio-ui/ui/client";

Usage

import { Badge } from "@nerio-ui/ui";import { Tabs, TabsContent, TabsIndicator, TabsList, TabsPanels, TabsTrigger } from "@nerio-ui/ui/client";<Tabs defaultValue="overview" variant="segmented">  <TabsList aria-label="Workspace sections">    <TabsTrigger value="overview" badge={<Badge size="sm">12</Badge>}>Overview</TabsTrigger>    <TabsTrigger value="activity">Activity</TabsTrigger>    <TabsIndicator />  </TabsList>  <TabsPanels>    <TabsContent value="overview">Overview content</TabsContent>    <TabsContent value="activity">Activity content</TabsContent>  </TabsPanels></Tabs>

Variants

12 tasks are due this week.
<Tabs defaultValue="overview" variant="bordered">...</Tabs>
12 tasks are due this week.
<Tabs defaultValue="overview" variant="separate">...</Tabs>
12 tasks are due this week.
<Tabs defaultValue="overview" variant="segmented">...</Tabs>
12 tasks are due this week.
12 tasks are due this week.
12 tasks are due this week.
<Tabs size="sm">...</Tabs><Tabs size="md">...</Tabs><Tabs size="lg">...</Tabs>
Equal-width triggers use the available space.
<TabsList layout="fill" aria-label="Equal workspace views">...</TabsList>
Vertical tabs use orientation-aware arrow keys.
<Tabs orientation="vertical">...</Tabs>
<TabsList scrollable aria-label="Narrow project sections">...</TabsList>
Consumer value: overview; direction: none; reason: none
<Tabs value={value} onValueChange={(nextValue, details) => { setValue(nextValue); setDirection(details.activationDirection); setReason(details.reason); }}>...</Tabs>
VariantUse
borderedQuiet default with an edge accent indicator.
separateIndependent compact triggers.
segmentedA compact shared control surface.

Anatomy

12 tasks are due this week.
<TabsTrigger leadingIcon={LayoutDashboard} badge={<Badge size="sm">12</Badge>} value="overview">Overview</TabsTrigger>
SlotPurpose
rootBase UI root with size, variant, and orientation.
listNamed controls with content or fill layout.
triggerVisible label with optional icons and Badge.
indicatorBase UI positioned selected treatment.
panels / contentTransition-safe panel association.

States

Focus selects this immediate panel.
<TabsList activateOnFocus aria-label="Immediate panels">...</TabsList>
12 tasks are due this week.
<div dir="rtl"><Tabs>...</Tabs></div>
StateBehavior
Default / activeThe indicator follows Base UI active-tab CSS variables.
Focus-visibleInset focus treatment remains visible inside a scrollable list.
DisabledDisabled tabs are visually muted and skipped by keyboard navigation.
ScrollableHorizontal lists scroll without wrapping labels.
Reduced motionIndicator and panel transitions become immediate.
RTLThe horizontal indicator follows physical active-tab geometry in either direction.

Motion

  • State changes should use shared motion tokens and preserve reduced-motion behavior.

Accessibility

  • Uses the Base UI Tabs primitive.
  • Uses Base UI tab, tablist, and tabpanel relationships and selected state; Nerio keeps keyboard focus on enabled tabs.
  • Provide aria-label or aria-labelledby when the tablist purpose is not clear from adjacent labelled content.
  • Every trigger requires a visible text label; decorative icons are hidden from assistive technology and Badge text remains available.
  • Manual activation is the default. Use activateOnFocus only when panels are available without noticeable latency.
  • Provide an enabled defaultValue for predictable SSR when the first trigger is disabled.

API

PropUse
variant / sizebordered, separate, segmented; sm, md, lg.
layout / scrollablecontent or fill, with horizontal overflow enabled by default.
TabsList activateOnFocusOpt in only when panels appear without noticeable latency.
onValueChangeReceives Base UI value and complete event details including activation direction.

Implementation contract

Tabs preserves Base UI tab, tablist, and tabpanel relationships. Use an explicit enabled defaultValue for predictable SSR when the first trigger is disabled.

Styling contract

ContractValue
AuthoringComplete, statically detectable Tailwind CSS v4 recipes own component visuals.
ValuesSemantic and component --n-* variables remain the canonical customization layer.
OverridesCustomizable slots merge consumer className values with tailwindCn so conflicting utilities resolve deterministically.
Residual CSSOnly shared keyframes and scoped no-Preflight compatibility rules remain; there is no parallel visual selector layer.

Design notes

  • Use Tabs to switch between related panels within the same context.

Do / do not

Do

Use a small set of concise peer panels and keep the selected tab visible in scrollable lists.

Do not

Use Tabs for global destinations, form values, icon-only labels, deep nesting, or slow automatic activation.

Tokens

These are the primary customization points. Override semantic or component tokens instead of changing component source.

TokenPurpose
--n-tabs-gapPublic customization point for this component contract.
--n-tabs-content-gapPublic customization point for this component contract.
--n-tabs-trigger-height-smPublic customization point for this component contract.
--n-tabs-trigger-height-mdPublic customization point for this component contract.
--n-tabs-trigger-height-lgPublic customization point for this component contract.
--n-tabs-trigger-padding-inline-smPublic customization point for this component contract.
--n-tabs-trigger-padding-inline-mdPublic customization point for this component contract.
--n-tabs-trigger-padding-inline-lgPublic customization point for this component contract.
--n-tabs-list-gapPublic customization point for this component contract.
--n-tabs-trigger-content-gap-smPublic customization point for this component contract.
--n-tabs-trigger-content-gap-mdPublic customization point for this component contract.
--n-tabs-trigger-content-gap-lgPublic customization point for this component contract.
--n-tabs-trigger-font-size-smPublic customization point for this component contract.
--n-tabs-trigger-font-size-mdPublic customization point for this component contract.
--n-tabs-trigger-font-size-lgPublic customization point for this component contract.
--n-tabs-icon-size-smPublic customization point for this component contract.
--n-tabs-icon-size-mdPublic customization point for this component contract.
--n-tabs-icon-size-lgPublic customization point for this component contract.
--n-tabs-radiusPublic customization point for this component contract.
--n-tabs-list-backgroundPublic customization point for this component contract.
--n-tabs-list-radiusPublic customization point for this component contract.
--n-tabs-list-paddingPublic customization point for this component contract.
--n-tabs-segmented-indicator-radiusPublic customization point for this component contract.
--n-tabs-foregroundPublic customization point for this component contract.
--n-tabs-foreground-hoverPublic customization point for this component contract.
--n-tabs-foreground-activePublic customization point for this component contract.
--n-tabs-foreground-disabledPublic customization point for this component contract.
--n-tabs-indicator-backgroundPublic customization point for this component contract.
--n-tabs-indicator-border-colorPublic customization point for this component contract.
--n-tabs-indicator-shadowPublic customization point for this component contract.
--n-tabs-divider-colorPublic customization point for this component contract.
--n-tabs-accent-colorPublic customization point for this component contract.
--n-tabs-indicator-thicknessPublic customization point for this component contract.
--n-tabs-indicator-durationPublic customization point for this component contract.
--n-tabs-indicator-easingPublic customization point for this component contract.
--n-tabs-content-durationPublic customization point for this component contract.
--n-tabs-content-easingPublic customization point for this component contract.
--n-tabs-content-translatePublic customization point for this component contract.
--n-motion-hover-durationPublic customization point for this component contract.
--n-motion-hover-easingPublic customization point for this component contract.
--n-focus-ringPublic customization point for this component contract.