HyTab
Usage examples on this page are written for Lit / plain HTML (
<hy-tab>). The same component ships asHyTabin@whitespaceux/harmony-react(native React 19), with typed wrappers for Angular, Solid, Svelte, and Vue. The API reference below applies to all frameworks.
Used inside <hy-tab-group> — it only means something as part of it.
A tab component designed to work within a tab group to control associated tab panels. Provides keyboard navigation, accessibility features, and customizable styling. Supports both horizontal and vertical orientations and can include icons alongside text labels.
Usage Guidelines
Tabs should be used within an hy-tab-group component for proper state management and keyboard navigation. Each tab controls a corresponding hy-tab-panel via the panel attribute.
Orientations
- horizontal (default): Tabs displayed in a row with bottom indicator
- vertical-left: Tabs displayed in a column with left-side indicator
- vertical-right: Tabs displayed in a column with right-side indicator
States
- default: Inactive tab state
- active: Selected tab that controls the visible panel
- disabled: Non-interactive tab state
Keyboard Navigation
When used within hy-tab-group:
- Arrow Right/Down: Move to next tab
- Arrow Left/Up: Move to previous tab
- Home: Move to first tab
- End: Move to last tab
- Enter/Space: Activate focused tab
When not to use
- Stages done in order:
hy-stepper. - Commands:
hy-menu-buttonor buttons. - Picking a value such as a view mode:
hy-toggle-group. - Each item is its own page:
hy-tab-nav. - Confirming or stopping a switch: listen for the cancelable
before-changeonhy-tab-group, not the tab'sselect.
Examples
Basic usage
<hy-tab-group>
<hy-tab slot="tab" label="Dashboard" panel="dashboard-panel"></hy-tab>
<hy-tab slot="tab" label="Settings" panel="settings-panel"></hy-tab>
<hy-tab-panel slot="panel" name="dashboard-panel"> Dashboard content </hy-tab-panel>
<hy-tab-panel slot="panel" name="settings-panel"> Settings content </hy-tab-panel>
</hy-tab-group>With active state
<hy-tab-group>
<hy-tab slot="tab" label="Overview" panel="overview-panel" active></hy-tab>
<hy-tab slot="tab" label="Analytics" panel="analytics-panel"></hy-tab>
<hy-tab slot="tab" label="Reports" panel="reports-panel"></hy-tab>
</hy-tab-group>With icons
<hy-tab-group>
<hy-tab slot="tab" label="Home" panel="home-panel" icon="home"> </hy-tab>
<hy-tab slot="tab" label="Settings" panel="settings-panel" icon="settings"> </hy-tab>
<hy-tab slot="tab" label="Profile" panel="profile-panel" icon="user"> </hy-tab>
</hy-tab-group>Disabled tab
<hy-tab-group>
<hy-tab slot="tab" label="Available" panel="available-panel" active></hy-tab>
<hy-tab slot="tab" label="Premium" panel="premium-panel" disabled icon="lock"> </hy-tab>
</hy-tab-group>Vertical orientation with left indicator
<hy-tab-group orientation="vertical-left">
<hy-tab slot="tab" label="Profile" panel="profile-panel" orientation="vertical-left" icon="user">
</hy-tab>
<hy-tab
slot="tab"
label="Security"
panel="security-panel"
orientation="vertical-left"
icon="shield"
>
</hy-tab>
<hy-tab
slot="tab"
label="Billing"
panel="billing-panel"
orientation="vertical-left"
icon="credit-card"
>
</hy-tab>
</hy-tab-group>Vertical orientation with right indicator
<hy-tab-group orientation="vertical-right">
<hy-tab slot="tab" label="Profile" panel="profile-panel" orientation="vertical-right" icon="user">
</hy-tab>
<hy-tab
slot="tab"
label="Security"
panel="security-panel"
orientation="vertical-right"
icon="shield"
>
</hy-tab>
<hy-tab
slot="tab"
label="Billing"
panel="billing-panel"
orientation="vertical-right"
icon="credit-card"
>
</hy-tab>
</hy-tab-group>Complete tabbed interface
<hy-tab-group>
<hy-tab slot="tab" label="Home" panel="home-content" active icon="home"> </hy-tab>
<hy-tab slot="tab" label="Products" panel="products-content" icon="box"> </hy-tab>
<hy-tab slot="tab" label="Support" panel="support-content" icon="help-circle"> </hy-tab>
<hy-tab-panel slot="panel" name="home-content">
<h2>Welcome Home</h2>
<p>This is the home content area.</p>
</hy-tab-panel>
<hy-tab-panel slot="panel" name="products-content">
<h2>Our Products</h2>
<p>Browse our product catalog.</p>
</hy-tab-panel>
<hy-tab-panel slot="panel" name="support-content">
<h2>Support Center</h2>
<p>Get help and support.</p>
</hy-tab-panel>
</hy-tab-group>Programmatic Methods
const tab = document.querySelector('hy-tab');
// Set active state
tab.active = true;
// Focus the tab
tab.focus();
// Blur the tab
tab.blur();
// Check if disabled
console.log(tab.disabled);API
Properties
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
label | label | string | 'Tab' | The text content of the tab. |
panel | panel | string | '' | The name of the tab panel this tab controls. |
disabled | disabled | boolean | false | Disables the tab, making it non-interactive. |
active | active | boolean | false | Marks the tab as active/selected. |
orientation | orientation | 'horizontal' | 'vertical-left' | 'vertical-right' | 'horizontal' | The orientation and indicator position of the tab, typically inherited from the parent tab-group. - 'horizontal': Horizontal layout with bottom indicator (default) - 'vertical-left': Vertical layout with left indicator - 'vertical-right': Vertical layout with right indicator |
emphasis | emphasis | 'solid' | 'soft' | 'outlined' | 'plain' | 'plain' | Visual chrome weight, typically inherited from the parent tab-group. - plain (default) — transparent rest, role underline indicator - soft — role-tinted pill on the active tab - outlined — boxed/bordered tabs - solid — fully filled active tab |
size | size | 'small' | 'medium' | 'large' | 'medium' | Type + padding rung, typically inherited from the parent tab-group. - small — label-md type on row-nav-md padding - medium (default) — body-md type on row-nav-lg padding - large — body-lg type on row-nav-lg padding |
icon | icon | string | '' | An icon before the label, a name from the design system's icon family (hy-icon). The React twin takes the same property as a node. |
Events
| Event | Detail | Description |
|---|---|---|
select | — | Fired when the tab is clicked or activated, includes panel ID and tab reference |
CSS Parts
| Part | Description |
|---|---|
base | The tab's base button element |
label | The tab's text label element |
CSS Custom Properties
The documented hooks. Every override hook the component reads — one per token it paints — is listed in @whitespaceux/harmony/theme-api.json, and @whitespaceux/harmony/component-bindings.json (the Harmony MCP get-bindings tool) says which part and state each one paints.
| Property | Default | Description |
|---|---|---|
--hy-tab-dimension-none | var(--hy-dimension-none) | Border radius of the plain tab (default: none) |
--hy-tab-radius-form-md | var(--hy-radius-form-md) | Border radius of the soft / outlined / solid tab (set var(--hy-radius-pill-md) for a full pill) |
--hy-tab-text-transform | none | Text transform for tab label |
--hy-tab-body-md-font-family | var(--hy-body-md-font-family) | Font family override for tab label |
--hy-tab-body-sm-font-family | var(--hy-body-sm-font-family) | Font family override for tab label |
--hy-tab-body-lg-font-family | var(--hy-body-lg-font-family) | Font family override for tab label |
--hy-tab-motion-transition-hover-duration | var(--hy-motion-transition-hover-duration) | Transition duration for hover and focus state feedback |
--hy-tab-motion-transition-hover-easing | var(--hy-motion-transition-hover-easing) | Transition easing for hover and focus state feedback |
--hy-tab-motion-transition-expand-duration | var(--hy-motion-transition-expand-duration) | Transition duration for the active-indicator slide animation |
--hy-tab-motion-transition-expand-easing | var(--hy-motion-transition-expand-easing) | Transition easing for the active-indicator slide animation |
--hy-tab-background-rest | transparent | Tab fill at rest (transparent unless set) |
Methods
focus()
Sets focus on the tab.
Parameters:
options- Optional focus options
const tab = document.querySelector('hy-tab');
tab.focus();blur()
Removes focus from the tab.
const tab = document.querySelector('hy-tab');
tab.blur();