Nav
A horizontal row of links with dropdown menus, or a vertical sidebar column with nested, multi-open disclosure sections. It stays a semantically correct navigation landmark in any context: standalone, in a sidebar, or composed by Header into a full top bar.
Import
import { Nav } from "@hyzer-labs/ui"Demo
An item with children becomes a dropdown. With an href the
label stays a navigable link and a separate chevron opens the menu; without one, the
whole label is the trigger. Keyboard: Enter/Space toggle, ArrowDown opens and focuses
the menu, Escape closes. Header composes this Nav
for you: hand it the same items for a full top bar with branding, actions, and
a mobile drawer built in.
<Nav
items={[
{ label: 'Home', href: '/docs' },
{ label: 'Components', href: '/components', children: [
{ label: 'Button', href: '/docs/components/button' }
] }
]}
ariaLabel="Main navigation"
/>orientation="vertical" renders a sidebar column. Submenus become inline disclosure
sections that nest and collapse independently, so you can have several open at once. The docs
sidebar you are reading is this Nav.
<Nav items={sidebarItems} orientation="vertical" ariaLabel="Docs navigation" />
<!-- children can nest, and carry { heading } group labels between links;
defaultOpen starts a section open. -->Props
| Name | Type | Default | Note |
|---|---|---|---|
items | NavItem[] | — | Required. See NavItem below. |
orientation | 'horizontal' | 'vertical' | 'horizontal' | horizontal: a row of links with dropdown menus. vertical: a sidebar column with inline, nested, multi-open disclosure sections. |
ariaLabel | string | 'Main navigation' | |
chevronIcon | Snippet | — | Replaces the dropdown chevron. |
class | string | — | Merged after the hz-nav class. |
NavItem
| Name | Type | Default | Note |
|---|---|---|---|
label | string | — | Required. |
href | string | — | Omit (with children present) for a trigger-only dropdown / section parent. |
children | NavChild[] | — | Makes the item a dropdown (horizontal) or a nested disclosure section (vertical). May contain items or { heading } group labels. |
external | boolean | — | Adds the external-link treatment. |
ariaCurrent | 'page' | 'step' | 'true' | — | Set on the active item. |
defaultOpen | boolean | — | Vertical only: the section starts open, and re-opens when items is rebuilt (e.g. on navigation). |
Theme hooks
What this component promises your CSS. The reference theme styles exactly these — from @layer hz-theme, so your unlayered rules win. See Styling Components for the how.
Root class: .hz-nav
Data attributes
| Hook | Values | Styles |
|---|---|---|
data-orientation | 'horizontal' | 'vertical' | Selects the layout mode — a horizontal row with popover dropdown panels, or a sidebar column with inline nested disclosure sections. Default horizontal. |
data-state | 'open' | 'closed' | On .hz-nav-panel — the dropdown/disclosure open/closed vocabulary to animate against. |
Part classes
| Hook | Values | Styles |
|---|---|---|
.hz-nav-links | child element | The link list — a row (horizontal) or a column (vertical). |
.hz-nav-dropdown | child element | The list item wrapping a submenu. |
.hz-nav-trigger | child element | The label-only section toggle (no href). |
.hz-nav-chevron | child element | The separate chevron button when the item is both a link and a toggle. |
.hz-nav-panel | child element | The submenu list — a popover when horizontal, an inline section when vertical. |
.hz-nav-heading | child element | A group label inside a panel: static text, no focus stop. |
Accessibility
Horizontal dropdowns follow the APG menu-button pattern. The trigger carries aria-haspopup/aria-expanded, the panel is a role=menu with roving arrow-key focus, and Escape closes it and returns focus to the trigger.
Vertical sections are plain disclosure (aria-expanded on each <button>), not menus, with native keyboard traversal.
A heading entry is static, non-focusable text read in sequence before the links it labels.
References: APG Menu Button pattern