• 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
12## Attributes
13
14
15| Name                          | Type                                    | Description                                      |
16| ---------------------------- | ---------------------------------------- | ---------------------------------------- |
17| bindMenu                     | content: Array<[MenuItem](#menuitem)&gt; \| [CustomBuilder](ts-types.md#custombuilder8),<br>options?: [MenuOptions](#menuoptions10) | Menu bound to the 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.<br>**content**: array of menu item icons and text, or custom component.<br>**options**: parameters of the context menu.|
18| bindContextMenu<sup>8+</sup> | content: [CustomBuilder](ts-types.md#custombuilder8),<br>responseType: [ResponseType](ts-appendix-enums.md#responsetype8)<br>options?: [ContextMenuOptions](#contextmenuoptions10) | Context menu bound to the component, which is displayed when the user long-presses or right-clicks the component. Only custom menu items are supported.<br>**responseType**: how the context menu is triggered, which can be long-press or right-click.<br>**options**: parameters of the context menu.|
19
20## MenuItem
21
22| Name                | Type                                    | Mandatory  | Description         |
23| ------------------ | -------------------------------------- | ---- | ----------- |
24| value              | string                                 | Yes   | Menu item text.     |
25| icon<sup>10+</sup> | [ResourceStr](ts-types.md#resourcestr) | No   | Menu item icon.     |
26| action             | () =&gt; void                | Yes   | Action triggered when a menu item is clicked.|
27
28## MenuOptions<sup>10+</sup>
29
30| Name       | Type                                        | Mandatory| Description                                                        |
31| ----------- | -------------------------------------------- | ---- | ------------------------------------------------------------ |
32| title       | string                                       | No  | Menu title.<br>**NOTE**<br>This parameter is available only when **content** is set to Array<[MenuItem](#menuitem)>.|
33| offset      | [Position](ts-types.md#position8)            | No  | Offset for showing the context menu, which should not cause the menu to extend beyond the screen.<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.RightTop**, 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.|
34| 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>If **placement** is set to **undefined** or **null** or is not set, the default value [BottomLeft](ts-appendix-enums.md#placement8) is used, and the position is relative to the parent component.|
35| onAppear    | () =&gt; void                      | No  | Callback triggered when the menu is displayed.                                      |
36| onDisappear | () =&gt; void                      | No  | Callback triggered when the menu is hidden.                                      |
37
38## ContextMenuOptions<sup>10+</sup>
39
40| Name       | Type                                        | Mandatory| Description                                                        |
41| ----------- | -------------------------------------------- | ---- | ------------------------------------------------------------ |
42| offset      | [Position](ts-types.md#position8)            | No  | Offset for showing the context menu, which should not cause the menu to extend beyond the screen.<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.RightTop**, 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.|
43| 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, and the context menu is displayed where the mouse is clicked.|
44| 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>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.|
45| arrowOffset | [Length](ts-types.md#length)                 | No  | Offset of the arrow relative to the context menu. When the arrow is placed in a horizontal position with the context menu: The value indicates the distance from the arrow to the leftmost; the arrow is centered by default. When the arrow is placed in a vertical position with the context menu: The value indicates the distance from the arrow to the top; the arrow is centered by default. 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. The value of **placement** determines whether the offset is horizontal or vertical.|
46| onAppear    | () =&gt; void                      | No  | Callback triggered when the menu is displayed.                                      |
47| onDisappear | () =&gt; void                      | No  | Callback triggered when the menu is hidden.                                      |
48
49## Example
50
51### Example 1
52
53Menu with Textual Menu Items
54
55```ts
56// xxx.ets
57@Entry
58@Component
59struct MenuExample {
60  build() {
61    Column() {
62      Text('click for Menu')
63    }
64    .width('100%')
65    .margin({ top: 5 })
66    .bindMenu([
67      {
68        value: 'Menu1',
69        action: () => {
70          console.info('handle Menu1 select')
71        }
72      },
73      {
74        value: 'Menu2',
75        action: () => {
76          console.info('handle Menu2 select')
77        }
78      },
79    ])
80  }
81}
82```
83
84![en_image_0000001174582862](figures/en_image_0000001174582862.gif)
85
86### Example 2
87
88Menu with Custom Menu Items
89
90```ts
91@Entry
92@Component
93struct MenuExample {
94  @State listData: number[] = [0, 0, 0]
95
96  @Builder MenuBuilder() {
97    Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
98      ForEach(this.listData, (item:number, index) => {
99        Column() {
100          Row() {
101            Image($r("app.media.icon")).width(20).height(20).margin({ right: 5 })
102            Text(`Menu${index as number + 1}`).fontSize(20)
103          }
104          .width('100%')
105          .height(30)
106          .justifyContent(FlexAlign.Center)
107          .align(Alignment.Center)
108          .onClick(() => {
109            console.info(`Menu${index as number + 1} Clicked!`)
110          })
111
112          if (index != this.listData.length - 1) {
113            Divider().height(10).width('80%').color('#ccc')
114          }
115        }.padding(5).height(40)
116      })
117    }.width(100)
118  }
119
120  build() {
121    Column() {
122      Text('click for menu')
123        .fontSize(20)
124        .margin({ top: 20 })
125        .bindMenu(this.MenuBuilder)
126    }
127    .height('100%')
128    .width('100%')
129    .backgroundColor('#f0f0f0')
130  }
131}
132```
133
134![en_image_0000001186807708](figures/en_image_0000001186807708.gif)
135
136### Example 3
137
138Context Menu (Displayed Upon Right-Click)
139
140```ts
141// xxx.ets
142@Entry
143@Component
144struct ContextMenuExample {
145  @Builder MenuBuilder() {
146    Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
147      Text('Test menu item 1')
148        .fontSize(20)
149        .width(100)
150        .height(50)
151        .textAlign(TextAlign.Center)
152      Divider().height(10)
153      Text('Test menu item 2')
154        .fontSize(20)
155        .width(100)
156        .height(50)
157        .textAlign(TextAlign.Center)
158    }.width(100)
159  }
160
161  build() {
162    Column() {
163      Text('rightclick for menu')
164    }
165    .width('100%')
166    .margin({ top: 5 })
167    .bindContextMenu(this.MenuBuilder, ResponseType.RightClick)
168  }
169}
170```
171
172### Example 4
173
174Directive Menu (Displayed Upon Right-Click)
175
176```ts
177// xxx.ets
178@Entry
179@Component
180struct DirectiveMenuExample {
181  @Builder MenuBuilder() {
182    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
183      Text('Options')
184      Divider().strokeWidth(2).margin(5).color('#F0F0F0')
185      Text('Hide')
186      Divider().strokeWidth(2).margin(5).color('#F0F0F0')
187      Text('Exit')
188    }
189    .width(200)
190  }
191
192  build() {
193    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
194      Column() {
195        Text("DirectiveMenuExample")
196          .fontSize(20)
197          .width('100%')
198          .height("25%")
199          .backgroundColor('#F0F0F0')
200          .textAlign(TextAlign.Center)
201          .bindContextMenu(this.MenuBuilder, ResponseType.RightClick, {
202            enableArrow: true,
203            placement: Placement.Bottom
204          })
205      }
206    }
207    .width('100%')
208    .height('100%')
209  }
210}
211```
212
213![en-us_image_0000001689126950](figures/en-us_image_0000001689126950.png)
214