Menu

The Menu component presents a structured list of actions, settings, or navigation targets within a transient surface. It supports icons, keyboard shortcuts, hint text, section titles, dividers, and submenu indicators.

import {MenuModule} from "@qualcomm-ui/angular/menu"

Examples

Item Customization

Compose the menu to include icons and commands.

import {Component} from "@angular/core"
import {Command, File, FileText, FolderOpen, ImageDown} from "lucide-angular"

import {provideIcons} from "@qualcomm-ui/angular-core/lucide"
import {PortalDirective} from "@qualcomm-ui/angular-core/portal"
import {ButtonModule} from "@qualcomm-ui/angular/button"
import {IconDirective} from "@qualcomm-ui/angular/icon"
import {MenuModule} from "@qualcomm-ui/angular/menu"

@Component({
  imports: [MenuModule, ButtonModule, PortalDirective, IconDirective],
  providers: [provideIcons({Command, File, FileText, FolderOpen, ImageDown})],
  selector: "menu-item-customization-demo",
  template: `
    <q-menu>
      <button emphasis="primary" q-menu-button variant="fill">Show Menu</button>
      <ng-container *qPortal>
        <div q-menu-positioner>
          <div q-menu-content>
            <button q-menu-item value="new-text-file">
              <div icon="FileText" q-menu-item-start-icon></div>
              New Text File
              <div q-menu-item-command>
                <svg qIcon="Command" size="xs"></svg>
                E
              </div>
            </button>
            <button q-menu-item value="new-file">
              <div icon="File" q-menu-item-start-icon></div>
              New File...
              <div q-menu-item-command>
                <svg qIcon="Command" size="xs"></svg>
                N
              </div>
            </button>
            <button q-menu-item value="open-file">
              <div icon="FolderOpen" q-menu-item-start-icon></div>
              Open File...
              <div q-menu-item-command>
                <svg qIcon="Command" size="xs"></svg>
                O
              </div>
            </button>
            <button q-menu-item value="export">
              <div icon="ImageDown" q-menu-item-start-icon></div>
              Export
              <div q-menu-item-command>
                <svg qIcon="Command" size="xs"></svg>
                S
              </div>
            </button>
          </div>
        </div>
      </ng-container>
    </q-menu>
  `,
})
export class MenuItemCustomizationDemo {}

Use q-menu-button for a labeled trigger and q-menu-icon-button for an icon-only trigger. Both automatically render a chevron indicator. Always provide an aria-label on q-menu-icon-button to give assistive technologies an accessible name. Control the menu position with positioning.placement.

import {Component} from "@angular/core"
import {
  Copy,
  Ellipsis,
  File,
  FileText,
  FolderOpen,
  Pencil,
  Trash2,
} from "lucide-angular"

import {provideIcons} from "@qualcomm-ui/angular-core/lucide"
import {PortalComponent} from "@qualcomm-ui/angular-core/portal"
import {MenuModule} from "@qualcomm-ui/angular/menu"

@Component({
  imports: [MenuModule, PortalComponent],
  providers: [
    provideIcons({Copy, Ellipsis, File, FileText, FolderOpen, Pencil, Trash2}),
  ],
  selector: "menu-button-demo",
  template: `
    <div class="flex gap-2.5">
      <q-menu [positioning]="{placement: 'bottom-end'}">
        <button emphasis="primary" q-menu-button startIcon="File">File</button>
        <q-portal>
          <div q-menu-positioner>
            <div q-menu-content>
              <button q-menu-item value="new-text-file">
                <div icon="FileText" q-menu-item-start-icon></div>
                New Text File
              </button>
              <button q-menu-item value="new-file">
                <div icon="File" q-menu-item-start-icon></div>
                New File...
              </button>
              <button q-menu-item value="open-file">
                <div icon="FolderOpen" q-menu-item-start-icon></div>
                Open File...
              </button>
            </div>
          </div>
        </q-portal>
      </q-menu>

      <q-menu size="sm">
        <button
          aria-label="More actions"
          emphasis="primary"
          icon="Ellipsis"
          q-menu-icon-button
        ></button>
        <q-portal>
          <div q-menu-positioner>
            <div q-menu-content>
              <button q-menu-item value="rename">
                <div icon="Pencil" q-menu-item-start-icon></div>
                Rename
              </button>
              <button q-menu-item value="duplicate">
                <div icon="Copy" q-menu-item-start-icon></div>
                Duplicate
              </button>
              <button q-menu-item value="delete">
                <div icon="Trash2" q-menu-item-start-icon></div>
                Delete
              </button>
            </div>
          </div>
        </q-portal>
      </q-menu>
    </div>
  `,
})
export class MenuButtonDemo {}

Split Button

Use q-menu-split-button for a split button trigger. The icon-only trigger provides a default "More options" aria-label; project a q-menu-icon-button with your own to override it. Optionally add an aria-label on the group when both halves share an accessible name. Control the menu position with positioning.placement on the parent <q-menu>.

import {Component} from "@angular/core"
import {Download, FileArchive, FileJson, FileText} from "lucide-angular"

