/// Navigation
Tabs
Underlined tab set — mono UPPERCASE triggers over a hairline rail, the active tab inking its label and growing a 2px underline.
import { Tabs } from "@protocore/pds";Basics
Compose Tabs.Root (aliased as Tabs) with a Tabs.List of Tabs.Triggers and one Tabs.Content per trigger value. Uncontrolled state lives in defaultValue.
Mainnet endpoint is live across 42 chains, settling in a single hop.
Controlled
Drive the active tab from your own state with value + onValueChange — useful when the URL, a wizard, or a query drives which panel shows.
4 messages in transit to the destination chain.
active: inflight
When to use it
Reach for Tabs to switch between peer views of the *same* subject inside a page — an entity's Overview / Config / Logs. It keeps one panel visible at a time and preserves the surrounding layout.
- Need a marketing-weight feature switcher with copy beside an illustration? Use TabbedShowcase.
- Two-to-four mutually exclusive *options* that filter a view (not navigate it)? Use SegmentedControl.
- Independent disclosure of stacked content where several can be open? Use Accordion.
- Moving between separate destinations/pages? That is navigation — use Breadcrumb or a nav, not Tabs.
Usage
Do
- Keep trigger labels to one or two words so the mono UPPERCASE row stays scannable.
- Give every Tabs.Content a value that matches exactly one Tabs.Trigger.
- Use Tabs for peer views of one subject; keep the page URL stable.
- Let Radix own focus — don't intercept arrow keys.
Don't
- Don't use Tabs to page through a sequence — that's Steps or Pagination.
- Don't hide required form fields behind an inactive tab where validation can't reach them.
- Don't nest Tabs inside Tabs; flatten the information architecture instead.
- Don't put more than ~5 triggers in one list; it stops reading as a rail.
Accessibility
| Keys | Action |
|---|---|
| Tab | Move focus to the active trigger, then into the panel |
| → / ← | Move to the next / previous trigger (roving focus, activates it) |
| Home / End | Move to the first / last trigger |
| Space / Enter | Activate the focused trigger |
- Built on Radix Tabs: the list is a `role="tablist"`, triggers are `role="tab"`, panels are `role="tabpanel"` and wired together via `aria-controls` / `aria-labelledby`.
- The active trigger carries `aria-selected` and `data-state="active"`; only the active panel is in the tab order.