Get GliaKit · €199

Navigation

Tabs

Switch between related views in the same place. A segmented pill list by default, or an underlined line list for page sections.

Source
src/components/ui/tabs.tsx
Figma
Tab · state (active, inactive) × leading (none, icon).

Usage

Included in the GliaKit boilerplate. Import it where you need it:

tsx
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";

When to use

  • Splitting one record or screen into a few peer views, like Overview, Activity and Settings.
  • Use the default list for compact view switches inside a card or toolbar.
  • Use the line list under a page header for top-level sections of a page.
  • For steps that must happen in order, use Stepper.
  • For more than six or seven options, or options that change, use a Select.
  • For navigating between separate pages with their own URLs, use links styled as tabs so the browser history works.

Examples

Line with icons

variant="line" draws an underline under the active tab. The GliaKit look colors the label and underline violet.

Vertical

orientation="vertical" puts the list beside the content. Up and down arrows move between tabs.

Controlled

Hold the value in state with value and onValueChange to react to the selection.

Disabled tab

A disabled tab is dimmed and skipped by the arrow keys.

API reference

Tabs

Radix Tabs root. Accepts every Radix Tabs.Root prop and native div attributes.

PropTypeDefaultDescription
defaultValuestring-Tab selected on first render when uncontrolled.
valuestring-Selected tab when controlled. Use with onValueChange.
onValueChange(value: string) => void-Called when the selected tab changes.
orientation"horizontal" | "vertical""horizontal"Horizontal stacks the list above the content; vertical puts the list beside it and switches arrow keys to up and down.
activationMode"automatic" | "manual""automatic"Automatic selects a tab as soon as it gets focus; manual waits for Enter or Space.
dir"ltr" | "rtl"-Reading direction for arrow key navigation.

TabsList

Wraps the triggers. Accepts Radix Tabs.List props and native div attributes.

PropTypeDefaultDescription
variant"default" | "line""default"Default is a muted segmented pill with a raised active tab. Line is transparent with an underline under the active tab.
loopbooleantrueWhether arrow key focus wraps from the last tab to the first.
classNamestring-Extra classes. The list is w-fit and h-8 when horizontal.

TabsTrigger

A single tab button. Accepts Radix Tabs.Trigger props and native button attributes. The line underline is an ::after element colored bg-foreground; for the GliaKit violet look pass className="data-active:text-primary after:bg-primary!".

PropTypeDefaultDescription
valuestring-Identifies the tab and links it to the TabsContent with the same value. Required.
disabledbooleanfalseDims the tab and skips it during keyboard navigation.
asChildbooleanfalseRender the child element instead of a <button>.

TabsContent

The panel for one tab. Accepts Radix Tabs.Content props and native div attributes.

PropTypeDefaultDescription
valuestring-Matches a TabsTrigger value. Required.
forceMounttrue-Keep the panel mounted while inactive, for example to preserve form state or animate it.

tabsListVariants

The cva function behind TabsList, for styling another element to match.

PropTypeDefaultDescription
variant"default" | "line""default"Same variants as TabsList.

Accessibility

  • Built on Radix Tabs: renders role="tablist", role="tab" and role="tabpanel", with aria-selected and aria-controls wired up.
  • Arrow keys move between tabs (left and right, or up and down when vertical), Home and End jump to the first and last tab, and disabled tabs are skipped.
  • Only the selected tab is in the tab order, so Tab moves from the list straight into the panel.
  • Icon-only triggers need an aria-label. Icons next to a text label are decorative.

Related