Skip to content
EspañolEnglish
All components (204)

Navigation menu

Navigation · NavigationMenu · .amset-navmenu

What it is and when to use it

A site's main navigation: direct links and buttons that unfold a panel with more links ("Productos", "El taller"), with a description if needed.

When to use it

  • In the header of a site or shop with sections that have several pages inside.
  • When it helps to explain where each link leads with a sentence.

When not to

  • For actions that do not change page: that is a Menubar or an ActionMenu.
  • For an application's side navigation: that is SideNav.
  • With few sections with nothing inside: plain links are enough.

Keyboard: it is ARIA's disclosure navigation, not a menu: they are real links inside a <nav>. Each panel comes right after its button, so Tab enters it and follows the order of the screen; the down arrow on an open button enters its panel. Escape closes returning focus, and leaving with Tab or pressing outside closes it.

Accessibility: the buttons carry aria-expanded and aria-controls, the current page carries aria-current="page" and a switched-off button cannot be reached with the keyboard. With the mouse it opens on hover (with a pause) and pressing the button pins it, which is what works on a touch screen.

Router: with onNavigate (or the one from RouterProvider) internal links navigate without reloading; Ctrl-click, middle-click and links to another site open as usual.

Fine-tuning: CSS variable --amset-navmenu-panel-width (width of the panel; never wider than the screen).

What it looks like

Hover over “Products” or reach it with the Tab key.

<NavigationMenu
  label="Main"
  items={[
    { key: "inicio", label: "Home", href: "/", current: true },
    { key: "productos", label: "Products", links: [{ key: "anillos", label: "Rings", href: "/anillos" }] },
  ]}
  onNavigate={(href) => router.push(href)}
/>

Props

Import it with import { NavigationMenu } from '@amset/ui'. Required props are marked.

PropTypeWhat it does
itemsrequiredreadonly NavigationMenuItem[]—
labelrequiredstringWhich navigation it is, for the screen reader: "Main".
classNamestringMerged with the library classes; it does not replace them.
closeDelaynumberMilliseconds of grace on leaving: it is what lets you cross from the button to the panel.
offsetnumber—
onNavigate(href: string) => voidIf passed, internal links call this instead of reloading the page.
openDelaynumberMilliseconds with the mouse over it before opening. With another panel already open, the switch is immediate.

It also accepts the attributes of the element it renders: className, style, data-*, aria-* and its events.

CSS variables

These CSS variables are how you adapt it. Declare them on the component's selector, not on :root: the stylesheet redeclares them in the rule itself, and a declaration on the same element always wins.

VariableDefault
--amset-navmenu-panel-widthmin(36rem, calc(100vw - 2rem))

How to change it

.amset-navmenu {
  --amset-navmenu-panel-width: ...;
}

In the test bench

Every state and variant, to try one at a time, on its page at ui.amset.tech: