Navbar and Navigation Menu
Use navbar and navigation menu with the current published Askr packages.
@askrjs/themes/navigation-menu0.0.13
How to use navbar and navigation menu
Navbar and Navigation Menu should use the standard themed surface unless the application is deliberately implementing its own design system on top of @askrjs/ui.
- Import the themed component from @askrjs/themes/components; use @askrjs/ui directly only when building a custom visual system.
- Keep navbar and navigation menu labels, state, and application actions visible at the call site instead of styling internal DOM nodes.
- Verify keyboard behavior, focus movement or return, disabled state, and both standard themes.
import { NavigationMenu, NavigationMenuItem, NavigationMenuLink, NavigationMenuList } from '@askrjs/themes/components';
<NavigationMenu aria-label="Primary navigation">
<NavigationMenuList>
<NavigationMenuItem><NavigationMenuLink href={projectsRoute}>Projects</NavigationMenuLink></NavigationMenuItem>
<NavigationMenuItem><NavigationMenuLink href={reportsRoute}>Reports</NavigationMenuLink></NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>Purpose
Despite the page title, the only export at `@askrjs/themes/navigation-menu` is `NavigationMenu` and its parts — there's no separate `Navbar` primitive on this subpath. Use these pieces to build a horizontal menu bar with flyout content: a top-level list of items, each optionally opening a panel of links. If you actually want the responsive app-header component (with a collapsing hamburger state), that's `Navbar` from the general themes component barrel, not this one.
Install and import
```tsx import { NavigationMenu, NavigationMenuList, NavigationMenuItem, NavigationMenuTrigger, NavigationMenuContent, NavigationMenuLink, NavigationMenuViewport, NavigationMenuIndicator, } from '@askrjs/themes/navigation-menu'; ``` This subpath is an alias into the shared components barrel, so importing the same names from `@askrjs/themes/components` works identically.
Live examples
Implement live examples at the navbar and navigation menu boundary: make inputs visible at the call site, keep cleanup with the work that created it, and render the success, unavailable, and failure states where a user can act on them.
Anatomy
`NavigationMenu` renders a `<nav>`, `NavigationMenuList` an `<ul>`, and `NavigationMenuItem` an `<li>` — a plain nested list under the hood. `NavigationMenuTrigger` is a real `<button type="button">` (with the `nav-item` class baked in), while `NavigationMenuContent`, `NavigationMenuLink`, `NavigationMenuViewport`, and `NavigationMenuIndicator` are generic slotted elements (a div, an anchor, a div, and a div respectively) that only exist to give you stable markup and `data-slot` hooks for the flyout panel, its links, the clipping viewport, and an active-tab indicator strip.
State model
None of these components track open/closed state, active item, or hover intent — there's no internal store or context here at all. You decide which trigger's content is visible, typically with a bit of local state or by composing `NavigationMenuTrigger`/`NavigationMenuContent` with the interaction primitives from `@askrjs/ui` (the same way the themed `Navbar` wires its own collapse menu with `Dropdown`/`DropdownTrigger`). Treat this package as markup, not behavior.
Keyboard and accessibility
Because `NavigationMenu` is a `<nav>` and `NavigationMenuTrigger` is a genuine `<button>`, you get landmark navigation and native Tab/Enter/Space activation for free. What you don't get automatically is `aria-expanded`, `aria-controls`, or Escape-to-close on the trigger/content pair, or arrow-key movement across items — those are your responsibility to wire up if you're building a real dropdown-style flyout rather than a flat link list.
Styling and tokens
Every part carries a `data-slot` attribute — `navigation-menu`, `navigation-menu-list`, `navigation-menu-item`, `navigation-menu-trigger`, `navigation-menu-content`, `navigation-menu-link`, `navigation-menu-viewport`, `navigation-menu-indicator` — and the trigger additionally gets the `nav-item` class. Style off those hooks instead of assuming a fixed DOM shape, since `as`/`asChild` let consumers swap the underlying element.
API
All parts accept the shared `CatalogComponentProps` shape: `as` to render a different tag, `asChild` to hand rendering off to a `Slot` (useful for wrapping your router's `Link`), plus `class`, `children`, `ref`, and arbitrary passthrough attributes. `NavigationMenuTrigger` also accepts a `type` override, though it defaults to `"button"` so it never accidentally submits a form.
Edge cases
Multi-level or mega-menu content is entirely on you to lay out inside `NavigationMenuContent` — there's no built-in positioning or collision handling in `NavigationMenuViewport`, it's just a slotted div. Since there's no shipped open state, SSR is trivially safe (everything renders closed/static by default), but that also means client hydration has to attach whatever interaction logic you add. If you need real click-outside dismissal or focus trapping for a flyout, reach for `@askrjs/ui`'s dropdown primitives rather than assuming this package provides it.
Related pages
See Sidebar and Menubar for the other two navigation-chrome building blocks, Application Chrome for how these fit into a full page shell, and Breadcrumb and Pagination for the smaller wayfinding controls that often sit alongside a nav bar.