@@ -28,7 +28,8 @@ import {
2828 ViewEncapsulation ,
2929} from '@angular/core' ;
3030import { CanDisableRipple , mixinDisableRipple } from '@angular/material/core' ;
31- import { merge , of as observableOf , Subscription } from 'rxjs' ;
31+ import { merge , of as observableOf , Subject } from 'rxjs' ;
32+ import { takeUntil } from 'rxjs/operators' ;
3233import { MatInkBar } from './ink-bar' ;
3334import { MatTabLabelWrapper } from './tab-label-wrapper' ;
3435import { FocusKeyManager } from '@angular/cdk/a11y' ;
@@ -87,8 +88,8 @@ export class MatTabHeader extends _MatTabHeaderMixinBase
8788 /** Whether the header should scroll to the selected index after the view has been checked. */
8889 private _selectedIndexChanged = false ;
8990
90- /** Combines listeners that will re-align the ink bar whenever they're invoked . */
91- private _realignInkBar = Subscription . EMPTY ;
91+ /** Emits when the component is destroyed . */
92+ private readonly _destroyed = new Subject < void > ( ) ;
9293
9394 /** Whether the controls for pagination should be displayed */
9495 _showPaginationControls = false ;
@@ -201,20 +202,31 @@ export class MatTabHeader extends _MatTabHeaderMixinBase
201202 . withHorizontalOrientation ( this . _getLayoutDirection ( ) )
202203 . withWrap ( ) ;
203204
204- this . _keyManager . updateActiveItemIndex ( 0 ) ;
205+ this . _keyManager . updateActiveItem ( 0 ) ;
205206
206207 // Defer the first call in order to allow for slower browsers to lay out the elements.
207208 // This helps in cases where the user lands directly on a page with paginated tabs.
208209 typeof requestAnimationFrame !== 'undefined' ? requestAnimationFrame ( realign ) : realign ( ) ;
209210
210- this . _realignInkBar = merge ( dirChange , resize ) . subscribe ( ( ) => {
211+ // On dir change or window resize, realign the ink bar and update the orientation of
212+ // the key manager if the direction has changed.
213+ merge ( dirChange , resize ) . pipe ( takeUntil ( this . _destroyed ) ) . subscribe ( ( ) => {
211214 realign ( ) ;
212215 this . _keyManager . withHorizontalOrientation ( this . _getLayoutDirection ( ) ) ;
213216 } ) ;
217+
218+ // If there is a change in the focus key manager we need to emit the `indexFocused`
219+ // event in order to provide a public event that notifies about focus changes. Also we realign
220+ // the tabs container by scrolling the new focused tab into the visible section.
221+ this . _keyManager . change . pipe ( takeUntil ( this . _destroyed ) ) . subscribe ( newFocusIndex => {
222+ this . indexFocused . emit ( newFocusIndex ) ;
223+ this . _setTabFocus ( newFocusIndex ) ;
224+ } ) ;
214225 }
215226
216227 ngOnDestroy ( ) {
217- this . _realignInkBar . unsubscribe ( ) ;
228+ this . _destroyed . next ( ) ;
229+ this . _destroyed . complete ( ) ;
218230 }
219231
220232 /**
@@ -242,11 +254,11 @@ export class MatTabHeader extends _MatTabHeaderMixinBase
242254
243255 /** When the focus index is set, we must manually send focus to the correct label */
244256 set focusIndex ( value : number ) {
245- if ( ! this . _isValidIndex ( value ) || this . focusIndex == value || ! this . _keyManager ) { return ; }
257+ if ( ! this . _isValidIndex ( value ) || this . focusIndex === value || ! this . _keyManager ) {
258+ return ;
259+ }
246260
247261 this . _keyManager . setActiveItem ( value ) ;
248- this . indexFocused . emit ( value ) ;
249- this . _setTabFocus ( value ) ;
250262 }
251263
252264 /**
0 commit comments