@@ -25,8 +25,8 @@ import {
25
25
OnDestroy ,
26
26
OnInit ,
27
27
Output ,
28
- QueryList ,
29
28
TemplateRef ,
29
+ QueryList ,
30
30
ViewChild ,
31
31
ViewEncapsulation ,
32
32
} from '@angular/core' ;
@@ -36,7 +36,7 @@ import {matMenuAnimations} from './menu-animations';
36
36
import { MatMenuContent } from './menu-content' ;
37
37
import { throwMatMenuInvalidPositionX , throwMatMenuInvalidPositionY } from './menu-errors' ;
38
38
import { MatMenuItem } from './menu-item' ;
39
- import { MatMenuPanel } from './menu-panel' ;
39
+ import { MAT_MENU_PANEL , MatMenuPanel } from './menu-panel' ;
40
40
import { MenuPositionX , MenuPositionY } from './menu-positions' ;
41
41
42
42
@@ -84,18 +84,28 @@ const MAT_MENU_BASE_ELEVATION = 2;
84
84
styleUrls : [ 'menu.css' ] ,
85
85
changeDetection : ChangeDetectionStrategy . OnPush ,
86
86
encapsulation : ViewEncapsulation . None ,
87
+ preserveWhitespaces : false ,
88
+ exportAs : 'matMenu' ,
87
89
animations : [
88
90
matMenuAnimations . transformMenu ,
89
91
matMenuAnimations . fadeInItems
90
92
] ,
91
- exportAs : 'matMenu'
93
+ providers : [
94
+ { provide : MAT_MENU_PANEL , useExisting : MatMenu }
95
+ ]
92
96
} )
93
- export class MatMenu implements OnInit , AfterContentInit , MatMenuPanel , OnDestroy {
97
+ export class MatMenu implements OnInit , AfterContentInit , MatMenuPanel < MatMenuItem > , OnDestroy {
94
98
private _keyManager : FocusKeyManager < MatMenuItem > ;
95
99
private _xPosition : MenuPositionX = this . _defaultOptions . xPosition ;
96
100
private _yPosition : MenuPositionY = this . _defaultOptions . yPosition ;
97
101
private _previousElevation : string ;
98
102
103
+ /** Menu items inside the current menu. */
104
+ private _items : MatMenuItem [ ] = [ ] ;
105
+
106
+ /** Emits whenever the amount of menu items changes. */
107
+ private _itemChanges = new Subject < MatMenuItem [ ] > ( ) ;
108
+
99
109
/** Subscription to tab events on the menu panel */
100
110
private _tabSubscription = Subscription . EMPTY ;
101
111
@@ -106,7 +116,10 @@ export class MatMenu implements OnInit, AfterContentInit, MatMenuPanel, OnDestro
106
116
_panelAnimationState : 'void' | 'enter' = 'void' ;
107
117
108
118
/** Emits whenever an animation on the menu completes. */
109
- _animationDone = new Subject < void > ( ) ;
119
+ _animationDone = new Subject < AnimationEvent > ( ) ;
120
+
121
+ /** Whether the menu is animating. */
122
+ _isAnimating : boolean ;
110
123
111
124
/** Parent menu of the current menu panel. */
112
125
parentMenu : MatMenuPanel | undefined ;
@@ -142,7 +155,11 @@ export class MatMenu implements OnInit, AfterContentInit, MatMenuPanel, OnDestro
142
155
/** @docs -private */
143
156
@ViewChild ( TemplateRef ) templateRef : TemplateRef < any > ;
144
157
145
- /** List of the items inside of a menu. */
158
+ /**
159
+ * List of the items inside of a menu.
160
+ * @deprecated
161
+ * @deletion -target 7.0.0
162
+ */
146
163
@ContentChildren ( MatMenuItem ) items : QueryList < MatMenuItem > ;
147
164
148
165
/**
@@ -218,7 +235,7 @@ export class MatMenu implements OnInit, AfterContentInit, MatMenuPanel, OnDestro
218
235
}
219
236
220
237
ngAfterContentInit ( ) {
221
- this . _keyManager = new FocusKeyManager < MatMenuItem > ( this . items ) . withWrap ( ) . withTypeAhead ( ) ;
238
+ this . _keyManager = new FocusKeyManager < MatMenuItem > ( this . _items ) . withWrap ( ) . withTypeAhead ( ) ;
222
239
this . _tabSubscription = this . _keyManager . tabOut . subscribe ( ( ) => this . close . emit ( 'tab' ) ) ;
223
240
}
224
241
@@ -229,16 +246,10 @@ export class MatMenu implements OnInit, AfterContentInit, MatMenuPanel, OnDestro
229
246
230
247
/** Stream that emits whenever the hovered menu item changes. */
231
248
_hovered ( ) : Observable < MatMenuItem > {
232
- if ( this . items ) {
233
- return this . items . changes . pipe (
234
- startWith ( this . items ) ,
235
- switchMap ( items => merge ( ...items . map ( item => item . _hovered ) ) )
236
- ) ;
237
- }
238
-
239
- return this . _ngZone . onStable
240
- . asObservable ( )
241
- . pipe ( take ( 1 ) , switchMap ( ( ) => this . _hovered ( ) ) ) ;
249
+ return this . _itemChanges . pipe (
250
+ startWith ( this . _items ) ,
251
+ switchMap ( items => merge ( ...items . map ( item => item . _hovered ) ) )
252
+ ) ;
242
253
}
243
254
244
255
/** Handle a keyboard event from the menu, delegating to the appropriate action. */
@@ -316,6 +327,35 @@ export class MatMenu implements OnInit, AfterContentInit, MatMenuPanel, OnDestro
316
327
}
317
328
}
318
329
330
+ /**
331
+ * Registers a menu item with the menu.
332
+ * @docs -private
333
+ */
334
+ addItem ( item : MatMenuItem ) {
335
+ // We register the items through this method, rather than picking them up through
336
+ // `ContentChildren`, because we need the items to be picked up by their closest
337
+ // `mat-menu` ancestor. If we used `@ContentChildren(MatMenuItem, {descendants: true})`,
338
+ // all descendant items will bleed into the top-level menu in the case where the consumer
339
+ // has `mat-menu` instances nested inside each other.
340
+ if ( this . _items . indexOf ( item ) === - 1 ) {
341
+ this . _items . push ( item ) ;
342
+ this . _itemChanges . next ( this . _items ) ;
343
+ }
344
+ }
345
+
346
+ /**
347
+ * Removes an item from the menu.
348
+ * @docs -private
349
+ */
350
+ removeItem ( item : MatMenuItem ) {
351
+ const index = this . _items . indexOf ( item ) ;
352
+
353
+ if ( this . _items . indexOf ( item ) > - 1 ) {
354
+ this . _items . splice ( index , 1 ) ;
355
+ this . _itemChanges . next ( this . _items ) ;
356
+ }
357
+ }
358
+
319
359
/** Starts the enter animation. */
320
360
_startAnimation ( ) {
321
361
// @deletion -target 7.0.0 Combine with _resetAnimation.
@@ -329,7 +369,8 @@ export class MatMenu implements OnInit, AfterContentInit, MatMenuPanel, OnDestro
329
369
}
330
370
331
371
/** Callback that is invoked when the panel animation completes. */
332
- _onAnimationDone ( ) {
333
- this . _animationDone . next ( ) ;
372
+ _onAnimationDone ( event : AnimationEvent ) {
373
+ this . _animationDone . next ( event ) ;
374
+ this . _isAnimating = false ;
334
375
}
335
376
}
0 commit comments