Axon 911 Frontend DocsAxon 911 Frontend Docs
Axon 911 Frontend Docs
    Loading navigation…
U
User
Switch to light mode
  1. Components
  2. Navbar
  3. Accessibility

Navbar

Accessibility

Navbar from @prepared911/ui/navbar provides a named application navigation landmark and composes link-based destinations with menu-based overflow and app switching. The component handles landmark, measurement, and menu primitives; your job is to supply meaningful localized names, accurate route state, and accessible custom content.
What the component handles
  • Banner landmark. The root is a header. Set landmark to a nav and pass label only when this bar is not the page banner. The route tabs are a labelled nav inside the bar.
  • Link semantics. Primary destinations use TabsTrigger, preserving native link focus, activation, modifier-click, and current-route semantics.
  • Responsive measurement. The duplicate measurement row is aria-hidden, so assistive technology encounters only the interactive destinations.
  • Overflow access. Hidden destinations move into a keyboard-operable labeled More menu instead of disappearing. The menu opens on click by default. Hover-open is opt-in.
  • Brand name. With href, label names the link and the mark is decorative. With only label, the mark is an image with that name.
  • App selection. Multi-app destinations use radio-menu semantics, including the current checked item.
  • Label in name. The app-switcher trigger combines the visible current app name with appMenuLabel. Account triggers composed in NavbarEnd must include the visible account name in their accessible name.
What you must provide
  • A landmark name. A page has one banner, so the bar needs no name unless you switch landmark to a nav. Then label must name that nav.
  • A brand name. Pass NavbarBrand label when the mark is a link or the only product name. Name the product, not the image file.
  • Localized controls. Localize destination and app labels, overflowMenuLabel, appMenuLabel, account controls, and icon-only action names.
  • Accurate active state. Keep currentPath synchronized with the router. Add extraRouteMatchers when nested routes belong to one destination.
  • Meaningful app-switcher language. Use an action phrase such as "Switch app" for appMenuLabel. Do not repeat the current app name in that prop; the component combines them.
  • Accessible custom renderers. A custom renderTab replaces the complete interactive link in the visible row, so it must implement native link focus and activation, routing, current-state, modifier-click, and keyboard semantics. Use renderMeasurementTab for a single width-matched, non-interactive measurement element; it does not need to be an anchor. A custom renderOverflowMenuItem must return a focusable menu item that calls the supplied onSelect from the in-menu row for destination activation and communicates the supplied active state. If that row opens secondary UI in a portal, call onInteractingChange(true) while pointer or focus remains in the row or portaled UI, call onInteractingChange(false) when the interaction ends and during unmount cleanup, and do not call onSelect from portaled close actions. Interaction ending alone does not dismiss More. Outside events are suppressed while interaction is active; onSelect, Escape, or a deferred hover dismiss closes the menu.
  • Named trailing actions. Every icon-only action in NavbarEnd needs a tooltip or accessible name that states its action.
  • Named account triggers. If you compose an account menu, include the visible name in the accessible name. Treat the chevron as decorative by omitting its title. Click-open is the default; hover-open is opt-in.
Keyboard behavior
  • Tab / Shift+Tab move through primary links, app-switcher and overflow triggers, and trailing actions in document order.
  • Enter activates a focused destination link.
  • Middle-click or Cmd/Ctrl+click opens a destination in a new tab when app routing preserves native link behavior.
  • Enter / Space open the app-switcher and overflow menus. Overflow opens on click by default; hover-open is opt-in.
  • Arrow keys move among menu items.
  • Enter / Space select the focused app or overflow destination.
  • Escape closes an open menu and returns focus to its trigger, including when a custom overflow row is interacting with portaled UI.
Semantics and roles
  • The Navbar root is a named navigation landmark.
  • Nested destination Tabs roots are presentation-only so they do not split that landmark.
  • Primary destinations are links, not ARIA tabs. The active route is exposed as the current destination by the underlying Tabs.
  • A labeled logo brand is one named image. Decorative details inside it do not need separate names.
  • The app-switcher trigger is a button followed by a menu of menuitemradio choices.
  • The overflow trigger is a labeled button with a decorative chevron, followed by menu items for destinations that do not fit inline. A hidden current destination uses aria-current="page" on its menu row.
  • An account trigger is app-owned. Visible name plus a decorative rotating chevron is the recommended composition; it is not a Navbar primitive. Truncate the visible name only after --pr-navbar-account-name-max-width (12rem default); keep the full name in the accessible name.
  • NavbarGroup is visual grouping only. If an action cluster needs a group name, provide it through the interactive controls or a higher-level labeled pattern.
Focus and responsive behavior
When resizing moves destinations between the inline row and overflow menu, the destination remains reachable. Avoid changing width while a person is interacting with the Navbar unless the viewport or surrounding content genuinely changed. After route navigation, move focus to the new page heading or main content according to the app routing policy; do not leave focus in global chrome indefinitely. When app selection replaces the destination model, update the route to a valid destination in the selected app. Keep focus on the switcher trigger after the menu closes, then let subsequent navigation follow the app focus policy.
Known caveats
  • Multiple landmarks. A Sidebar and Navbar can both be navigation landmarks. Distinct labels are required so screen-reader users can tell them apart.
  • Custom tabs. renderTab replaces TabsTrigger in the visible row only. Keep that output semantically equivalent to a current-aware destination link. Measurement uses renderMeasurementTab or an inert default TabsTrigger and reads every list child, so a non-anchor stand-in still occupies a slot. Do not put interactive side effects in the measurement renderer.
  • Custom overflow rows. Returning plain visual content instead of a menu item removes keyboard and menu semantics. Portaled secondary UI must call onInteractingChange(true) while engaged and false when the interaction ends and during unmount cleanup; every true call must be balanced so the menu cannot remain retained. Wire onSelect to the in-menu destination row only; Navbar dismisses More when onSelect runs.
  • Action-like destinations. Do not use onClickReplacesNavigation to turn primary navigation into an unrelated command. Put actions in NavbarEnd or a menu.
  • Disabled apps. If a disabled app remains visible, explain why it is unavailable through surrounding product guidance rather than relying on disabled styling alone.
Related accessibility pages
  • Tab nav accessibility for route-link behavior.
  • Menu accessibility for app-switcher and overflow keyboard behavior.
  • Sidebar accessibility for coordinating multiple navigation landmarks.
  • Icon button accessibility for trailing actions.
Previous
Navbar / API and Development
Next
Number Field / Usage
On this page
What the component handles
What you must provide
Keyboard behavior
Semantics and roles
Focus and responsive behavior
Known caveats
Related accessibility pages