import {provideIcons} from "@qualcomm-ui/angular-core/lucide"
import {PortalDirective} from "@qualcomm-ui/angular-core/portal"
import {MenuModule} from "@qualcomm-ui/angular/menu"

@Component({
  imports: [MenuModule, PortalDirective],
  providers: [provideIcons({Download, FileArchive, FileJson, FileText})],
  selector: "menu-split-button-demo",
  template: `
    <q-menu [positioning]="{placement: 'bottom-end'}">
      <div
        aria-label="Download"
        emphasis="primary"
        q-menu-split-button
        startIcon="Download"
        (actionClicked)="onDownload()"
      >
        Download
      </div>
      <ng-container *qPortal>
        <div q-menu-positioner>
          <div q-menu-content>
            <button q-menu-item value="pdf">
              <div icon="FileText" q-menu-item-start-icon></div>
              Download as PDF
            </button>
            <button q-menu-item value="json">
              <div icon="FileJson" q-menu-item-start-icon></div>
              Download as JSON
            </button>
            <button q-menu-item value="zip">
              <div icon="FileArchive" q-menu-item-start-icon></div>
              Download as ZIP
            </button>
          </div>
        </div>
      </ng-container>
    </q-menu>
  `,
})
export class MenuSplitButtonDemo {
  onDownload() {
    console.log("Download")
  }
}

Custom Action Button

To set HTML attributes on the action button (type, form, name, etc.), project a <button q-button>. Listen on its (click) directly as (actionClicked) will be ignored in that case. Group props (density, emphasis, size, variant) still cascade to the projected button via context.

import {Component} from "@angular/core"
import {Copy, FilePlus, Save} from "lucide-angular"

import {provideIcons} from "@qualcomm-ui/angular-core/lucide"
import {PortalDirective} from "@qualcomm-ui/angular-core/portal"
import {ButtonModule} from "@qualcomm-ui/angular/button"
import {MenuModule} from "@qualcomm-ui/angular/menu"

@Component({
  imports: [ButtonModule, MenuModule, PortalDirective],
  providers: [provideIcons({Copy, FilePlus, Save})],
  selector: "menu-split-button-projection-demo",
  template: `
    <q-menu [positioning]="{placement: 'bottom-end'}">
      <div emphasis="primary" q-menu-split-button size="sm">
        <button
          form="settings-form"
          name="save"
          q-button
          startIcon="Save"
          type="submit"
          (click)="onSave($event)"
        >
          Save
        </button>
      </div>
      <ng-container *qPortal>
        <div q-menu-positioner>
          <div q-menu-content>
            <button q-menu-item value="save-as">
              <div icon="FilePlus" q-menu-item-start-icon></div>
              Save As…
            </button>
            <button q-menu-item value="save-copy">
              <div icon="Copy" q-menu-item-start-icon></div>
              Save a Copy
            </button>
          </div>
        </div>
      </ng-container>
    </q-menu>
  `,
})
export class MenuSplitButtonProjectionDemo {
  onSave(event: MouseEvent) {
    console.log("Save", event)
  }
}

Context Menu

Demonstrates how to trigger a menu on right-click or other context events.

import {Component} from "@angular/core"

import {PortalDirective} from "@qualcomm-ui/angular-core/portal"
import {MenuModule} from "@qualcomm-ui/angular/menu"

@Component({
  imports: [MenuModule, PortalDirective],
  selector: "menu-context-menu-demo",
  template: `
    <q-menu class="w-full">
      <button
        class="flex h-48 w-full flex-1 items-center justify-center border border-dashed"
        q-menu-context-trigger
      >
        Right click here
      </button>
      <ng-container *qPortal>
        <div q-menu-positioner>
          <div q-menu-content>
            <button q-menu-item value="new-text-file">New Text File</button>
            <button q-menu-item value="new-file">New File...</button>
            <button q-menu-item value="open-file">Open File...</button>
            <button q-menu-item value="export">Export</button>
          </div>
        </div>
      </ng-container>
    </q-menu>
  `,
})
export class MenuContextMenuDemo {}

Nested Menus

Compose nested menus by nesting <Menu.Root> components inside each other.

<q-menu>
  <button emphasis="primary" q-menu-button variant="fill">Show Menu</button>
  <ng-container *qPortal>
    <div q-menu-positioner>
      <div q-menu-content>
        <button q-menu-item value="new-text-file">New Text File</button>
        <button q-menu-item value="new-file">New File...</button>
        <q-menu>
          <button q-menu-trigger-item value="open-recent">
            Open Recents
          </button>

          <ng-container *qPortal>
            <div q-menu-positioner>
              <div q-menu-content>
                <button q-menu-item value="file-1">File 1</button>
                <button q-menu-item value="file-2">File 2</button>
                <button q-menu-item value="file-3">File 3</button>
              </div>
            </div>
          </ng-container>
        </q-menu>
      </div>
    </div>
  </ng-container>
</q-menu>

Menu items can be links.

<div q-menu-content>
  <a
    href="https://angular.dev"
    q-menu-item
    target="_blank"
    value="angular-dev"
  >
    <div icon="ExternalLink" q-menu-item-start-icon></div>
    angular.dev
  </a>
  <a
    fragment="links"
    q-menu-item
    routerLink="/components/menu"
    value="menu-links-demo"
  >
    Menu Links Demo
  </a>
