Tabs

Related views with keyboard navigation and associated panels.

Overview

  • Keep related panels within one page. Use page navigation for views with separate URLs.

Aliases

tabset

When to use

  • Use Tabs when the user is switching between closely related views or information groups.
  • Use short tab labels that remain stable across states.

When not to use

  • Keep content visible together when users need to compare it. Use Stepper for an ordered workflow.
  • Do not overload tab labels with long explanatory text.

Structural parts

tab list

list

Group of tab triggers.

tab trigger

tab

Single trigger selecting a panel.

tab panel

panel

Visible content for the selected tab.

Public interface

Props
NameTypeDefaultDescription
valuestring—Controlled selected tab value.
itemsArray<{ value: string; label: string; disabled?: boolean }>—Tab trigger definitions.
panelsRecord<string, string>—Panel content keyed by tab value.
orientation'horizontal' | 'vertical''horizontal'Chooses trigger layout orientation.
activation'automatic' | 'manual''automatic'Chooses whether focus movement activates tabs immediately.
size'sm' | 'md''md'Chooses the tab size recipe.
onChange(detail: { value: string }) => void—Runs when the active tab changes.
themeThemeContract—Sets the theme used to resolve component styles.
Events
NamePayloadDescription
change{ value: string }Fires with the active tab value.
Slots
NameDescription
defaultTabs is data-driven and panels are supplied by value map.

Variants, sizes, and states

Variants

  • horizontal: Default row of tab triggers
  • vertical: Stacked tab trigger layout for some side-panel cases

Sizes

  • sm: Compact tabs
  • md: Default tabs

States

  • rest: Unselected tab
  • selected: Active tab
  • disabled: Unavailable tab

Accessibility

Semantics

  • Uses tablist, tab, and tabpanel roles.

Keyboard

  • Arrow keys move focus between tabs and activation follows the chosen activation mode.

Screen readers

  • Active tab and associated panel relationship remain explicit.

Checklist

  • Verify that the control has an accessible name.
  • Verify that keyboard focus is visible in every state and size.
  • Identify disabled, selected, and error states with text or symbols as well as color.

Tokens and CSS variables

root

--dk-tabs-gap
clamp(1.333rem, 1.2222rem + 0.494vw, 1.667rem)

list

--dk-tabs-list-gap
clamp(0.563rem, 0.5156rem + 0.208vw, 0.703rem)
--dk-tabs-list-bg
#e5e8ed
--dk-tabs-list-radius
clamp(0.75rem, 0.6875rem + 0.278vw, 0.938rem)

trigger

--dk-tabs-trigger-bg
transparent
--dk-tabs-trigger-fg
#16181c
--dk-tabs-trigger-radius
clamp(0.75rem, 0.6875rem + 0.278vw, 0.938rem)
--dk-tabs-trigger-block-size
36px
--dk-tabs-trigger-inline-padding
clamp(1.333rem, 1.2222rem + 0.494vw, 1.667rem)
--dk-tabs-trigger-font-size
clamp(0.75rem, 0.6875rem + 0.278vw, 0.938rem)
--dk-tabs-trigger-font-weight
600
--dk-tabs-trigger-motion-duration
200ms

indicator

--dk-tabs-indicator-bg
#2072e4
--dk-tabs-indicator-thickness
2px

panel

--dk-tabs-panel-bg
#f2f5fb
--dk-tabs-panel-fg
#16181c
--dk-tabs-panel-radius
clamp(0.75rem, 0.6875rem + 0.278vw, 0.938rem)
--dk-tabs-panel-padding
clamp(1.778rem, 1.6296rem + 0.658vw, 2.222rem)

Examples

Starter

Two-view tabset

Switch between two related views.

<Tabs items={[{ value: 'overview', label: 'Overview' }, { value: 'activity', label: 'Activity' }]} value="overview" panels={{ overview: 'Overview content', activity: 'Activity content' }} />

Common patterns

Manual activation

Use manual activation when changing panels is more expensive or disruptive.

<Tabs activation="manual" items={tabItems} value="overview" panels={panels} />

Edge cases

