Skip to content

HyTabNavItem

Usage examples on this page are written for Lit / plain HTML (<hy-tab-nav-item>). The same component ships as HyTabNavItem in @whitespaceux/harmony-react (native React 19), with typed wrappers for Angular, Solid, Svelte, and Vue. The API reference below applies to all frameworks.

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 — .claude/rules/components.md "Press / current / selected"). 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-shapedhy-tab-group / hy-tabhy-tab-nav / hy-tab-nav-item
Value pickerhy-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.

Examples

Inside a tab nav

html
<hy-tab-nav label="Settings section" emphasis="soft" size="small">
  <hy-tab-nav-item href="/settings/primitives" active>Primitives</hy-tab-nav-item>
  <hy-tab-nav-item href="/settings/semantics">Semantics</hy-tab-nav-item>
  <hy-tab-nav-item href="/settings/components">Components</hy-tab-nav-item>
</hy-tab-nav>

Client-side routing

javascript
<hy-tab-nav-item value="inbox" href="/inbox">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

html
<hy-tab-nav-item href="/reports">
  <hy-icon slot="icon" name="chart" decorative></hy-icon>
  Reports
</hy-tab-nav-item>

API

Properties

PropertyAttributeTypeDefaultDescription
valuevaluestring''Identifier emitted in the activate event.
hrefhrefstring''When set (and not disabled), the item renders as an <a>.
targettargetstring''Anchor target; paired with href.
activeactivebooleanfalseMarks the item as the current page. Sets aria-current="page".
disableddisabledbooleanfalseDisables the item. Forces <button disabled> regardless of href.
labellabelstring''Explicit accessible name (aria-label) overriding the visible label. Useful for i18n or when the visible label alone is ambiguous.
sizesize'small' | 'medium' | 'large''medium'Type + padding rung, typically inherited from the parent tab nav. - smalllabel-md type on row-nav-md padding - medium (default) — body-md type on row-nav-lg padding - largebody-lg type on row-nav-lg padding
emphasisemphasis'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
orientationorientation'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
hasIconhas-iconbooleanfalseSSR optimization hint indicating the icon slot has content.

Events

EventDetailDescription
activateFired on click, before navigation. Consumers with client-side routing call detail.originalEvent.preventDefault() to intercept. Detail: { value, href, originalEvent }

Slots

SlotDescription
defaultThe visible label.
iconIcon content displayed before the label.

CSS Parts

PartDescription
baseThe interactive <a> or <button> element.
labelThe label wrapper.

CSS Custom Properties

PropertyDescription
--hy-tab-nav-item-background-brand-restUnderline / outlined-border / solid fill at rest
--hy-tab-nav-item-background-brand-hoverSolid fill on hover of the current item
--hy-tab-nav-item-background-brand-pressedSolid fill while pressed
--hy-tab-nav-item-background-active-fillSoft fill of the current item
--hy-tab-nav-item-background-active-hoverHover of the current item (plain / soft)
--hy-tab-nav-item-background-active-pressedPressed fill of the current item (plain / soft)
--hy-tab-nav-item-background-muted-hoverHover of a non-current item
--hy-tab-nav-item-background-muted-pressedPressed fill of a non-current item
--hy-tab-nav-item-background-restBackground at rest
--hy-tab-nav-item-foreground-brand-restRole-coloured ink on a tint (soft / outlined current item)
--hy-tab-nav-item-foreground-on-brand-restInk on the solid fill
--hy-tab-nav-item-foreground-default-restInk at rest
--hy-tab-nav-item-foreground-default-disabledInk when disabled
--hy-tab-nav-item-gapGap between icon and label
--hy-tab-nav-item-padding-blockBlock padding
--hy-tab-nav-item-padding-inlineInline padding
--hy-tab-nav-item-radiusBorder radius (plain)
--hy-tab-nav-item-radius-formBorder radius of the soft / outlined / solid item (default: var(--hy-radius-form-md); set var(--hy-radius-pill-md) for a full pill)
--hy-tab-nav-item-text-transformText transform for the label
--hy-tab-nav-item-font-familyFont family override for the label
--hy-tab-nav-item-hover-durationTransition duration for hover and focus state feedback
--hy-tab-nav-item-hover-easingTransition easing for hover and focus state feedback
--hy-tab-nav-item-expand-durationTransition duration for the indicator slide animation
--hy-tab-nav-item-expand-easingTransition 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.

Built with Lit. Documented with VitePress.