</div>

Groups

Use the q-menu-item-group component to group menu items.

Item Types

There are three item types, each corresponding to one of the three types of aria menu item roles:

  • q-menu-itemmenuitem
  • q-menu-radio-itemmenuitemradio
  • q-menu-checkbox-itemmenuitemcheckbox

Checkbox Items

There are two appearance options:

<div q-menu-item-group>
  <label q-menu-item-group-label>Choose an option</label>
  <button q-menu-checkbox-item value="item-1-1">
    <div q-menu-checkbox-item-control></div>
    <div q-menu-item-label>Option 1</div>
  </button>
  <button q-menu-checkbox-item value="item-1-2">
    <div q-menu-checkbox-item-control></div>
    <div q-menu-item-label>Option 2</div>
  </button>
</div>

<div q-menu-item-group>
  <label q-menu-item-group-label>Choose an option</label>
  <button q-menu-checkbox-item value="item-2-1">
    <div q-menu-item-label>Option 1</div>
    <div q-menu-item-indicator></div>
  </button>
  <button q-menu-checkbox-item value="item-2-2">
    <div q-menu-item-label>Option 2</div>
    <div q-menu-item-indicator></div>
  </button>
</div>

Checkbox Selection State

Illustrates how to manage and reflect the checked state of checkbox menu items. The useCheckboxGroup helper from @qualcomm-ui/angular-core/checkbox manages a group of values; wire each item's checked and (checkedChanged) bindings to it.

<div q-menu-item-group>
  <label q-menu-item-group-label>Choose an option</label>
  @for (item of items; track item.value) {
    <button
      q-menu-checkbox-item
      [checked]="checkboxGroup.isChecked(item.value)"
      [value]="item.value"
      (checkedChanged)="checkboxGroup.toggleValue(item.value)"
    >
      {{ item.label }}
      <div q-menu-item-indicator></div>
    </button>
  }
</div>

Radio Group

Demonstrates how to group radio menu items so only one can be selected at a time.

<div q-menu-radio-item-group>
  <label q-menu-item-group-label>Choose an option</label>
  <button q-menu-radio-item value="one">
    <div q-menu-radio-item-control></div>
    <div q-menu-item-label>Option 1</div>
  </button>
  <button q-menu-radio-item value="two">
    <div q-menu-radio-item-control></div>
    <div q-menu-item-label>Option 2</div>
  </button>
  <button q-menu-radio-item value="three">
    <div q-menu-radio-item-control></div>
    <div q-menu-item-label>Option 3</div>
  </button>
</div>

Radio Group State

Radio item state can be controlled via the value input on the parent q-menu-radio-item-group element.

<div q-menu-radio-item-group>
  <label q-menu-item-group-label>Choose an option</label>
  <div q-menu-radio-item-group [(value)]="value">
    <button q-menu-radio-item value="option-1">
      Option 1
      <div q-menu-item-indicator></div>
    </button>
    <button q-menu-radio-item value="option-2">
      Option 2
      <div q-menu-item-indicator></div>
    </button>
    <button q-menu-radio-item value="option-3">
      Option 3
      <div q-menu-item-indicator></div>
    </button>
  </div>
</div>

Controlled State

The menu's visibility can be controlled via the open, openChanged, and defaultOpen properties.

  • Use open to explicitly set whether the menu is open (controlled mode).
  • Use openChanged to be notified when the menu requests to open or close.
  • Use defaultOpen to set the initial open state when you don't need to control it yourself (uncontrolled mode).

In controlled mode, the open prop should be updated in response to openChanged events to reflect the desired visibility.

import {Component, signal} from "@angular/core"

import {PortalDirective} from "@qualcomm-ui/angular-core/portal"
import {MenuModule} from "@qualcomm-ui/angular/menu"

@Component({
  imports: [MenuModule, PortalDirective],
  selector: "menu-controlled-state-demo",
  template: `
    <q-menu [open]="open()" (openChanged)="open.set($event)">
      <button emphasis="primary" q-menu-button variant="fill">Show Menu</button>
      <ng-container *qPortal>
        <div q-menu-positioner>
          <div q-menu-content>
            <button q-menu-item value="new-text-file">New Text File</button>
            <button q-menu-item value="new-file">New File...</button>
            <button q-menu-item value="open-file">Open File...</button>
            <button q-menu-item value="export">Export</button>
          </div>
        </div>
      </ng-container>
    </q-menu>
  `,
})
export class MenuControlledStateDemo {
  protected readonly open = signal(false)
}

Placement

Configure the menu's placement using the positioning.placement prop.

import {Component} from "@angular/core"

import {PortalDirective} from "@qualcomm-ui/angular-core/portal"
import {MenuModule} from "@qualcomm-ui/angular/menu"

