Tabs
Tabs show one of several views in the same place and allow users to switch between them from a list of labels.
When to Use
- for views of one record that each have their own content, such as a client’s invoices, estimates, and payments
- when one view is always shown, as a click on the active tab doesn’t close its panel
- for a few views with short labels
When Not to Use
- to change what one view shows, such as the period of a chart (use a Segmented Control)
- to navigate to another page, as a tab is a
buttonand has nohref(use a link in a Sidebar or a Navigation Menu) - for sections that open and close one under another (use an Accordion)
See Segmented Control for a comparison of the Segmented Control, the Toggle Group, and Tabs.
Anatomy
| Element | Usage |
|---|---|
| Indicator | Active tab only |
| Tab | Required |
| List | Required |
| Panel | Required |
| Line | Line variant only |
TabsList renders the indicator, so you don’t need to add it. A TabsTrigger and a TabsContent with the same value form one tab and its panel.
Variants
variant on TabsList sets the mark of the active tab.
| Variant | Purpose |
|---|---|
default | Tabs inside a Card, a Dialog, or one section of a page |
line | Tabs under a page’s title that divide the whole page |
States
To disable a tab, set disabled on TabsTrigger. The arrow keys still stop on a disabled tab, but neither Enter nor Space selects it.
Behavior
If defaultValue isn’t set, the first tab that isn’t disabled is active. By default, the arrow keys move focus only. If you want them to show the panel too, set activateOnFocus on TabsList. Only the active panel is in the page’s markup. To keep the other panels in the markup with the hidden attribute, set keepMounted on TabsContent.
Size and Overflow
A horizontal list is 32px tall, which is the height of a default Button, and it has no other size. The list is as wide as its tabs, and a tab doesn’t shrink or wrap. If the list is wider than its container, it scrolls sideways.
Orientation
To stack the tabs, set orientation="vertical" on Tabs. The panel is then positioned beside the list. ArrowDown and ArrowUp move focus, and ArrowRight and ArrowLeft do nothing.
Content
| String | Rule | Example | Counterexample |
|---|---|---|---|
| Tab | One or two words that name the view | “Invoices” | “View invoices” |
Accessibility
Base UI’s Tabs sets the roles, connects each tab to its panel, and makes the list a single stop for Tab.
Keyboard
| Key | Result |
|---|---|
Tab | Moves focus to the active tab or to the tab that last had focus. From a tab, it moves to the panel. |
ArrowRight, ArrowLeft | Moves focus to the next or the previous tab and wraps at the ends. The panel doesn’t change. |
ArrowDown, ArrowUp | The same, in a vertical list |
Home, End | Moves focus to the first or the last tab |
Enter, Space | Shows the panel of the focused tab |
If the Tabs are inside Base UI’s DirectionProvider with direction="rtl", ArrowLeft moves focus to the next tab. See Right-to-Left for the keys that swap.
Requirements
Give every TabsTrigger a TabsContent with the same value. If a tab has no panel, it has role="tab" and controls nothing.
Installation
npx shadcn@latest add @summit/tabsUsage
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
<Tabs defaultValue="invoices">
<TabsList>
<TabsTrigger value="invoices">Invoices</TabsTrigger>
<TabsTrigger value="estimates">Estimates</TabsTrigger>
</TabsList>
<TabsContent value="invoices">Every invoice you sent to this client.</TabsContent>
<TabsContent value="estimates">Every estimate you sent to this client.</TabsContent>
</Tabs>;With an Icon
To place an icon before or after the label, mark it with data-icon="inline-start" or data-icon="inline-end".
import { ReceiptIcon } from '@phosphor-icons/react';
<TabsTrigger value="invoices">
<ReceiptIcon data-icon="inline-start" />
Invoices
</TabsTrigger>;API Reference
The parts accept the props of their matching parts in Base UI’s Tabs, where TabsTrigger is Tabs.Tab and TabsContent is Tabs.Panel. tabsListVariants is a function that returns the classes of TabsList. See the Base UI Tabs documentation for value, defaultValue, onValueChange, activateOnFocus, loopFocus, and keepMounted.
Tabs
| Prop | Type | Default | Description |
|---|---|---|---|
orientation | 'horizontal' | 'vertical' | 'horizontal' | The direction of the list and the pair of arrow keys that move focus |
TabsList
| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'default' | 'line' | 'default' | The mark of the active tab |