@@ -64,7 +64,8 @@ export abstract class _MatTabNavBase
64
64
implements AfterContentChecked , AfterContentInit , OnDestroy
65
65
{
66
66
/** Query list of all tab links of the tab navigation. */
67
- abstract override _items : QueryList < MatPaginatedTabHeaderItem & { active : boolean ; id : string} > ;
67
+ abstract override _items : QueryList <
68
+ MatPaginatedTabHeaderItem & { active : boolean ; id : string ; index : number } > ;
68
69
69
70
/** Background color of the tab nav. */
70
71
@Input ( )
@@ -101,7 +102,7 @@ export abstract class _MatTabNavBase
101
102
* follows the ARIA link / navigation landmark pattern. If provided, it follows the
102
103
* ARIA tabs design pattern.
103
104
*/
104
- @Input ( ) panel ?: MatTabNavPanel ;
105
+ @Input ( ) tabPanel ?: MatTabNavPanel ;
105
106
106
107
constructor (
107
108
elementRef : ElementRef ,
@@ -124,6 +125,7 @@ export abstract class _MatTabNavBase
124
125
// selectedIndex is up-to-date by the time the super class starts looking for it.
125
126
this . _items . changes . pipe ( startWith ( null ) , takeUntil ( this . _destroyed ) ) . subscribe ( ( ) => {
126
127
this . updateActiveLink ( ) ;
128
+ this . updateIndices ( ) ;
127
129
} ) ;
128
130
129
131
super . ngAfterContentInit ( ) ;
@@ -142,8 +144,8 @@ export abstract class _MatTabNavBase
142
144
this . selectedIndex = i ;
143
145
this . _changeDetectorRef . markForCheck ( ) ;
144
146
145
- if ( this . panel ) {
146
- this . panel . _activeTabId = items [ i ] . id ;
147
+ if ( this . tabPanel ) {
148
+ this . tabPanel . _activeTabId = items [ i ] . id ;
147
149
}
148
150
149
151
return ;
@@ -154,6 +156,19 @@ export abstract class _MatTabNavBase
154
156
this . selectedIndex = - 1 ;
155
157
this . _inkBar . hide ( ) ;
156
158
}
159
+
160
+ /** Updates the indices of the tabs within the nav bar. */
161
+ updateIndices ( ) {
162
+ if ( ! this . _items ) {
163
+ return ;
164
+ }
165
+
166
+ const items = this . _items . toArray ( ) ;
167
+
168
+ for ( let i = 0 ; i < items . length ; i ++ ) {
169
+ items [ i ] . index = i ;
170
+ }
171
+ }
157
172
}
158
173
159
174
/**
@@ -260,6 +275,9 @@ export class _MatTabLinkBase
260
275
/** Unique id for the tab. */
261
276
@Input ( ) id = `mat-tab-link-${ nextUniqueId ++ } ` ;
262
277
278
+ /** Index of the tab within the nav bar. Managed by the nav bar. */
279
+ index = - 1 ;
280
+
263
281
constructor (
264
282
private _tabNavBar : _MatTabNavBase ,
265
283
/** @docs -private */ public elementRef : ElementRef ,
@@ -294,31 +312,26 @@ export class _MatTabLinkBase
294
312
_handleFocus ( ) {
295
313
// Since we allow navigation through tabbing in the nav bar, we
296
314
// have to update the focused index whenever the link receives focus.
297
- this . _tabNavBar . focusIndex = this . _getIndex ( ) ;
315
+ this . _tabNavBar . focusIndex = this . index ;
298
316
}
299
317
300
318
_handleKeydown ( event : KeyboardEvent ) {
301
- if ( this . _tabNavBar . panel && event . keyCode === SPACE ) {
319
+ if ( this . _tabNavBar . tabPanel && event . keyCode === SPACE ) {
302
320
this . elementRef . nativeElement . click ( ) ;
303
321
}
304
322
}
305
323
306
324
/** Returns the tab's tabindex. */
307
325
_getTabIndex ( ) : number {
308
- if ( ! this . _tabNavBar . panel ) {
326
+ if ( ! this . _tabNavBar . tabPanel ) {
309
327
return this . tabIndex ;
310
328
}
311
329
312
330
if ( ! this . _tabNavBar . _items ) {
313
331
return this . _isActive ? 0 : - 1 ;
314
332
}
315
333
316
- return this . _tabNavBar . focusIndex === this . _getIndex ( ) ? 0 : - 1 ;
317
- }
318
-
319
- /** Returns this item's index in the nav bar. */
320
- _getIndex ( ) : number {
321
- return this . _tabNavBar . _items . toArray ( ) . indexOf ( this ) ;
334
+ return ( this . _tabNavBar . focusIndex === this . index ) ? 0 : - 1 ;
322
335
}
323
336
324
337
static ngAcceptInputType_active : BooleanInput ;
@@ -336,13 +349,13 @@ export class _MatTabLinkBase
336
349
inputs : [ 'disabled' , 'disableRipple' , 'tabIndex' ] ,
337
350
host : {
338
351
'class' : 'mat-tab-link mat-focus-indicator' ,
339
- '[attr.aria-controls]' : '_tabNavBar.panel ? _tabNavBar.panel .id : null' ,
340
- '[attr.aria-current]' : '(active && !_tabNavBar.panel ) ? "page" : null' ,
352
+ '[attr.aria-controls]' : '_tabNavBar.tabPanel ? _tabNavBar.tabPanel .id : null' ,
353
+ '[attr.aria-current]' : '(active && !_tabNavBar.tabPanel ) ? "page" : null' ,
341
354
'[attr.aria-disabled]' : 'disabled' ,
342
- '[attr.aria-selected]' : '_tabNavBar.panel ? (active ? "true" : "false") : null' ,
355
+ '[attr.aria-selected]' : '_tabNavBar.tabPanel ? (active ? "true" : "false") : null' ,
343
356
'[attr.id]' : 'id' ,
344
357
'[attr.tabIndex]' : '_getTabIndex()' ,
345
- '[attr.role]' : '_tabNavBar.panel ? "tab" : null' ,
358
+ '[attr.role]' : '_tabNavBar.tabPanel ? "tab" : null' ,
346
359
'[class.mat-tab-disabled]' : 'disabled' ,
347
360
'[class.mat-tab-label-active]' : 'active' ,
348
361
'(focus)' : '_handleFocus()' ,
0 commit comments