Primitives

Menu

A menu is a list of options or commands presented to the user in a dropdown list.

Import

Import the Menu primitives from ng-primitives/menu.

import { NgpMenu, NgpMenuItem, NgpMenuTrigger, NgpSubmenuTrigger } from 'ng-primitives/menu';

Usage

Assemble the menu directives in your template.

<button [ngpMenuTrigger]="menu" ngpButton></button>

<ng-template #menu>
  <div ngpMenu>
    <button ngpMenuItem>Item 1</button>
    <button ngpMenuItem>Item 2</button>
    <button ngpMenuItem>Item 3</button>
  </div>
</ng-template>

Reusable Component

Create reusable components that use the NgpMenu directive.

import { Component } from '@angular/core';
import { NgpButton } from 'ng-primitives/button';
import { NgpMenuTrigger } from 'ng-primitives/menu';
import { Menu } from './menu';
import { MenuItem } from './menu-item';

@Component({
  selector: 'app-root',
  imports: [Menu, NgpButton, NgpMenuTrigger, MenuItem],
  template: `
    <button [ngpMenuTrigger]="menu" ngpButton>Open Menu</button>

    <ng-template #menu>
      <app-menu>
        <button app-menu-item>Item 1</button>
        <button app-menu-item>Item 2</button>
        <button app-menu-item>Item 3</button>
      </app-menu>
    </ng-template>
  `,
  styles: `
    [ngpButton] {
      padding-left: 1rem;
      padding-right: 1rem;
      border-radius: 0.5rem;
      color: var(--ngp-text-primary);
      border: none;
      outline: none;
      height: 2.5rem;
      font-weight: 500;
      background-color: var(--ngp-background);
      transition: background-color 300ms cubic-bezier(0.4, 0, 0.2, 1);
      box-shadow: var(--ngp-button-shadow);
    }

    [ngpButton][data-hover] {
      background-color: var(--ngp-background-hover);
    }

    [ngpButton][data-focus-visible] {
      outline: 2px solid var(--ngp-focus-ring);
      outline-offset: 2px;
    }

    [ngpButton][data-press] {
      background-color: var(--ngp-background-active);
    }
  `,
})
export default class App {}

Schematics

Generate a reusable menu component using the Angular CLI.

ng g ng-primitives:primitive menu

Options

  • path: The path at which to create the component file.
  • prefix: The prefix to apply to the generated component selector.
  • componentSuffix: The suffix to apply to the generated component class name.
  • fileSuffix: The suffix to apply to the generated component file name. Defaults to component.
  • exampleStyles: Whether to include example styles in the generated component file. Defaults to true.

Examples

Here are some additional examples of how to use the Menu primitives.

The menu can contain submenus, which are nested menus that can be opened by hovering on a menu item.

API Reference

The following directives are available to import from the ng-primitives/menu package:

NgpMenuTrigger

The `NgpMenuTrigger` directive allows you to turn an element into a menu trigger.

  • Selector: [ngpMenuTrigger]
  • Exported As: ngpMenuTrigger
ngpMenuTrigger
NgpOverlayContent<T> | undefined

Access the menu template ref.

ngpMenuTriggerDisabled
boolean
default: "false"

Define if the trigger should be disabled.

ngpMenuTriggerPlacement
Placement
default: "'bottom-start'"

Define the placement of the menu relative to the trigger.

ngpMenuTriggerOffset
number
default: "0"

Define the offset of the menu relative to the trigger.

ngpMenuTriggerFlip
boolean
default: "true"

Define whether the menu should flip when there is not enough space for the menu.

ngpMenuTriggerContainer
HTMLElement | null
default: "document.body"

Define the container in which the menu should be attached.

ngpMenuTriggerScrollBehavior
"block" | "reposition"
default: "'block'"

Defines how the menu behaves when the window is scrolled.

ngpMenuTriggerContext
T | undefined

Provide context to the menu. This can be used to pass data to the menu content.

Data Attributes

The following data attributes are available on the NgpMenuTrigger directive:

Attribute Description
data-open Applied when the menu is open.

NgpMenu

The `NgpMenu` is a container for menu items.

  • Selector: [ngpMenu]
  • Exported As: ngpMenu

The following CSS custom properties are applied to the ngpMenu directive:

Property Description
--ngp-menu-transform-origin The transform origin of the menu for animations.
--ngp-menu-trigger-width The width of the trigger element.

NgpMenuItem

The `NgpMenuItem` directive represents a menu item.

  • Selector: [ngpMenuItem]
  • Exported As: ngpMenuItem

Data Attributes

The following data attributes are available on the NgpMenuItem directive:

Attribute Description
data-disabled Applied when the item is disabled.

NgpSubmenuTrigger

  • Selector: [ngpSubmenuTrigger]
  • Exported As: ngpSubmenuTrigger
ngpSubmenuTrigger
NgpOverlayContent<T> | undefined

Access the submenu template ref.

ngpSubmenuTriggerDisabled
boolean
default: "false"

Define if the trigger should be disabled.

ngpSubmenuTriggerPlacement
Placement
default: "'right-start'"

Define the placement of the menu relative to the trigger.

ngpSubmenuTriggerOffset
number
default: "0"

Define the offset of the menu relative to the trigger.

ngpSubmenuTriggerFlip
boolean
default: "true"

Define whether the menu should flip when there is not enough space for the menu.

Data Attributes

The following data attributes are available on the NgpSubmenuTrigger directive:

Attribute Description
data-open Applied when the submenu is open.

Styling

For the menu to be positioned correctly relative to the trigger element, it should use fixed positioning. For example, you can use the following CSS:

[ngpMenu] {
  position: fixed;
}

Animations

The ngpMenu primitive adds a CSS custom property --ngp-menu-transform-origin to the element that can be used to animate the menu from the trigger element.

The ngpMenu will also add the data-enter and data-exit attributes to the element when it is being added or removed from the DOM. This can be used to trigger animations.

:host[data-enter] {
  animation: fade-in 0.2s ease-in-out;
}

:host[data-exit] {
  animation: fade-out 0.2s ease-in-out;
}

Global Configuration

You can configure the default options for all menus in your application by using the provideMenuConfig function in a providers array.

import { provideMenuConfig } from 'ng-primitives/menu';

bootstrapApplication(AppComponent, {
  providers: [
    provideMenuConfig({
      offset: 4,
      placement: 'top',
      flip: true,
      container: document.body,
      scrollBehavior: 'reposition',
    }),
  ],
});

NgpMenuConfig

offset
number

Define the offset from the trigger element.

placement
'top' | 'right' | 'bottom' | 'left'

Define the placement of the menu.

flip
boolean

Define if the menu should flip when it reaches the edge of the viewport.

container
HTMLElement

Define the container element for the menu. This is the document body by default.

scrollBehavior
reposition | block

Defines how the menu behaves when the window is scrolled. If set to `reposition`, the menu will adjust its position automatically during scrolling. Make sure the menu uses `position: absolute` in this mode. If set to `block`, scrolling will be disabled while the menu is open. In this case, the menu should use `position: fixed`.

Accessibility

Adhere to the WAI-ARIA Authoring Practices for menus and submenus.

Copyright © 2025 Angular Primitives