Vertical trigger set

Vertical tabs can work in inspector or side-panel layouts.

<Tabs orientation="vertical" items={tabItems} value="details" panels={panels} />

Mathematical fixtures

Calculated fixtures; browser evidence is not collected. Layout estimates use declared text behavior and maximum token values.

horizontal-default (orientation=horizontal|size=sm)

pass

orientation=horizontal|size=sm

  • Evidence: mathematical
  • Coverage: complete (2 / 2 declared kinds evaluated)
  • Declared: contrast, target
  • Evaluated: contrast, target
  • Contrast: 90.8 Lc
  • Target: 32 px

vertical-default (orientation=vertical|size=sm)

pass

orientation=vertical|size=sm

  • Evidence: mathematical
  • Coverage: complete (2 / 2 declared kinds evaluated)
  • Declared: contrast, target
  • Evaluated: contrast, target
  • Contrast: 90.8 Lc
  • Target: 32 px

horizontal-default (orientation=horizontal|size=md)

pass

orientation=horizontal|size=md

  • Evidence: mathematical
  • Coverage: complete (2 / 2 declared kinds evaluated)
  • Declared: contrast, target
  • Evaluated: contrast, target
  • Contrast: 90.8 Lc
  • Target: 36 px

vertical-default (orientation=vertical|size=md)

pass

orientation=vertical|size=md

  • Evidence: mathematical
  • Coverage: complete (2 / 2 declared kinds evaluated)
  • Declared: contrast, target
  • Evaluated: contrast, target
  • Contrast: 90.8 Lc
  • Target: 36 px

horizontal-default (orientation=horizontal|size=lg)

pass

orientation=horizontal|size=lg

  • Evidence: mathematical
  • Coverage: complete (2 / 2 declared kinds evaluated)
  • Declared: contrast, target
  • Evaluated: contrast, target
  • Contrast: 90.8 Lc
  • Target: 44 px

vertical-default (orientation=vertical|size=lg)

pass

orientation=vertical|size=lg

  • Evidence: mathematical
  • Coverage: complete (2 / 2 declared kinds evaluated)
  • Declared: contrast, target
  • Evaluated: contrast, target
  • Contrast: 90.8 Lc
  • Target: 44 px

selected (orientation=horizontal|size=sm)

pass

orientation=horizontal|size=sm

  • Evidence: mathematical
  • Coverage: complete (2 / 2 declared kinds evaluated)
  • Declared: contrast, target
  • Evaluated: contrast, target
  • Contrast: 90.8 Lc
  • Target: 32 px

selected (orientation=vertical|size=sm)

pass

orientation=vertical|size=sm

  • Evidence: mathematical
  • Coverage: complete (2 / 2 declared kinds evaluated)
  • Declared: contrast, target
  • Evaluated: contrast, target
  • Contrast: 90.8 Lc
  • Target: 32 px

selected (orientation=horizontal|size=md)

pass

orientation=horizontal|size=md

  • Evidence: mathematical
  • Coverage: complete (2 / 2 declared kinds evaluated)
  • Declared: contrast, target
  • Evaluated: contrast, target
  • Contrast: 90.8 Lc
  • Target: 36 px

selected (orientation=vertical|size=md)

pass

orientation=vertical|size=md

  • Evidence: mathematical
  • Coverage: complete (2 / 2 declared kinds evaluated)
  • Declared: contrast, target
  • Evaluated: contrast, target
  • Contrast: 90.8 Lc
  • Target: 36 px

selected (orientation=horizontal|size=lg)

pass

orientation=horizontal|size=lg

  • Evidence: mathematical
  • Coverage: complete (2 / 2 declared kinds evaluated)
  • Declared: contrast, target
  • Evaluated: contrast, target
  • Contrast: 90.8 Lc
  • Target: 44 px

selected (orientation=vertical|size=lg)

pass

orientation=vertical|size=lg

  • Evidence: mathematical
  • Coverage: complete (2 / 2 declared kinds evaluated)
  • Declared: contrast, target
  • Evaluated: contrast, target
  • Contrast: 90.8 Lc
  • Target: 44 px