@Component({
  imports: [MenuModule, PortalDirective],
  selector: "menu-placement-demo",
  template: `
    <q-menu [positioning]="{placement: 'right-start'}">
      <button emphasis="primary" q-menu-button variant="fill">Show Menu</button>
      <ng-container *qPortal>
        <div q-menu-positioner>
          <div q-menu-content>
            <button q-menu-item value="new-text-file">New Text File</button>
            <button q-menu-item value="new-file">New File...</button>
            <button q-menu-item value="open-file">Open File...</button>
            <button q-menu-item value="export">Export</button>
          </div>
        </div>
      </ng-container>
    </q-menu>
  `,
})
export class MenuPlacementDemo {}

Sizes

Use the size input on q-menu to control the size of the menu. The default size is md.

The q-menu-button and q-menu-icon-button triggers inherit the menu's size, so the trigger and menu match by default. Such a trigger can run larger than its menu: set size on it to override the inherited value. An md menu pairs with an md or lg trigger. A compact trigger should always pair with an sm menu. When a trigger uses density="compact", set size="sm" on q-menu.

Other trigger content does not inherit the menu size. A link, an avatar, or a custom element placed in the trigger must be sized directly.

import {Component} from "@angular/core"
import {LogOut, Settings, User} from "lucide-angular"

import {provideIcons} from "@qualcomm-ui/angular-core/lucide"
import {PortalComponent} from "@qualcomm-ui/angular-core/portal"
import {MenuModule} from "@qualcomm-ui/angular/menu"

@Component({
  imports: [MenuModule, PortalComponent],
  providers: [provideIcons({LogOut, Settings, User})],
  selector: "menu-sizes-demo",
  template: `
    <q-menu size="sm">
      <button emphasis="primary" q-menu-button>Show Menu</button>
      <q-portal>
        <div q-menu-positioner>
          <div q-menu-content>
            <button q-menu-item value="account">
              <div icon="User" q-menu-item-start-icon></div>
              Account
            </button>
            <button q-menu-item value="settings">
              <div icon="Settings" q-menu-item-start-icon></div>
              Settings
            </button>
            <button q-menu-item value="logout">
              <div icon="LogOut" q-menu-item-start-icon></div>
              Logout
            </button>
          </div>
        </div>
      </q-portal>
    </q-menu>
  `,
})
export class MenuSizesDemo {}

Anchor Point

Use the positioning.anchorPoint prop to control the anchor point of the menu.

Anchor
import {Component, computed, type ElementRef, viewChild} from "@angular/core"

import {PortalDirective} from "@qualcomm-ui/angular-core/portal"
import {MenuModule} from "@qualcomm-ui/angular/menu"
import type {PositioningOptions} from "@qualcomm-ui/dom/floating-ui"

@Component({
  imports: [MenuModule, PortalDirective],
  selector: "menu-anchor-point-demo",
  template: `
    <div class="flex flex-col gap-4">
      <q-menu [positioning]="positioning()">
        <button emphasis="primary" q-menu-button variant="fill">
          Show Menu
        </button>
        <div
          #anchorRef
          class="font-body-lg text-neutral-primary bg-neutral-04 border-neutral-01 rounded-md border p-4"
        >
          Anchor
        </div>
        <ng-container *qPortal>
          <div q-menu-positioner>
            <div q-menu-content>
              <button q-menu-item value="new-text-file">New Text File</button>
              <button q-menu-item value="new-file">New File...</button>
              <button q-menu-item value="open-file">Open File...</button>
              <button q-menu-item value="export">Export</button>
            </div>
          </div>
        </ng-container>
      </q-menu>
    </div>
  `,
})
export class MenuAnchorPointDemo {
  protected readonly anchorRef =
    viewChild.required<ElementRef<HTMLDivElement>>("anchorRef")

  protected readonly positioning = computed<PositioningOptions>(() => ({
    getAnchorRect: () => this.anchorRef().nativeElement.getBoundingClientRect(),
  }))
}

Avatar

Here's an example that composes the Menu with the Avatar component to display a user account menu.

import {Component} from "@angular/core"
import {LogOut, Settings, User} from "lucide-angular"

import {provideIcons} from "@qualcomm-ui/angular-core/lucide"
import {PortalDirective} from "@qualcomm-ui/angular-core/portal"
import {AvatarModule} from "@qualcomm-ui/angular/avatar"
import {MenuModule} from "@qualcomm-ui/angular/menu"

@Component({
  imports: [AvatarModule, MenuModule, PortalDirective],
  providers: [provideIcons({LogOut, Settings, User})],
  selector: "menu-avatar-demo",
  template: `
    <q-menu [positioning]="{placement: 'right-start'}">
      <button q-avatar q-menu-trigger status="active">
        <img alt="John Doe" q-avatar-image src="/images/avatar-man.png" />
        <div q-avatar-content>JD</div>
        <div q-avatar-status></div>
      </button>
      <ng-container *qPortal>
        <div q-menu-positioner>
          <div q-menu-content>
            <button q-menu-item value="account">
              <div icon="User" q-menu-item-start-icon></div>
              Account
            </button>
            <button q-menu-item value="settings">
              <div icon="Settings" q-menu-item-start-icon></div>
              Settings
            </button>
            <button q-menu-item value="logout">
              <div icon="LogOut" q-menu-item-start-icon></div>
              Logout
            </button>
          </div>
        </div>
      </ng-container>
    </q-menu>
  `,
})
export class MenuAvatarDemo {}

