目录

Menu Control

A context menu – a vertical list of items – can be bound to a component and displayed by long-pressing, clicking, or right-clicking the component. Menu control is applicable to scenarios where shortcut operations, setting options, or context-related operations are required. It provides users with convenient operation entries and improves the interaction experience of applications. The menu content and style can be customized to flexibly adapt to different service requirements.

  • The feature is supported since API version 7. Updates will be marked with a superscript to indicate their earliest API version.

  • Multi-level menus cannot be displayed using bindMenu and bindContextMenu in CustomBuilder. Use the Menu component instead.

  • The text in the context menu cannot be selected by long-pressing.

  • When the window size changes or the menu content area is tapped, the menu is automatically hidden.

  • If the component bound to the menu is a draggable node and preview is not specified for bindContextMenu, the drag preview will be displayed when the menu is displayed, and the menu options and preview will not avoid each other. You can set preview or set the target node to be non-draggable based on the application scenario.

  • Since API version 12, menus allow users to display a submenu with a 500 ms long press, with the pressed state following the movement of the finger.

    1. This feature is only available in scenarios where the Menu component is used and the child components include MenuItem or MenuItemGroup.

    2. This feature is only available for menus with MenuPreviewMode set to NONE.

  • The maximum width of a menu is limited by the grids occupied by the device. Even if the width is set to 100%, the menu does not occupy the entire screen.

  • When the component object bound to the menu is destroyed, the menu disappears.

  • bindContextMenu can be displayed only in the subwindow. bindMenu can be configured to display in subwindows by setting the showInSubWindow property in MenuOptions.

bindMenu

bindMenu(content: Array<MenuElement> | CustomBuilder, options?: MenuOptions): T

Binds a menu to this component, which is displayed when the user clicks the component. The displayed menu items support icon+text arrangement and component customization.

This API can be called within attributeModifier since API version 20 only if the input parameter type of content is Array<MenuElement>.

Atomic service API: This API can be used in atomic services since API version 11.

System capability: SystemCapability.ArkUI.ArkUI.Full

Parameters

Name Type Mandatory Description
content Array<MenuElement> | CustomBuilder Yes Array of menu item icons and text, or custom component.
options MenuOptions No Parameters of the context menu.

Return value

Type Description
T Current component.

bindMenu11+

bindMenu(isShow: boolean, content: Array<MenuElement> | CustomBuilder, options?: MenuOptions): T

Binds a menu to a component. isShow specifies whether to display a menu. The displayed menu items support icon+text arrangement and component customization.

This API can be called within attributeModifier since API version 20 only if the input parameter type of content is Array<MenuElement>.

Atomic service API: This API can be used in atomic services since API version 12.

Model restriction: This API can be used only in the stage model.

System capability: SystemCapability.ArkUI.ArkUI.Full

Parameters

Name Type Mandatory Description
isShow boolean Yes

Menu visibility. The menu can be displayed only after the entire page is fully constructed. Setting this parameter to true during page construction will cause incorrect positioning and layout. Since API version 18, this parameter supports two-way binding through the !! syntax.

true: Display the menu. false: Close the menu.

Default value: false

content Array<MenuElement> | CustomBuilder Yes Array of menu item icons and text, or custom component.
options MenuOptions No Parameters of the context menu.

Return value

Type Description
T Current component.

bindContextMenu8+

bindContextMenu(content: CustomBuilder, responseType: ResponseType, options?: ContextMenuOptions): T

Binds a menu to a component. The display or hiding of the menu is triggered via long press or right-click, with custom menu items. To use the code logic to control the display and hiding of menus, use bindContextMenu12+.

  • bindContextMenu (implemented in subwindows by default) is not supported in input method windows. For details, see the constraints in createPanel of the input method framework documentation.

  • This API cannot be called within attributeModifier.

Atomic service API: This API can be used in atomic services since API version 11.

System capability: SystemCapability.ArkUI.ArkUI.Full

Parameters

Name Type Mandatory Description
content CustomBuilder Yes Builder of the custom menu content.
responseType ResponseType Yes How the context menu is triggered, which can be long-press or right-click. Long pressing with a mouse device is not supported.
options ContextMenuOptions No Parameters of the context menu.

Return value

Type Description
T Current component.

bindContextMenu12+

bindContextMenu(isShown: boolean, content: CustomBuilder, options?: ContextMenuOptions): T

Binds a menu to a component. isShown specifies whether to display a menu.

When isShown is true, the menu is displayed. When isShown is false, the menu is hidden. Menu items can be customized.

The position where the menu is displayed is determined only by the placement parameter, and is irrelevant to the tap position.

  • bindContextMenu (implemented in subwindows by default) is not supported in input method windows. For details, see the constraints in createPanel of the input method framework documentation.

  • This API cannot be called within attributeModifier.

Model restriction: This API can be used only in the stage model.

System capability: SystemCapability.ArkUI.ArkUI.Full

Atomic service API: This API can be used in atomic services since API version 12.

Parameters

Name Type Mandatory Description
isShown boolean Yes

Menu visibility. The menu can be displayed properly only when the related page has been constructed. If this parameter is set to true before the construction is complete, display issues, such as misplacement, distortion, or failure to pop up, may occur. To trigger dragging by long presses is not supported. Since API version 18, this parameter supports two-way binding through the !! syntax.

true: Display the menu. false: Close the menu.

Default value: false

content CustomBuilder Yes Builder of the custom menu content.
options ContextMenuOptions No Parameters of the context menu.

Return value

Type Description
T Current component.

bindContextMenuWithResponse23+

bindContextMenuWithResponse(content: CustomBuilderT<ResponseType> | undefined, options?: ContextMenuOptions): T

Binds a menu to a component. The display or hiding of the menu is triggered via long press or right-click, with custom styles and content.

  • bindContextMenuWithResponse (implemented in subwindows by default) is not supported in input method windows. For details, see the constraints in createPanel of the input method framework documentation.

  • This API cannot be called within attributeModifier.

Atomic service API: This API can be used in atomic services since API version 23.

System capability: SystemCapability.ArkUI.ArkUI.Full

Model restriction: This API can be used only in the stage model.

Parameters

Name Type Mandatory Description
content CustomBuilderT<ResponseType> | undefined Yes Builder of the custom menu content. The input parameter is the menu triggering mode, which can be used to implement differentiated content. If this parameter is set to undefined, no menu is displayed.
options ContextMenuOptions No Parameters of the context menu.

Return value

Type Description
T Current component.

bindContextMenuByResponseType

bindContextMenuByResponseType(content: CustomBuilder | Array<MenuElement>, responseType: ResponseType, options?: ContextMenuOptions): T

Binds a menu to the component. The menu is displayed or hidden when the user long-presses or right-clicks the component. Menu items in custom or fixed styles are supported.

  • The bindContextMenuByResponseType method (implemented by the default subwindow) cannot be used in the input method window. For details, see the restrictions of the input method framework createPanel.

  • This API cannot be called within attributeModifier.

Since: 26.0.0

Model restriction: This API can be used only in the stage model.

Atomic service API: This API can be used in atomic services since API version 26.0.0.

System capability: SystemCapability.ArkUI.ArkUI.Full

Parameters

Name Type Mandatory Description
content CustomBuilder | Array<MenuElement> Yes Custom menu content builder, or a menu with a fixed style. If this parameter is set to undefined, no menu is displayed.
responseType ResponseType Yes How the context menu is triggered, which can be long-press or right-click. Long pressing with a mouse device is not supported.
options ContextMenuOptions No Parameters of the context menu.

Return value

Type Description
T Current component.

bindContextMenuWithResponse

bindContextMenuWithResponse(content: CustomBuilderT<ResponseType> | Array<MenuElement> | undefined, options?: ContextMenuOptions): T

Binds a menu to the component. The menu is displayed or hidden by long-pressing or right-clicking. The menu items can be customized or have a fixed style. When the menu items are customized, you can implement differentiated content based on the triggering mode.

  • bindContextMenuWithResponse (implemented in subwindows by default) is not supported in input method windows. For details, see the constraints in createPanel of the input method framework documentation.

  • This API cannot be called within attributeModifier.

Since: 26.0.0

Model restriction: This API can be used only in the stage model.

Atomic service API: This API can be used in atomic services since API version 26.0.0.

System capability: SystemCapability.ArkUI.ArkUI.Full

Parameters

Name Type Mandatory Description
content CustomBuilderT<ResponseType> | Array<MenuElement> | undefined Yes Builder of the custom menu content. The input parameter is the menu triggering mode, which can be used to implement differentiated content. Alternatively, use a fixed-style menu. If this parameter is set to undefined, no menu is displayed.
options ContextMenuOptions No Parameters of the context menu.

