Back to Tooljet

Tabs — Rocket Design Spec

frontend/src/components/ui/Rocket/Tabs/Tabs.spec.md

3.20.154-lts5.7 KB
Original Source

Tabs — Rocket Design Spec

<!-- figma: https://www.figma.com/design/XQdM9x8x9YHcj1lUK8abUG/Rocket-components?node-id=6848-534 --> <!-- figma: https://www.figma.com/design/XQdM9x8x9YHcj1lUK8abUG/Rocket-components?node-id=7579-4973 --> <!-- synced: 2026-03-25 -->

Overview

Tab navigation component for switching between content panels. Compound component (Shape E) wrapping shadcn tabs primitives (Radix @radix-ui/react-tabs). Three visual variants (underline, underline-inverted, pill) and three sizes.

Sub-components

Sub-componentshadcn baseRocket wrapper?Notes
TabsTabs (Root)Re-exportStructural root, no styling needed
TabsListTabsList (List)YesToken-styled container, variant-aware
TabsTriggerTabsTrigger (Trigger)YesStyled tab button with variant/size/state
TabsContentTabsContent (Content)YesContent panel with minimal token styling

Props

TabsList

PropTypeValuesDefault
variantstringunderline | underline-inverted | pillunderline

TabsTrigger

PropTypeValuesDefault
sizestringlarge | default | smalldefault
disabledbooleanfalse

Sizes

ValueHeightTailwindFont
large40pxtw-h-10tw-font-body-large
default32pxtw-h-8tw-font-body-default
small28pxtw-h-7tw-font-body-small

States

StateApplies toBehaviour
defaultTabsTriggerInactive tab appearance
hoverTabsTriggerBackground overlay or text darkens
active (selected)TabsTriggerVisually distinct — underline indicator or pill background
disabledTabsTriggerReduced opacity, no pointer events
focus-visibleTabsTriggerFocus ring

Token Mapping

Underline variant

ElementStateToolJet tokenTailwind class
list containerborder-weak (bottom border)tw-border-b tw-border-solid tw-border-border-weak
trigger textdefaulttext-placeholdertw-text-text-placeholder
trigger texthovertext-defaulthover:tw-text-text-default
trigger bghoverinteractive-hoverhover:tw-bg-interactive-hover
trigger textactivetext-branddata-[state=active]:tw-text-text-brand
trigger indicatoractiveborder-accent-strongbottom border/pseudo-element tw-bg-border-accent-strong
trigger textdisabledtext-disabledtw-text-text-disabled
triggerfocusinteractive-focus-outlinefocus-visible:tw-ring-2 focus-visible:tw-ring-interactive-focus-outline

Underline-inverted variant

ElementStateToolJet tokenTailwind class
list containerborder-weak (top border)tw-border-t tw-border-solid tw-border-border-weak
trigger textdefaulttext-placeholdertw-text-text-placeholder
trigger texthovertext-defaulthover:tw-text-text-default
trigger bghoverinteractive-hoverhover:tw-bg-interactive-hover
trigger textactivetext-branddata-[state=active]:tw-text-text-brand
trigger indicatoractiveborder-accent-strongtop border/pseudo-element tw-bg-border-accent-strong
trigger textdisabledtext-disabledtw-text-text-disabled
triggerfocusinteractive-focus-outlinefocus-visible:tw-ring-2 focus-visible:tw-ring-interactive-focus-outline

Pill variant

ElementStateToolJet tokenTailwind class
list containerbackground-surface-layer-02tw-bg-background-surface-layer-02 tw-rounded-lg tw-p-1
trigger textdefaulttext-placeholdertw-text-text-placeholder
trigger texthovertext-defaulthover:tw-text-text-default
trigger bghoverinteractive-hoverhover:tw-bg-interactive-hover
trigger bgactiveswitch-tabdata-[state=active]:tw-bg-switch-tab
trigger textactivetext-defaultdata-[state=active]:tw-text-text-default
trigger shadowactiveelevation-100data-[state=active]:tw-shadow-elevation-100
trigger textdisabledtext-disabledtw-text-text-disabled
triggerfocusinteractive-focus-outlinefocus-visible:tw-ring-2 focus-visible:tw-ring-interactive-focus-outline

Slots

  • icon (optional, ReactNode) — leading icon inside TabsTrigger, rendered before label
  • badge (optional, ReactNode) — trailing badge/counter inside TabsTrigger, rendered after label

CVA Shape

Shape E — compound/multi-part

  • TabsList: CVA with variant (underline | underline-inverted | pill) — Shape B
  • TabsTrigger: CVA with size (large | default | small) — Shape C
  • Variant-specific trigger styling handled via compound variants or data-[variant=*] from parent list
  • Tabs (root): re-export, no CVA
  • TabsContent: static cn(), no CVA

Notes

  • Underline variant uses a bottom border on the list and an active indicator (bottom pseudo-element) on the trigger
  • Underline-inverted variant mirrors underline but with the indicator and list border on top instead of bottom
  • Pill variant uses a contained background on the list with rounded pill-shaped active triggers
  • TabsTrigger receives variant context from its parent TabsList via data-variant attribute (already set by shadcn)
  • Uses group-data-[variant=*]/tabs-list: modifier to style triggers differently per variant
  • Typography uses plugin tokens: tw-font-body-large, tw-font-body-default, tw-font-body-small — never manual font combos
  • Icons inside triggers should inherit text color and size via [&_svg]:tw-size-4 pattern
  • Badges are passed as children after the label text — no special wrapper needed
  • tw-border-solid required on all border elements (preflight is off)