• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Menu Control
2
3A context menu – a vertical list of items – can be bound to a component and displayed by long-pressing, clicking, or right-clicking the component.
4
5>  **NOTE**
6>
7>  - The APIs of this module are supported since API version 7. Updates will be marked with a superscript to indicate their earliest API version.
8>
9>  - **CustomBuilder** does not support the use of **bindMenu** and **bindContextMenu** methods. To display a multi-level menu, use the [Menu](ts-basic-components-menu.md) component instead.
10>
11>  - The text in the context menu cannot be selected by long-pressing.
12>
13>  - When the window size changes, the menu is automatically hidden.
14>
15>  - 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 the menu from responding to other events after it disappears.
16>
17>  - If a component is a draggable node and **bindContextMenu** is used without a preview specified, the menu will display a floating drag preview, and the menu options will not avoid the preview. To address this issue, you can set a preview or configure the target node to be non-draggable, based on the use case.
18>
19>  - 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.
20>
21>    1. This feature is only available in scenarios where the [Menu](ts-basic-components-menu.md) component is used and the child components include [MenuItem](ts-basic-components-menuitem.md) or [MenuItemGroup](ts-basic-components-menuitemgroup.md).
22>
23>    2. This feature is only available for menus with [MenuPreviewMode](#menupreviewmode11) set to **NONE**.
24
25
26## bindMenu
27
28bindMenu(content: Array<MenuElement&gt; | CustomBuilder, options?: MenuOptions)
29
30Binds a menu to this component, which is displayed when the user clicks the component. A menu item can be a combination of text and icons or a custom component.
31
32**Atomic service API**: This API can be used in atomic services since API version 11.
33
34**System capability**: SystemCapability.ArkUI.ArkUI.Full
35
36**Parameters**
37
38| Name | Type                                                        | Mandatory| Description                                        |
39| ------- | ------------------------------------------------------------ | ---- | -------------------------------------------- |
40| content | Array<[MenuElement](#menuelement)&gt; \| [CustomBuilder](ts-types.md#custombuilder8) | Yes  | Array of menu item icons and text, or custom component.|
41| options | [MenuOptions](#menuoptions10)                                | No  | Parameters of the context menu.                        |
42
43## bindMenu<sup>11+</sup>
44
45bindMenu(isShow: boolean, content: Array<MenuElement&gt; | CustomBuilder, options?: MenuOptions)
46
47Binds a menu to this component, which is displayed when the user clicks the component. A menu item can be a combination of text and icons or a custom component.
48
49**Atomic service API**: This API can be used in atomic services since API version 12.
50
51**System capability**: SystemCapability.ArkUI.ArkUI.Full
52
53**Parameters**
54
55| Name              | Type                                                        | Mandatory| Description                                                        |
56| -------------------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ |
57| isShow<sup>11+</sup> | boolean                                                      | Yes  | Whether to show the menu. The default value is **false**. The menu can be displayed only after the entire page is fully constructed. Therefore, to avoid incorrect display positions and shapes, do not set this parameter to **true** while the page is still being constructed.|
58| content              | Array<[MenuElement](#menuelement)&gt; \| [CustomBuilder](ts-types.md#custombuilder8) | Yes  | Array of menu item icons and text, or custom component.                |
59| options              | [MenuOptions](#menuoptions10)                                | No  | Parameters of the context menu.                                        |
60
61## bindContextMenu<sup>8+</sup>
62
63bindContextMenu(content: CustomBuilder, responseType: ResponseType, options?: ContextMenuOptions)
64
65Binds a context menu to this component, which is displayed when the user long-presses or right-clicks the component. Only custom menu items are supported.
66
67**Atomic service API**: This API can be used in atomic services since API version 11.
68
69**System capability**: SystemCapability.ArkUI.ArkUI.Full
70
71**Parameters**
72
73| Name      | Type                                              | Mandatory| Description                            |
74| ------------ | -------------------------------------------------- | ---- | -------------------------------- |
75| content      | [CustomBuilder](ts-types.md#custombuilder8)        | Yes  | Builder of the custom menu content.          |
76| responseType | [ResponseType](ts-appendix-enums.md#responsetype8) | Yes  | How the context menu is triggered, which can be long-press or right-click. Long pressing with a mouse device is not supported.|
77| options      | [ContextMenuOptions](#contextmenuoptions10)        | No  | Parameters of the context menu.            |
78
79## bindContextMenu<sup>12+</sup>
80
81bindContextMenu(isShown: boolean, content: CustomBuilder, options?: ContextMenuOptions)
82
83Binds a context menu to the component, whose visibility is subject to the **isShown** settings.
84
85If **isShown** is **true**, the menu is displayed. If **isShown** is set to **false**, the menu is hidden. The menu items need to be customized.
86
87The position of the context menu is subject to the **placement** settings, rather than where the component is clicked.
88
89
90**System capability**: SystemCapability.ArkUI.ArkUI.Full
91
92**Atomic service API**: This API can be used in atomic services since API version 11.
93
94**Parameters**
95
96| Name      | Type                                              | Mandatory| Description                                        |
97| ------------ | -------------------------------------------------- | ---- | -------------------------------------------- |
98| isShown | boolean | Yes  | Whether to show the context menu. The value **true** means to show the context menu, and **false** (default) means the opposite. 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](../../../quick-start/arkts-new-binding.md).|
99| content      | [CustomBuilder](ts-types.md#custombuilder8)        | Yes  | Builder of the custom menu content.|
100| options      | [ContextMenuOptions](#contextmenuoptions10)                      | No  | Parameters of the context menu.                        |
101
102## MenuElement
103
104| Name                 | Type                                  | Mandatory| Description                                                        |
105| --------------------- | -------------------------------------- | ---- | ------------------------------------------------------------ |
106| value                 | [ResourceStr](ts-types.md#resourcestr) | Yes  | Menu item text.<br>**Atomic service API**: This API can be used in atomic services since API version 11.                                                |
107| icon<sup>10+</sup>    | [ResourceStr](ts-types.md#resourcestr) | No  | Menu item icon.<br>**Atomic service API**: This API can be used in atomic services since API version 11.                                                |
108| enabled<sup>11+</sup> | boolean                                | No  | Whether to enable interactions with the menu item.<br>Default value: **true**, indicating that interactions with the menu item are enabled.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
109| action                | () =&gt; void                | Yes  | Action triggered when a menu item is clicked.<br>**Atomic service API**: This API can be used in atomic services since API version 11.                                      |
110| symbolIcon<sup>12+</sup>                | [SymbolGlyphModifier](ts-universal-attributes-attribute-modifier.md)                | No  | Icon of a menu item. When this parameter is set, the original icon is not displayed.<br>**Atomic service API**: This API can be used in atomic services since API version 12.                                      |
111
112## MenuOptions<sup>10+</sup>
113
114Inherits from [ContextMenuOptions](#contextmenuoptions10).
115
116| Name                         | Type                                  | Mandatory| Description                                                        |
117| ----------------------------- | -------------------------------------- | ---- | ------------------------------------------------------------ |
118| title                         | [ResourceStr](ts-types.md#resourcestr) | No  | Menu title.<br>**NOTE**<br>This parameter is effective only when **content** is set to Array<[MenuElement](#menuelement)>.<br>**Atomic service API**: This API can be used in atomic services since API version 11.|
119| showInSubWindow<sup>11+</sup> | boolean                                | No  | Whether to show the menu in a subwindow.<br>Default value: **true** for 2-in-1 devices and **false** for other devices<br>**Atomic service API**: This API can be used in atomic services since API version 12.                    |
120
121## ContextMenuOptions<sup>10+</sup>
122
123| Name                 | Type                                                        | Mandatory| Description                                                        |
124| --------------------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ |
125| offset                | [Position](ts-types.md#position)                            | No  | Offset for showing the context menu, which should not cause the menu to extend beyond the screen.<br>Default value: **{x:0, y:0}**<br>**NOTE**<br>When the menu is displayed relative to the parent component area, the width or height of the area is automatically counted into the offset based on the **placement** attribute of the menu.<br>When the menu is displayed above the parent component (that is, **placement** is set to **Placement.TopLeft**, **Placement.Top**, or **Placement.TopRight**), a positive value of **x** indicates rightward movement relative to the parent component, and a positive value of **y** indicates upward movement.<br>When the menu is displayed below the parent component (that is, **placement** is set to **Placement.BottomLeft**, **Placement.Bottom**, or **Placement.BottomRight**), a positive value of **x** indicates rightward movement relative to the parent component, and a positive value of **y** indicates downward movement.<br>When the menu is displayed on the left of the parent component (that is, **placement** is set to **Placement.LeftTop**, **Placement.Left**, or **Placement.LeftBottom**), a positive value of **x** indicates leftward movement relative to the parent component, and a positive value of **y** indicates downward movement.<br>When the menu is displayed on the right of the parent component (that is, **placement** is set to **Placement.RightTop**, **Placement.Right**, or **Placement.RightBottom**), a positive value of **x** indicates rightward movement relative to the parent component, and a positive value of **y** indicates downward movement.<br>If the display position of the menu is adjusted (different from the main direction of the initial **placement** value), the offset value is invalid.<br>**Atomic service API**: This API can be used in atomic services since API version 11.|
126| placement             | [Placement](ts-appendix-enums.md#placement8)                 | No  | Preferred position of the context menu. If the set position is insufficient for holding the component, it will be automatically adjusted.<br>**NOTE**<br>Setting **placement** to **undefined** or **null** is equivalent to not setting it at all. In this case, if [bindMenu](#bindmenu11) is used, the default value of **placement** is **Placement.BottomLeft**; if [bindContextMenu<sup>8+</sup>](#bindcontextmenu8) is used, the menu is displayed at the touched position; if [bindContextMenu<sup>12+</sup>](#bindcontextmenu12) is used, the default value is **Placement.BottomLeft**.<br>**Atomic service API**: This API can be used in atomic services since API version 11.|
127| enableArrow           | boolean                                                      | No  | Whether to display an arrow. If the size and position of the context menu are insufficient for holding an arrow, no arrow is displayed.<br>Default value: **false**, indicating that no arrow is displayed<br>**NOTE**<br>When **enableArrow** is **true**, an arrow is displayed in the position specified by **placement**. If **placement** is not set or its value is invalid, the arrow is displayed above the target. If the position is insufficient for holding the arrow, it is automatically adjusted. When **enableArrow** is **undefined**, no arrow is displayed. This API is supported in **bindContextMenu** since API version 10 and **bindMenu** since API version 12.<br>**Atomic service API**: This API can be used in atomic services since API version 11.|
128| arrowOffset           | [Length](ts-types.md#length)                                 | No  | 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.<br>Default value: **0**<br>Unit: vp<br>**NOTE**<br>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.<br>The value of **placement** determines whether the offset is horizontal or vertical.<br>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.<br>The default position where the arrow is displayed varies with the value of **placement**:<br>Without any avoidance by the menu, when **placement** is set to **Placement.Top** or **Placement.Bottom**, the arrow is displayed horizontally and is centered by default;<br>when **placement** is set to **Placement.Left** or **Placement.Right**, the arrow is displayed vertically and is centered by default;<br>when **placement** is set to **Placement.TopLeft** or **Placement.BottomLeft**, the arrow is displayed horizontally by default, and the distance from the arrow to the left edge of the menu is the arrow's safe distance;<br>when **placement** is set to **Placement.TopRight** or **Placement.BottomRight**, the arrow is displayed horizontally by default, and the distance from the arrow to the right edge of the menu is the arrow's safe distance;<br>when **placement** is set to **Placement.LeftTop** or **Placement.RightTop**, the arrow is displayed vertically by default, and the distance from the arrow to the top edge of the menu is the arrow's safe distance;<br>when **placement** is set to **Placement.LeftBottom** or **Placement.RightBottom**, the arrow is displayed vertically by default, and the distance from the arrow to the bottom edge of the menu is the arrow's safe distance.<br>  This API is supported in **bindContextMenu** since API version 10 and **bindMenu** since API version 12.<br>**Atomic service API**: This API can be used in atomic services since API version 11.|
129| preview<sup>11+</sup> | [MenuPreviewMode](#menupreviewmode11)\| [CustomBuilder](ts-types.md#custombuilder8) | No  | Preview displayed when the context menu is triggered by a long-press or by calling [bindContextMenu<sup>12+</sup>](#bindcontextmenu12). It can be a screenshot of the target component or custom content.<br>Default value: **MenuPreviewMode.NONE**, indicating no preview.<br>**NOTE**<br>- This parameter has no effect when **responseType** is set to **ResponseType.RightClick**.<br>- If **preview** is set to **MenuPreviewMode.NONE** or is not set, the **enableArrow** parameter is effective.<br>- If **preview** is set to **MenuPreviewMode.IMAGE** or **CustomBuilder**, no arrow will be displayed even when **enableArrow** is **true**.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
130| previewAnimationOptions<sup>11+</sup> | [ContextMenuAnimationOptions](#contextmenuanimationoptions11) | No   | Start scale ratio and end scale ratio (relative to the original preview image) of the preview animation displayed when the component is long pressed<br>Default value: **{ scale: [0.95, 1.1], transition: undefined, hoverScale: undefined }**<br>**NOTE**<br>If the value is less than or equal to 0, this API does not take effect.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
131| onAppear              | () =&gt; void                                      | No  | Callback triggered when the menu is displayed.<br>**Atomic service API**: This API can be used in atomic services since API version 11.                                      |
132| onDisappear           | () =&gt; void                                      | No  | Callback triggered when the menu is hidden.<br>**Atomic service API**: This API can be used in atomic services since API version 11.                                      |
133| aboutToAppear              | () =&gt; void                                      | No  | Callback triggered when the menu is about to appear.<br>**Atomic service API**: This API can be used in atomic services since API version 12.                                      |
134| aboutToDisappear           | () =&gt; void                                      | No  | Callback triggered when the menu is about to disappear.<br>**Atomic service API**: This API can be used in atomic services since API version 12.                                      |
135| backgroundColor<sup>11+</sup> | [ResourceColor](ts-types.md#resourcecolor)  | No| Backplane color of the dialog box.<br>Default value: **Color.Transparent**<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
136| backgroundBlurStyle<sup>11+</sup> | [BlurStyle](ts-universal-attributes-background.md#blurstyle9) | No| Background blur style of the dialog box.<br>Default value: **BlurStyle.COMPONENT_ULTRA_THICK**<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
137| transition<sup>12+</sup> | [TransitionEffect](ts-transition-animation-component.md#transitioneffect10)| No  | Transition effect for the entrance and exit of the menu.<br>**NOTE**<br>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.<br>For details, see [TransitionEffect](ts-transition-animation-component.md#transitioneffect10).<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
138| borderRadius<sup>12+</sup>  | [Length](ts-types.md#length) \| [BorderRadiuses](ts-types.md#borderradiuses9) \| [LocalizedBorderRadiuses](ts-types.md#localizedborderradiuses12) | No  | Border radius of the menu.<br>Default value: **8vp** for 2-in-1 devices and **20vp** for other devices<br>**NOTE**<br> The value can be in percentage.<br>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.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
139| layoutRegionMargin<sup>13+</sup>  | [Margin](ts-types.md#margin) | No  | Minimum margin between the preview and menu layout for top, bottom, left, and right edges.<br>**NOTE**<br> Only vp, px, fp, lpx, and percentage units are supported.<br> Any abnormal or negative values will be treated as the default values.<br> If **preview** is set to **CustomBuilder**, setting **margin.left** or **margin.right** will remove the maximum grid width restriction for the preview.<br> 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.<br>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.<br> If the sum of vertical margins exceeds the maximum layout width, **margin.top** and **margin.bottom** will be ignored and default values will be applied.<br>**Atomic service API**: This API can be used in atomic services since API version 13.|
140
141## MenuPreviewMode<sup>11+</sup>
142
143**Atomic service API**: This API can be used in atomic services since API version 12.
144
145**System capability**: SystemCapability.ArkUI.ArkUI.Full
146
147| Name | Description                                  |
148| ----- | -------------------------------------- |
149| NONE  | No preview is displayed.                      |
150| IMAGE | The preview is a screenshot of the component on which a long-press triggers the context menu.|
151
152## ContextMenuAnimationOptions<sup>11+</sup>
153
154**Atomic service API**: This API can be used in atomic services since API version 12.
155
156| Name | Type                                      | Mandatory| Description                                |
157| ----- | ------------------------------------------ | ---- | ------------------------------------ |
158| scale | [AnimationRange](#animationrange11)\<number> | No  | Relative scale ratio at the start and end of the animation compared to the original preview image.<br>**NOTE**<br>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.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
159| transition<sup>12+</sup> | [TransitionEffect](ts-transition-animation-component.md#transitioneffect10)| No  | Transition effect for the entrance and exit of the menu.<br>**NOTE**<br>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.<br>For details, see [TransitionEffect](ts-transition-animation-component.md#transitioneffect10).|
160| hoverScale<sup>12+</sup> | [AnimationRange](#animationrange11)\<number> | No  | Sets the scale ratio of the original component snapshot to the preview image at the beginning and end of the scale animation in a custom long press scenario. There is a transition animation for the switch with the preview image.<br>**NOTE**<br> If the value is less than or equal to 0, this API does not take effect.<br>This API does not take effect in [bindContextMenu<sup>12+</sup>](#bindcontextmenu12) scenarios.<br> This API does not take effect when **transition** is set.<br> If this API and the **scale** API are used at the same time, the start value of the **scale** API does not take effect.<br> To ensure the optimal experience, it is not recommended that the final preview image size be smaller than the size of the original component snapshot. The width and height of the preview animation are affected by the component snapshot and the custom preview size. Verify the display effect based on the actual use case.|
161
162## AnimationRange<sup>11+</sup>
163
164Describes the scale ratio relative to the preview image at the beginning and end of the scale animation.
165
166**System capability**: SystemCapability.ArkUI.ArkUI.Full
167
168**Atomic service API**: This API can be used in atomic services since API version 12.
169
170| Value Range        | Description                                                                          |
171| ---------------- | ------------------------------------------------------------------------------ |
172| [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.|
173
174## Example
175
176### Example 1: Displaying a Basic Menu
177
178This example demonstrates how to use **bindMenu** to display a basic menu using **MenuElement**.
179
180```ts
181// xxx.ets
182@Entry
183@Component
184struct MenuExample {
185  build() {
186    Column() {
187      Text('click for Menu')
188        .bindMenu([
189          {
190            value: 'Menu1',
191            action: () => {
192              console.info('handle Menu1 select')
193            }
194          },
195          {
196            value: 'Menu2',
197            action: () => {
198              console.info('handle Menu2 select')
199            }
200          },
201        ])
202    }
203    .width('100%')
204    .margin({ top: 5 })
205  }
206}
207```
208
209![en_image_0000001174582862](figures/en_image_0000001174582862.gif)
210
211### Example 2: Displaying a Custom Menu
212
213This example shows how to use **bindMenu** with a custom builder to create a custom menu.
214
215```ts
216@Entry
217@Component
218struct MenuExample {
219  @State listData: number[] = [0, 0, 0]
220
221  @Builder MenuBuilder() {
222    Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
223      ForEach(this.listData, (item:number, index) => {
224        Column() {
225          Row() {
226            Image($r("app.media.icon")).width(20).height(20).margin({ right: 5 })
227            Text(`Menu${index as number + 1}`).fontSize(20)
228          }
229          .width('100%')
230          .height(30)
231          .justifyContent(FlexAlign.Center)
232          .align(Alignment.Center)
233          .onClick(() => {
234            console.info(`Menu${index as number + 1} Clicked!`)
235          })
236
237          if (index != this.listData.length - 1) {
238            Divider().height(10).width('80%').color('#ccc')
239          }
240        }.padding(5).height(40)
241      })
242    }.width(100)
243  }
244
245  build() {
246    Column() {
247      Text('click for menu')
248        .fontSize(20)
249        .margin({ top: 20 })
250        .bindMenu(this.MenuBuilder)
251    }
252    .height('100%')
253    .width('100%')
254    .backgroundColor('#f0f0f0')
255  }
256}
257```
258
259![en_image_0000001186807708](figures/en_image_0000001186807708.gif)
260
261### Example 3: Displaying a Menu on Long Press
262
263This example demonstrates how to use **bindContextMenu** with **ResponseType.LongPress** to display a menu on long press.
264
265```ts
266// xxx.ets
267@Entry
268@Component
269struct ContextMenuExample {
270  @Builder MenuBuilder() {
271    Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
272      Text('Test menu item 1')
273        .fontSize(20)
274        .width(100)
275        .height(50)
276        .textAlign(TextAlign.Center)
277      Divider().height(10)
278      Text('Test menu item 2')
279        .fontSize(20)
280        .width(100)
281        .height(50)
282        .textAlign(TextAlign.Center)
283    }.width(100)
284  }
285
286  build() {
287    Column() {
288      Text('LongPress for menu')
289    }
290    .width('100%')
291    .margin({ top: 5 })
292    .bindContextMenu(this.MenuBuilder, ResponseType.LongPress)
293  }
294}
295```
296
297![longMenu](figures/longMenu.gif)
298
299### Example 4: Displaying a Menu with an Arrow on Right-Clicking
300
301This example shows how to use **bindContextMenu** with **ResponseType.RightClick** and **enableArrow** to display a menu with an arrow on right-clicking.
302
303```ts
304// xxx.ets
305@Entry
306@Component
307struct DirectiveMenuExample {
308  @Builder MenuBuilder() {
309    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
310      Text('Options')
311      Divider().strokeWidth(2).margin(5).color('#F0F0F0')
312      Text('Hide')
313      Divider().strokeWidth(2).margin(5).color('#F0F0F0')
314      Text('Exit')
315    }
316    .width(200)
317  }
318
319  build() {
320    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
321      Column() {
322        Text("DirectiveMenuExample")
323          .fontSize(20)
324          .width('100%')
325          .height("25%")
326          .backgroundColor('#F0F0F0')
327          .textAlign(TextAlign.Center)
328          .bindContextMenu(this.MenuBuilder, ResponseType.RightClick, {
329            enableArrow: true,
330            placement: Placement.Bottom
331          })
332      }
333    }
334    .width('100%')
335    .height('100%')
336  }
337}
338```
339
340![en-us_image_0000001689126950](figures/en-us_image_0000001689126950.png)
341
342### Example 5: Displaying a Menu with a Screenshot Preview on Long Press
343
344This example demonstrates how to use **bindContextMenu** with **ResponseType.LongPress** and **MenuPreviewMode.IMAGE** to display a menu with a screenshot preview on long pressure.
345
346```ts
347// xxx.ets
348@Entry
349@Component
350struct Index {
351  private iconStr: ResourceStr = $r("app.media.icon")
352
353  @Builder
354  MyMenu() {
355    Menu() {
356      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
357      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
358      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
359    }
360  }
361
362  build() {
363    Column({ space: 50 }) {
364      Column() {
365        Column() {
366          Text('preview-image')
367            .width(200)
368            .height(100)
369            .textAlign(TextAlign.Center)
370            .margin(100)
371            .fontSize(30)
372            .bindContextMenu(this.MyMenu, ResponseType.LongPress,
373              { preview: MenuPreviewMode.IMAGE,
374                previewAnimationOptions: {scale: [0.8, 1.0]},
375              })
376            .backgroundColor("#ff3df2f5")
377        }
378      }.width('100%')
379    }
380  }
381}
382```
383
384![preview-image](figures/preview-image.png)
385
386### Example 6: Displaying a Menu with a Custom Preview on Long Press
387
388This example shows how to use **bindContextMenu** with **ResponseType.LongPress** and a custom preview builder to display a menu with a custom preview on long pressure.
389
390```ts
391// xxx.ets
392@Entry
393@Component
394struct Index {
395  private iconStr: ResourceStr = $r("app.media.icon")
396
397  @Builder
398  MyMenu() {
399    Menu() {
400      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
401      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
402      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
403    }
404  }
405
406  @Builder
407  MyPreview() {
408    Column() {
409      Image($r('app.media.icon'))
410        .width(200)
411        .height(200)
412    }
413  }
414
415  build() {
416    Column({ space: 50 }) {
417      Column() {
418        Column() {
419          Text('preview-builder')
420            .width(200)
421            .height(100)
422            .textAlign(TextAlign.Center)
423            .margin(100)
424            .fontSize(30)
425            .bindContextMenu(this.MyMenu, ResponseType.LongPress,
426              {
427                preview: this.MyPreview
428              })
429        }
430      }.width('100%')
431    }
432  }
433}
434```
435
436![preview-builder](figures/preview-builder.png)
437
438### Example 7: Using a State Variable for Menu Visibility
439
440This example demonstrates how to use **bindContextMenu** with a state variable to control the visibility of the menu.
441
442```ts
443// xxx.ets
444@Entry
445@Component
446struct Index {
447  private iconStr: ResourceStr = $r("app.media.icon")
448  @State isShown: boolean = false
449
450  @Builder
451  MyMenu() {
452    Menu() {
453      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
454      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
455      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
456    }
457  }
458
459  @Builder
460  MyPreview() {
461    Column() {
462      Image($r('app.media.icon'))
463        .width(200)
464        .height(200)
465    }
466  }
467
468  build() {
469    Column({ space: 50 }) {
470      Column() {
471        Column() {
472          Text('preview-builder')
473            .width(200)
474            .height(100)
475            .textAlign(TextAlign.Center)
476            .margin(100)
477            .fontSize(30)
478            .bindContextMenu(this.isShown, this.MyMenu,
479              {
480                preview: this.MyPreview,
481                onDisappear: ()=>{
482                    this.isShown = false;
483                }
484              })
485          Button('click')
486            .onClick(()=>{
487                this.isShown = true;
488             })
489        }
490      }.width('100%')
491    }
492  }
493}
494```
495
496### Example 8: Using Custom Menu and Preview Animations
497
498This example demonstrates how to use **bindContextMenu** with custom animations for the menu and preview.
499
500```ts
501// xxx.ets
502@Entry
503@Component
504struct MenuExample {
505  @Builder MenuBuilder() {
506    Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
507      Text('Test menu item 1')
508        .fontSize(12)
509        .width(200)
510        .height(30)
511        .textAlign(TextAlign.Center)
512      Divider().height(10)
513      Text('Test menu item 2')
514        .fontSize(12)
515        .width(100)
516        .height(30)
517        .textAlign(TextAlign.Center)
518    }.width(100)
519  }
520  @Builder
521  MyPreview() {
522    Column() {
523      Image($r('app.media.icon'))
524        .width(50)
525        .height(50)
526    }
527  }
528  @State isShow:boolean = false
529  private iconStr: ResourceStr = $r("app.media.icon")
530
531  @Builder
532  MyMenu() {
533    Menu() {
534      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
535      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
536      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
537    }
538  }
539  build() {
540    Column() {
541      Button('LongPress bindContextMenu')
542        .margin({ top: 15 })
543        .bindContextMenu(
544          this.MenuBuilder,
545          ResponseType.LongPress,{
546          transition: TransitionEffect.OPACITY.animation({ duration: 4000, curve: Curve.Ease }).combine(
547            TransitionEffect.rotate({ z: 1, angle: 180 })),
548          preview: this.MyPreview,
549          previewAnimationOptions: {
550            scale: [0.8, 1.0],
551            transition: TransitionEffect.OPACITY.animation({ duration: 4000, curve: Curve.Ease }).combine(
552              TransitionEffect.rotate({ z: 1, angle: 180 }))
553          }
554        })
555    }
556    .width('100%')
557    .margin({ top: 5 })
558  }
559}
560```
561
562![preview-builder](figures/menu2.gif)
563
564### Example 9: Setting the Symbol Icon
565
566This example shows how to use **bindMenu** with **symbolIcon** to display a menu with symbol icons.
567
568```ts
569// xxx.ets
570import { SymbolGlyphModifier } from '@kit.ArkUI';
571@Entry
572@Component
573struct MenuExample {
574  @State symbolIconModifier1: SymbolGlyphModifier = new SymbolGlyphModifier($r('sys.symbol.ohos_photo')).fontSize('24vp');
575  @State symbolIconModifier2: SymbolGlyphModifier = new SymbolGlyphModifier($r('sys.symbol.ohos_photo')).fontSize('24vp');
576  build() {
577    Column() {
578      Text('click for Menu')
579    }
580    .width('100%')
581    .margin({ top: 5 })
582    .bindMenu([
583      {
584        value: 'Menu1',
585        symbolIcon:this.symbolIconModifier1,
586        action: () => {
587          console.info('handle Menu1 select')
588        }
589      },
590      {
591        value: 'Menu2',
592        symbolIcon:this.symbolIconModifier2,
593        action: () => {
594          console.info('handle Menu2 select')
595        }
596      },
597    ])
598  }
599}
600```
601
602![zh-cn_image_0000001174582862](figures/preview-symbol.jpeg)
603
604### Example 10: Using Shared Element Transition
605
606This example demonstrates how to use **bindContextMenu** with **hoverScale** to create a shared element transition effect from the component screenshot to the custom preview.
607
608```ts
609// xxx.ets
610@Entry
611@Component
612struct Index {
613  private iconStr: ResourceStr = $r("app.media.app_icon")
614
615  @Builder
616  MyMenu() {
617    Menu() {
618      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
619      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
620      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
621    }
622  }
623
624  @Builder
625  MyPreview() {
626    Column() {
627      Image($r('app.media.example'))
628        .width(200)
629        .height(200)
630    }
631  }
632
633  build() {
634    Column({ space: 50 }) {
635      Column() {
636        Column() {
637          Image($r('app.media.example'))
638            .width(100)
639            .height(100)
640            .margin(100)
641            .bindContextMenu(this.MyMenu, ResponseType.LongPress,
642              {
643                preview: this.MyPreview,
644                previewAnimationOptions: {
645                  hoverScale: [1.0, 0.95]
646                }
647              })
648        }
649      }.width('100%')
650    }
651  }
652}
653```
654
655![preview-builder](figures/hoverScale.gif)
656