Return value

Type Description
T Current component.

bindContextMenuByIsShow

bindContextMenuByIsShow(isShow: boolean, content: CustomBuilder | Array<MenuElement>, options?: ContextMenuOptions): T

Binds a menu to a component. isShow specifies whether to display a menu.

The menu items support custom and fixed style arrays.

The position where the menu is displayed is determined only by the placement parameter, and is irrelevant to the position where the menu is tapped.

  • The bindContextMenuByIsShow method (implemented by the default subwindow) cannot be used in the input method window. For details, see the restrictions of the input method framework createPanel.

  • This API cannot be called within attributeModifier.

Since: 26.0.0

Model restriction: This API can be used only in the stage model.

Atomic service API: This API can be used in atomic services since API version 26.0.0.

System capability: SystemCapability.ArkUI.ArkUI.Full

Parameters

Name Type Mandatory Description
isShow boolean Yes

Allows you to control the display and hiding of the menu through status variables. The menu can be displayed properly only when the related page has been constructed. If this parameter is set to true before the construction is complete, display issues, such as misplacement, distortion, or failure to pop up, may occur. To trigger dragging by long presses is not supported. This parameter supports two-way binding through the !! syntax.

true: Display the menu. false: Close the menu.

Default value: false

content CustomBuilder | Array<MenuElement> Yes Custom menu content builder or menu with a fixed style.
options ContextMenuOptions No Parameters of the context menu.

Return value

Type Description
T Current component.

ContextMenuOptions10+

Configures menu item information.

Model restriction: This API can be used only in the stage model.

System capability: SystemCapability.ArkUI.ArkUI.Full

Name Type Read-Only Optional Description
offset Position No Yes

Offset for showing the context menu. This offset does not cause the menu to extend beyond the screen

Default value: { x: 0, y: 0 }, in vp. The percentage cannot be set.

NOTE

When the menu is displayed relative to the parent component area, the width or height of the area is automatically included in the offset based on the placement attribute of the menu.

Table 1 describes the relationship between the final offset value and the placement value.

If this parameter is not set, or set to an abnormal value or undefined, the default value { x: 0, y: 0 } is used. If the offset exceeds the screen range, it will be constrained to the nearest point within the screen range.

If the display position of the menu is adjusted (different from the main direction of the initial placement value), the offset value is invalid.

Atomic service API: This API can be used in atomic services since API version 11.

placement Placement No Yes

Preferred position of the context menu. If the set position is insufficient for holding the component, it will be automatically adjusted.

NOTE

1. When this parameter is used as the input parameter of bindMenu, its default value is Placement.BottomLeft.

2. When this parameter is used as the input parameter of bindContextMenu8+ or bindContextMenuWithResponse23+, the menu is displayed at the click position.

3. When this parameter is used as the input parameter of bindContextMenu12+, its default value is Placement.BottomLeft.

4. If the value of placement is undefined, null, or empty, the default value is used.

Atomic service API: This API can be used in atomic services since API version 11.

enableArrow boolean No Yes

Whether to display an arrow. If the size and position of the context menu are insufficient for holding an arrow, no arrow is displayed.

Default value: false, indicating that no arrow is displayed.

NOTE

When enableArrow is set to true and placement is not set or set to an invalid value, the arrow is displayed above the target object by default. (For details about the relationship between the default menu position and the API, see Table 3.) Otherwise, the arrow is displayed based on the position specified by placement. If the position is insufficient for holding the arrow, it is automatically adjusted. When enableArrow is undefined, no arrow is displayed. If preview is set to MenuPreviewMode.IMAGE or CustomBuilder, no arrow will be displayed even when enableArrow is true. This API is supported in bindContextMenu since API version 10 and bindMenu since API version 12.

Atomic service API: This API can be used in atomic services since API version 11.

enableHoverMode18+ boolean No Yes

Whether the menu component responds to changes in the hover state (half-folded state), that is, whether to trigger avoidance of the crease area in the hover state.

true: responds to hover state changes; false: does not respond to hover state changes.

Default value: false, and the default value is true on PCs/2-in-1 devices. When not set or set to an invalid value, the default value takes effect.

NOTE

1. If the popup position of the menu is in the crease area of the hover state, the menu component does not respond to the hover state.

2. On PCs/2-in-1 devices, this takes effect since API version 20.

3. On PCs/2-in-1 devices, this takes effect only in window waterfall mode.

Atomic service API: This API can be used in atomic services since API version 18.

arrowOffset Length No Yes

Offset of the arrow relative to the context menu. The offset settings take effect only when the value is valid, can be converted to a number greater than 0, and does not cause the arrow to extend beyond the safe area of the context menu.

Default value: 0

Unit: vp

NOTE

The safe distance of the arrow from the four sides of the menu is the sum of the menu's corner radius and half the width of the arrow.

The value of placement determines whether the offset is horizontal or vertical.

When the arrow is in the horizontal direction of the menu, the offset is the distance from the arrow to the leftmost arrow's safe distance. When the arrow is in the vertical direction of the menu, the offset is the distance from the arrow to the topmost arrow's safe distance.

The default position where the arrow is displayed varies with the value of placement:

Table 2 describes the relationship between the final position of the arrow and the value of placement in cases where the menu does not trigger repositioning.

This API is supported in bindContextMenu since API version 10 and bindMenu since API version 12.

Atomic service API: This API can be used in atomic services since API version 11.

preview11+ MenuPreviewMode | CustomBuilder No Yes

Preview displayed when the context menu is triggered by a long-press or by calling bindContextMenu12+. It can be a screenshot of the target component or custom content.

Default value: MenuPreviewMode.NONE, indicating no preview.

NOTE

- This parameter has no effect when responseType is set to ResponseType.RightClick.

- If preview is set to MenuPreviewMode.NONE or is not set, the enableArrow parameter is effective.

- If preview is set to MenuPreviewMode.IMAGE or CustomBuilder, no arrow will be displayed even when enableArrow is true.

Atomic service API: This API can be used in atomic services since API version 12.

previewAnimationOptions11+ ContextMenuAnimationOptions No Yes

Display effect of the long-press preview.

Default value: { scale: [0.95, 1.1], transition: undefined, hoverScale: undefined }

NOTE

If the value is less than or equal to 0, this parameter does not take effect.

Atomic service API: This API can be used in atomic services since API version 12.

previewBorderRadius19+ BorderRadiusType No Yes

Border corner radius for the preview image.

Default value: 16vp

NOTE

If the sum of the two corner radii in the horizontal direction exceeds the width of the preview image, or the sum of the two corner radii in the vertical direction exceeds the height of the preview image, the maximum allowable radius should be used.

A larger corner radius results in a faster animation change for the corners.

Atomic service API: This API can be used in atomic services since API version 19.

layoutRegionMargin13+ Margin No Yes

Minimum margin between the preview and menu layout for top, bottom, left, and right edges.

NOTE

Only vp, px, fp, lpx, and percentage units are supported.

Any abnormal or negative values will be treated as the default values.

If preview is set to CustomBuilder, setting margin.left or margin.right will remove the maximum grid width restriction for the preview.

Be cautious not to set excessively large margins that are too large, which could reduce the layout area and affect the proper layout of the preview and menu.

If the sum of horizontal margins exceeds the maximum layout width, margin.left and margin.right will be ignored and default values will be applied.

If the sum of vertical margins exceeds the maximum layout height, margin.top and margin.bottom will be ignored and default values will be applied.

The default margin values are 16 vp for the left and right, 16 vp for top, and 4 vp for bottom.

Atomic service API: This API can be used in atomic services since API version 13.

previewScaleMode20+ PreviewScaleMode No Yes

Preview image scaling mode.

Default value: PreviewScaleMode.AUTO

NOTE

This parameter applies to the scenarios where the layout space is insufficient. If this parameter is not set or is set to undefined, the value PreviewScaleMode.AUTO will be used. When this parameter is set to PreviewScaleMode.CONSTANT, if the preview image is too large and the remaining space is insufficient for placing the menu, the menu is displayed under the preview image.

The maximum width and height of the preview image do not exceed the maximum available layout area of the preview image (the window size minus the safe margins on all sides).

Atomic service API: This API can be used in atomic services since API version 20.

availableLayoutArea20+ AvailableLayoutArea No Yes

Available layout area of the preview image. The percentage of the preview image is calculated based on this setting. The preview image may be compressed or cropped due to the safe area restriction.

NOTE

If this parameter is not set or is set to undefined, the percentage is calculated based on the window size. If this parameter is set to AvailableLayoutArea.SAFE_AREA, the available layout area of the preview image is the window size minus the safe margins on all sides.

Atomic service API: This API can be used in atomic services since API version 20.

