Skip to content
← Inventory

Tabs

Tabbed content switcher (Radix Tabs) that composes TabsList / TabsTrigger / TabsContent. Provides shared variant/size/fullWidth through context so the parts stay in sync, and tracks the active value to drive the sliding TabsIndicator. Controlled via value/onValueChange, uncontrolled via defaultValue.

Glazed terracotta hex with a matte, hand-finished surface — a warm, tactile field tile for feature walls and splashbacks.

Dimensions
200 × 200 × 10 mm
Wear rating
PEI III
Finish
Matte glaze

Veneto Ceramiche · Italy

Clayworks London · United Kingdom

Terra Studio · Portugal

Usage

@desk/ui/components/tabs

<Tabs className="w-96" defaultValue="specs">
  <TabsList>
    <TabsTrigger value="overview">Overview</TabsTrigger>
    <TabsTrigger value="specs">Specs</TabsTrigger>
    <TabsTrigger value="suppliers">Suppliers</TabsTrigger>
  </TabsList>
  <TabsContent className="mt-4" value="overview">
    <Text size="sm" variant="muted">
      Glazed terracotta hex with a matte, hand-finished surface — a warm,
      tactile field tile for feature walls and splashbacks.
    </Text>
  </TabsContent>
  <TabsContent className="mt-4" value="specs">
    <DescriptionList>
      <DescriptionItem>
        <DescriptionTerm>Dimensions</DescriptionTerm>
        <DescriptionDetails>200 × 200 × 10 mm</DescriptionDetails>
      </DescriptionItem>
      <DescriptionItem>
        <DescriptionTerm>Wear rating</DescriptionTerm>
        <DescriptionDetails>PEI III</DescriptionDetails>
      </DescriptionItem>
      <DescriptionItem>
        <DescriptionTerm>Finish</DescriptionTerm>
        <DescriptionDetails>Matte glaze</DescriptionDetails>
      </DescriptionItem>
    </DescriptionList>
  </TabsContent>
  <TabsContent className="mt-4" value="suppliers">
    <Stack gap="xs">
      <Text size="sm">Veneto Ceramiche · Italy</Text>
      <Text size="sm">Clayworks London · United Kingdom</Text>
      <Text size="sm">Terra Studio · Portugal</Text>
    </Stack>
  </TabsContent>
</Tabs>

Best practices

  • Reach for Tabs to swap in-page panels via TabsContent; when each tab is a route, use TabNavigation instead (renders links, no panels).

  • Compose TabsList/TabsTrigger/TabsContent — shared variant/size/fullWidth flow through context, so set them on Tabs, not each trigger.

Props

Tabs

PropTypeDefaultDescription
variant"line" | "pill""pill"

Indicator style: "pill" (filled capsule) or "line" (underline).

sizeResponsiveSize"base"

Trigger sizing on the shared component-size scale — a single token or a per-breakpoint object like { base: "sm", md: "lg" }.

fullWidthboolean

When true, tabs fill container width with equal proportional widths

TabsList

PropTypeDefaultDescription
variant"line" | "pill" | null | undefined
size"base" | "2xs" | "xs" | "sm" | "lg" | "xl" | "2xl" | "3xl" | null | undefined

TabsPanel

PropTypeDefaultDescription
children(required)import("react").ReactNode
classNamestring
layoutboolean | "position" | "size" | "preserve-aspect"

TabsTrigger

PropTypeDefaultDescription
variant"line" | "pill" | null | undefined
size"base" | "2xs" | "xs" | "sm" | "lg" | "xl" | "2xl" | "3xl" | null | undefined
countnumber

Optional count to display alongside the tab label

dotstring

Dot color indicator (CSS color value)

iconIconComponent | undefined

Leading/trailing icon, rendered through Icon.

iconPlacement"end" | "start"

Which side the icon sits on. Requires icon. Defaults to "start".

Also exports

  • consttabsAnatomy
  • componentTabsContent

Anatomy

Tabs

tabs

Tabbed content switcher

TabsList

tabs-list

Container for tab triggers

TabsTrigger

tabs-trigger

Button to switch tab content

TabsContent

tabs-content

Content panel for each tab

Composition