Skip to the content
BooleanPress UI

Panel

Tabs

Shows one panel of content at a time, chosen from a row of tabs.

Import

import { Tabs, TabsList, TabsTrigger, TabsContent } from "@booleanpress/ui/tabs"

Usage

Tabs switch between views of the same thing, on one page. For a move to another page, use links or a navigation menu.

import { Tabs, TabsContent, TabsList, TabsTrigger } from "@booleanpress/ui/tabs"

export function Mailer() {
  return (
    <Tabs defaultValue="overview">
      <TabsList>
        <TabsTrigger value="overview">Overview</TabsTrigger>
        <TabsTrigger value="logs">Logs</TabsTrigger>
      </TabsList>
      <TabsContent value="overview">Delivered today: 1,284</TabsContent>
      <TabsContent value="logs">The 50 most recent emails.</TabsContent>
    </Tabs>
  )
}

Each TabsTrigger and its TabsContent share a value. It is uncontrolled with defaultValue, or controlled with value and onValueChange. TabsList takes variant: default is a filled bar with a raised selected tab; line is a row with an underline. orientation="vertical" on Tabs stacks the triggers; give Tabs flex-row to put the panel beside them. Only the active panel is in the page.

Examples

Basic

Three tabs, the first selected, each with its own panel.

Line

variant="line" removes the fill and underlines the selected tab.

Vertical

orientation="vertical" stacks the tabs; Up and Down Arrow move between them.

Disabled

A disabled tab keeps its place, is skipped by the arrow keys and cannot be selected.

Accessibility

Semantics
A tablist of tab buttons (aria-selected, aria-controls) and a tabpanel named by its tab (aria-labelledby). aria-orientation is set on the list when vertical.
Labels
The text of each tab is its name. Name an icon-only tab with aria-label. If a page has more than one tab list, give each TabsList an aria-label.
Focus
The tab list is one tab stop: it is the selected tab, and the other tabs are reached with the arrow keys. Tab then moves into the active panel, which is itself focusable when it holds no focusable content.
Known limits
  • Selecting happens as focus moves (automatic activation). A panel that is slow to load should not be a tab: set activationMode="manual" on Tabs so the arrow keys move focus and Enter or Space selects.
  • The selected tab is shown by fill, shadow and weight, and in the line variant by the underline: the underline is 2 px. The state is also in aria-selected.

Keyboard

Keyboard
KeyBehaviour
TabMoves focus into the tab list, onto the selected tab, then into the active panel.
Right ArrowMoves to and selects the next tab, wrapping from the last to the first.
Left ArrowMoves to and selects the previous tab, wrapping from the first to the last.
Down ArrowUp ArrowIn a vertical list, moves to the next or previous tab.
HomeMoves to the first tab.
EndMoves to the last tab.

API

Tabs

Renders Radix Tabs.Root and passes it every other prop.

Tabs props
PropTypeDefaultDescription
activationMode"manual" | "automatic"Whether a tab is activated automatically or manually.
asChildboolean
defaultValuestringThe value of the tab to select by default, if uncontrolled
dir"ltr" | "rtl"The direction of navigation between toolbar items.
onValueChange((value: string) => void)A function called when a new tab is selected
orientation"horizontal" | "vertical"horizontalThe orientation the tabs are layed out. Mainly so arrow navigation is done accordingly (left & right vs. up & down)
valuestringThe value for the selected tab, if controlled

TabsList

Renders Radix Tabs.List and passes it every other prop.

TabsList props
PropTypeDefaultDescription
asChildboolean
loopboolean

TabsTrigger

Renders Radix Tabs.Trigger and passes it every other prop.

TabsTrigger props
PropTypeDefaultDescription
asChildboolean
valuestringThe value for the selected tab, if controlled

TabsContent

Renders Radix Tabs.Content and passes it every other prop.

TabsContent props
PropTypeDefaultDescription
asChildboolean
forceMounttrueUsed to force mounting when more control is needed. Useful when controlling animation with React animation libraries.
valuestringThe value for the selected tab, if controlled

Also exported: tabsListVariants, the class names of TabsList's variants and sizes (cva), to give another element the same look.

Every part takes className, merged with its defaults by cn(), and ref, which reaches the element it renders.

Data attributes: data-slot="tabs" (Tabs), data-slot="tabs-list" (TabsList), data-slot="tabs-trigger" (TabsTrigger), data-slot="tabs-content" (TabsContent), and data-orientation, data-variant.

Theming

The selected tab is bg-card (not the page colour, which is grey in BooleanSMTP and would be darker than the list). Inactive labels are text-muted-foreground.

The tokens its classes read. Change their values in your theme, and it follows.

Theme tokens
TokenUsed for
--cardbackground
--foregroundtext, background
--inputborder, background
--mutedbackground
--muted-foregroundtext
--ringborder, focus ring, outline