onAppear () => void No Yes

Callback invoked after the menu appears.

Atomic service API: This API can be used in atomic services since API version 11.

onDisappear () => void No Yes

Callback invoked after the menu disappears.

Atomic service API: This API can be used in atomic services since API version 11.

aboutToAppear11+ () => void No Yes

Callback triggered when the menu is about to appear.

Atomic service API: This API can be used in atomic services since API version 12.

aboutToDisappear11+ () => void No Yes

Callback triggered when the menu is about to disappear.

Atomic service API: This API can be used in atomic services since API version 12.

backgroundColor11+ ResourceColor No Yes

Background color of the menu.

Default value: Color.Transparent

Atomic service API: This API can be used in atomic services since API version 12.

backgroundBlurStyle11+ BlurStyle No Yes

Background blur style of the menu.

Default value: BlurStyle.COMPONENT_ULTRA_THICK

Atomic service API: This API can be used in atomic services since API version 12.

transition12+ TransitionEffect No Yes

Transition effect for the entrance and exit of the menu.

NOTE

During the exit animation of the menu, if there is a switch between landscape and portrait modes, the menu will make way. Level-2 menus do not inherit custom animations. The level-2 menu can be clicked during the pop-up process, but not during the execution of the exit animation.

For details, see TransitionEffect.

The menu animation uses a spring curve. Due to the rebound and oscillation of the spring curve during the exit of the animation, there is a prolonged tail effect, which prevents other events from responding after the menu disappears after it disappears.

When the custom transition animation is set, the default display and exit animations of the menu do not take effect.

Atomic service API: This API can be used in atomic services since API version 12.

borderRadius12+ Length | BorderRadiuses | LocalizedBorderRadiuses No Yes

Border radius of the menu.

Default value: 8 vp on PCs and 2-in-1 devices, and 20 vp on other devices.

NOTE

The value can be in percentage.

If the sum of the two maximum corner radii in the horizontal direction exceeds the menu's width, or if the sum of the two maximum corner radii in the vertical direction exceeds the menu's height, the default corner radius of the menu will be used.

When the Length type is used: Invalid input values will trigger a fallback to the default corner radius.

When the BorderRadiuses or LocalizedBorderRadiuses type is used: Invalid input values will result in the menu having no rounded corners by default.

Atomic service API: This API can be used in atomic services since API version 12.

backgroundBlurStyleOptions18+ BackgroundBlurStyleOptions No Yes

Background blur style.

Atomic service API: This API can be used in atomic services since API version 18.

backgroundEffect18+ BackgroundEffectOptions No Yes

Background effect.

Atomic service API: This API can be used in atomic services since API version 18.

hapticFeedbackMode18+ HapticFeedbackMode No Yes

Haptic feedback mode when the menu is displayed.

Default value: HapticFeedbackMode.DISABLED, indicating no vibration when the menu is displayed.

NOTE

The haptic feedback mode is only configurable for level-1 menus.

This parameter takes effect only when the user enables the haptic feedback function and the ohos.permission.VIBRATE permission is added to the requestPermissions field in the module.json5 file. The configuration is as follows:

Atomic service API: This API can be used in atomic services since API version 18.

outlineWidth20+ Dimension | EdgeOutlineWidths No Yes

Outline width of the menu border.

Default value: 0vp

NOTE

Percentage values are not supported. outlineWidth is mandatory for customizing an outline effect.

Atomic service API: This API can be used in atomic services since API version 20.

outlineColor20+ ResourceColor | EdgeColors No Yes

Outline color of the menu border.

NOTE

Default value: '#19ffffff'

Atomic service API: This API can be used in atomic services since API version 20.

mask20+ boolean | MenuMaskType No Yes

Sets whether a menu has a mask and the mask style.

true: yes; false: no; MenuMaskType: custom mask style

Default value: If a preview image is displayed for a menu, a mask is displayed by default. Otherwise, no mask is displayed.

NOTE

This API takes effect only when **$r('sys.string.ohos_id_menu_has_filter') **is set to true. If it is set to false, this API does not take effect.

Atomic service API: This API can be used in atomic services since API version 20.

modalMode20+ ModalMode No Yes

Modal mode of a menu.

NOTE

Default value: ModalMode.AUTO

Atomic service API: This API can be used in atomic services since API version 20.

anchorPosition20+ Position No Yes

Display position of the menu relative to the upper left corner of the bound component by setting the horizontal and vertical offsets. Unlike using the offset API alone, this allows the menu to overlay the bound component.

Default value: { x: undefined, y: undefined }, in vp. Percentages are not supported.

NOTE

1. Offsets do not apply during menu preview state.

2. The preset value of placement does not take effect.

3. The offset parameter is added to determine the exact display position of the menu.

4. When both horizontal and vertical offsets are set to negative values, the menu is reset to Placement.BottomLeft for display.

5. If the horizontal or vertical offset is undefined or null, the effect is the same as that of not setting anchorPosition. In this case, the preset value of placement can take effect.

Atomic service API: This API can be used in atomic services since API version 20.

onWillAppear20+ Callback<void> No Yes

Callback triggered when the menu is about to appear.

NOTE

1. The normal sequence is aboutToAppear > onWillAppear > onAppear > onDidAppear > aboutToDisappear > onWillDisappear > onDisappear > onDidDisappear.

2. aboutToAppear is invoked during initialization; onWillAppear is invoked before the animation starts but after aboutToAppear.

Atomic service API: This API can be used in atomic services since API version 20.

onDidAppear20+ Callback<void> No Yes

Callback invoked after the menu appears.

NOTE

1. The normal sequence is aboutToAppear > onWillAppear > onAppear > onDidAppear > aboutToDisappear > onWillDisappear > onDisappear > onDidDisappear.

2. If rapid clicks are triggered to display and then dismiss the menu, there may be cases where onWillDisappear is invoked before onDidAppear.

3. If the menu is closed before the menu entrance animation is complete, this callback is not triggered.

4. onAppear and onDidAppear are invoked at the same time. onDidAppear takes effect after onAppear.

Atomic service API: This API can be used in atomic services since API version 20.

onWillDisappear20+ Callback<void> No Yes

Callback triggered when the menu is about to disappear.

NOTE

1. The normal sequence is aboutToAppear > onWillAppear > onAppear > onDidAppear > aboutToDisappear > onWillDisappear > onDisappear > onDidDisappear.

2. If rapid clicks are triggered to display and then dismiss the menu, there may be cases where onWillDisappear is invoked before onDidAppear.

3. aboutToDisappear and onWillDisappear are invoked at the same time, but onWillDisappear takes effect after aboutToDisappear.

Atomic service API: This API can be used in atomic services since API version 20.

onDidDisappear20+ Callback<void> No Yes

Callback invoked after the menu disappears.

NOTE

1. The normal sequence is aboutToAppear > onWillAppear > onAppear > onDidAppear > aboutToDisappear > onWillDisappear > onDisappear > onDidDisappear.

2. onDisappear and onDidDisappear are triggered at the same time, but onDidDisappear takes effect after onDisappear.

Atomic service API: This API can be used in atomic services since API version 20.

keyboardAvoidMode23+ MenuKeyboardAvoidMode No Yes

Whether the menu avoids the soft keyboard.

NOTE

If this parameter is not set or is set to undefined, the value MenuKeyboardAvoidMode.NONE will be used.

Atomic service API: This API can be used in atomic services since API version 23.

Model restriction: This API can be used only in the stage model.

minKeyboardAvoidDistance23+ LengthMetrics No Yes

Minimum distance for the menu to avoid the soft keyboard.

NOTE

If this parameter is not set, or set to a negative value or undefined, the value will be treated as 8 vp. This API is valid only when keyboardAvoidMode is set to avoid the soft keyboard.

Atomic service API: This API can be used in atomic services since API version 23.

Model restriction: This API can be used only in the stage model.

scrollBar BarState No Yes

Scrollbar status of the menu.

Default value: BarState.Auto

If this parameter is not set or is set to undefined, the value is processed as BarState.Auto.

Since: 26.0.0

Atomic service API: This API can be used in atomic services since API version 26.0.0.

Model restriction: This API can be used only in the stage model.

maxHeight LengthMetrics No Yes

Maximum height of the menu.

Note: The default maximum height is 80% of the available height.

If this parameter is set to 0 or a negative number, or is set to undefined, the default maximum height is used. The maximum height of the menu cannot exceed 100% of the available height.

This capability is not supported in the preview image scenario. The menu is displayed with the default maximum height.

If the total height of all menu options is less than the specified height, the menu is displayed with the actual height.

Since: 26.0.0

Atomic service API: This API can be used in atomic services since API version 26.0.0.