Within Dialog

When using the Menu inside a Dialog, don't render the q-menu-positioner within a portal element.

import {Component} from "@angular/core"

import {PortalDirective} from "@qualcomm-ui/angular-core/portal"
import {ButtonModule} from "@qualcomm-ui/angular/button"
import {DialogModule} from "@qualcomm-ui/angular/dialog"
import {MenuModule} from "@qualcomm-ui/angular/menu"

@Component({
  imports: [MenuModule, ButtonModule, DialogModule, PortalDirective],
  selector: "menu-within-dialog-demo",
  template: `
    <div q-dialog-root>
      <button emphasis="primary" q-button q-dialog-trigger variant="fill">
        Show Dialog
      </button>

      <ng-container *qPortal>
        <div q-dialog-backdrop></div>
        <div q-dialog-positioner>
          <section class="w-72" q-dialog-content>
            <div q-dialog-body>
              <button q-dialog-close-button></button>
              <h3 q-dialog-heading>Dialog Title</h3>
              <q-menu>
                <button
                  class="place-self-start"
                  emphasis="primary"
                  q-menu-button
                  variant="fill"
                >
                  Show Menu
                </button>

                <div q-menu-positioner>
                  <div q-menu-content>
                    <button q-menu-item value="new-text-file">
                      New Text File
                    </button>
                    <button q-menu-item value="new-file">New File...</button>
                    <button q-menu-item value="open-file">Open File...</button>
                    <button q-menu-item value="export">Export</button>
                  </div>
                </div>
              </q-menu>
            </div>
          </section>
        </div>
      </ng-container>
    </div>
  `,
})
export class MenuWithinDialogDemo {}

Hide When Detached

Use the positioning.hideWhenDetached prop to hide the menu when it's detached from the trigger.

Item 0
Item 1
Item 2
Item 3
Item 4
Item 5
import {Component, signal} from "@angular/core"

import {IntersectionObserverDirective} from "@qualcomm-ui/angular-core/observers"
import {PortalDirective} from "@qualcomm-ui/angular-core/portal"
import {MenuModule} from "@qualcomm-ui/angular/menu"

@Component({
  imports: [MenuModule, PortalDirective, IntersectionObserverDirective],
  selector: "menu-hide-when-detached-demo",
  template: `
    <q-menu [open]="open()" [positioning]="{hideWhenDetached: true}">
      <div
        class="border-neutral-03 box-border flex max-w-72 gap-2 overflow-x-scroll rounded-md border p-4"
      >
        @for (item of items; track item) {
          <div
            class="font-body-md text-neutral-primary border-neutral-01 bg-neutral-04 rounded-md border p-3 whitespace-nowrap"
          >
            Item {{ item }}
          </div>
        }
        <button
          class="whitespace-nowrap"
          emphasis="primary"
          q-menu-button
          variant="fill"
          (qIntersectionObserver)="handleIntersection($event)"
        >
          Show Menu
        </button>
      </div>

      <ng-container *qPortal>
        <div q-menu-positioner>
          <div q-menu-content>
            <button q-menu-item value="new-text-file">New Text File</button>
            <button q-menu-item value="new-file">New File...</button>
            <button q-menu-item value="open-file">Open File...</button>
            <button q-menu-item value="export">Export</button>
          </div>
        </div>
      </ng-container>
    </q-menu>
  `,
})
export class MenuHideWhenDetachedDemo {
  items = [...Array(6).keys()]

  readonly open = signal(false)

  handleIntersection(entries: IntersectionObserverEntry[]) {
    if (entries[0]?.isIntersecting) {
      // only open the menu when the button is in view,
      // but keep it open after to demonstrate the use case.
      this.open.set(true)
    }
  }
}

Explorer

API

<q-menu>

