Navigation

Tabs

Tabbed navigation between related views.

Preview
01 Installation

Install

Pull Tabs from the barrel for everyday use, or the granular path when you want a tighter bundle.

tsxBarrel1 line
import { Tabs } from "@brika/clay";
tsxGranular1 line
import { Tabs } from "@brika/clay/components/tabs";
02 Usage

A minimal example

Drop this into a page. Native HTML attributes pass through to the underlying primitive.

tsxTabs.tsx25 lines
'use client';

import { Tabs, TabsContent, TabsList, TabsTrigger } from '@brika/clay/components/tabs';

/** Standard tabs with a pill-style list and three content panels. */
export default function TabsDefaultDemo() {
  return (
    <Tabs defaultValue="overview" className="w-full max-w-md">
      <TabsList>
        <TabsTrigger value="overview">Overview</TabsTrigger>
        <TabsTrigger value="activity">Activity</TabsTrigger>
        <TabsTrigger value="settings">Settings</TabsTrigger>
      </TabsList>
      <TabsContent value="overview" className="mt-4 text-clay-default text-sm">
        <p>Your project at a glance, key metrics, recent deploys, and health status.</p>
      </TabsContent>
      <TabsContent value="activity" className="mt-4 text-clay-default text-sm">
        <p>A chronological feed of commits, reviews, and comments from the last 7 days.</p>
      </TabsContent>
      <TabsContent value="settings" className="mt-4 text-clay-default text-sm">
        <p>Configure environment variables, access control, and notification preferences.</p>
      </TabsContent>
    </Tabs>
  );
}
03 Examples

Tabs, every way

Controlled

Controlled tabs, drive the active tab programmatically with `value` and `onValueChange`.

Line

Line-style variant with an underline indicator instead of a pill.

Vertical

Vertical orientation, tabs stack on the left and content fills the right.

With Badge

Badge inside a tab trigger, compose freely to show counts or status.

04 Accessibility

Accessibility

  • Arrow keys navigate between triggers inside the list, Tab moves focus to the active panel.
  • Active panel carries aria-labelledby pointing to its trigger.
  • Triggers carry role="tab" and aria-selected; the list carries role="tablist".
  • Vertical tabs require orientation="vertical" so AT uses the correct arrow key direction.
05 Tokens 24 theme-overridable

Theme tokens

Every CSS variable Tabs reads, with its default and the dotted path you'd write in a ThemeConfig JSON to override it. Set any of these in your theme to retune Tabs without touching component code.

Tabs tokens

24 tokens
ColorFill, border, and text colors.10
  • --tabs-list-containercolorvar(--muted)
    components.tabs.listContainer

    Background of the tabs list rail in the default (pill) variant. The line variant keeps the list transparent.

  • --tabs-list-labelcolorvar(--muted-foreground)
    components.tabs.listLabel

    Default label color for tabs in their inactive state. Active tabs override to `trigger-active-label`.

  • --tabs-trigger-active-containercolorvar(--background)
    components.tabs.triggerActiveContainer

    Background of the active tab pill (default variant).

  • --tabs-trigger-active-labelcolorvar(--foreground)
    components.tabs.triggerActiveLabel

    Foreground color of the active tab.

  • --tabs-trigger-hover-labelcolorvar(--foreground)
    components.tabs.triggerHoverLabel

    Foreground color of an inactive tab on hover.

  • --tabs-line-indicatorcolorvar(--foreground)
    components.tabs.lineIndicator

    Color of the underline rule painted under the active tab in the line variant.

  • --tabs-trigger-focus-bordercolorvar(--ring)
    components.tabs.triggerFocusBorder

    Border color drawn on a tab trigger on `focus-visible`. Pairs with `trigger-focus-ring` to render the keyboard focus halo.

  • --tabs-trigger-focus-outlinecolorvar(--ring)
    components.tabs.triggerFocusOutline

    Outline color drawn on a tab trigger on `focus-visible`. Sits underneath the focus ring at 1px width.

  • --tabs-trigger-focus-ringcolorvar(--ring)
    components.tabs.triggerFocusRing

    Color of the 3px focus halo painted around a tab trigger on `focus-visible`. Rendered at 50% opacity to soften the outer glow.

  • --tabs-trigger-active-border-darkcolorvar(--input)
    components.tabs.triggerActiveBorderDark

    Border color of the active tab pill in dark mode (default variant). Light mode keeps the transparent resting border so only the pill background reads as active.