Model restriction: This API can be used only in the stage model.

colorMode AnchoredColorMode No Yes

Dark/light color mode of the menu. By default, the dark/light color mode of the bound component is used.

Default value: AnchoredColorMode.FOLLOW_TARGET

NOTE

1. This parameter takes effect only when the bound component uses the WithTheme tag.

2. This attribute affects only the default style of the component and the attributes related to the dark/light color resource set by the developer.

3. If this parameter is set to AnchoredColorMode.FOLLOW_SYSTEM, the blurred material can follow the dark/light color mode, and the text color and attributes that involve dark/light color resources still follow the dark/light color configuration of the bound component.

Since: 26.0.0

Atomic service API: This API can be used in atomic services since API version 26.0.0.

Model restriction: This API can be used only in the stage model.

targetSpace LengthMetrics No Yes

Spacing between the menu and the target component.

NOTE

- When both targetSpace and offset are used, they take effect together. You are advised to use the targetSpace attribute to set the spacing between the menu and the target, and use the offset attribute to set the offset of the menu pop-up position.

- The level-2 menu will avoid the targetSpace range.

- If this attribute is set to a negative value or undefined, the spacing between the menu and the target component is 8 vp by default, and the submenu does not avoid the targetSpace range.

- The targetSpace attribute takes effect directly when there is a default placement. If there is no default placement, the targetSpace attribute takes effect only when used together with the placement attribute.

- The priority of anchorPosition is higher than that of targetSpace.

- This attribute cannot be set in percentage.

Since: 26.0.0

Atomic service API: This API can be used in atomic services since API version 26.0.0.

Model restriction: This API can be used only in the stage model.

systemMaterial SystemUiMaterial No Yes

System material of the menu. Different system materials correspond to different attribute effects. This API affects the background color backgroundColor, border color borderColor, border width borderWidth, and shadow shadow. When the system material is set, the preceding APIs do not take effect. If the material is set to an invalid value or undefined, no system material is set.

Default value: undefined

Since: 26.0.0

Atomic service API: This API can be used in atomic services since API version 26.0.0.

Model restriction: This API can be used only in the stage model.

gridStyle MenuGridStyleOptions No Yes

Grid style of the menu. Only the fixed style menu takes effect. For example, MenuElement is used in bindMenu, bindContextMenu, bindContextMenuByResponseType, bindContextMenuByIsShow or bindContextMenuWithResponse, or MenuItemOptions is used in MenuItem.

Since: 26.0.0

Atomic service API: This API can be used in atomic services since API version 26.0.0.

Model restriction: This API can be used only in the stage model.

Table 1: Menu offset when both offset and placement are set

Value of placement Menu Offset
Placement.TopLeft, Placement.Top, or Placement.TopRight If the value of x is a positive number for offset, the menu shifts to the right relative to the component. If the value of y is a positive number, the menu shifts upward relative to the component.
Placement.BottomLeft, Placement.Bottom, or Placement.BottomRight If the value of x is a positive number for offset, the menu shifts to the left relative to the component. If the value of y is a positive number, the menu shifts downward relative to the component.
Placement.RightTop, Placement.Right, or Placement.RightBottom If the value of x is a positive number for offset, the menu shifts to the right relative to the component. If the value of y is a positive number, the menu shifts downward relative to the component.

Table 2: Default position of the menu arrow when both arrowOffset and placement are set

Value of placement Menu Arrow Position
Placement.Top or Placement.Bottom The arrow is displayed horizontally and centered by default, with a distance from the left edge of the menu equal to the arrow's safe distance.
Placement.Left or Placement.Right The arrow is displayed vertically and centered by default, with a distance from the top edge of the menu equal to the arrow's safe distance.
Placement.TopLeft or Placement.BottomLeft The arrow is displayed horizontally by default, with a distance from the left edge of the menu equal to the arrow's safe distance.
Placement.TopRight or Placement.BottomRight The arrow is displayed horizontally by default, with a distance from the right edge of the menu equal to the arrow's safe distance.
Placement.LeftTop or Placement.RightTop The arrow is displayed vertically by default, with a distance from the top edge of the menu equal to the arrow's safe distance.
Placement.LeftBottom or Placement.RightBottom The arrow is displayed vertically by default, with a distance from the bottom edge of the menu equal to the arrow's safe distance.

Table 3 Default menu position when enableArrow is set to true and placement is not set or set to an invalid value

API Default Menu Position
bindMenu Placement.BottomLeft
bindMenu11+ Placement.BottomLeft
bindContextMenu8+ Placement.Top
bindContextMenu12+ Placement.BottomLeft
bindContextMenuWithResponse23+ Placement.Top

ContextMenuAnimationOptions11+

Defines the style for displaying a long-press preview.

Model restriction: This API can be used only in the stage model.

System capability: SystemCapability.ArkUI.ArkUI.Full

Name Type Read-Only Optional Description
scale AnimationRange<number> No Yes

Relative scale ratio at the start and end of the animation compared to the original preview image.

Default value: [0.95, 1.1]

NOTE

The scale ratio must be set based on the specific use case. It is recommended that it be less than the width of the preview image or the maximum constraint of the layout.

Atomic service API: This API can be used in atomic services since API version 12.

transition12+ TransitionEffect No Yes

Transition effect for the entrance and exit of the menu.

NOTE

If the screen orientation is switched during the exit animation of a menu, the menu will avoid obstacles. Level-2 menus do not inherit custom animations. The level-2 menu can be clicked during the display process, but not during the execution of the exit animation.

For details, see TransitionEffect.

When the transition is set, hoverScale and hoverScaleInterruption do not take effect.

Atomic service API: This API can be used in atomic services since API version 12.

hoverScale12+ AnimationRange<number> No Yes

In the custom preview (preview is of the CustomBuilder type) and menu displayed in long-press (responseType is set to LongPress) scenarios, hoverScale is used to set two parameters for the screenshot floating animation of the bound component: the start and end scale ratios relative to the original preview image. After hoverScale is set, the floating animation and preview image are switched with a transition effect.

NOTE

If the value is less than or equal to 0, this parameter does not take effect.

This API does not take effect in bindContextMenu12+ scenarios.

This API does not take effect when transition is set.

If this API and the scale API are used at the same time, the start value of the scale API does not take effect.

To ensure the optimal experience, it is not recommended that the final preview image size be smaller than the size of the original component screenshot. The width and height of the preview animation are affected by the component screenshot and the custom preview size. Verify the display effect based on the actual use case.

Atomic service API: This API can be used in atomic services since API version 12.

hoverScaleInterruption20+ boolean No Yes

Whether lifting the finger before triggering the drag effect allows preview menu pop-up cancellation in scenarios where preview is of the CustomBuilder type (custom preview image), responseType is set to LongPress (display is triggered by a long-press action), and hoverScaleInterruption is set to true. The options are true (yes) and false (no).

Default value: false

NOTE

If the hoverScale API is not set or the transition API is set, this parameter does not take effect. If the finger is lifted before the long-press duration is sufficient to trigger the drag effect, the hoverScale effect of the preview menu will revert, the preview menu will not pop up, and gesture events such as click bound to the original component can still be triggered. If the finger is lifted after the long-press duration is sufficient to trigger the drag effect, the preview menu will pop up properly, and gesture events such as click bound to the original component will no longer be triggered.

Atomic service API: This API can be used in atomic services since API version 20.

AnimationRange11+

type AnimationRange<T>=[from: T, to: T]

Sets the relative scale ratio at the start and end of the animation compared to the original preview image.

Model restriction: This API can be used only in the stage model.

System capability: SystemCapability.ArkUI.ArkUI.Full

Atomic service API: This API can be used in atomic services since API version 12.

Type Description
[from: T, to: T] from indicates the scale ratio at the beginning of the animation, and to indicates the scale ratio at the end of the animation.

HapticFeedbackMode18+

Enumerates the haptic feedback modes used when the menu is displayed.

Atomic service API: This API can be used in atomic services since API version 18.

Model restriction: This API can be used only in the stage model.

System capability: SystemCapability.ArkUI.ArkUI.Full

Name Value Description
DISABLED 0 The menu is displayed without haptic feedback.
ENABLED 1 The menu is displayed with haptic feedback.
AUTO 2 Whether to enable haptic feedback is subject to system settings. It is enabled when the menu has a mask.

BorderRadiusType19+

type BorderRadiusType = Length | BorderRadiuses | LocalizedBorderRadiuses

Enumerates the border corner radius types.

Atomic service API: This API can be used in atomic services since API version 19.

Model restriction: This API can be used only in the stage model.

System capability: SystemCapability.ArkUI.ArkUI.Full