PropTypeDefault
The positioning point for the menu. Can be set by the context menu trigger or the button trigger.
{
x: number
y: number
}
Whether to close the menu when an option is selected
boolean
true
Whether the menu is composed with other composite widgets like a combobox or tabs
boolean
true
The initial highlighted value of the menu item when rendered. Use when you don't need to control the highlighted value of the menu item.
string
The initial open state of the menu when rendered. Use when you don't need to control the open state of the menu.
boolean
The document's text/writing direction.
'ltr' | 'rtl'
"ltr"
A root node to correctly resolve the Document in custom environments. i.e., Iframes, Electron.
() =>
| Node
| ShadowRoot
| Document
The controlled highlighted value of the menu item.
string
id attribute. If omitted, a unique identifier will be generated for accessibility.)
string
Whether to synchronize the present change immediately or defer it to the next frame.
boolean
false
When true, the component will not be rendered in the DOM until it becomes visible or active.
boolean
false
Whether to loop the keyboard navigation.
boolean
false
The controlled open state of the menu
boolean
The options used to dynamically position the menu
The controlled presence of the node.
boolean
'sm' | 'md'
Whether to allow the initial presence animation.
boolean
false
Whether the pressing printable characters should trigger typeahead navigation
boolean
true
When true, the component will be completely removed from the DOM when it becomes inactive or hidden, rather than just being hidden with CSS.
boolean
false
Function called when the escape key is pressed
KeyboardEvent
Function called when the animation ends in the closed state
void
Function called when the focus is moved outside the component
CustomEvent<{
event?: E
}>
Function called when the highlighted menu item changes.
string
Function called when an interaction happens outside the component
| CustomEvent<{event?: E}>
| CustomEvent<{event?: E}>
Function to navigate to the selected item if it's an anchor element
{
href: string
node: HTMLAnchorElement
value: string
}
Function called when the open state changes
boolean
Function called when the pointer is pressed down outside the component
CustomEvent<{
event?: E
}>
Function called when this layer is closed due to a parent layer being closed
CustomEvent<{
originalIndex: number
originalLayer: HTMLElement
targetIndex: number
targetLayer: HTMLElement
}>
Function called when a menu item is selected.
string
Type
{
x: number
y: number
}
Description
The positioning point for the menu. Can be set by the context menu trigger or the button trigger.
Type
boolean
Description
Whether to close the menu when an option is selected
Type
boolean
Description
Whether the menu is composed with other composite widgets like a combobox or tabs
Type
string
Description
The initial highlighted value of the menu item when rendered. Use when you don't need to control the highlighted value of the menu item.
Type
boolean
Description
The initial open state of the menu when rendered. Use when you don't need to control the open state of the menu.
Type
'ltr' | 'rtl'
Description
The document's text/writing direction.
Type
() =>
| Node
| ShadowRoot
| Document
Description
A root node to correctly resolve the Document in custom environments. i.e., Iframes, Electron.
Type
string
Description
The controlled highlighted value of the menu item.
Type
string
Description
id attribute. If omitted, a unique identifier will be generated for accessibility.)
Type
boolean
Description
Whether to synchronize the present change immediately or defer it to the next frame.
Type
boolean
Description
When true, the component will not be rendered in the DOM until it becomes visible or active.
Type
boolean
Description
Whether to loop the keyboard navigation.
Type
boolean
Description
The controlled open state of the menu
Description
The options used to dynamically position the menu
Type
boolean
Description
The controlled presence of the node.
Type
'sm' | 'md'
Type
boolean
Description
Whether to allow the initial presence animation.
Type
boolean
Description
Whether the pressing printable characters should trigger typeahead navigation
Type
boolean
Description
When true, the component will be completely removed from the DOM when it becomes inactive or hidden, rather than just being hidden with CSS.
Type
KeyboardEvent
Description
Function called when the escape key is pressed
Type
void
Description
Function called when the animation ends in the closed state
Type
CustomEvent<{
event?: E
}>
Description
Function called when the focus is moved outside the component
Type
string
Description
Function called when the highlighted menu item changes.
Type
| CustomEvent<{event?: E}>
| CustomEvent<{event?: E}>
Description
Function called when an interaction happens outside the component
Type
{
href: string
node: HTMLAnchorElement
value: string
}
Description
Function to navigate to the selected item if it's an anchor element
Type
boolean
Description
Function called when the open state changes
Type
CustomEvent<{
event?: E
}>
Description
Function called when the pointer is pressed down outside the component
Type
CustomEvent<{
originalIndex: number
originalLayer: HTMLElement
targetIndex: number
targetLayer: HTMLElement
}>
Description
Function called when this layer is closed due to a parent layer being closed
Type
string
Description
Function called when a menu item is selected.

q-menu-button

PropTypeDefault
The density of the button. Governs padding and height.
| 'default'
| 'compact'
'default'
Controls whether the component is interactive. When true, pointer/focus events are blocked, and the component is visually dimmed.
boolean
false
The variant of the button.
| 'neutral'
| 'primary'
| 'danger'
| 'white-persistent'
| 'black-persistent'
| 'inverse'
'neutral'
The size of the component and its icons.
| 'sm'
| 'md'
| 'lg'
'md'
lucide-angular icon, positioned before the label.
| LucideIconData
| string
The variant of the button.
| 'fill'
| 'ghost'
| 'outline'
'fill'
Type
| 'default'
| 'compact'
Description
The density of the button. Governs padding and height.
Type
boolean
Description
Controls whether the component is interactive. When true, pointer/focus events are blocked, and the component is visually dimmed.
Type
| 'neutral'
| 'primary'
| 'danger'
| 'white-persistent'
| 'black-persistent'
| 'inverse'
Description
The variant of the button.
Type
| 'sm'
| 'md'
| 'lg'
Description
The size of the component and its icons.
Type
| LucideIconData
| string
Description
lucide-angular icon, positioned before the label.
Type
| 'fill'
| 'ghost'
| 'outline'
Description
The variant of the button.

q-menu-icon-button

