Angular Navigation Menu Component | ng-hub-ui-nav

Angular navigation component with dropdowns, drill-down panels, responsive collapse, router integration and CSS-variable theming.

API reference

Here's the full contract for nav: everything you can bind, listen to, project and theme, gathered in one place. Wire up what you need and style what you want — it's standalone and signal-friendly.

Inputs

Dial nav in with 40 inputs. Bind them like any Angular @Input.

NameTypeDefaultDescription
itemsRequiredHubNavItem[]—Array of navigation items to render. Each item defines its type (link, dropdown, header, separator, custom), label, route, icon, badge, children, and more.
configPartial<HubNavConfig>{}Partial configuration overrides merged with global defaults. Controls orientation, dropdown trigger, collapse mode, breakpoint, position, and more.
navClassstring''Additional CSS class applied to the nav container element.
itemTemplateTemplateRef<unknown> | nullnullOptional custom template for rendering nav items via input binding. The hubNavItemTemplate directive takes priority over this input.
iconTemplateTemplateRef<HubNavItemIconContext> | nullnullTemplate drawn in place of the icon class, for entries that declare an icon. Receives HubNavItemIconContext with $implicit (the item) and rail. The hubNavItemIcon directive takes priority over this input.
autoOpenFromRoutebooleanfalseWhen true, the nav automatically opens the dropdowns and drill-down panels matching the active router URL on initialization and after every navigation. Useful for sidebar navigations where the URL drives the open state. In a menu whose roots expand in different ways only one section stays open: arriving at an accordion root closes the panel of the panel root you left, and the other way round.
color'primary' | 'success' | 'danger' | 'warning' | 'info' | stringundefinedSemantic accent applied to hover/active affordances. Accepts a semantic name (primary, success, danger, warning, info), a registered accent name, a CSS named colour, or a literal #hex / rgb() / oklch() / var(). Barewords resolve to the --hub-sys-color-<name> token; defaults to primary when omitted.
railboolean (two-way: model)falseDesktop-only icon rail. When true, a vertical nav renders at rail width showing icons only. Ignored below collapseBreakpoint, where the offcanvas behavior always wins. Two-way bindable via [(rail)].
activeItemIdstring | null (two-way: model)nullEntry to mark active, named by its `id` or its `fragment`, when the router is not what says where the reader is. While it is set it answers for the whole menu: route matching stands down and the marked entry announces `aria-current="location"` rather than `page`. Two-way bindable, which is how `hubNavScrollSpy` drives the mark.
orientation (config)'horizontal' | 'vertical''horizontal'Orientation of the navigation: horizontal renders a top bar, vertical renders a sidebar.
verticalExpandMode (config)'accordion' | 'flyout' | 'panel''accordion'How child items expand in vertical orientation: accordion expands inline, flyout opens a positioned side submenu, panel opens stacked drill-down panels.
dropdownTrigger (config)'hover' | 'click' | 'both''click'Mechanism that opens dropdown menus: on hover, on click, or both.
dropdownRenderMode (config)'inline' | 'overlay''inline'Rendering strategy for dropdown and flyout menus: inline inside the nav DOM, or overlay in a body-level layer to avoid clipping. Panel drill-down mode is not affected.
position (config)'static' | 'sticky' | 'fixed''static'CSS positioning strategy for the nav container. Sticky positioning is only activated for vertical navigation.
stickyTop (config)string'0px'Top offset used when sticky positioning is enabled. Accepts any valid CSS length value.
collapseMode (config)'offcanvas' | 'dropdown' | 'fullscreen''offcanvas'Display mode when the menu collapses on small viewports: offcanvas slide-in drawer, dropdown below the toggler, or fullscreen overlay.
collapseBreakpoint (config)number992Viewport width in pixels below which the menu collapses. Set to 0 to disable responsive collapsing.
offcanvasPosition (config)'start' | 'end' | 'top' | 'bottom''start'Side from which the offcanvas panel slides in. Only applies when collapseMode is offcanvas.
ariaLabel (config)string'Navigation'Accessible label applied to the nav element.
panelMaxVisible (config)number3Maximum number of simultaneously visible panels in panel expand mode. Beyond it, the last panel drills down in place with back navigation.
sidebarSide (config)'left' | 'right''left'Physical side of the sidebar: left (panels extend to the right) or right (panels extend to the left).
panelWidth (config)string'16rem'Width of each drill-down panel. Accepts any valid CSS width value.
railToggle (config)booleantrueWhether the built-in edge toggle renders on the primary column of a vertical desktop nav. Disable it when the app ships its own toggle. Fully themeable through the --hub-nav-rail-toggle-* tokens, including a replaceable SVG arrow.
followReplacedUrls (config)boolean | numbertrueHow eagerly the nav follows a scroll spy, which reports the reader position by replacing the URL: true follows each report, a number of milliseconds follows only once they go quiet, false never follows.
activeIndicator (config)booleanfalseWhether the active mark travels between items instead of appearing and disappearing in place. Off by default; honours prefers-reduced-motion.
labels (config)Partial<HubNavLabels>undefinedPer-instance overrides for the built-in accessible labels. Omitted labels resolve from the shared HUBUI.NAV.* dictionary keys, then from the English defaults.
enabled (hubNavScrollSpy) — bound as [hubNavScrollSpy]booleantrueEnables or disables section tracking. Bound through the selector itself: [hubNavScrollSpy]="false" turns the spy off.
offset (hubNavScrollSpy)number120Top offset in pixels used to compensate sticky headers when computing the active section.
sectionSelector (hubNavScrollSpy)string'[data-hub-nav-scroll-spy-section]'CSS selector used to locate trackable section elements inside the host container.
nav (hubNavScrollSpy)HubNavComponent | nullnullThe nav this spy answers for. Bound, the two halves join up: the section under the reader marks the matching entry, and a click on an entry scrolls here. No URL is written and no history entry is pushed. Left unbound the spy only reports through `activeSectionChange`.
scrollContainer (hubNavScrollSpy)HTMLElement | nullnullThe element these sections actually scroll in, when it is not the one the spy would find by walking up from them. It is also what `scrollTo` moves, which is what keeps a jump from dragging every scrollable ancestor with it.
clickSettleMs (hubNavScrollSpy)number0How long, in milliseconds, a click's answer survives the reader appearing to take over. During this window a wheel, a touch or a key is ignored, so a jump still in flight is not overruled mid-animation. `0`, the default, keeps the previous behaviour.
sectionId (hubNavScrollSpySection)string | nullnullOptional section id for a tracked section. When omitted, the host element id attribute is used.
item (hub-nav-item)RequiredHubNavItem—The navigation item rendered by the internal hub-nav-item child. Managed automatically by hub-nav; rarely bound directly.
depth / isActive / isExpanded / forceAccordionMode (hub-nav-item; depth and forceAccordionMode also on hub-nav-item-list)number / boolean / boolean / boolean0 / false / false / falseInternal state inputs of hub-nav-item: nesting depth, active and expanded flags, and forced accordion behaviour inside mobile or panel contexts. hub-nav-item-list carries depth and forceAccordionMode too, so a whole level can be forced at once.
items (hub-nav-item-list)RequiredHubNavItem[]—Items rendered by the internal hub-nav-item-list child. Managed automatically by hub-nav.
panels (hub-nav-panel-container)RequiredHubNavPanelState[]—Stack of open panel states rendered by the internal hub-nav-panel-container in panel expand mode.
panel (hub-nav-panel)RequiredHubNavPanelState—State of a single drill-down panel rendered by the internal hub-nav-panel child.
itemTemplate / dropdownRenderMode / panelWidth / sidebarSide / showHeader / hideFirstPanelHeader / isLast (hub-nav-item-list / hub-nav-panel / hub-nav-panel-container)TemplateRef<unknown> | null / HubNavDropdownRenderMode / string / HubNavSidebarSide / boolean / boolean / boolean—Internal wiring inputs the root hub-nav forwards to its children; each exists on the subset of these components that needs it, and isLast marks the outermost panel of a stack so it can close the stack's edge. Configure them through the config input on hub-nav instead of binding them directly.
overlayOwnerClass / overlayOrientationClass (hub-nav-item-list / hub-nav-panel / hub-nav-panel-container)string / 'hub-nav--horizontal' | 'hub-nav--vertical''' / 'hub-nav--vertical' ('hub-nav--horizontal' on hub-nav-item-list)Overlay wiring the root hub-nav forwards when submenus render in a body-level overlay: overlayOwnerClass is the unique class that ties an overlay back to its nav for outside-click handling, and overlayOrientationClass carries the nav's orientation so the host-context styles still apply outside the component tree.

