Yugen UI

NavigationMenu

NavigationMenu is a website header menu: links and triggers that open dropdown panels (mega menus).

Built on Radix Navigation Menu, following the WAI-ARIA disclosure navigation pattern: a labelled <nav>, triggers with aria-expanded, and aria-current="page" on the current page link (the active prop). Hovering opens a panel after a short delay so it doesn't open by accident, and moving to another trigger skips the delay; activationMode="manual" opens on click only. Keyboard: Tab moves through the items, Enter / Space opens, left / right arrows move between items, Tab enters the panel, Esc closes it and returns focus to the trigger. Panels sit in one floating viewport that resizes to the content (Motion tokens, off with reduced motion); RTL follows YugenProvider. Links in a panel take icon and description; asChild uses your router's Link. On narrow screens, put the same links in a Drawer, like the AppShell sidebar.
Sakura Studio

Import

Install from npm, copy the source into your project with @yugen-ui/cli or the shadcn CLI, or import directly when working in this repo.

TSX
// npm install yugen-uiimport {  NavigationMenu,  NavigationMenuList,  NavigationMenuItem,  NavigationMenuTrigger,  NavigationMenuContent,  NavigationMenuLink,  NavigationMenuIndicator,} from "yugen-ui";

Variants

Each tile is a standalone example: hover to copy, or press Code to see the source.

Sakura Studio

Narrow screens: Drawer

A container query hides the menu in a narrow header; a button opens a Drawer with the same links in a Nav.

Current page: /blog

Router links (asChild) & current page

active sets aria-current="page" and a brand bar under the link.

Open on click only

activationMode="manual": hover and focus don't open panels — suited to touch screens and busy headers.

Usage

Do
  • Keep 3–7 top-level items; group subpages in panels with a title and a short description.
  • Mark the current page with active so it gets aria-current="page".
  • On narrow screens, move the links into a Drawer instead of shrinking the menu.
Don't
  • Don't use NavigationMenu for commands (Save, Delete…). Use Menu or Menubar.
  • Don't make a trigger a link: pressing it only opens the panel; put the overview page as a link inside the panel.
  • Don't use it for in-app navigation with a sidebar. Use Nav / AppShell.

Props

Prop · TypeDefaultDescription
value / defaultValue / onValueChangestring / (value: string) => voidDefault: —Open item (controlled / uncontrolled); "" when closed.
activationMode"automatic" | "manual"Default: "automatic"automatic: hover / focus opens panels; manual: only a click does.
delayDuration / skipDelayDurationnumberDefault: 200 / 300Delay (ms) before hover opens a panel; time during which moving to another trigger skips the delay.
orientation"horizontal" | "vertical"Default: "horizontal"Direction of the list and of the arrow keys.
aria-labelstringDefault: "Main"Label of the <nav> element.
viewportClassNamestringDefault: —Class for the floating viewport that holds the open panel.
NavigationMenuItem.valuestringDefault: —Item key (generated by default).
NavigationMenuLink.activebooleanDefault: —Current page: aria-current="page" and the selected style.
NavigationMenuLink.icon / descriptionReactNodeDefault: —Icon and one-line description (links inside NavigationMenuContent).
NavigationMenuLink.asChildbooleanDefault: —Uses the child element (your router's Link) as the link.
NavigationMenuIndicatorcomponentDefault: —Small arrow under the open trigger (place it inside NavigationMenuList).
navigationMenuTriggerClassstringDefault: —Class of the top-level trigger / link, for elements you build yourself.
refRef<HTMLElement>Default: —Points to the <nav> element.

Messages

Text built into the component: labels, aria-labels, screen reader announcements.

English by default. Change it with the messages prop of YugenProvider, by the namespace below; messagesVi has the Vietnamese set. See Interface language.

messages.navigationMenu

Key · TypeDefault (English)messagesVi
labelstring

aria-label của thẻ <nav> (khi không truyền aria-label).

Default (English)"Main"messagesVi"Điều hướng chính"