DhTabs
M3E underline tab strip with a sliding, resizing active indicator. Variant (primary/secondary/tertiary/error) is colour only; per-tab content (label / icon / label+icon stacked) is inferred from each item; equal-width or scrollable. Keyboard nav (arrow keys, Home/End).
Variant · primary
Default colour role. The selected label and the sliding 3px indicator pick up --color-primary; the indicator slides and resizes as selection changes.
<DhTabs
bind:value={selected}
tabs={[
{ id: 'video', label: 'Video' },
{ id: 'photos', label: 'Photos' },
{ id: 'audio', label: 'Audio' }
]}
ariaLabel="Media type"
/>Variant · secondary
<DhTabs
bind:value={selected}
tabs={[
{ id: 'video', label: 'Video' },
{ id: 'photos', label: 'Photos' },
{ id: 'audio', label: 'Audio' }
]}
variant="secondary"
ariaLabel="Media type"
/>Variant · tertiary
<DhTabs
bind:value={selected}
tabs={[
{ id: 'video', label: 'Video' },
{ id: 'photos', label: 'Photos' },
{ id: 'audio', label: 'Audio' }
]}
variant="tertiary"
ariaLabel="Media type"
/>Variant · error
<DhTabs
bind:value={selected}
tabs={[
{ id: 'video', label: 'Video' },
{ id: 'photos', label: 'Photos' },
{ id: 'audio', label: 'Audio' }
]}
variant="error"
ariaLabel="Media type"
/>Icon only
A tab with an icon and no label renders icon-only. Provide ariaLabel so the tab has an accessible name.
<DhTabs
bind:value={selected}
tabs={[
{ id: 'people', icon: 'user', ariaLabel: 'People' },
{ id: 'edit', icon: 'edit', ariaLabel: 'Edit' }
]}
ariaLabel="Quick actions"
/>Label & icon
A tab that has both a label and an icon stacks them vertically at 64px.
<DhTabs
bind:value={selected}
tabs={[
{ id: 'video', label: 'Video', icon: 'film' },
{ id: 'photos', label: 'Photos', icon: 'image' }
]}
ariaLabel="Media type"
/>Scrollable
Intrinsic-width tabs in a horizontally scrolling strip (90px minimum). The indicator stays aligned while scrolling.
<DhTabs
bind:value={selected}
tabs={[
{ id: 'summary', label: 'Summary' },
{ id: 'recordings', label: 'Recordings' },
{ id: 'transcripts', label: 'Transcripts' },
{ id: 'exports', label: 'Exports' }
]}
scrollable
ariaLabel="Workspace sections"
/>Disabled tab
Disabled tabs are skipped by arrow-key navigation.
<DhTabs bind:value={selected} tabs={[
{ id: 'one', label: 'One' },
{ id: 'two', label: 'Two' },
{ id: 'three', label: 'Three (disabled)', disabled: true },
{ id: 'four', label: 'Four' }
]} />