elements
Demos UI Feed Discuss Install
Style System
  • Style
  • Themes
  • Behaviors
Forms
  • Button
  • ButtonGroup
  • Checkbox
  • ColorPicker
  • Combobox
  • Field
  • FileUpload
  • Input
  • InputGroup
  • InputOTP
  • Label
  • NativeSelect
  • NumberInput
  • PasswordInput
  • RadioGroup
  • Select
  • Slider
  • Switch
  • TagsInput
  • Textarea
  • Toggle
  • ToggleGroup
Overlays
  • AlertDialog
  • Command
  • ContextMenu
  • Dialog
  • Drawer
  • DropdownMenu
  • HoverCard
  • Menubar
  • NavigationMenu
  • Popover
  • Sheet
  • Toast
  • Tooltip
Display
  • Accordion
  • Alert
  • AspectRatio
  • Avatar
  • Badge
  • Breadcrumb
  • Card
  • Collapsible
  • Empty
  • Item
  • Kbd
  • Pagination
  • Progress
  • Separator
  • Skeleton
  • Spinner
  • Table
  • Tabs
  • Tree
Layout
  • Carousel
  • Resizable
  • ScrollArea
  • Sidebar
Dates
  • Calendar
  • DatePicker
  • DateRangePicker
  • TimePicker
Data
  • AreaChart
  • BarChart
  • Chart
  • DataTable
  • Kanban
  • LineChart
  • PieChart
  • RadarChart
  • RadialChart
  • VirtualList
Chat
  • Attachment
  • Message
  • MessageList
  • PromptInput
Elements UI / Overlays / NavigationMenu

NavigationMenu

Site navigation with large animated dropdown panels.

Site navigation

Hover a trigger, or click it. Moving across the triggers swaps the panel in the shared viewport, which animates to the new size; the indicator follows.

  • Docs
Code
<NavigationMenu indicator>
  <NavigationMenuItem label="Home">
    <ul class="grid is-home">
      <li class="featured">
        <NavigationMenuLink href="/">Elements UI ...</NavigationMenuLink>
      </li>
      <li><NavigationMenuLink href="/docs">Introduction ...</NavigationMenuLink></li>
      ...
    </ul>
  </NavigationMenuItem>
  <NavigationMenuItem label="Components">
    <ul class="grid is-two">
      <li e:for={c of components}>
        <NavigationMenuLink href={c.href}>
          <div class="title">{c.title}</div>
          <p class="desc">{c.description}</p>
        </NavigationMenuLink>
      </li>
    </ul>
  </NavigationMenuItem>
  <NavigationMenuItem>
    <NavigationMenuLink href="/docs" trigger>Docs</NavigationMenuLink>
  </NavigationMenuItem>
  <NavigationMenuItem label="With Icon">...</NavigationMenuItem>
</NavigationMenu>

Usage

import { NavigationMenu, NavigationMenuItem, NavigationMenuLink, navigationMenuTriggerClass } from "@elements/ui/navigation-menu";

<NavigationMenu indicator>
  <NavigationMenuItem label="Getting started">
    <ul class="nav-grid">
      <li><NavigationMenuLink href="/docs">Introduction</NavigationMenuLink></li>
      <li><NavigationMenuLink href="/docs/install">Installation</NavigationMenuLink></li>
    </ul>
  </NavigationMenuItem>
  <NavigationMenuItem label="Components">...</NavigationMenuItem>
  <NavigationMenuItem>
    <NavigationMenuLink href="/docs" trigger>Docs</NavigationMenuLink>
  </NavigationMenuItem>
</NavigationMenu>

Examples

Without the viewport

viewport={false} opens each panel under its own trigger, with its own box. The current page's link is active. This menu keeps Escape (onEscapeKeyDown prevented) and logs presses and focus outside.

outside: none
Code
<NavigationMenu viewport={false}
                onEscapeKeyDown={(e) => e.preventDefault()}
                onPointerDownOutside={(e) => log("pointer")}
                onFocusOutside={(e) => log("focus")}
                onInteractOutside={(e) => log("interact")}>
  <NavigationMenuItem label="List">...</NavigationMenuItem>
  <NavigationMenuItem label="Simple">...</NavigationMenuItem>
</NavigationMenu>

Vertical

orientation=vertical stacks the list; panels open beside it and Up and Down move between triggers.

  • Pricing
Code
<NavigationMenu orientation="vertical" indicator>
  <NavigationMenuItem label="Products">...</NavigationMenuItem>
  <NavigationMenuItem label="Resources">...</NavigationMenuItem>
</NavigationMenu>

Controlled, delay and disabled

value is two-way; delay={0} opens on hover at once. A disabled trigger never opens. onSelect with preventDefault() keeps the panel open. onOpenChangeComplete fires once a panel has finished opening and once the menu has finished closing.

value: none · no changes · complete: none · selected: none
Code
<NavigationMenu value={state.nav}
                delay={0}
                onValueChange={(v) => log(v)}
                onOpenChangeComplete={(open) => log(open ? "open complete" : "closed complete")}>
  <NavigationMenuItem value="learn" label="Learn">...</NavigationMenuItem>
  <NavigationMenuItem value="overview" label="Overview">...</NavigationMenuItem>
  <NavigationMenuItem value="soon" label="Soon" disabled>...</NavigationMenuItem>