Type Description
Length Size unit.
BorderRadiuses Corner radius of a component's border.
LocalizedBorderRadiuses Localized corner radius of a component's border.

ModalMode20+

Enumerates modal modes of the sub-window menu.

Atomic service API: This API can be used in atomic services since API version 20.

Model restriction: This API can be used only in the stage model.

System capability: SystemCapability.ArkUI.ArkUI.Full

Name Value Description
AUTO 0 Automatic mode, which is the default behavior of the menu component on the current device. In the current version, the effect on all devices is the same as that of ModalMode.NONE.
NONE 1 Events can be passed through areas other than the menu itself, allowing underlying controls to respond to events.
TARGET_WINDOW 2 Events cannot be passed through the application window where the menu is located and the menu area, but can be passed through other areas.

PreviewScaleMode20+

Enumerates the scale modes of the preview image.

Atomic service API: This API can be used in atomic services since API version 20.

Model restriction: This API can be used only in the stage model.

System capability: SystemCapability.ArkUI.ArkUI.Full

Name Value Description
AUTO 0 The preview image automatically adjusts its width, height, and scale based on Placement.
CONSTANT 1 The preview image retains its original size. However, the preview image may still be compressed or cropped due to the safe area constraints.
MAINTAIN 2 The preview image maintains its aspect ratio when scaled.

AvailableLayoutArea20+

Enumerates the reference sizes of the available layout area when the preview image width and height are set to percentages.

Atomic service API: This API can be used in atomic services since API version 20.

Model restriction: This API can be used only in the stage model.

System capability: SystemCapability.ArkUI.ArkUI.Full

Name Value Description
SAFE_AREA 0 The reference size of the available layout area is the window size minus the safe margins on all sides.

Examples

[h2]Example 1: Displaying a Basic Menu

This example demonstrates how to display a basic menu by configuring MenuElement for bindMenu.

@Entry
@Component
struct MenuExample {
  build() {
    Column() {
      Text('click for Menu')
        .bindMenu([
          {
            value: 'Menu1',
            action: () => {
              console.info('handle Menu1 select');
            }
          },
          {
            value: 'Menu2',
            action: () => {
              console.info('handle Menu2 select');
            }
          },
        ])
    }
    .width('100%')
    .margin({ top: 5 })
  }
}

[h2]Example 2: Displaying a Custom Menu

This example shows how to use bindMenu with a custom builder to create a custom menu. In addition, starting from API version 18, the hapticFeedbackMode property in ContextMenuOptions can be configured to implement the haptic feedback effect when the menu is displayed.

@Entry
@Component
struct MenuExample {
  @State listData: number[] = [0, 0, 0];

  @Builder MenuBuilder() {
    Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
      ForEach(this.listData, (item:number, index) => {
        Column() {
          Row() {
            // Replace $r('app.media.icon') with the image resource file you use.
            Image($r("app.media.icon")).width(20).height(20).margin({ right: 5 })
            Text(`Menu${index as number + 1}`).fontSize(20)
          }
          .width('100%')
          .height(30)
          .justifyContent(FlexAlign.Center)
          .align(Alignment.Center)
          .onClick(() => {
            console.info(`Menu${index as number + 1} Clicked!`);
          })

          if (index != this.listData.length - 1) {
            Divider().height(10).width('80%').color('#ccc')
          }
        }.padding(5).height(40)
      })
    }.width(100)
  }

  build() {
    Column() {
      Text('click for menu')
        .fontSize(20)
        .margin({ top: 20 })
        .bindMenu(this.MenuBuilder, { hapticFeedbackMode: HapticFeedbackMode.ENABLED })
    }
    .height('100%')
    .width('100%')
    .backgroundColor('#f0f0f0')
  }
}

[h2]Example 3: Displaying a Menu on Long Press

This example demonstrates how to display a menu by setting responseType.LongPress for bindContextMenu.

@Entry
@Component
struct ContextMenuExample {
  @Builder MenuBuilder() {
    Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
      Text('Test menu item 1')
        .fontSize(20)
        .width(100)
        .height(50)
        .textAlign(TextAlign.Center)
      Divider().height(10)
      Text('Test menu item 2')
        .fontSize(20)
        .width(100)
        .height(50)
        .textAlign(TextAlign.Center)
    }.width(100)
  }

  build() {
    Column() {
      Text('LongPress for menu')
    }
    .width('100%')
    .margin({ top: 5 })
    .bindContextMenu(this.MenuBuilder, ResponseType.LongPress)
  }
}

[h2]Example 4: Displaying a Menu with an Arrow on Right-Clicking

This example demonstrates how to display a menu with an arrow by setting the enableArrow property in responseType.RightClick and ContextMenuOptions for bindContextMenu. In addition, starting from API version 18, the hapticFeedbackMode property in ContextMenuOptions can be configured to implement the haptic feedback effect when the menu is displayed.

@Entry
@Component
struct DirectiveMenuExample {
  @Builder MenuBuilder() {
    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
      Text('Options')
      Divider().strokeWidth(2).margin(5).color('#F0F0F0')
      Text('Hide')
      Divider().strokeWidth(2).margin(5).color('#F0F0F0')
      Text('Exit')
    }
    .width(200)
  }

  build() {
    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
      Column() {
        Text("DirectiveMenuExample")
          .fontSize(20)
          .width('100%')
          .height("25%")
          .backgroundColor('#F0F0F0')
          .textAlign(TextAlign.Center)
          .bindContextMenu(this.MenuBuilder, ResponseType.RightClick, {
            enableArrow: true,
            placement: Placement.Bottom,
            hapticFeedbackMode: HapticFeedbackMode.ENABLED
          })
      }
    }
    .width('100%')
    .height('100%')
  }
}

[h2]Example 5: Displaying a Menu with a Screenshot Preview on Long Press

This example demonstrates how to display a menu with a screenshot preview by setting MenuPreviewMode of the preview property in responseType.LongPress and ContextMenuOptions for bindContextMenu.

@Entry
@Component
struct Index {
  // Replace $r('app.media.icon') with the image resource file you use.
  private iconStr: ResourceStr = $r("app.media.icon");

  @Builder
  MyMenu() {
    Menu() {
      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
    }
  }

  build() {
    Column({ space: 50 }) {
      Column() {
        Column() {
          Text('preview-image')
            .width(200)
            .height(100)
            .textAlign(TextAlign.Center)
            .margin(100)
            .fontSize(30)
            .bindContextMenu(this.MyMenu, ResponseType.LongPress,
              { preview: MenuPreviewMode.IMAGE,
                previewAnimationOptions: {scale: [0.8, 1.0]},
              })
            .backgroundColor("#ff3df2f5")
        }
      }.width('100%')
    }
  }
}

[h2]Example 6: Displaying a Menu with a Custom Preview on Long Press

This example demonstrates how to display a menu with a custom preview by setting CustomBuilder of the preview property in responseType.LongPress and ContextMenuOptions for bindContextMenu.

@Entry
@Component
struct Index {
  // Replace $r('app.media.icon') with the image resource file you use.
  private iconStr: ResourceStr = $r("app.media.icon");

  @Builder
  MyMenu() {
    Menu() {
      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
    }
  }

  @Builder
  MyPreview() {
    Column() {
      Image($r('app.media.icon'))
        .width(200)
        .height(200)
    }
  }

  build() {
    Column({ space: 50 }) {
      Column() {
        Column() {
          Text('preview-builder')
            .width(200)
            .height(100)
            .textAlign(TextAlign.Center)
            .margin(100)
            .fontSize(30)
            .bindContextMenu(this.MyMenu, ResponseType.LongPress,
              {
                preview: this.MyPreview
              })
        }
      }.width('100%')
    }
  }
}

[h2]Example 7: Using a State Variable for Menu Visibility

This example demonstrates how to use bindContextMenu with isShown to control the visibility of the menu.

@Entry
@Component
struct Index {
  // Replace $r('app.media.icon') with the image resource file you use.
  private iconStr: ResourceStr = $r("app.media.icon");
  @State isShown: boolean = false;

  @Builder
  MyMenu() {
    Menu() {
      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
    }
  }

  @Builder
  MyPreview() {
    Column() {
      Image($r('app.media.icon'))
        .width(200)
        .height(200)
    }
  }

  build() {
    Column({ space: 50 }) {
      Column() {
        Column() {
          Text('preview-builder')
            .width(200)
            .height(100)
            .textAlign(TextAlign.Center)
            .margin(100)
            .fontSize(30)
            .bindContextMenu(this.isShown, this.MyMenu,
              {
                preview: this.MyPreview,
                aboutToDisappear: ()=>{
                  this.isShown = false;
                }
              })
          Button('click')
            .onClick(()=>{
              this.isShown = true;
            })
        }
      }.width('100%')
    }
  }
}

