Build · New

Tabs

Switch between peer views of the same content without leaving the page; one view shows at a time.

Preview

Mirrored is the same English content laid out right to left: it separates a mirroring bug from a translation one.

Installation

SoonInstalling from the registry opens at launch. Until then the command below is what it will be.
npx shadcn@latest add @ritla/tabs

Dependencies it brings: @base-ui/react

Usage

import { Tab, Tabs, TabsList, TabsPanel } from "@/components/ui/tabs";
<Tabs defaultValue="overview">
  <TabsList aria-label="Account">
    <Tab value="overview">Overview</Tab>
    <Tab value="transactions">Transactions</Tab>
  </TabsList>
  <TabsPanel value="overview">…</TabsPanel>
  <TabsPanel value="transactions">…</TabsPanel>
</Tabs>

Examples

Button type

A fill on the selected tab and lines between the others; suits compact toolbars.

Vertical

A column for settings on wide screens that becomes a sideways scrolling row on a phone.

Icons and badges

An icon on every tab or none, and a count after the label.

Breakpoints

breakpoint pins the desktop (16) or mobile (14) size; the default auto follows the screen.

API reference

Tabs

PropTypeDefaultDescription
type"underline" | "button""underline"Figma's Type: a line under the selected tab, or a fill on it.
orientation"horizontal" | "vertical""horizontal"Figma's Horizontal tabs or Vertical tabs.
breakpoint"auto" | "desktop" | "mobile""auto"Figma's Breakpoint. auto is the mobile size below md and desktop from md; vertical tabs become a row on a phone.
dividersbooleantrueFigma's Show line divider: lines between horizontal Button tabs.
value / defaultValuestringThe selected tab (controlled or initial).
onValueChange(value) => voidCalled when a tab is selected.

TabsList

PropTypeDefaultDescription
aria-labelstringThe tab set's name for screen readers.
activateOnFocusbooleantrueSelects a tab as soon as the arrows reach it. Turn off when a panel is slow to load.

Tab

PropTypeDefaultDescription
valuestringMatches its panel's value.
childrenReactNodeFigma's Label: one or two words, on one line.
iconLeadingIconComponentFigma's Icon and Leading icon.
badgenumber | stringFigma's Badge and its Count: a Brand badge after the label.
disabledbooleanfalseNot in Figma: a tab you can't select yet.

TabsPanel

PropTypeDefaultDescription
valuestringMatches its tab's value; hidden unless its tab is selected.

Accessibility

Keyboard

Keys are written for left-to-right. In right-to-left the arrow keys swap: the one pointing toward the reading direction moves forward.

KeyAction
TabEnters the list on the selected tab; the next press moves to the panel.
ArrowRightArrowLeftMoves to the next or previous tab and selects it, wrapping at the ends. Flips in Arabic; vertical tabs use ArrowDown and ArrowUp.
HomeEndJumps to the first or last tab.

ARIA

  • A role="tablist" named by aria-label; each role="tab" carries aria-selected and controls its role="tabpanel".
  • The icon is decorative; the badge count is part of the tab's name.
  • For moving between pages or steps, use links or a stepper, not tabs.

Arabic and RTL notes

Mirrors

  • The first tab sits on the right, and the arrows flip: ArrowLeft is next.
  • Vertical tabs put the column and the selected line on the right, with the panel to its left.
  • A scrolling row starts at the right and scrolls to the left.

Does not mirror

  • Decorative icons stay as drawn, except directional ones on the mirror list.
Numerals
The badge count follows the numerals setting (0-9 or ٠-٩).
Arabic typography
body-16 or body-14 Semibold, with a minimum height rather than a fixed one: Arabic lines are taller.
Mixed-direction text
Tab labels never wrap onto two lines. Put an English brand name inside an Arabic label in <bdi>.

All components ›