GeometrySizes, lengths, and corner radii.3
  • --tabs-trigger-padding-xsizecalc(var(--spacing) * 3)
    components.tabs.triggerPaddingX

    Inline padding inside a tab trigger.

  • --tabs-trigger-padding-ysizecalc(var(--spacing) * 1.5)
    components.tabs.triggerPaddingY

    Block padding inside a tab trigger.

  • --tabs-radiusradiusvar(--radius-control)
    components.tabs.radius

    Tabs corner radius.

BorderBorder width and style.2
  • --tabs-border-widthborder-width1px
    components.tabs.borderWidth

    Border width on the tabs. Set non-zero for outline-style variants.

  • --tabs-border-styleborder-stylesolid
    components.tabs.borderStyle

    Border style on the tabs (`solid`, `dashed`, `double`, `none`).

TypographyTypeface, size, weight, spacing.6
  • --tabs-font-familyfont-familyvar(--font-sans)
    components.tabs.fontFamily

    Typeface for tabs.

  • --tabs-font-sizefont-sizevar(--text-label-lg)
    components.tabs.fontSize

    Font size for tabs.

  • --tabs-font-weightfont-weight500
    components.tabs.fontWeight

    Font weight for tabs.

  • --tabs-line-heightline-height1.25
    components.tabs.lineHeight

    Line height for tabs.

  • --tabs-letter-spacingletter-spacing0
    components.tabs.letterSpacing

    Letter spacing for tabs. Useful for caps labels.

  • --tabs-text-transformtext-transformnone
    components.tabs.textTransform

    Text transform for tabs (`uppercase`, `lowercase`, `capitalize`, `none`).

ElevationDrop shadow and depth.1
  • --tabs-backdrop-blurblur0px
    components.tabs.backdropBlur

    Backdrop blur applied to the tab pill bar. Set non-zero (with a translucent muted color) for a frosted-glass tab strip.

MotionAnimation duration and easing.2
  • --tabs-durationdurationvar(--motion-standard-duration)
    components.tabs.duration

    Transition duration for tabs state changes.

  • --tabs-easingeasingvar(--motion-standard-easing)
    components.tabs.easing

    Transition easing for tabs state changes.

Override in a theme

Authoring a theme is plain JSON. Drop overrides under components.tabs, the names are camelCase versions of the variable suffix.

jsonmy-theme.json12 lines
{
  "id": "my-theme",
  "name": "My Theme",
  "description": "...",
  "accentSwatches": ["#000"],

  "components": {
    "tabs": {
      "radius": "var(--radius-control)"
    }
  }
}

Then apply with applyTheme(myTheme) (see the theming guide), scope it to a subtree with themeToCssVars(myTheme, mode), or consume any token directly in your own JSX with the matching Tailwind utility (e.g. bg-tabs-…) — see the chips on each token row.

06 API reference

API reference

Props specific to Tabs. Native HTML attributes pass through to the underlying primitive, see the component source on GitHub for the full type signature.

<Tabs />

passthrough

No wrapper-specific props, all attributes pass through to the underlying primitive.

<TabsContent />

passthrough

No wrapper-specific props, all attributes pass through to the underlying primitive.

<TabsList />

1 prop
  • variantdefault 'default'
    'default' | 'line'
    "default" pill-style or "line" underline-style.

<TabsTrigger />

passthrough

No wrapper-specific props, all attributes pass through to the underlying primitive.