[h2]Example 8: Using Custom Menu and Preview Animations

This example demonstrates how implement custom entrance and exit animations for the menu and preview by setting the transition property in ContextMenuOptions of bindContextMenu.

@Entry
@Component
struct MenuExample {
  @Builder
  MenuBuilder() {
    Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
      Text('Menu item 1')
        .fontSize(12)
        .width(200)
        .height(30)
        .textAlign(TextAlign.Center)
      Divider().height(10)
      Text('Menu item 2')
        .fontSize(12)
        .width(100)
        .height(30)
        .textAlign(TextAlign.Center)
    }.width(100)
  }

  @Builder
  MyPreview() {
    Column() {
      // Replace $r('app.media.startIcon') with the image resource file you use.
      Image($r('app.media.startIcon'))
        .width(50)
        .height(50)
    }
  }

  build() {
    Column() {
      Button('LongPress bindContextMenu')
        .margin({ top: 15 })
        .bindContextMenu(
          this.MenuBuilder,
          ResponseType.LongPress, {
          transition: TransitionEffect.OPACITY.animation({ duration: 4000, curve: Curve.Ease }).combine(
            TransitionEffect.rotate({ z: 1, angle: 180 })),
          preview: this.MyPreview,
          previewAnimationOptions: {
            scale: [0.8, 1.0],
            transition: TransitionEffect.OPACITY.animation({ duration: 4000, curve: Curve.Ease }).combine(
              TransitionEffect.rotate({ z: 1, angle: 180 }))
          }
        })
    }
    .width('100%')
    .margin({ top: 5 })
  }
}

[h2]Example 9: Setting the Symbol Icon

This example shows how to display a menu with symbol icons by setting symbolIcon in MenuElement of bindMenu.

import { SymbolGlyphModifier } from '@kit.ArkUI';
@Entry
@Component
struct MenuExample {
  @State symbolIconModifier1: SymbolGlyphModifier = new SymbolGlyphModifier($r('sys.symbol.ohos_photo')).fontSize('24vp');
  @State symbolIconModifier2: SymbolGlyphModifier = new SymbolGlyphModifier($r('sys.symbol.ohos_photo')).fontSize('24vp');
  build() {
    Column() {
      Text('click for Menu')
    }
    .width('100%')
    .margin({ top: 5 })
    .bindMenu([
      {
        value: 'Menu1',
        symbolIcon:this.symbolIconModifier1,
        action: () => {
          console.info('handle Menu1 select');
        }
      },
      {
        value: 'Menu2',
        symbolIcon:this.symbolIconModifier2,
        action: () => {
          console.info('handle Menu2 select');
        }
      },
    ])
  }
}

[h2]Example 10: Using Shared Element Transition

This example demonstrates how to implement a shared element transition effect from the component screenshot to the custom preview by setting hoverScale of the previewAnimationOptions property in ContextMenuOptions for bindContextMenu.

@Entry
@Component
struct Index {
  // Replace $r('app.media.xxx') with the image resource file you use.
  private iconStr: ResourceStr = $r("app.media.app_icon");

  @Builder
  MyMenu() {
    Menu() {
      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
    }
  }

  @Builder
  MyPreview() {
    Column() {
      Image($r('app.media.example'))
        .width(200)
        .height(200)
    }
  }

  build() {
    Column({ space: 50 }) {
      Column() {
        Column() {
          Image($r('app.media.example'))
            .width(100)
            .height(100)
            .margin(100)
            .bindContextMenu(this.MyMenu, ResponseType.LongPress,
              {
                preview: this.MyPreview,
                previewAnimationOptions: {
                  hoverScale: [1.0, 0.95]
                }
              })
        }
      }.width('100%')
    }
  }
}

[h2]Example 11: Customizing the Background Blur Effect

This example demonstrates how to customize the background blur effect of a menu by setting the backgroundBlurStyleOptions property in ContextMenuOptions for bindMenu.

The backgroundBlurStyleOptions property is added to ContextMenuOptions since API version 18.

@Entry
@Component
struct MenuExample {
  build() {
    Stack() {
      // Replace $r('app.media.bg') with the image resource file you use.
      Image($r('app.media.bg'))
      Column() {
        Text('click for Menu')
          .bindMenu([
            {
              value: 'Menu1',
              action: () => {
                console.info('handle Menu1 select')
              }
            },
            {
              value: 'Menu2',
              action: () => {
                console.info('handle Menu2 select')
              }
            },
          ],
            {
              backgroundBlurStyle: BlurStyle.BACKGROUND_THIN,
              backgroundBlurStyleOptions: {
                colorMode: ThemeColorMode.LIGHT,
                blurOptions: { grayscale: [20, 20] },
                policy: BlurStyleActivePolicy.ALWAYS_ACTIVE,
                adaptiveColor: AdaptiveColor.AVERAGE,
                scale: 1
              },
            }
          )
      }
      .width('100%')
      .margin({ top: 5 })
    }
  }
}

[h2]Example 12: Customizing the Background Effect

This example demonstrates how to customize the background effect of a menu by setting the backgroundEffect property in ContextMenuOptions for bindMenu.

The backgroundEffect property is added to ContextMenuOptions since API version 18.

@Entry
@Component
struct MenuExample {
  build() {
    Stack() {
      // Replace $r('app.media.bg') with the image resource file you use.
      Image($r('app.media.bg'))
      Column() {
        Text('click for Menu')
          .bindMenu([
            {
              value: 'Menu1',
              action: () => {
                console.info('handle Menu1 select');
              }
            },
            {
              value: 'Menu2',
              action: () => {
                console.info('handle Menu2 select');
              }
            },
          ],
            {
              backgroundBlurStyle: BlurStyle.BACKGROUND_THIN,
              backgroundEffect: {
                radius: 60,
                saturation: 10,
                brightness: 1,
                color: '#661A1A1A',
                adaptiveColor: AdaptiveColor.AVERAGE,
                blurOptions:{grayscale:[20,20]}
              }
            }
          )
      }
      .width('100%')
      .margin({ top: 5 })
    }
  }
}

[h2]Example 13: Configuring Lift-Finger Interruption for a Shared Element Transition

This example demonstrates how to implement a shared element transition by setting the previewAnimationOptions property in ContextMenuOptions for bindContextMenu and how to control whether lifting the finger after a long press can cancel the menu pop-up by setting hoverScaleInterruption.

From API version 20, the hoverScaleInterruption property is added to the ContextMenuAnimationOptions type of previewAnimationOptions.

@Entry
@Component
struct Index {
  // Replace $r('app.media.xxx') with the image resource file you use.
  private iconStr: ResourceStr = $r("app.media.app_icon");

  @Builder
  MyMenu() {
    Menu() {
      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
    }
  }

  @Builder
  MyPreview() {
    Column() {
      Image($r('app.media.example'))
        .width(300)
        .height(200)
    }
  }

  build() {
    Column({ space: 50 }) {
      Column() {
        Column() {
          Image($r('app.media.example'))
            .width(100)
            .height(100)
            .margin(100)
            .bindContextMenu(this.MyMenu, ResponseType.LongPress,
              {
                preview: this.MyPreview,
                previewAnimationOptions: {
                  hoverScale: [1.0, 0.8],
                  hoverScaleInterruption: true
                }
              })
            .onClick(() => {
              console.info('trigger onClick')
            })
        }
      }.width('100%')
    }
  }
}

[h2]Example 14: Setting the Radius of the Rounded Corners of the Preview Image Border

This example demonstrates how to implement the function using bindContextMenu with responseType.LongPress set. In addition, the MenuPreviewMode type of the preview property in ContextMenuOptions is set to determine the menu preview mode. previewBorderRadius is set to implement the radius of the rounded corners of the preview image.

In API version 19, the previewBorderRadius property is added to ContextMenuOptions.

@Entry
@Component
struct Index {
  // Replace $r('app.media.startIcon') with the image resource file you use.
  private iconStr: ResourceStr = $r("app.media.startIcon");

  @Builder
  MyMenu() {
    Menu() {
      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
    }
  }

  build() {
    Column({ space: 50 }) {
      Column() {
        Column() {
          Text('preview-image')
            .width(200)
            .height(100)
            .textAlign(TextAlign.Center)
            .margin(100)
            .fontSize(30)
            .bindContextMenu(this.MyMenu, ResponseType.LongPress,
              {
                preview: MenuPreviewMode.IMAGE,
                previewBorderRadius: 50
              })
            .backgroundColor("#ff7fcdff")
        }
      }.width('100%')
    }
  }
}

[h2]Example 15: Configuring Lifecycle Callbacks for bindMenu

This sample shows how to configure lifecycle callbacks for bindMenu11+.

