HyTabNavItem
Usage examples on this page are written for Lit / plain HTML (
<hy-tab-nav-item>). The same component ships asHyTabNavItemin@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-nav> — it only means something as part of it.
One link inside an hy-tab-nav: looks exactly like an hy-tab but navigates instead of switching a panel.
It renders a real link with its own URL, so the back button works and the current page is announced through aria-current.
Renders as <a> when href is set and not disabled, otherwise <button> (for apps whose router owns the URL). disabled always wins — a disabled item is a <button disabled> regardless of href, because HTML has no native disabled attribute on anchors.
The current item carries aria-current="page" (the persistent "you are here" state, distinct from a press or a selection). There is no role="tab", no aria-selected and no roving tabindex: these are links, and Tab moves between them.
Tabs vs tab nav vs toggle group
| In place (no URL) | Navigates (URL) | |
|---|---|---|
| Tab-shaped | hy-tab-group / hy-tab | hy-tab-nav / hy-tab-nav-item |
| Value picker | hy-toggle-group | — |
Emphasis and size
Both are normally inherited from the parent hy-tab-nav. The chrome is pixel-identical to hy-tab at every rung of both axes: plain (underline indicator), soft (role-tinted rounded rectangle on the current item), outlined (boxed), solid (filled current item); small / medium / large share hy-tab's type + padding ladder.
When not to use
- Navigation your router handles: keep
hrefand cancel theactivateevent's original event. Withouthrefthe item is a button and loses open in new tab. - A single link outside a tab nav:
hy-link. - Something that changes state without leaving the page:
hy-button, orhy-togglefor an on and off state.
Accessibility: your part
- The
iconis decorative; the label names the item.
Examples
Inside a tab nav
<hy-tab-nav label="Tokens section" emphasis="soft" size="small">
<hy-tab-nav-item label="Primitives" href="/tokens/primitives" active></hy-tab-nav-item>
<hy-tab-nav-item label="Semantics" href="/tokens/semantics"></hy-tab-nav-item>
<hy-tab-nav-item label="Components" href="/tokens/components"></hy-tab-nav-item>
</hy-tab-nav>Client-side routing
<hy-tab-nav-item label="Inbox" value="inbox" href="/inbox"></hy-tab-nav-item>
<script>
document.querySelector('hy-tab-nav-item').addEventListener('activate', (e) => {
e.detail.originalEvent.preventDefault(); // intercept, then route client-side
router.push(e.detail.href);
});
</script>With an icon
<hy-tab-nav-item label="Reports" href="/reports" icon="bar-chart"></hy-tab-nav-item>API
Properties
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
value | value | string | '' | Identifier emitted in the activate event. |
href | href | string | '' | When set (and not disabled), the item renders as an <a>. |
target | target | string | '' | Anchor target; paired with href. |
active | active | boolean | false | Marks the item as the current page. Sets aria-current="page". |
disabled | disabled | boolean | false | Disables the item. Forces <button disabled> regardless of href. |
label | label | string | '' | The visible label — the name of the page the link opens. |
size | size | 'small' | 'medium' | 'large' | 'medium' | Type + padding rung, typically inherited from the parent tab nav. - 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 |
emphasis | emphasis | 'solid' | 'soft' | 'outlined' | 'plain' | 'plain' | Visual chrome weight, typically inherited from the parent tab nav. - plain (default) — transparent rest, role underline indicator - soft — role-tinted rounded rectangle on the current item - outlined — boxed/bordered items - solid — fully filled current item |
orientation | orientation | 'horizontal' | 'vertical' | 'horizontal' | Layout axis, typically inherited from the parent tab nav. - horizontal (default) — indicator on the block-end edge - vertical — indicator on the inline-start edge |
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 |
|---|---|---|
activate | — | Fired on click, before navigation. Consumers with client-side routing call detail.originalEvent.preventDefault() to intercept. Detail: { value, href, originalEvent } |
CSS Parts
| Part | Description |
|---|---|
base | The interactive <a> or <button> element. |
label | The label wrapper. |
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-nav-item-background-brand-on-rest | var(--hy-background-brand-on-rest) | Outlined border and solid fill of the current item — the on token (C6) |
--hy-tab-nav-item-background-brand-on-hover | var(--hy-background-brand-on-hover) | Solid fill on hover of the current item |
--hy-tab-nav-item-background-brand-on-pressed | var(--hy-background-brand-on-pressed) | Solid fill of the current item while pressed |
--hy-tab-nav-item-background-selection-rest | var(--hy-background-selection-rest) | Soft fill of the current item |
--hy-tab-nav-item-background-selection-hover | var(--hy-background-selection-hover) | Hover of the current item (plain / soft) |
--hy-tab-nav-item-background-muted-hover | var(--hy-background-muted-hover) | Hover of a non-current item |
--hy-tab-nav-item-background-muted-pressed | var(--hy-background-muted-pressed) | Pressed fill of a non-current item |
--hy-tab-nav-item-background-rest | transparent | Background at rest |
--hy-tab-nav-item-foreground-brand-rest | var(--hy-foreground-brand-rest) | Role-colored ink on a tint (soft / outlined current item) |
--hy-tab-nav-item-foreground-brand-hover | var(--hy-foreground-brand-hover) | Role-colored ink of a hovered soft / outlined current item (on the strong tint) |
--hy-tab-nav-item-foreground-brand-on-rest | var(--hy-foreground-brand-on-rest) | Ink on the solid fill |
--hy-tab-nav-item-foreground-default-rest | var(--hy-foreground-default-rest) | Ink at rest |
--hy-tab-nav-item-foreground-default-disabled | var(--hy-foreground-default-disabled) | Ink when disabled |
--hy-tab-nav-item-gap-row-nav-md-inline | var(--hy-gap-row-nav-md-inline) | Gap between icon and label |
--hy-tab-nav-item-padding-row-nav-md-block | var(--hy-padding-row-nav-md-block) | Block padding |
--hy-tab-nav-item-padding-row-nav-sm-block | var(--hy-padding-row-nav-sm-block) | Block padding |
--hy-tab-nav-item-padding-row-nav-lg-block | var(--hy-padding-row-nav-lg-block) | Block padding |
--hy-tab-nav-item-padding-row-nav-md-inline | var(--hy-padding-row-nav-md-inline) | Inline padding |
--hy-tab-nav-item-padding-row-nav-sm-inline | var(--hy-padding-row-nav-sm-inline) | Inline padding |
--hy-tab-nav-item-padding-row-nav-lg-inline | var(--hy-padding-row-nav-lg-inline) | Inline padding |
--hy-tab-nav-item-dimension-none | var(--hy-dimension-none) | Border radius (plain) |
--hy-tab-nav-item-radius-form-md | var(--hy-radius-form-md) | Border radius of the soft / outlined / solid item (set var(--hy-radius-pill-md) for a full pill) |
--hy-tab-nav-item-text-transform | none | Text transform for the label |
--hy-tab-nav-item-body-md-font-family | var(--hy-body-md-font-family) | Font family override for the label |
--hy-tab-nav-item-body-sm-font-family | var(--hy-body-sm-font-family) | Font family override for the label |
--hy-tab-nav-item-body-lg-font-family | var(--hy-body-lg-font-family) | Font family override for the label |
--hy-tab-nav-item-motion-transition-hover-duration | var(--hy-motion-transition-hover-duration) | Transition duration for hover and focus state feedback |
--hy-tab-nav-item-motion-transition-hover-easing | var(--hy-motion-transition-hover-easing) | Transition easing for hover and focus state feedback |
--hy-tab-nav-item-motion-transition-expand-duration | var(--hy-motion-transition-expand-duration) | Transition duration for the indicator slide animation |
--hy-tab-nav-item-motion-transition-expand-easing | var(--hy-motion-transition-expand-easing) | Transition easing for the indicator slide animation |
Methods
focus()
Sets focus on the item's interactive element.
blur()
Removes focus from the item's interactive element.