Outputs

React to what nav does — 12 events to hook your logic onto.

NameTypeDescription
itemClickOutputEmitterRef<HubNavItem>Emitted when a link item is clicked. Provides the clicked HubNavItem.
dropdownOpenOutputEmitterRef<HubNavItem>Emitted when a dropdown item is opened.
dropdownCloseOutputEmitterRef<HubNavItem>Emitted when a dropdown item is closed.
mobileToggleOutputEmitterRef<boolean>Emitted when the mobile panel is toggled. Provides true when open, false when closed.
panelChangeOutputEmitterRef<HubNavPanelEvent>Emitted when a panel is opened, closed, drilled-down, or navigated back. Provides the item, panel index, and action type.
railChangeOutputEmitterRef<boolean>Emitted when the rail model value flips, enabling [(rail)] two-way binding and app-side persistence.
activeItemIdChangeOutputEmitterRef<string | null>Emitted when the marked entry changes, which is what makes `activeItemId` two-way bindable. A scroll spy bound with `[nav]` reports the section it lands on through this output.
activeSectionChange (hubNavScrollSpy)OutputEmitterRef<string>Emits the id of the newly active section whenever the visible section changes.
clicked / toggleDropdown (hub-nav-item)OutputEmitterRef<{ item: HubNavItem; event: Event }> / OutputEmitterRef<HubNavItem>Internal hub-nav-item events: clicked emits the item plus the original DOM event, toggleDropdown emits the dropdown item being toggled. Both bubble up to the hub-nav outputs.
itemClick / dropdownToggle / panelOpen (hub-nav-item-list / hub-nav-panel / hub-nav-panel-container)OutputEmitterRef<{ item: HubNavItem; event: Event }> / OutputEmitterRef<HubNavItem> / OutputEmitterRef<HubNavItem>Item interaction events re-emitted by the internal list and panel children while bubbling up to hub-nav: itemClick (item plus DOM event), dropdownToggle (toggled item), and panelOpen (item whose children should open a panel).
closePanel / backClick (hub-nav-panel)OutputEmitterRef<string>Emitted by the internal hub-nav-panel with the panel id when the close button (closePanel) or back button (backClick) is pressed.
panelClose / panelBack (hub-nav-panel-container)OutputEmitterRef<string>Emitted by the internal hub-nav-panel-container with the panel id, relaying close (panelClose) and back (panelBack) requests to hub-nav.