From API version 20, the onWillAppear, onDidAppear, onWillDisappear, and onDidDisappear properties are added to ContextMenuOptions.

@Entry
@Component
struct Index {
  // Replace $r('app.media.startIcon') with the image resource file you use.
  private iconStr: ResourceStr = $r("app.media.startIcon");
  @State isShown: boolean = false;
  @State textColor: Color = Color.Black;
  @State blueColor: Color = Color.Blue;
  @State onWillAppear: boolean = false;
  @State onDidAppear: boolean = false;
  @State onWillDisappear: boolean = false;
  @State onDidDisappear: boolean = false;

  @Builder
  MyMenu() {
    Menu() {
      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
    }
  }

  build() {
    Column() {
      Column({ space: 30 }) {
        Text('onWillAppear').fontColor(this.onWillAppear ? this.blueColor : this.textColor)
        Text('onDidAppear').fontColor(this.onDidAppear ? this.blueColor : this.textColor)
        Text('onWillDisappear').fontColor(this.onWillDisappear ? this.blueColor : this.textColor)
        Text('onDidDisappear').fontColor(this.onDidDisappear ? this.blueColor : this.textColor)
        Button('click')
          .onClick(() => {
            this.isShown = true;
          })
          .width(100)
          .height(50)
        Text('callback')
          .width(200)
          .height(100)
          .textAlign(TextAlign.Center)
          .fontSize(20)
          .fontColor(this.textColor)
          .bindMenu(this.isShown, this.MyMenu,
            {
              onWillAppear: () => {
                console.info("menu cycle life onWillAppear");
                this.onWillAppear = true;
              },
              onDidAppear: () => {
                console.info("menu cycle life onDidAppear");
                this.onDidAppear = true;
              },
              onWillDisappear: () => {
                this.isShown = false;
                console.info("menu cycle life onWillDisappear");
                this.onWillDisappear = true;
              },
              onDidDisappear: () => {
                console.info("menu cycle life onDidDisappear");
                this.onDidDisappear = true;
              }
            })
      }
    }.width('100%')
  }
}

[h2]Example 16: Setting the Menu Mask

This example demonstrates how to implement the menu mask using bindMenu with the mask property.

In API version 20, the mask property is added to ContextMenuOptions.

import { SymbolGlyphModifier } from '@kit.ArkUI';

@Entry
@Component
struct Index {
  @State startIconModifier: SymbolGlyphModifier = new SymbolGlyphModifier($r('sys.symbol.ohos_star'))
  @State isShow: boolean = false;

  @Builder
  MyMenu() {
    Menu() {
      MenuItem({
        symbolStartIcon: this.startIconModifier,
        content: "New folder",
      })
      MenuItem({
        symbolStartIcon: this.startIconModifier,
        content: "Sort by",
      })
      MenuItem({
        symbolStartIcon: this.startIconModifier,
        content: "View mode",
      })
    }
  }

  build() {
    Button('bindMenu')
      .position({ top: 80, left: 80 })
      .onClick(() => {
        this.isShow = !this.isShow;
      })
      .bindMenu(this.isShow, this.MyMenu, {
        mask: { color: 'rgba(23,169,141,0.5)', backgroundBlurStyle: BlurStyle.Thin }
      })
  }
}

[h2]Example 17: Setting the Outline Style of a Drop-Down Menu Using bindMenu

This example demonstrates how to set the outline style of the drop-down menu by setting the outlineWidth and outlineColor properties of bindMenu.

In API version 20, the outlineWidth and outlineColor properties are added to ContextMenuOptions.

@Entry
@Component
struct Index {
  @Builder
  MyMenu() {
    Menu() {
      MenuItem({ content: "Menu option" })
      MenuItem({ content: "Menu option" })
      MenuItem({ content: "Menu option" })
    }.width(200)
  }

  build() {
    Column({ space: 50 }) {
      Column() {
        Column() {
          Text('click for Menu')
            .width(200)
            .height(100)
            .textAlign(TextAlign.Center)
            .margin(100)
            .fontSize(30)
            .bindMenu(this.MyMenu,
              {
                outlineWidth: '5vp',
                outlineColor: Color.Blue
              })
        }
      }
      .width('100%')
      .height('100%')
      .backgroundColor('#F0F2F5')
    }
  }
}

[h2]Example 18: Passing a CustomBuilder with Parameters to bindMenu

This example demonstrates how to configure the properties of a menu by passing a CustomBuilder with parameters to bindMenu.

@Entry
@Component
struct Index {
  @State menuItemList: string[] = ['New', 'History', 'Bookmark', 'Settings']

  @Builder
  MenuBuilder(itemList: string[]) {
    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center }) {
      ForEach(itemList, (item: string, index) => {
        Row() {
          Text(item)
            .width('100%')
            .height(32)
            .fontWeight(400)
            .fontSize(14)
            .fontColor(Color.Black)
            .textAlign(TextAlign.Center)
        }
        .onClick(() => {
          console.info('handle' + item + 'Clicked!')
        })
        if (index != itemList.length - 1) {
          Divider().height(10).width('80%').color('#ccc')
        }
      })
    }
    .width(100)
  }

  build() {
    Column() {
      Text('click for Menu')
        .bindMenu(this.MenuBuilder(this.menuItemList))
    }
    .height('100%')
    .width('100%')
    .backgroundColor('#f0f0f0')
  }
}

[h2]Example 19: Displaying Different Menus Based on the Trigger Mode

This example demonstrates how to bind a menu to the target component by passing CustomBuilderT<ResponseType> to bindContextMenuWithResponse. The component returns the mode of triggering menu display in the UI function. You can implement differentiated display based on the returned trigger mode.

The bindContextMenuWithResponse API is added since API version 23.

@Entry
@Component
struct Index {
  @State longPress: string = 'LONG_PRESS';
  @State rightClick: string = 'RIGHT_CLICK';

  @Builder
  MenuBuilderWithParam(type: ResponseType) {
    Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
      Text('Current ResponseType = ' + (type === ResponseType.RightClick ? 'RIGHT_CLICK' : 'LONG_PRESS'))
      Divider().height(10)
      if (type === ResponseType.LongPress) {
        Text('Item: ' + this.longPress)
          .fontSize(20)
          .width(200)
          .height(20)
          .textAlign(TextAlign.Center)
      }
      if (type === ResponseType.RightClick) {
        Text('Item: ' + this.rightClick)
          .fontSize(20)
          .width(200)
          .height(20)
          .textAlign(TextAlign.Center)
      }
    }
  }

  build() {
    Stack() {
      Button ('BindContextMenu - Long Press and Right-Click to Trigger Menu')
        .bindContextMenuWithResponse(this.MenuBuilderWithParam, {
          enableArrow: true,
        })
    }
    .height('100%')
    .width('100%')
    .backgroundColor('#f0f0f0')
  }
}

[h2]Example 20: Setting the Menu to Avoid the Soft Keyboard

This example demonstrates how to configure the menu to avoid the soft keyboard by setting keyboardAvoidMode in bindMenu and set the minimum distance for avoiding the soft keyboard by setting minKeyboardAvoidDistance.

Starting from API version 23, the** keyboardAvoidMode** and minKeyboardAvoidDistance properties are added to ContextMenuOptions.

import { inputMethod } from '@kit.IMEKit';
import { LengthMetrics } from '@kit.ArkUI';

@Entry
@Component
struct Index {
  private inputController: inputMethod.InputMethodController = inputMethod.getController();

  @Builder
  MyMenu() {
    Menu() {
      MenuItem({ content: 'MenuItemContent' })
      MenuItem({ content: 'MenuItemContent' })
      MenuItem({ content: 'MenuItemContent' })
      MenuItem({ content: 'MenuItemContent' })
      MenuItem({ content: 'MenuItemContent' })
    }
  }

  build() {
    RelativeContainer() {
      Button('Click Show Menu')
        .alignRules({
          center: { anchor: '__container__', align: VerticalAlign.Center },
          middle: { anchor: '__container__', align: HorizontalAlign.Center },
        })
        .bindMenu(this.MyMenu, {
          keyboardAvoidMode: MenuKeyboardAvoidMode.TRANSLATE_AND_RESIZE,
          minKeyboardAvoidDistance: LengthMetrics.vp(20)
        })
        .onClick(() => {
          setTimeout(() => {
            this.attachAndListener()
          }, 2000)
        })
    }
    .height('100%')
    .width('100%')

  }

  async attachAndListener() {
    focusControl.requestFocus('Index')
    try {
      await this.inputController.attach(true, {
        inputAttribute: {
          textInputType: inputMethod.TextInputType.TEXT,
          enterKeyType: inputMethod.EnterKeyType.SEARCH
        }
      })
    } catch (err) {
      console.error('Fail to attach')
    }
  }
}

