@@ -28,7 +28,8 @@ import {
28
28
ViewEncapsulation ,
29
29
} from '@angular/core' ;
30
30
import { 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' ;
32
33
import { MatInkBar } from './ink-bar' ;
33
34
import { MatTabLabelWrapper } from './tab-label-wrapper' ;
34
35
import { FocusKeyManager } from '@angular/cdk/a11y' ;
@@ -87,8 +88,8 @@ export class MatTabHeader extends _MatTabHeaderMixinBase
87
88
/** Whether the header should scroll to the selected index after the view has been checked. */
88
89
private _selectedIndexChanged = false ;
89
90
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 > ( ) ;
92
93
93
94
/** Whether the controls for pagination should be displayed */
94
95
_showPaginationControls = false ;
@@ -201,20 +202,31 @@ export class MatTabHeader extends _MatTabHeaderMixinBase
201
202
. withHorizontalOrientation ( this . _getLayoutDirection ( ) )
202
203
. withWrap ( ) ;
203
204
204
- this . _keyManager . updateActiveItemIndex ( 0 ) ;
205
+ this . _keyManager . updateActiveItem ( 0 ) ;
205
206
206
207
// Defer the first call in order to allow for slower browsers to lay out the elements.
207
208
// This helps in cases where the user lands directly on a page with paginated tabs.
208
209
typeof requestAnimationFrame !== 'undefined' ? requestAnimationFrame ( realign ) : realign ( ) ;
209
210
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 ( ( ) => {
211
214
realign ( ) ;
212
215
this . _keyManager . withHorizontalOrientation ( this . _getLayoutDirection ( ) ) ;
213
216
} ) ;
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
+ } ) ;
214
225
}
215
226
216
227
ngOnDestroy ( ) {
217
- this . _realignInkBar . unsubscribe ( ) ;
228
+ this . _destroyed . next ( ) ;
229
+ this . _destroyed . complete ( ) ;
218
230
}
219
231
220
232
/**
@@ -242,11 +254,11 @@ export class MatTabHeader extends _MatTabHeaderMixinBase
242
254
243
255
/** When the focus index is set, we must manually send focus to the correct label */
244
256
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
+ }
246
260
247
261
this . _keyManager . setActiveItem ( value ) ;
248
- this . indexFocused . emit ( value ) ;
249
- this . _setTabFocus ( value ) ;
250
262
}
251
263
252
264
/**
0 commit comments