PropTypeDefault
The density of the button. Governs padding and height.
| 'default'
| 'compact'
'default'
Controls whether the component is interactive. When true, pointer/focus events are blocked, and the component is visually dimmed.
boolean
false
The variant of the button.
| 'neutral'
| 'primary'
| 'danger'
| 'white-persistent'
| 'black-persistent'
| 'inverse'
'neutral'
| LucideIconData
| string
Governs the shape of the icon button.
| 'square'
| 'rounded'
'square'
The size of the component and its icons.
| 'sm'
| 'md'
| 'lg'
'md'
The variant of the button.
| 'fill'
| 'ghost'
| 'outline'
'fill'
Type
| 'default'
| 'compact'
Description
The density of the button. Governs padding and height.
Type
boolean
Description
Controls whether the component is interactive. When true, pointer/focus events are blocked, and the component is visually dimmed.
Type
| 'neutral'
| 'primary'
| 'danger'
| 'white-persistent'
| 'black-persistent'
| 'inverse'
Description
The variant of the button.
Type
| LucideIconData
| string
Description
Type
| 'square'
| 'rounded'
Description
Governs the shape of the icon button.
Type
| 'sm'
| 'md'
| 'lg'
Description
The size of the component and its icons.
Type
| 'fill'
| 'ghost'
| 'outline'
Description
The variant of the button.

q-menu-split-button

PropType
string
string
The density of both buttons.
| 'default'
| 'compact'
Disables both buttons.
boolean
The emphasis applied to both buttons.
| 'neutral'
| 'primary'
| 'danger'
| 'white-persistent'
| 'black-persistent'
| 'inverse'
Icon positioned after the primary action label.
| LucideIconData
| string
The size of both buttons.
| 'sm'
| 'md'
| 'lg'
Icon positioned before the primary action label.
| LucideIconData
| string
The variant applied to both buttons.
| 'fill'
| 'ghost'
| 'outline'
Emitted when the default action button is clicked.
MouseEvent
Type
string
Description
aria-label attribute.
Type
string
Description
aria-labelledby attribute.
Type
| 'default'
| 'compact'
Description
The density of both buttons.
Type
boolean
Description
Disables both buttons.
Type
| 'neutral'
| 'primary'
| 'danger'
| 'white-persistent'
| 'black-persistent'
| 'inverse'
Description
The emphasis applied to both buttons.
Type
| LucideIconData
| string
Description
Icon positioned after the primary action label.
Type
| 'sm'
| 'md'
| 'lg'
Description
The size of both buttons.
Type
| LucideIconData
| string
Description
Icon positioned before the primary action label.
Type
| 'fill'
| 'ghost'
| 'outline'
Description
The variant applied to both buttons.
Type
MouseEvent
Description
Emitted when the default action button is clicked.

q-menu-trigger

PropType
id attribute. If omitted, a unique identifier will be generated for accessibility.
string
Type
string
Description
id attribute. If omitted, a unique identifier will be generated for accessibility.

q-menu-content

PropType
id attribute. If omitted, a unique identifier will be generated for accessibility.
string
Type
string
Description
id attribute. If omitted, a unique identifier will be generated for accessibility.

q-menu-item-group

PropType
id attribute. If omitted, a unique identifier will be generated for accessibility.
string
Type
string
Description
id attribute. If omitted, a unique identifier will be generated for accessibility.

q-menu-item-group-label

q-menu-item

Each menu item type shares the same base properties.
PropType
The unique value of the menu item option.
string
Whether the menu should be closed when the option is selected.
boolean
Whether the menu item is disabled
boolean
The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used.
string
Emitted when the item is selected
void
Type
string
Description
The unique value of the menu item option.
Type
boolean
Description
Whether the menu should be closed when the option is selected.
Type
boolean
Description
Whether the menu item is disabled
Type
string
Description
The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used.
Type
void
Description
Emitted when the item is selected

q-menu-item-label

q-menu-item-start-icon

PropType
| LucideIconData
| string
Type
| LucideIconData
| string

q-menu-item-description

q-menu-item-indicator

q-menu-separator

q-menu-checkbox-item

Each menu item type shares the same base properties.
PropType
The unique value of the menu item option.
string
Whether the option is checked
boolean
Whether the menu should be closed when the option is selected.
boolean
boolean
Whether the menu item is disabled
boolean
The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used.
string
boolean
Emitted when the item is selected
void
Type
string
Description
The unique value of the menu item option.
Type
boolean
Description
Whether the option is checked
Type
boolean
Description
Whether the menu should be closed when the option is selected.
Type
boolean
Type
boolean
Description
Whether the menu item is disabled
Type
string
Description
The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used.
Type
boolean
Type
void
Description
Emitted when the item is selected

q-menu-checkbox-item-control

Visual control rendered within a checkbox menu item. Defaults to a checkmark icon; project custom content to override.

q-menu-radio-item-control

Visual control rendered within a radio menu item. Place custom content (e.g. an indicator SVG) as a child.

PositioningOptions

The positioning prop accepts an object with the following shape:

