On this page Nav Menu Nav Menu

The m3e-nav-menu component is a hierarchical menu optimized for sidebars and drawers on larger devices. It enables users to explore nested menu structures and seamlessly switch between application views.

Installation
npm i @m3e/nav-menu
Usage

This section outlines usage examples and configuration guidance for the components in this package.

Multilevel menus

Use the m3e-nav-menu and m3e-nav-menu-item to create a multilevel navigation menu.

Use the label slot of a m3e-nav-menu-item to specify an item's label. In addition, use the icon slot to include an icon before the item's label and use the badge slot to specify to specify a compact status indicator or supplementary text.

To create multiple levels, nest one or more m3e-nav-menu-item components.

Getting Started Overview Installation Actions Button Icon Icon Button
<m3e-nav-menu>
  <m3e-nav-menu-item open>
    <m3e-icon slot="icon" name="rocket_launch" aria-hidden="true"></m3e-icon>
    <span slot="label">Getting Started</span>
    <m3e-nav-menu-item>
      <m3e-icon slot="icon" name="widgets" aria-hidden="true"></m3e-icon>
      <span slot="label">Overview</span>
    </m3e-nav-menu-item>
    <!-- Additional items omitted for brevity -->;
  </m3e-nav-menu-item>
  <m3e-nav-menu-item>
    <span slot="label">Actions</span>
    <!-- Items omitted for brevity -->;
  </m3e-nav-menu-item>
</m3e-nav-menu>
Grouping top-level items

You can use a m3e-nav-menu-item-group to group top-level items in a menu. Use the label slot to specify a group's label. Use a m3e-divider to separate groups in a menu. See Divider for more information.

Mail Inbox 24 Outbox Favorites Trash Personal folders Family Wedding
<m3e-nav-menu>
  <m3e-nav-menu-item-group>
    <m3e-heading slot="label" variant="label" size="large">Mail</m3e-heading>
    <m3e-nav-menu-item>
      <m3e-icon slot="icon" name="mail"></m3e-icon>
      <span slot="label">Inbox</span>
      <span slot="badge">24</span>
    </m3e-nav-menu-item>
    <!-- Additional items omitted for brevity -->
  </m3e-nav-menu-item-group>
  <m3e-divider></m3e-divider>
  <m3e-nav-menu-item-group>
    <m3e-heading slot="label" variant="label" size="large">Personal folders</m3e-heading>
    <!-- Items omitted for brevity -->;
  </m3e-nav-menu-item-group>
</m3e-nav-menu>
Disabling

Use the disabled attribute of a m3e-nav-menu-item to disable the item and any children. Disabling an item with children will not automatically close it.

Getting Started Overview Installation Actions Button Icon Icon Button
<m3e-nav-menu>
  <m3e-nav-menu-item open disabled>
    <m3e-icon slot="icon" name="rocket_launch" aria-hidden="true"></m3e-icon>
    <span slot="label">Getting Started</span>
    <m3e-nav-menu-item>
      <m3e-icon slot="icon" name="widgets" aria-hidden="true"></m3e-icon>
      <span slot="label">Overview</span>
    </m3e-nav-menu-item>
    <!-- Additional items omitted for brevity -->;
  </m3e-nav-menu-item>
  <m3e-nav-menu-item open>
    <span slot="label">Actions</span>
    <m3e-nav-menu-item disabled><span slot="label">Button</span></m3e-nav-menu-item>
    <!-- Additional items omitted for brevity -->;
  </m3e-nav-menu-item>
</m3e-nav-menu>
Accessibility

Nav menus are given ARIA role="tree", and items are assigned role="treeitem", indicating a structured, hierarchical navigation model that supports keyboard interaction, semantic grouping, and accessible labeling. Expandable items use aria-expanded to indicate visibility of nested content, and current items may use aria-current to signal the active page or view.

Focus is managed on the m3e-nav-menu container using tabindex="0", and the currently active item is referenced via aria-activedescendant, which points to the ID of the focused m3e-nav-menu-item. This enables roving focus without shifting DOM focus, ensuring accessible keyboard navigation and consistent screen reader feedback.

Groups are given ARIA role="group", indicating that their contents form a semantic unit within the navigation tree and are labeled by the content of the group's label slot.

Icons and dividers are given aria-hidden="true" ensure they're treated as purely decorative and excluded from the accessibility tree.

Disabling an item sets aria-disabled="true" signaling to assistive technologies that the item is not interactive.

Native module support

This package uses JavaScript Modules. To use it directly in a browser without a bundler, use a module script similar to the following.

<script type="module" src="/node_modules/@m3e/nav-menu/dist/index.js"></script>

In addition, you must use an import map to include dependencies.

<script type="importmap">
  {
    "imports": {
      "lit": "https://cdn.jsdelivr.net/npm/lit@3.3.0/+esm",
      "@m3e/core": "/node_modules/@m3e/core/dist/index.js",
      "@m3e/core/a11y": "/node_modules/@m3e/core/dist/a11y.js"
    }
  }
</script>

For production, use index.min.js and a11y.min.js for faster load times.

API

This package includes a Custom Elements Manifest (custom-elements.json), which documents the properties, attributes, slots, events and CSS custom properties of each component.

You can explore the API below, or integrate the manifest into your own tooling.