@@ -10,68 +10,113 @@ directives apply their associated ARIA roles to their host element.
10
10
The directives in ` @angular/cdk/menu ` set the appropriate roles on their host element.
11
11
12
12
| Directive | ARIA Role |
13
- | ------------------- | ---------------- |
13
+ | --------------------- | ------------------ |
14
14
| CdkMenuBar | menubar |
15
15
| CdkMenu | menu |
16
16
| CdkMenuGroup | group |
17
17
| CdkMenuItem | menuitem |
18
18
| CdkMenuItemRadio | menuitemradio |
19
19
| CdkMenuItemCheckbox | menuitemcheckbox |
20
+ | CdkMenuTrigger | button |
21
+
22
+ ### CSS Styles and Classes
23
+
24
+ The ` @angular/cdk/menu ` is designed to be highly customizable to your needs. It therefore does not
25
+ make any assumptions about how elements should be styled. You are expected to apply any required
26
+ CSS styles, but the directives do apply CSS classes to make it easier for you to add custom styles.
27
+ The available CSS classes are listed below, by directive.
28
+
29
+ | Directive | CSS Class | Applied... |
30
+ | :----------------------| --------------------------| ------------------------------------------------|
31
+ | ` cdkMenu ` | ` cdk-menu ` | Always |
32
+ | ` cdkMenu ` | ` cdk-menu-inline ` | If the menu is an [ inline menu] ( #menu-content ) |
33
+ | ` cdkMenuBar ` | ` cdk-menu-bar ` | Always |
34
+ | ` cdkMenuGroup ` | ` cdk-menu-group ` | Always |
35
+ | ` cdkMenuItem ` | ` cdk-menu-item ` | Always |
36
+ | ` cdkMenuItemCheckbox ` | ` cdk-menu-item ` | Always |
37
+ | ` cdkMenuItemCheckbox ` | ` cdk-menu-item-checkbox ` | Always |
38
+ | ` cdkMenuItemRadio ` | ` cdk-menu-item ` | Always |
39
+ | ` cdkMenuItemRadio ` | ` cdk-menu-item-radio ` | Always |
40
+ | ` cdkMenuTriggerFor ` | ` cdk-menu-trigger ` | Always |
20
41
21
42
### Getting started
22
43
23
44
Import the ` CdkMenuModule ` into the ` NgModule ` in which you want to create menus. You can then apply
24
45
menu directives to build your custom menu. A typical menu consists of the following directives:
25
46
26
- - ` cdkMenuTriggerFor ` - links a trigger button to a menu you intend to open
27
- - ` cdkMenuPanel ` - wraps the menu and provides a link between the ` cdkMenuTriggerFor ` and the
28
- ` cdkMenu `
29
- - ` cdkMenu ` - the actual menu you want to open
30
- - ` cdkMenuItem ` - added to each button
47
+ - ` cdkMenuTriggerFor ` - links a trigger element to an ` ng-template ` containing the menu to be opened
48
+ - ` cdkMenu ` - creates the menu content opened by the trigger
49
+ - ` cdkMenuItem ` - added to each item in the menu
31
50
32
51
<!-- example({
33
- "example": "cdk-menu-standalone-menu ",
34
- "file": "cdk-menu-standalone-menu -example.html"
52
+ "example": "cdk-menu-standalone-trigger ",
53
+ "file": "cdk-menu-standalone-trigger -example.html"
35
54
}) -->
36
55
37
56
Most menu interactions consist of two parts: a trigger and a menu panel.
38
57
39
58
#### Triggers
40
59
41
- You must add the ` cdkMenuItem ` and ` cdkMenuTriggerFor ` directives to triggers like so,
60
+ You can add ` cdkMenuTriggerFor ` to any button to make it a trigger for the given menu, or any menu
61
+ item to make it a trigger for a submenu. When adding this directive, be sure to pass a reference to
62
+ the template containing the menu it should open. Users can toggle the associated menu using a mouse
63
+ or keyboard.
64
+
65
+ <!-- example({"example":"cdk-menu-standalone-trigger",
66
+ "file":"cdk-menu-standalone-trigger-example.html",
67
+ "region":"trigger"}) -->
42
68
43
- ``` html
44
- <button cdkMenuItem [cdkMenuTriggerFor] =" menu" >Click me!</button >
45
- ```
69
+ When creating a submenu trigger, add both ` cdkMenuItem ` and ` cdkMenuTriggerFor ` like so,
46
70
47
- Adding ` cdkMenuItem ` gives you keyboard navigation and focus management. Associating a trigger with
48
- a menu is done through the ` cdkMenuTriggerFor ` directive and you must provide a template reference
49
- variable to it. Once both of these directives are set, you can toggle the associated menu
50
- programmatically, using a mouse or using a keyboard.
71
+ <!-- example({"example":"cdk-menu-menubar",
72
+ "file":"cdk-menu-menubar-example.html",
73
+ "region":"file-trigger"}) -->
51
74
52
- #### Menu panels
75
+ #### Menu content
53
76
54
- You must wrap pop-up menus with an ` ng-template ` with the ` cdkMenuPanel ` directive and a reference
55
- variable which must be of type ` cdkMenuPanel ` . Further, the ` cdkMenu ` must also reference the
56
- ` cdkMenuPanel ` .
77
+ There are two types of menus:
78
+ * _ inline menus _ are always present on the page
79
+ * _ pop-up menus _ can be toggled to hide or show by the user
57
80
58
- ``` html
59
- <ng-template cdkMenuPanel #panel =" cdkMenuPanel" >
60
- <div cdkMenu [cdkMenuPanel] =" panel" >
61
- <!-- some content -->
62
- </div >
63
- </ng-template >
64
- ```
81
+ You can create menus by marking their content element with the ` cdkMenu ` or ` cdkMenuBar `
82
+ directives. You can create several types of menu interaction which are discussed below.
83
+
84
+ All type of menus should exclusively contain elements with role ` menuitem ` , ` menuitemcheckbox ` ,
85
+ ` menuitemradio ` , or ` group ` . Supporting directives that automatically apply these roles are
86
+ discussed below.
65
87
66
88
Note that Angular CDK provides no styles; you must add styles as part of building your custom menu.
67
89
90
+ ### Inline Menus
91
+
92
+ An _ inline menu_ is a menu that lives directly on the page rather than in a pop-up associated with a
93
+ trigger. You can use an inline menu when you want a persistent menu interaction on a page. Menu
94
+ items within an inline menus are logically grouped together, and you can navigate through them
95
+ using your keyboard. You can create an inline menu by adding the ` cdkMenu ` directive to the element
96
+ you want to serve as the menu content.
97
+
98
+ <!-- example({
99
+ "example": "cdk-menu-inline",
100
+ "file": "cdk-menu-inline-example.html"
101
+ }) -->
102
+
103
+ ### Pop-up Menus
104
+
105
+ You can create pop-up menus using the ` cdkMenu ` directive as well. Add this directive to the
106
+ element you want to serve as the content for your pop-up menu. Then wrap the content element in an
107
+ ` ng-template ` and reference the template from the ` cdkMenuTriggerFor ` property of the trigger. This
108
+ will allow the trigger to show and hide the menu content as needed.
109
+
110
+ <!-- example({
111
+ "example": "cdk-menu-standalone-menu",
112
+ "file": "cdk-menu-standalone-menu-example.html"
113
+ }) -->
114
+
68
115
### Menu Bars
69
116
70
- The ` CdkMenuBar ` directive follows the [ ARIA menubar] [ menubar ] spec and behaves similar to a desktop
71
- app menubar. It consists of at least one ` CdkMenuItem ` which triggers a submenu. A menubar can be
72
- layed out horizontally or vertically (defaulting to horizontal). If the layout changes, you must set
73
- the ` orientation ` attribute to match in order for the keyboard navigation to work properly and for
74
- menus to open up in the correct location.
117
+ Menu bars are a type of inline menu that you can create using the ` cdkMenuBar ` directive. They
118
+ follow the [ ARIA menubar] [ menubar ] spec and behave similarly to a desktop application menubar. Each
119
+ bar consists of at least one ` cdkMenuItem ` that triggers a submenu.
75
120
76
121
<!-- example({
77
122
"example": "cdk-menu-menubar",
@@ -80,7 +125,8 @@ menus to open up in the correct location.
80
125
81
126
### Context Menus
82
127
83
- A context menu opens when a user right-clicks within some container element. You can mark a
128
+ A context menus is a type of pop-up menu that doesn't have a traditional trigger element, instead
129
+ it is triggered when a user right-clicks within some container element. You can mark a
84
130
container element with the ` cdkContextMenuTriggerFor ` , which behaves like ` cdkMenuTriggerFor ` except
85
131
that it responds to the browser's native ` contextmenu ` event. Custom context menus appear next to
86
132
the cursor, similarly to native context menus.
@@ -93,69 +139,58 @@ the cursor, similarly to native context menus.
93
139
You can nest context menu container elements. Upon right-click, the menu associated with the closest
94
140
container element will open.
95
141
96
- ``` html
97
- <div [cdkContextMenuTriggerFor] =" outer" >
98
- My outer context
99
- <div [cdkContextMenuTriggerFor] =" inner" >My inner context</div >
100
- </div >
101
- ```
102
-
103
- In the example above, right clicking on "My inner context" will open up the "inner" menu and right
104
- clicking inside "My outer context" will open up the "outer" menu.
105
-
106
- ### Inline Menus
107
-
108
- An _ inline menu_ is a menu that lives directly on the page rather than a pop-up associated with a
109
- trigger. You can use an inline menu when you want a persistent menu interaction on a page. Menu
110
- items within an inline menus are logically grouped together and you can navigate through them using
111
- your keyboard.
112
-
113
142
<!-- example({
114
- "example": "cdk-menu-inline",
115
- "file": "cdk-menu-inline-example.html"
143
+ "example": "cdk-menu-nested-context",
144
+ "file": "cdk-menu-nested-context-example.html",
145
+ "region": "triggers"
116
146
}) -->
117
147
118
- ### Menu Items
119
-
120
- Both menu and menubar elements should exclusively contain menuitem elements. This directive allows
121
- the items to be navigated to via keyboard interaction.
148
+ In the example above, right-clicking on "Inner context menu" will open up the "inner" menu and
149
+ right-clicking inside "Outer context menu" will open up the "outer" menu.
122
150
123
- A menuitem by itself can provide some user defined action by hooking into the ` cdkMenuItemTriggered `
124
- output. An example may be a close button which performs some closing logic.
151
+ ### Menu Items
125
152
126
- ``` html
127
- <ng-template cdkMenuPanel #panel =" cdkMenuPanel" >
128
- <div cdkMenu [cdkMenuPanel] =" panel" >
129
- <button cdkMenuItem (cdkMenuItemTriggered) =" closeApp()" >Close</button >
130
- </div >
131
- </ng-template >
132
- ```
153
+ The ` cdkMenuItem ` directive allows users to navigate menu items via keyboard.
154
+ You can add a custom action to a menu item with the ` cdkMenuItemTriggered ` output.
133
155
134
- You can create nested menus by using a menuitem as the trigger for another menu.
156
+ <!-- example({"example":"cdk-menu-standalone-stateful-menu",
157
+ "file":"cdk-menu-standalone-stateful-menu-example.html",
158
+ "region":"reset-item"}) -->
135
159
136
- ``` html
137
- <ng-template cdkMenuPanel #panel =" cdkMenuPanel" >
138
- <div cdkMenu [cdkMenuPanel] =" panel" >
139
- <button cdkMenuItem [cdkMenuTriggerFor] =" submenu" >Open Submenu</button >
140
- </div >
141
- </ng-template >
142
- ```
160
+ You can create nested menus by using a menu item as the trigger for another menu.
143
161
144
- A menuitem also has two sub-types, neither of which should trigger a menu: CdkMenuItemCheckbox and
145
- CdkMenuItemRadio
162
+ <!-- example({"example":"cdk-menu-menubar",
163
+ "file":"cdk-menu-menubar-example.html",
164
+ "region":"file-trigger"}) -->
146
165
147
166
#### Menu Item Checkboxes
148
167
149
- A ` cdkMenuItemCheckbox ` is a special type of menuitem that behaves as a checkbox. You can use this
150
- type of menuitem to toggle items on and off. An element with the ` cdkMenuItemCheckbox ` directive
168
+ A ` cdkMenuItemCheckbox ` is a special type of menu item that behaves as a checkbox. You can use this
169
+ type of menu item to toggle items on and off. An element with the ` cdkMenuItemCheckbox ` directive
151
170
does not need the additional ` cdkMenuItem ` directive.
152
171
172
+ Checkbox items do not track their own state. You must bind the checked state using the
173
+ ` cdkMenuItemChecked ` input and listen to ` cdkMenuItemTriggered ` to know when it is toggled. If you
174
+ don't bind the state it will reset when the menu is closed and re-opened.
175
+
176
+ <!-- example({"example":"cdk-menu-standalone-stateful-menu",
177
+ "file":"cdk-menu-standalone-stateful-menu-example.html",
178
+ "region":"bold-item"}) -->
179
+
153
180
#### Menu Item Radios
154
181
155
- A ` cdkMenuItemRadio ` is a special type of menuitem that behaves as a radio button. You can use this
156
- type of menuitem for menus with exclusively selectable items. An element with the ` cdkMenuItemRadio `
182
+ A ` cdkMenuItemRadio ` is a special type of menu item that behaves as a radio button. You can use this
183
+ type of menu item for menus with exclusively selectable items. An element with the ` cdkMenuItemRadio `
157
184
directive does not need the additional ` cdkMenuItem ` directive.
158
185
186
+ As with checkbox items, radio items do not track their own state, but you can track it by binding
187
+ ` cdkMenuItemChecked ` and listening for ` cdkMenuItemTriggered ` . If you do not bind the state the
188
+ selection will reset when the menu is closed and reopened.
189
+
190
+ <!-- example({"example":"cdk-menu-standalone-stateful-menu",
191
+ "file":"cdk-menu-standalone-stateful-menu-example.html",
192
+ "region":"size-items"}) -->
193
+
159
194
#### Groups
160
195
161
196
By default ` cdkMenu ` acts as a group for ` cdkMenuItemRadio ` elements. Elements with
@@ -165,40 +200,18 @@ can have the checked state.
165
200
If you would like to have unrelated groups of radio buttons within a single menu you should use the
166
201
` cdkMenuGroup ` directive.
167
202
168
- ``` html
169
- <ng-template cdkMenuPanel #panel =" cdkMenuPanel" >
170
- <div cdkMenu [cdkMenuPanel] =" panel" >
171
- <!-- Font size -->
172
- <div cdkMenuGroup >
173
- <button cdkMenuItemRadio >Small</button >
174
- <button cdkMenuItemRadio >Medium</button >
175
- <button cdkMenuItemRadio >Large</button >
176
- </div >
177
- <hr />
178
- <!-- Paragraph alignment -->
179
- <div cdkMenuGroup >
180
- <button cdkMenuItemRadio >Left</button >
181
- <button cdkMenuItemRadio >Center</button >
182
- <button cdkMenuItemRadio >Right</button >
183
- </div >
184
- </div >
185
- </ng-template >
186
- ```
187
-
188
- Note however that when the menu is closed and reopened any state is lost. You must subscribe to the
189
- groups ` change ` output, or to ` cdkMenuItemToggled ` on each radio item and track changes your self.
190
- Finally, you can provide state for each item using the ` checked ` attribute.
191
-
192
203
<!-- example({
193
204
"example": "cdk-menu-standalone-stateful-menu",
194
205
"file": "cdk-menu-standalone-stateful-menu-example.html"
195
206
}) -->
196
207
197
208
### Smart Menu Aim
198
209
199
- ` @angular/cdk/menu ` intelligently predicts when a user intends to navigate to an open submenu and
200
- prevent premature closeouts. This functionality prevents users from having to hunt through the open
201
- menus in a maze-like fashion to reach their destination.
210
+ ` @angular/cdk/menu ` is capable of intelligently predicting when a user intends to navigate to an
211
+ open submenu and preventing premature closeouts. This functionality prevents users from having to
212
+ hunt through the open menus in a maze-like fashion to reach their destination. To enable this
213
+ feature for a menu and its sub-menus, add the ` cdkMenuTargetAim ` directive to the ` cdkMenu ` or
214
+ ` cdkMenuBar ` element.
202
215
203
216
![ menu aim diagram] [ diagram ]
204
217
@@ -208,8 +221,8 @@ service if it can perform its close actions. In order to determine if the curren
208
221
closed out, the Menu Aim service calculates the slope between a selected target coordinate in the
209
222
submenu and the previous mouse point, and the slope between the target and the current mouse point.
210
223
If the slope of the current mouse point is greater than the slope of the previous that means the
211
- user is moving towards the submenu and we shouldn't close out. Users however may sometimes stop
212
- short in a sibling item after moving towards the submenu. The service is intelligent enough the
224
+ user is moving towards the submenu, so we shouldn't close out. Users however may sometimes stop
225
+ short in a sibling item after moving towards the submenu. The service is intelligent enough to
213
226
detect this intention and will trigger the next menu.
214
227
215
228
### Accessibility
@@ -227,4 +240,4 @@ Finally, keyboard interaction is supported as defined in the [ARIA menubar keybo
227
240
[ keyboard] :
228
241
https://www.w3.org/TR/wai-aria-practices-1.1/#keyboard-interaction-12
229
242
'ARIA Menubar Keyboard Interaction'
230
- [ diagram ] : menuaim.png ' Menu Aim Diagram '
243
+ [ diagram ] : https://material.angular.io/assets/img/ menuaim.png ' Menu Aim Diagram '
0 commit comments