PropTypeDefault
The minimum padding between the arrow and the floating element's corner.
number
4
CSS selector used to locate the arrow element within the floating element. Components override this with their own anatomy-namespaced selector (e.g. [data-menu-part=arrow]).
string
The overflow boundary of the reference element
    () =>
    | 'clippingAncestors'
    | Element
    | Array<Element>
    | {
    height: number
    width: number
    x: number
    y: number
    }
    Whether the popover should fit the viewport.
    boolean
    Whether to flip the placement when the floating element overflows the boundary.
    | boolean
    | Array<
    | 'bottom'
    | 'bottom-end'
    | 'bottom-start'
    | 'left'
    | 'left-end'
    | 'left-start'
    | 'right'
    | 'right-end'
    | 'right-start'
    | 'top'
    | 'top-end'
    | 'top-start'
    >
    true
    
    Function that returns the anchor rect
      (
      element:
      | HTMLElement
      | VirtualElement,
      ) => {
      height?: number
      width?: number
      x?: number
      y?: number
      }
      The main axis offset or gap between the reference and floating element
      number
      8
      
      Whether the popover should be hidden when the reference element is detached
      boolean
      Options to activate auto-update listeners
      | boolean
      | {
      ancestorResize?: boolean
      ancestorScroll?: boolean
      animationFrame?: boolean
      elementResize?: boolean
      layoutShift?: boolean
      }
      true
      
      The offset of the floating element
      {
      crossAxis?: number
      mainAxis?: number
      }
      Function called when the placement is computed
        (
        data: ComputePositionReturn,
        ) => void
        Function called when the floating element is positioned or not
          (data: {
          placed: boolean
          }) => void
          The virtual padding around the viewport edges to check for overflow
          number
          Whether the floating element can overlap the reference element
          boolean
          false
          
          The initial placement of the floating element
          | 'bottom'
          | 'bottom-end'
          | 'bottom-start'
          | 'left'
          | 'left-end'
          | 'left-start'
          | 'right'
          | 'right-end'
          | 'right-start'
          | 'top'
          | 'top-end'
          | 'top-start'
          'bottom'
          
          Whether to make the floating element same width as the reference element
          boolean
          The secondary axis offset or gap between the reference and floating elements
          number
          Whether the popover should slide when it overflows.
          boolean
          The strategy to use for positioning
          | 'absolute'
          | 'fixed'
          'absolute'
          
          A callback that will be called when the popover needs to calculate its position.
            (data: {
            updatePosition: () => Promise<void>
            }) => void | Promise<void>
            Type
            number
            Description
            The minimum padding between the arrow and the floating element's corner.
            Type
            string
            Description
            CSS selector used to locate the arrow element within the floating element. Components override this with their own anatomy-namespaced selector (e.g. [data-menu-part=arrow]).
            Type
            () =>
            | 'clippingAncestors'
            | Element
            | Array<Element>
            | {
            height: number
            width: number
            x: number
            y: number
            }
            Description
            The overflow boundary of the reference element
              Type
              boolean
              Description
              Whether the popover should fit the viewport.
              Type
              | boolean
              | Array<
              | 'bottom'
              | 'bottom-end'
              | 'bottom-start'
              | 'left'
              | 'left-end'
              | 'left-start'
              | 'right'
              | 'right-end'
              | 'right-start'
              | 'top'
              | 'top-end'
              | 'top-start'
              >
              Description
              Whether to flip the placement when the floating element overflows the boundary.
              Type
              (
              element:
              | HTMLElement
              | VirtualElement,
              ) => {
              height?: number
              width?: number
              x?: number
              y?: number
              }
              Description
              Function that returns the anchor rect
                Type
                number
                Description
                The main axis offset or gap between the reference and floating element
                Type
                boolean
                Description
                Whether the popover should be hidden when the reference element is detached
                Type
                | boolean
                | {
                ancestorResize?: boolean
                ancestorScroll?: boolean
                animationFrame?: boolean
                elementResize?: boolean
                layoutShift?: boolean
                }
                Description
                Options to activate auto-update listeners
                Type
                {
                crossAxis?: number
                mainAxis?: number
                }
                Description
                The offset of the floating element
                Type
                (
                data: ComputePositionReturn,
                ) => void
                Description
                Function called when the placement is computed
                  Type
                  (data: {
                  placed: boolean
                  }) => void
                  Description
                  Function called when the floating element is positioned or not
                    Type
                    number
                    Description
                    The virtual padding around the viewport edges to check for overflow
                    Type
                    boolean
                    Description
                    Whether the floating element can overlap the reference element
                    Type
                    | 'bottom'
                    | 'bottom-end'
                    | 'bottom-start'
                    | 'left'
                    | 'left-end'
                    | 'left-start'
                    | 'right'
                    | 'right-end'
                    | 'right-start'
                    | 'top'
                    | 'top-end'
                    | 'top-start'
                    Description
                    The initial placement of the floating element
                    Type
                    boolean
                    Description
                    Whether to make the floating element same width as the reference element
                    Type
                    number
                    Description
                    The secondary axis offset or gap between the reference and floating elements
                    Type
                    boolean
                    Description
                    Whether the popover should slide when it overflows.
                    Type
                    | 'absolute'
                    | 'fixed'
                    Description
                    The strategy to use for positioning
                    Type
                    (data: {
                    updatePosition: () => Promise<void>
                    }) => void | Promise<void>
                    Description
                    A callback that will be called when the popover needs to calculate its position.
                      Last updated on by Olaf Kappes