Templates

Make it yours — 4 template slots let you project custom markup.

NameDescriptionExample
hubNavStartProjects custom content in the start slot. Horizontal: visual start (left in LTR, right in RTL). Vertical: top of the primary column.<hub-nav [items]="items"> <ng-template hubNavStart let-collapsed="collapsed"> <img src="logo.svg" alt="Brand" /> @if (!collapsed) { <span>App Name</span> } </ng-template> </hub-nav>
hubNavEndProjects custom content in the end slot. Horizontal: visual end (right in LTR, left in RTL). Vertical: bottom of the primary column.<hub-nav [items]="items"> <ng-template hubNavEnd> <button type="button">Sign out</button> </ng-template> </hub-nav>
hubNavItemTemplateOverrides the default item rendering with a custom template. Receives HubNavItemTemplateContext with $implicit (item), active, expanded, and depth properties.<hub-nav [items]="items"> <ng-template hubNavItemTemplate let-item let-active="active"> <span [class.fw-bold]="active">{{ item.label }}</span> @if (item.badge) { <hub-badge shape="rounded">{{ item.badge }}</hub-badge> } </ng-template> </hub-nav>
hubNavItemIconReplaces the glyph of every entry that declares an icon, and nothing else. Receives HubNavItemIconContext with $implicit (the item) and rail, so a nav can draw its icons with ng-hub-ui-icons — or any other pack — without the library depending on one. Entries with no icon are untouched.<hub-nav [items]="items"> <ng-template hubNavItemIcon let-item let-rail="rail"> <hub-icon [name]="item.icon" [size]="rail ? 'lg' : 'md'" /> </ng-template> </hub-nav>