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, a 500 ms long-press on the menu reveals submenus.
20>
21>  - Since API version 12, the pressed state of the menu follows finger movement.
22>
23>    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).
24>
25>    2. This feature is only available for menus with [MenuPreviewMode](#menupreviewmode11) set to **NONE**.
26
27
28## bindMenu
29
30bindMenu(content: Array<MenuElement&gt; | CustomBuilder, options?: MenuOptions)
31
32Binds 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.
33
34**Atomic service API**: This API can be used in atomic services since API version 11.
35
36**System capability**: SystemCapability.ArkUI.ArkUI.Full
37
38**Parameters**
39
40| Name | Type                                                        | Mandatory| Description                                        |
41| ------- | ------------------------------------------------------------ | ---- | -------------------------------------------- |
42| content | Array<[MenuElement](#menuelement)&gt; \| [CustomBuilder](ts-types.md#custombuilder8) | Yes  | Array of menu item icons and text, or custom component.|
43| options | [MenuOptions](#menuoptions10)                                | No  | Parameters of the context menu.                        |
44
45## bindMenu<sup>11+</sup>
46
47bindMenu(isShow: boolean, content: Array<MenuElement&gt; | CustomBuilder, options?: MenuOptions)
48
49Binds 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.
50
51**Atomic service API**: This API can be used in atomic services since API version 12.
52
53**System capability**: SystemCapability.ArkUI.ArkUI.Full
54
55**Parameters**
56
57| Name              | Type                                                        | Mandatory| Description                                                        |
58| -------------------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ |
59| 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.|
60| content              | Array<[MenuElement](#menuelement)&gt; \| [CustomBuilder](ts-types.md#custombuilder8) | Yes  | Array of menu item icons and text, or custom component.                |
61| options              | [MenuOptions](#menuoptions10)                                | No  | Parameters of the context menu.                                        |
62
63## bindContextMenu<sup>8+</sup>
64
65bindContextMenu(content: CustomBuilder, responseType: ResponseType, options?: ContextMenuOptions)
66
67Binds 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.
68
69**Atomic service API**: This API can be used in atomic services since API version 11.
70
71**System capability**: SystemCapability.ArkUI.ArkUI.Full
72
73**Parameters**
74
75| Name      | Type                                              | Mandatory| Description                            |
76| ------------ | -------------------------------------------------- | ---- | -------------------------------- |
77| content      | [CustomBuilder](ts-types.md#custombuilder8)        | Yes  | Builder of the custom menu content.          |
78| 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.|
79| options      | [ContextMenuOptions](#contextmenuoptions10)        | No  | Parameters of the context menu.            |
80
81## bindContextMenu<sup>12+</sup>
82
83bindContextMenu(isShown: boolean, content: CustomBuilder, options?: ContextMenuOptions)
84
85Binds a context menu to the component, whose visibility is subject to the **isShown** settings.
86
87If **isShown** is **true**, the menu is displayed. If **isShown** is set to **false**, the menu is hidden. The menu items need to be customized.
88
89The position of the context menu is subject to the **placement** settings, rather than where the component is clicked.
90
91
92**System capability**: SystemCapability.ArkUI.ArkUI.Full
93
94**Atomic service API**: This API can be used in atomic services since API version 11.
95
96**Parameters**
97
98| Name      | Type                                              | Mandatory| Description                                        |
99| ------------ | -------------------------------------------------- | ---- | -------------------------------------------- |
100| 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).|
101| content      | [CustomBuilder](ts-types.md#custombuilder8)        | Yes  | Builder of the custom menu content.|
102| options      | [ContextMenuOptions](#contextmenuoptions10)                      | No  | Parameters of the context menu.                        |
103
104## MenuElement
105
106| Name                 | Type                                  | Mandatory| Description                                                        |
107| --------------------- | -------------------------------------- | ---- | ------------------------------------------------------------ |
108| 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.                                                |
109| 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.                                                |
110| 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.|
111| 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.                                      |
112| 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.                                      |
113
114## MenuOptions<sup>10+</sup>
115
116Inherits from [ContextMenuOptions](#contextmenuoptions10).
117
118| Name                         | Type                                  | Mandatory| Description                                                        |
119| ----------------------------- | -------------------------------------- | ---- | ------------------------------------------------------------ |
120| 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.|
121| 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.                    |
122
123## ContextMenuOptions<sup>10+</sup>
124
125| Name                 | Type                                                        | Mandatory| Description                                                        |
126| --------------------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ |
127| 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.|
128| 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.|
129| 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.|
130| enableHoverMode<sup>13+</sup>      | boolean                                                      | No  | Whether to enable the hover mode, that is, whether the menu responds in hover mode. When its touched position is within the crease region of the foldable device, the menu does not respond in hover mode.<br>Default value: **false**, indicating that the menu does not respond in hover mode<br>**NOTE**<br>The menu responds in hover mode when **enableHoverMode** is set to **true** and does not when **enableHoverMode** is set to **false** or an invalid value or is not set at all.<br>**Atomic service API**: This API can be used in atomic services since API version 13.|
131| 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.|
132| 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.|
133| 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.|
134| 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.                                      |
135| 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.                                      |
136| 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.                                      |
137| 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.                                      |
138| 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.|
139| 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.|
140| 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.|
141| 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.|
142| 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.|
143
144## MenuPreviewMode<sup>11+</sup>
145
146**Atomic service API**: This API can be used in atomic services since API version 12.
147
148**System capability**: SystemCapability.ArkUI.ArkUI.Full
149
150| Name | Description                                  |
151| ----- | -------------------------------------- |
152| NONE  | No preview is displayed.                      |
153| IMAGE | The preview is a screenshot of the component on which a long-press triggers the context menu.|
154
155## ContextMenuAnimationOptions<sup>11+</sup>
156
157**Atomic service API**: This API can be used in atomic services since API version 12.
158
159| Name | Type                                      | Mandatory| Description                                |
160| ----- | ------------------------------------------ | ---- | ------------------------------------ |
161| scale | [AnimationRange](#animationrange11)\<number> | No  | Scale ratio of the preview image when the animation starts and scale ratio when the animation ends.<br>**Atomic service API**: This API can be used in atomic services since API version 12.|
162| 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).|
163| 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.|
164
165## AnimationRange<sup>11+</sup>
166
167Describes the scale ratio relative to the preview image at the beginning and end of the scale animation.
168
169**System capability**: SystemCapability.ArkUI.ArkUI.Full
170
171**Atomic service API**: This API can be used in atomic services since API version 12.
172
173| Value Range        | Description                                                                          |
174| ---------------- | ------------------------------------------------------------------------------ |
175| [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.|
176
177## Example
178
179### Example 1
180
181Menu with textual menu items:
182
183```ts
184// xxx.ets
185@Entry
186@Component
187struct MenuExample {
188  build() {
189    Column() {
190      Text('click for Menu')
191        .bindMenu([
192          {
193            value: 'Menu1',
194            action: () => {
195              console.info('handle Menu1 select')
196            }
197          },
198          {
199            value: 'Menu2',
200            action: () => {
201              console.info('handle Menu2 select')
202            }
203          },
204        ])
205    }
206    .width('100%')
207    .margin({ top: 5 })
208  }
209}
210```
211
212![en_image_0000001174582862](figures/en_image_0000001174582862.gif)
213
214### Example 2
215
216Menu with custom menu items:
217
218```ts
219@Entry
220@Component
221struct MenuExample {
222  @State listData: number[] = [0, 0, 0]
223
224  @Builder MenuBuilder() {
225    Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
226      ForEach(this.listData, (item:number, index) => {
227        Column() {
228          Row() {
229            Image($r("app.media.icon")).width(20).height(20).margin({ right: 5 })
230            Text(`Menu${index as number + 1}`).fontSize(20)
231          }
232          .width('100%')
233          .height(30)
234          .justifyContent(FlexAlign.Center)
235          .align(Alignment.Center)
236          .onClick(() => {
237            console.info(`Menu${index as number + 1} Clicked!`)
238          })
239
240          if (index != this.listData.length - 1) {
241            Divider().height(10).width('80%').color('#ccc')
242          }
243        }.padding(5).height(40)
244      })
245    }.width(100)
246  }
247
248  build() {
249    Column() {
250      Text('click for menu')
251        .fontSize(20)
252        .margin({ top: 20 })
253        .bindMenu(this.MenuBuilder)
254    }
255    .height('100%')
256    .width('100%')
257    .backgroundColor('#f0f0f0')
258  }
259}
260```
261
262![en_image_0000001186807708](figures/en_image_0000001186807708.gif)
263
264### Example 3
265
266Context menu displayed upon long-press:
267
268```ts
269// xxx.ets
270@Entry
271@Component
272struct ContextMenuExample {
273  @Builder MenuBuilder() {
274    Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
275      Text('Test menu item 1')
276        .fontSize(20)
277        .width(100)
278        .height(50)
279        .textAlign(TextAlign.Center)
280      Divider().height(10)
281      Text('Test menu item 2')
282        .fontSize(20)
283        .width(100)
284        .height(50)
285        .textAlign(TextAlign.Center)
286    }.width(100)
287  }
288
289  build() {
290    Column() {
291      Text('LongPress for menu')
292    }
293    .width('100%')
294    .margin({ top: 5 })
295    .bindContextMenu(this.MenuBuilder, ResponseType.LongPress)
296  }
297}
298```
299
300![longMenu](figures/longMenu.gif)
301
302### Example 4
303
304Directive menu displayed upon right-click:
305
306```ts
307// xxx.ets
308@Entry
309@Component
310struct DirectiveMenuExample {
311  @Builder MenuBuilder() {
312    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
313      Text('Options')
314      Divider().strokeWidth(2).margin(5).color('#F0F0F0')
315      Text('Hide')
316      Divider().strokeWidth(2).margin(5).color('#F0F0F0')
317      Text('Exit')
318    }
319    .width(200)
320  }
321
322  build() {
323    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
324      Column() {
325        Text("DirectiveMenuExample")
326          .fontSize(20)
327          .width('100%')
328          .height("25%")
329          .backgroundColor('#F0F0F0')
330          .textAlign(TextAlign.Center)
331          .bindContextMenu(this.MenuBuilder, ResponseType.RightClick, {
332            enableArrow: true,
333            placement: Placement.Bottom
334          })
335      }
336    }
337    .width('100%')
338    .height('100%')
339  }
340}
341```
342
343![en-us_image_0000001689126950](figures/en-us_image_0000001689126950.png)
344
345### Example 5
346
347Context menu displayed upon long-pressing (with preview of component screenshot):
348
349```ts
350// xxx.ets
351@Entry
352@Component
353struct Index {
354  private iconStr: ResourceStr = $r("app.media.icon")
355
356  @Builder
357  MyMenu() {
358    Menu() {
359      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
360      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
361      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
362    }
363  }
364
365  build() {
366    Column({ space: 50 }) {
367      Column() {
368        Column() {
369          Text('preview-image')
370            .width(200)
371            .height(100)
372            .textAlign(TextAlign.Center)
373            .margin(100)
374            .fontSize(30)
375            .bindContextMenu(this.MyMenu, ResponseType.LongPress,
376              { preview: MenuPreviewMode.IMAGE,
377                previewAnimationOptions: {scale: [0.8, 1.0]},
378              })
379            .backgroundColor("#ff3df2f5")
380        }
381      }.width('100%')
382    }
383  }
384}
385```
386
387![preview-image](figures/preview-image.png)
388
389### Example 6
390
391Context menu displayed upon long-pressing (with preview of custom content):
392
393```ts
394// xxx.ets
395@Entry
396@Component
397struct Index {
398  private iconStr: ResourceStr = $r("app.media.icon")
399
400  @Builder
401  MyMenu() {
402    Menu() {
403      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
404      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
405      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
406    }
407  }
408
409  @Builder
410  MyPreview() {
411    Column() {
412      Image($r('app.media.icon'))
413        .width(200)
414        .height(200)
415    }
416  }
417
418  build() {
419    Column({ space: 50 }) {
420      Column() {
421        Column() {
422          Text('preview-builder')
423            .width(200)
424            .height(100)
425            .textAlign(TextAlign.Center)
426            .margin(100)
427            .fontSize(30)
428            .bindContextMenu(this.MyMenu, ResponseType.LongPress,
429              {
430                preview: this.MyPreview
431              })
432        }
433      }.width('100%')
434    }
435  }
436}
437```
438
439![preview-builder](figures/preview-builder.png)
440
441### Example 7
442
443Context menu displayed upon setting isShown (with preview of custom content):
444
445```ts
446// xxx.ets
447@Entry
448@Component
449struct Index {
450  private iconStr: ResourceStr = $r("app.media.icon")
451  @State isShown: boolean = false
452
453  @Builder
454  MyMenu() {
455    Menu() {
456      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
457      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
458      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
459    }
460  }
461
462  @Builder
463  MyPreview() {
464    Column() {
465      Image($r('app.media.icon'))
466        .width(200)
467        .height(200)
468    }
469  }
470
471  build() {
472    Column({ space: 50 }) {
473      Column() {
474        Column() {
475          Text('preview-builder')
476            .width(200)
477            .height(100)
478            .textAlign(TextAlign.Center)
479            .margin(100)
480            .fontSize(30)
481            .bindContextMenu(this.isShown, this.MyMenu,
482              {
483                preview: this.MyPreview,
484                onDisappear: ()=>{
485                    this.isShown = false;
486                }
487              })
488          Button('click')
489            .onClick(()=>{
490                this.isShown = true;
491             })
492        }
493      }.width('100%')
494    }
495  }
496}
497```
498
499### Example 8
500
501This example customizes the display and exit animation effects of the menu and preview through the **transition** attribute.
502
503```ts
504// xxx.ets
505@Entry
506@Component
507struct MenuExample {
508  @Builder MenuBuilder() {
509    Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
510      Text('Test menu item 1')
511        .fontSize(12)
512        .width(200)
513        .height(30)
514        .textAlign(TextAlign.Center)
515      Divider().height(10)
516      Text('Test menu item 2')
517        .fontSize(12)
518        .width(100)
519        .height(30)
520        .textAlign(TextAlign.Center)
521    }.width(100)
522  }
523  @Builder
524  MyPreview() {
525    Column() {
526      Image($r('app.media.icon'))
527        .width(50)
528        .height(50)
529    }
530  }
531  @State isShow:boolean = false
532  private iconStr: ResourceStr = $r("app.media.icon")
533
534  @Builder
535  MyMenu() {
536    Menu() {
537      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
538      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
539      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
540    }
541  }
542  build() {
543    Column() {
544      Button('LongPress bindContextMenu')
545        .margin({ top: 15 })
546        .bindContextMenu(
547          this.MenuBuilder,
548          ResponseType.LongPress,{
549          transition: TransitionEffect.OPACITY.animation({ duration: 4000, curve: Curve.Ease }).combine(
550            TransitionEffect.rotate({ z: 1, angle: 180 })),
551          preview: this.MyPreview,
552          previewAnimationOptions: {
553            scale: [0.8, 1.0],
554            transition: TransitionEffect.OPACITY.animation({ duration: 4000, curve: Curve.Ease }).combine(
555              TransitionEffect.rotate({ z: 1, angle: 180 }))
556          }
557        })
558    }
559    .width('100%')
560    .margin({ top: 5 })
561  }
562}
563```
564
565![preview-builder](figures/menu2.gif)
566
567### Example 9
568
569This example demonstrates a regular menu (using symbol-type icons).
570
571```ts
572// xxx.ets
573import { SymbolGlyphModifier } from '@kit.ArkUI';
574@Entry
575@Component
576struct MenuExample {
577  @State symbolIconModifier1: SymbolGlyphModifier = new SymbolGlyphModifier($r('sys.symbol.ohos_photo')).fontSize('24vp');
578  @State symbolIconModifier2: SymbolGlyphModifier = new SymbolGlyphModifier($r('sys.symbol.ohos_photo')).fontSize('24vp');
579  build() {
580    Column() {
581      Text('click for Menu')
582    }
583    .width('100%')
584    .margin({ top: 5 })
585    .bindMenu([
586      {
587        value: 'Menu1',
588        symbolIcon:this.symbolIconModifier1,
589        action: () => {
590          console.info('handle Menu1 select')
591        }
592      },
593      {
594        value: 'Menu2',
595        symbolIcon:this.symbolIconModifier2,
596        action: () => {
597          console.info('handle Menu2 select')
598        }
599      },
600    ])
601  }
602}
603```
604
605![zh-cn_image_0000001174582862](figures/preview-symbol.jpeg)
606
607### Example 10
608
609This example uses **hoverScale** to implement the transition from the component snapshot to the custom preview image.
610
611```ts
612// xxx.ets
613@Entry
614@Component
615struct Index {
616  private iconStr: ResourceStr = $r("app.media.app_icon")
617
618  @Builder
619  MyMenu() {
620    Menu() {
621      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
622      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
623      MenuItem({ startIcon: this.iconStr, content: "Menu option" })
624    }
625  }
626
627  @Builder
628  MyPreview() {
629    Column() {
630      Image($r('app.media.example'))
631        .width(200)
632        .height(200)
633    }
634  }
635
636  build() {
637    Column({ space: 50 }) {
638      Column() {
639        Column() {
640          Image($r('app.media.example'))
641            .width(100)
642            .height(100)
643            .margin(100)
644            .bindContextMenu(this.MyMenu, ResponseType.LongPress,
645              {
646                preview: this.MyPreview,
647                previewAnimationOptions: {
648                  hoverScale: [1.0, 0.95]
649                }
650              })
651        }
652      }.width('100%')
653    }
654  }
655}
656```
657
658![preview-builder](figures/hoverScale.gif)
659