@@ -231,6 +231,9 @@ export class MatChip extends _MatChipMixinBase implements AfterContentInit, Afte
231231 /** The unstyled chip selector for this component. */
232232 protected basicChipAttrName = 'mat-basic-chip' ;
233233
234+ /** Subject that emits when the component has been destroyed. */
235+ protected _destroyed = new Subject < void > ( ) ;
236+
234237 /** The chip's leading icon. */
235238 @ContentChild ( MAT_CHIP_AVATAR ) leadingIcon : MatChipAvatar ;
236239
@@ -275,7 +278,15 @@ export class MatChip extends _MatChipMixinBase implements AfterContentInit, Afte
275278 notifyNavigation : ( ) => this . _notifyNavigation ( ) ,
276279 notifyTrailingIconInteraction : ( ) =>
277280 this . removeIconInteraction . emit ( this . id ) ,
278- notifyRemoval : ( ) => this . remove ( ) ,
281+ notifyRemoval :
282+ ( ) => {
283+ this . removed . emit ( { chip : this } ) ;
284+
285+ // When MDC removes a chip it just transitions it to `width: 0px`
286+ // which means that it's still in the DOM and it's still focusable.
287+ // Make it `display: none` so users can't tab into it.
288+ this . _elementRef . nativeElement . style . display = 'none' ;
289+ } ,
279290 notifyEditStart :
280291 ( ) => {
281292 this . _onEditStart ( ) ;
@@ -364,17 +375,24 @@ export class MatChip extends _MatChipMixinBase implements AfterContentInit, Afte
364375
365376 ngOnDestroy ( ) {
366377 this . destroyed . emit ( { chip : this } ) ;
378+ this . _destroyed . next ( ) ;
379+ this . _destroyed . complete ( ) ;
367380 this . _chipFoundation . destroy ( ) ;
368381 }
369382
370383 /** Sets up the remove icon chip foundation, and subscribes to remove icon events. */
371- private _initRemoveIcon ( ) {
384+ _initRemoveIcon ( ) {
372385 if ( this . removeIcon ) {
373386 this . _chipFoundation . setShouldRemoveOnTrailingIconClick ( true ) ;
387+ this . _listenToRemoveIconInteraction ( ) ;
374388 this . removeIcon . disabled = this . disabled ;
389+ }
390+ }
375391
376- this . removeIcon . interaction
377- . pipe ( takeUntil ( this . destroyed ) )
392+ /** Handles interaction with the remove icon. */
393+ _listenToRemoveIconInteraction ( ) {
394+ this . removeIcon . interaction
395+ . pipe ( takeUntil ( this . _destroyed ) )
378396 . subscribe ( event => {
379397 // The MDC chip foundation calls stopPropagation() for any trailing icon interaction
380398 // event, even ones it doesn't handle, so we want to avoid passing it keyboard events
@@ -387,7 +405,7 @@ export class MatChip extends _MatChipMixinBase implements AfterContentInit, Afte
387405 return ;
388406 }
389407
390- this . remove ( ) ;
408+ this . _chipFoundation . handleTrailingActionInteraction ( ) ;
391409
392410 if ( isKeyboardEvent && ! hasModifierKey ( event as KeyboardEvent ) ) {
393411 const keyCode = ( event as KeyboardEvent ) . keyCode ;
@@ -398,7 +416,6 @@ export class MatChip extends _MatChipMixinBase implements AfterContentInit, Afte
398416 }
399417 }
400418 } ) ;
401- }
402419 }
403420
404421 /**
@@ -408,7 +425,7 @@ export class MatChip extends _MatChipMixinBase implements AfterContentInit, Afte
408425 */
409426 remove ( ) : void {
410427 if ( this . removable ) {
411- this . removed . emit ( { chip : this } ) ;
428+ this . _chipFoundation . beginExit ( ) ;
412429 }
413430 }
414431
0 commit comments