@@ -40,7 +40,7 @@ import {
40
40
OnInit ,
41
41
} from '@angular/core' ;
42
42
import { merge , Observable , Subject , Subscription } from 'rxjs' ;
43
- import { startWith , switchMap , take } from 'rxjs/operators' ;
43
+ import { startWith , switchMap , take , debounceTime } from 'rxjs/operators' ;
44
44
import { matMenuAnimations } from './menu-animations' ;
45
45
import { MatMenuContent } from './menu-content' ;
46
46
import { MenuPositionX , MenuPositionY } from './menu-positions' ;
@@ -244,11 +244,34 @@ export class _MatMenuBase implements AfterContentInit, MatMenuPanel<MatMenuItem>
244
244
ngAfterContentInit ( ) {
245
245
this . _keyManager = new FocusKeyManager < MatMenuItem > ( this . _items ) . withWrap ( ) . withTypeAhead ( ) ;
246
246
this . _tabSubscription = this . _keyManager . tabOut . subscribe ( ( ) => this . closed . emit ( 'tab' ) ) ;
247
+
248
+ // TODO(crisbeto): the `debounce` here should be removed since it's something
249
+ // that people have to flush in their tests. It'll be possible once we switch back
250
+ // to using a QueryList in #11720.
251
+ this . _ngZone . runOutsideAngular ( ( ) => {
252
+ // Move focus to another item, if the active item is removed from the list.
253
+ // We need to debounce the callback, because multiple items might be removed
254
+ // in quick succession.
255
+ this . _itemChanges . pipe ( debounceTime ( 50 ) ) . subscribe ( items => {
256
+ const manager = this . _keyManager ;
257
+
258
+ if ( manager . activeItem && items . indexOf ( manager . activeItem ) === - 1 ) {
259
+ const index = Math . max ( 0 , Math . min ( items . length - 1 , manager . activeItemIndex || 0 ) ) ;
260
+
261
+ if ( items [ index ] && ! items [ index ] . disabled ) {
262
+ manager . setActiveItem ( index ) ;
263
+ } else {
264
+ manager . setNextItemActive ( ) ;
265
+ }
266
+ }
267
+ } ) ;
268
+ } ) ;
247
269
}
248
270
249
271
ngOnDestroy ( ) {
250
272
this . _tabSubscription . unsubscribe ( ) ;
251
273
this . closed . complete ( ) ;
274
+ this . _itemChanges . complete ( ) ;
252
275
}
253
276
254
277
/** Stream that emits whenever the hovered menu item changes. */
@@ -359,7 +382,7 @@ export class _MatMenuBase implements AfterContentInit, MatMenuPanel<MatMenuItem>
359
382
removeItem ( item : MatMenuItem ) {
360
383
const index = this . _items . indexOf ( item ) ;
361
384
362
- if ( this . _items . indexOf ( item ) > - 1 ) {
385
+ if ( index > - 1 ) {
363
386
this . _items . splice ( index , 1 ) ;
364
387
this . _itemChanges . next ( this . _items ) ;
365
388
}
0 commit comments