[h2]Example 21: Setting the Position of the Menu to Display Relative to the Upper Left Corner of the Bound Component

This example shows how to set the anchorPosition property in ContextMenuOptions to display the menu relative to the upper left corner of the bound component.

The anchorPosition property is added to ContextMenuOptions since API version 20.

@Entry
@Component
struct Index {
  // Replace $r('app.media.startIcon') with the image resource file you use.
  private iconStr: ResourceStr = $r('app.media.startIcon');
  @State isShown: boolean = false;

  @Builder
  MyMenu() {
    Menu() {
      MenuItem({ startIcon: this.iconStr, content: 'Menu option' })
      MenuItem({ startIcon: this.iconStr, content: 'Menu option' })
      MenuItem({ startIcon: this.iconStr, content: 'Menu option' })
    }
  }

  @State menuAnchorPositionIndex: number = 0;
  private menuAnchorPositionArray: Array<Position> = new Array<Position>(
    { x: 0, y: 0 },
    { x: 150, y: 0 },
    { x: 0, y: 150 },
    { x: 150, y: 150 },
  );

  build() {
    Column({ space: 50 }) {
      Column() {
        Column() {
          Text('Test Menu AnchorPosition')
            .width(500)
            .height(100)
            .textAlign(TextAlign.Center)
            .margin(100)
            .fontSize(30)
            .bindContextMenu(this.isShown, this.MyMenu,
              {
                anchorPosition: this.menuAnchorPositionArray[this.menuAnchorPositionIndex],
                aboutToDisappear: () => {
                  this.isShown = false;
                }
              })
          Button('click')
            .margin(5)
            .onClick(() => {
              this.isShown = true;
            })

          Button('AnchorPosition change')
            .margin(5)
            .onClick(() => {
              this.menuAnchorPositionIndex++;
              if (this.menuAnchorPositionIndex >= this.menuAnchorPositionArray.length) {
                this.menuAnchorPositionIndex = 0;
              }
            })
          Text('Current x: ' + this.menuAnchorPositionArray[this.menuAnchorPositionIndex]?.x +
            ' , y: ' + this.menuAnchorPositionArray[this.menuAnchorPositionIndex]?.y)
        }
      }.width('100%')
    }
  }
}

[h2]Example 22: Setting the Maximum Height of a Menu

This sample shows how to use the maxHeight attribute in ContextMenuOptions to set the maximum height of a menu.

If the maxHeight attribute is not set, the maximum height of the menu is 80% of the available height by default, and all list items can be displayed. If the maxHeight attribute is set to 50% of the available height, only eight list items can be displayed.

The maxHeight attribute is added to ContextMenuOptions as of API version 26.0.0.

import { LengthMetrics } from '@kit.ArkUI';

@Entry
@Component
struct Index {
  // Replace $r('app.media.startIcon') with the image resource file you use.
  private iconStr: ResourceStr = $r('app.media.startIcon');

  @Builder
  MyMenu() {
    Menu() {
      MenuItem({ startIcon: this.iconStr, content: 'MenuItem1' })
      MenuItem({ startIcon: this.iconStr, content: 'MenuItem2' })
      MenuItem({ startIcon: this.iconStr, content: 'MenuItem3' })
      MenuItem({ startIcon: this.iconStr, content: 'MenuItem4' })
      MenuItem({ startIcon: this.iconStr, content: 'MenuItem5' })
      MenuItem({ startIcon: this.iconStr, content: 'MenuItem6' })
      MenuItem({ startIcon: this.iconStr, content: 'MenuItem7' })
      MenuItem({ startIcon: this.iconStr, content: 'MenuItem8' })
      MenuItem({ startIcon: this.iconStr, content: 'MenuItem9' })
    }
  }

  build() {
    Column({ space: 50 }) {
      Column() {
        Column() {
          Text('LongPress-image')
            .width(200)
            .height(100)
            .textAlign(TextAlign.Center)
            .margin(100)
            .fontSize(30)
            .bindContextMenu(this.MyMenu, ResponseType.LongPress,
              {
                maxHeight: LengthMetrics.percent(50)
              })
            .backgroundColor('#ff7fcdff')
        }
      }.width('100%')
    }
  }
}

[h2]Example 23: Setting the Spacing Between the Menu and Target Component

This example describes how to increase the spacing between the menu and the target component by setting the targetSpace attribute in ContextMenuOptions.

The targetSpace attribute is added to ContextMenuOptions as of API version 26.0.0.

import { LengthMetrics } from '@kit.ArkUI';

@Entry
@Component
struct Alone {
  @Builder
  MyMenu() {
    Menu() {
      MenuItem({ startIcon: $r('app.media.startIcon'), content: 'Menu item 1' })
      MenuItem({ startIcon: $r('app.media.startIcon'), content: 'Menu item 2' })
      MenuItem({ startIcon: $r('app.media.startIcon'), content: 'menu option 3' })
    }
  }

  build() {
    Column() {
      Stack() {
        Column()
          .width(120 + 40 * 2)
          .height(120 + 40 * 2)
          .borderWidth(2)
          .borderColor(Color.Orange)
          .borderStyle(BorderStyle.Dotted)

        Image($r('app.media.startIcon'))
          .width(120)
          .height(120)
          .bindMenu(this.MyMenu,
            {
              targetSpace: LengthMetrics.vp(40)
            })
      }.height('75%')
      .width('100%')
    }
    .height('100%')
    .width('100%')
  }
}

[h2]Example 24: Setting the Immersive Light Effect of a Menu

This example sets the system material of a component through the systemMaterial attribute in ContextMenuOptions, implementing the immersive light effect of the menu. After the system material is set, nonlinear deformation and edge light flow occur during the menu popup process.

The illustration of this example shows the strong effect on a high-performance device. The immersive light effect of the component is adaptively adjusted based on the device computing power and the immersive light effect set by the user in the system, and you do not need to perform additional adaptation.

The systemMaterial attribute is added to ContextMenuOptions as of API version 26.0.0.

import { uiMaterial } from '@kit.ArkUI';

@Entry
@Component
struct Index {
  @Builder
  MyMenu() {
    Menu() {
      MenuItem({ startIcon: $r('app.media.startIcon'), content: 'Menu item' })
      MenuItem({ startIcon: $r('app.media.startIcon'), content: 'Menu item' })
      MenuItem({ startIcon: $r('app.media.startIcon'), content: 'Menu item' })
    }
  }

  build() {
    Stack() {
      Button('bindMenu with THICK material')
        .bindMenu(this.MyMenu, {
          systemMaterial: new uiMaterial.ImmersiveMaterial({
            style: uiMaterial.ImmersiveStyle.THICK
          })
        })
    }
    .height('100%')
    .width('100%')
    // Replace this with the actual resource file.
    .backgroundImage($r("app.media.img"))
  }
}

[h2]Example 25: Setting a Grid Menu Using gridStyle

This example shows how to use gridStyle to set the grid menu style in bindContextMenuByIsShow. You can customize the grid layout of the menu by setting the count, horizontalSize, and position attributes.

In API version 26.0.0 and later, the bindContextMenuByIsShow API is added, and the gridStyle attribute is added to ContextMenuOptions.

@Entry
@Component
struct ContextMenuGridStyleExample {
  @State isShown: boolean = false;

  @Builder
  MyMenu() {
   Menu() {
     MenuItem({ startIcon: $r('app.media.startIcon'), content: 'Copy')
     MenuItem({ startIcon: $r('app.media.startIcon'), content: 'Paste' })
     MenuItem({ startIcon: $r('app.media.startIcon'), content: 'Cut' })
     MenuItem({ startIcon: $r('app.media.startIcon'), content: 'Delete' })
     MenuItem({ startIcon: $r('app.media.startIcon'), content: 'Share' })
     MenuItem({ startIcon: $r('app.media.startIcon'), content: 'Select All' })
     MenuItem({ startIcon: $r('app.media.startIcon'), content: 'Translate' })
     MenuItem({ startIcon: $r('app.media.startIcon'), content: 'Favorite' })
   }
   .width(150)
  }

  build() {
    Column({ space: 20 }) {
      Text('bindContextMenuByIsShow grid menu')
        .fontSize(20)
        .bindContextMenuByIsShow(this.isShown, this.MyMenu, {
          gridStyle: {
            count: 4,
            horizontalSize: 3,
            position: MenuGridPosition.BOTTOM
          },
          onWillDisappear: () => {
            this.isShown = false;
          },
        })
        .onClick(() => {
          this.isShown = true;
        })
    }
    .width('100%')
    .margin({ top: 50 })
  }
}