Tabs.
Related views, one focused workspace.
Four selected treatments, three sizes and a clear composition. Base UI owns selection, roving focus and tab-to-panel relationships.
Make it yours
Preparing the example…
Composition
AnatomyRoot owns value/defaultValue and orientation. List owns the accessible group name, activateOnFocus and loopFocus. Each Tab value matches its Panel value. Indicator belongs inside List; it adds decoration while the tab still exposes aria-selected. Omit Indicator when you want the static selected treatment. Keep action buttons and links inside panels rather than nesting them inside a Tab.
Tabs.Root
├── Tabs.List (accessible name)
│ ├── Tabs.Tab value=overview
│ ├── Tabs.Tab value=activity
│ └── Tabs.Indicator (decoration)
├── Tabs.Panel value=overview
└── Tabs.Panel value=activityA place to start
UsageImport the stylesheet once at your application root. This complete example reflects the properties selected above.
Loading example…
Details that make a difference
Examples & statesLoading tab comparisons…
The finer details
API referenceGenerated from Dixy’s local TypeScript interfaces. Native and Base UI Tabs props are forwarded; this table covers the options Dixy adds.
TabsRoot
| Prop | Type / description | Default |
|---|---|---|
size | "sm" | "md" | "lg"Trigger proportions; preserves the shared minimum interaction target. | md |
variant | "line" | "soft" | "solid" | "outline" | "segmented"Selected emphasis. Line preserves Dixy's original underline treatment. Segmented draws a sunken track with a raised surface thumb for dense view switchers; it stays neutral, so `color` does not tint it. | line |
color | "neutral" | "accent" | "danger" | "success"Selected semantic color; inactive labels stay neutral. | accent |
radius | "none" | "sm" | "md" | "lg" | "full"Trigger and selected-surface rounding. | Theme.radius |
material | "matte" | "glossy" | "soft" | "metal" | "paper"Static selected-surface finish for filled variants; import materials.css. | Theme.material |
align | "center" | "end" | "start"Align content inside each trigger. | center |
fullWidth | booleanExpand horizontal triggers to fill the list. | false |
Built from the same foundations
Styling tokensChange Theme settings above to compare appearance, accent, neutral, radius, spacing density, motion and direction. Override component aliases on a Theme root so custom properties follow portaled content too. The wrapper merges className, style, refs and render composition with its owning primitive.
| Token | Purpose |
|---|---|
--dixy-tabs-height | The component-specific starting point. |
--dixy-font-label-md | Control label font and line height; body roles remain readable in text inputs. |
--dixy-color-background-selected | Selected surfaces use semantic color across appearances. |
--dixy-color-border-focus | Focus indication remains visible independently of shadows. |
--dixy-spacing-inset-sm | Density-aware component padding. |
--dixy-motion-transition-feedback | Short state feedback, reduced by the inherited motion setting. |
Consider everyone
AccessibilityName every List with aria-label or aria-labelledby. Base UI connects each tab/panel pair and manages aria-selected and roving focus. Use automatic activation only when panels appear without noticeable latency; manual activation is the default. The selected shape/underline provides a cue beyond color, and focus has its own outline. Icons are decorative beside a stable text label. Disabled tabs remain discoverable by arrow-key focus but cannot activate. WCAG 2.2 AA is the validation target; passing primitive and automated tests does not certify the whole application.
Target: WCAG 2.2 AA. Automated tests cover selected behavior; manual screen-reader, contrast, and zoom validation remain part of the release checklist.
Build it. Then understand it.
Root adds visual settings while the primitive keeps selection, refs, events, render composition and panel presence. List keeps activateOnFocus and loopFocus. Material applies to the moving selected surface in filled variants, never to text. Indicator uses Base UI physical coordinates, logical inline edges for a vertical line, and shared 200ms enter motion. Reduced motion makes geometry changes immediate. Panels switch immediately without a second animation lifecycle. Nested Roots scope their visual settings independently.
--dixy-tabs-height