</NavigationMenu>
<Button onclick={() => state.nav = "overview"}>Open Overview</Button>

Offset and arrow

alignOffset moves the viewport along the list from its aligned spot. arrow draws an arrow on the viewport's edge that points at the open trigger and follows it from panel to panel; arrowPadding keeps it off the viewport's corners.

Code
<NavigationMenu align="start" alignOffset={16}>
  <NavigationMenuItem label="Shifted">...</NavigationMenuItem>
</NavigationMenu>

<NavigationMenu arrow>
  <NavigationMenuItem label="Guides">...</NavigationMenuItem>
  <NavigationMenuItem label="Reference">...</NavigationMenuItem>
</NavigationMenu>

<!-- the arrow keeps arrowPadding px from the viewport's corners -->
<NavigationMenu arrow arrowPadding={24} align="start" alignOffset={30}>...</NavigationMenu>

Keep open on click

closeOnClick={false} on a link follows it and leaves the panel open, for links that jump within the page. Links close the menu by default.

    • Jump, keep open
    • Jump and close
Code
<NavigationMenu>
  <NavigationMenuItem label="Sections">
    <ul>
      <!-- follows the link and leaves the panel open -->
      <li><NavigationMenuLink href="#close-off" closeOnClick={false}>Jump, keep open</NavigationMenuLink></li>
      <li><NavigationMenuLink href="#close-on">Jump and close</NavigationMenuLink></li>
    </ul>
  </NavigationMenuItem>
</NavigationMenu>

Backdrop and positioning

backdrop dims the page under an open panel and leaves the list above it; a press on it closes the menu. positionMethod="absolute" places the viewport in page coordinates and disableAnchorTracking places it once when it opens. collisionBoundary names a box whose edges count like the screen's. When the list scrolls out of view the viewport hides (data-anchor-hidden), unless sticky="always" keeps it in view. anchor places the viewport against another element, such as a whole header. collisionPadding keeps the viewport that far from the screen's edges, and collisionAvoidance with side "flip" opens it above the list when there is no room below.

Code
<!-- dims the page under the open panel; the list stays above it -->
<NavigationMenu backdrop>...</NavigationMenu>

<!-- placed once, in page coordinates -->
<NavigationMenu positionMethod="absolute" disableAnchorTracking>...</NavigationMenu>

<!-- the panel stays inside .box, and in view when the list scrolls away -->
<NavigationMenu collisionBoundary=".box" sticky="always">...</NavigationMenu>

<!-- opens under the whole header instead of the list -->
<header id="site-header">
  <NavigationMenu anchor="#site-header">...</NavigationMenu>
</header>

<!-- 24px from the screen edges; flips above the list when there is no room below -->
<NavigationMenu collisionPadding={24} collisionAvoidance={{ side: "flip" }}>...</NavigationMenu>

Submenus

A NavigationMenu with sub inside a panel keeps one item open, like tabs; hover or click switches it.

Code
<NavigationMenuItem label="Products">
  <NavigationMenu sub>
    <NavigationMenuItem value="ui" label="UI">...links...</NavigationMenuItem>
    <NavigationMenuItem value="data" label="Data">...links...</NavigationMenuItem>
  </NavigationMenu>
</NavigationMenuItem>

Nested flyouts, keepMounted

A vertical NavigationMenu with viewport={false} inside a panel opens its own panels as flyouts beside the panel. Escape closes the flyout first; a link closes them all. keepMounted renders the Docs panel with the page, so its links are in the document for crawlers while it is closed.

    • Quick start
    • Installation
  • Blog
Code
<NavigationMenu label="Docs">
  <NavigationMenuItem label="Docs" keepMounted>
    <ul>
      <li><NavigationMenuLink href="/quick-start">Quick start</NavigationMenuLink></li>
    </ul>
    <NavigationMenu orientation="vertical" viewport={false} label="Handbook">
      <NavigationMenuItem label="Guides">
        <ul>
          <li><NavigationMenuLink href="/styling">Styling</NavigationMenuLink></li>
          <li><NavigationMenuLink href="/animation">Animation</NavigationMenuLink></li>
        </ul>
      </NavigationMenuItem>
      <NavigationMenuItem label="Reference">...</NavigationMenuItem>
    </NavigationMenu>
  </NavigationMenuItem>
</NavigationMenu>

Right to left

Under dir=rtl the list runs right to left and ArrowLeft moves to the next trigger.

Code
<NavigationMenu dir="rtl" indicator>
  <NavigationMenuItem label="البدء">...</NavigationMenuItem>
  <NavigationMenuItem label="المكونات">...</NavigationMenuItem>
</NavigationMenu>
Reference NavigationMenu in the manual Every part, attribute, slot, key and data attribute.
Prev MenubarNext Popover
Product
Manual Pricing Compare
Company
History Contact
Legal
Privacy Policy Acceptable Use Terms License Agreement
© Elements Dev Corporation 2026