Menu
import {Menu} from "@qualcomm-ui/react/menu"Examples
Item Customization
Compose the menu to include icons and commands.
Context Menu
Demonstrates how to trigger a menu on right-click or other context events.
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>
<q-portal>
<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>
<q-portal>
<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>
</q-portal>
</q-menu>
</div>
</div>
</q-portal>
</q-menu>Links
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-item—menuitemq-menu-radio-item—menuitemradioq-menu-checkbox-item—menuitemcheckbox
Checkbox Items
Use checkbox items when you need options that are individually selectable.
Checkbox Group State
Checkbox item state is controlled individually on each item. Use the useCheckboxGroup hook to manage the state of a group of checkbox items.
<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
Radio items are grouped such that only one can be selected at a time.
<div q-menu-radio-item-group>
<label q-menu-item-group-label>Choose an option</label>
<div q-menu-radio-item-group>
<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>Radio Group State
Radio item state can be controlled via the value property on the parent 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, openChange, and defaultOpen properties.
- Use
opento explicitly set whether the menu is open (controlled mode). - Use
openChangedto be notified when the menu requests to open or close. - Use
defaultOpento 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.
Placement
Configure the menu's placement using the positioning.placement prop.
Anchor Point
Use the positioning.anchorPoint prop to control the anchor point of the menu.
Avatar
Here's an example that composes the Menu with the Avatar component to display a user account menu.
Within Dialog
When using the Menu inside a Dialog, don't render the q-menu-positioner within a <q-portal> element.
Hide When Detached
Use the positioning.hideWhenDetached prop to hide the menu when it's detached from the trigger.
API
<q-menu>
| Prop | Type | Default |
|---|---|---|
The positioning point for the menu. Can be set by the context menu trigger or
the button trigger. | { | |
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. | () => | |
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<{ | |
Function called when the highlighted menu item changes. | string | |
Function called when an interaction happens outside the component | | CustomEvent<{event?: E}> | |
Function to navigate to the selected item if it's an anchor element | { | |
Function called when the open state changes | boolean | |
Function called when the pointer is pressed down outside the component | CustomEvent<{ | |
Function called when this layer is closed due to a parent layer being closed | CustomEvent<{ | |
Function called when a menu item is selected. | string |
{
x: number
y: number
}
booleanbooleanstringboolean'ltr' | 'rtl'
() =>
| Node
| ShadowRoot
| Document
stringstringbooleanbooleanbooleanbooleanboolean'sm' | 'md'
booleanbooleanbooleanKeyboardEventvoidCustomEvent<{
event?: E
}>
string| CustomEvent<{event?: E}>
| CustomEvent<{event?: E}>
{
href: string
node: HTMLAnchorElement
value: string
}
booleanCustomEvent<{
event?: E
}>
CustomEvent<{
originalIndex: number
originalLayer: HTMLElement
targetIndex: number
targetLayer: HTMLElement
}>
stringq-menu-item
| Prop | Type |
|---|---|
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 |
stringbooleanbooleanstringvoidq-menu-checkbox-item
| Prop | Type |
|---|---|
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 |
stringbooleanbooleanbooleanbooleanstringbooleanvoidPositioningOptions
The positioning prop accepts an object with the following shape:
| Prop | Type | Default |
|---|---|---|
The minimum padding between the arrow and the floating element's corner. | number | 4 |
The overflow boundary of the reference element | () => | |
Whether the popover should fit the viewport. | boolean | |
Whether to flip the placement when the floating element overflows the boundary. | | boolean | true |
Function that returns the anchor rect | ( | |
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 | true |
The offset of the floating element | { | |
Function called when the placement is computed | ( | |
Function called when the floating element is positioned or not | (data: { | |
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' |
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' | 'absolute' |
A callback that will be called when the popover needs to calculate its
position. | (data: { |
number() =>
| 'clippingAncestors'
| Element
| Array<Element>
| {
height: number
width: number
x: number
y: number
}
boolean| boolean
| Array<
| 'bottom'
| 'bottom-end'
| 'bottom-start'
| 'left'
| 'left-end'
| 'left-start'
| 'right'
| 'right-end'
| 'right-start'
| 'top'
| 'top-end'
| 'top-start'
>
(
element:
| HTMLElement
| VirtualElement,
) => {
height?: number
width?: number
x?: number
y?: number
}
numberboolean| boolean
| {
ancestorResize?: boolean
ancestorScroll?: boolean
animationFrame?: boolean
elementResize?: boolean
layoutShift?: boolean
}
{
crossAxis?: number
mainAxis?: number
}
(
data: ComputePositionReturn,
) => void
(data: {
placed: boolean
}) => void
numberboolean| 'bottom'
| 'bottom-end'
| 'bottom-start'
| 'left'
| 'left-end'
| 'left-start'
| 'right'
| 'right-end'
| 'right-start'
| 'top'
| 'top-end'
| 'top-start'
booleannumberboolean| 'absolute'
| 'fixed'
(data: {
updatePosition: () => Promise<void>
}) => void | Promise<void>