@@ -10,6 +10,7 @@ import {FocusableOption, FocusMonitor, FocusOrigin} from '@angular/cdk/a11y';
10
10
import { ENTER , hasModifierKey , SPACE } from '@angular/cdk/keycodes' ;
11
11
import {
12
12
AfterViewInit ,
13
+ Attribute ,
13
14
ChangeDetectionStrategy ,
14
15
ChangeDetectorRef ,
15
16
Component ,
@@ -23,6 +24,8 @@ import {
23
24
ViewEncapsulation ,
24
25
} from '@angular/core' ;
25
26
import { ANIMATION_MODULE_TYPE } from '@angular/platform-browser/animations' ;
27
+ import { HasTabIndex , HasTabIndexCtor , mixinTabIndex } from '@angular/material/core' ;
28
+ import { NumberInput } from '@angular/cdk/coercion' ;
26
29
import { EMPTY , merge , Subscription } from 'rxjs' ;
27
30
import { filter } from 'rxjs/operators' ;
28
31
import { MatAccordionTogglePosition } from './accordion-base' ;
@@ -34,6 +37,15 @@ import {
34
37
} from './expansion-panel' ;
35
38
36
39
40
+ // Boilerplate for applying mixins to MatExpansionPanelHeader.
41
+ /** @docs -private */
42
+ abstract class MatExpansionPanelHeaderBase {
43
+ abstract readonly disabled : boolean ;
44
+ }
45
+ const _MatExpansionPanelHeaderMixinBase :
46
+ HasTabIndexCtor &
47
+ typeof MatExpansionPanelHeaderBase = mixinTabIndex ( MatExpansionPanelHeaderBase ) ;
48
+
37
49
/**
38
50
* Header element of a `<mat-expansion-panel>`.
39
51
*/
@@ -43,14 +55,15 @@ import {
43
55
templateUrl : 'expansion-panel-header.html' ,
44
56
encapsulation : ViewEncapsulation . None ,
45
57
changeDetection : ChangeDetectionStrategy . OnPush ,
58
+ inputs : [ 'tabIndex' ] ,
46
59
animations : [
47
60
matExpansionAnimations . indicatorRotate ,
48
61
] ,
49
62
host : {
50
63
'class' : 'mat-expansion-panel-header mat-focus-indicator' ,
51
64
'role' : 'button' ,
52
65
'[attr.id]' : 'panel._headerId' ,
53
- '[attr.tabindex]' : 'disabled ? -1 : 0 ' ,
66
+ '[attr.tabindex]' : 'tabIndex ' ,
54
67
'[attr.aria-controls]' : '_getPanelId()' ,
55
68
'[attr.aria-expanded]' : '_isExpanded()' ,
56
69
'[attr.aria-disabled]' : 'panel.disabled' ,
@@ -63,7 +76,8 @@ import {
63
76
'(keydown)' : '_keydown($event)' ,
64
77
} ,
65
78
} )
66
- export class MatExpansionPanelHeader implements AfterViewInit , OnDestroy , FocusableOption {
79
+ export class MatExpansionPanelHeader extends _MatExpansionPanelHeaderMixinBase implements
80
+ AfterViewInit , OnDestroy , FocusableOption , HasTabIndex {
67
81
private _parentChangeSubscription = Subscription . EMPTY ;
68
82
69
83
constructor (
@@ -73,11 +87,14 @@ export class MatExpansionPanelHeader implements AfterViewInit, OnDestroy, Focusa
73
87
private _changeDetectorRef : ChangeDetectorRef ,
74
88
@Inject ( MAT_EXPANSION_PANEL_DEFAULT_OPTIONS ) @Optional ( )
75
89
defaultOptions ?: MatExpansionPanelDefaultOptions ,
76
- @Optional ( ) @Inject ( ANIMATION_MODULE_TYPE ) public _animationMode ?: string ) {
90
+ @Optional ( ) @Inject ( ANIMATION_MODULE_TYPE ) public _animationMode ?: string ,
91
+ @Attribute ( 'tabindex' ) tabIndex ?: string ) {
92
+ super ( ) ;
77
93
const accordionHideToggleChange = panel . accordion ?
78
94
panel . accordion . _stateChanges . pipe (
79
95
filter ( changes => ! ! ( changes [ 'hideToggle' ] || changes [ 'togglePosition' ] ) ) ) :
80
96
EMPTY ;
97
+ this . tabIndex = parseInt ( tabIndex || '' ) || 0 ;
81
98
82
99
// Since the toggle state depends on an @Input on the panel, we
83
100
// need to subscribe and trigger change detection manually.
@@ -210,6 +227,8 @@ export class MatExpansionPanelHeader implements AfterViewInit, OnDestroy, Focusa
210
227
this . _parentChangeSubscription . unsubscribe ( ) ;
211
228
this . _focusMonitor . stopMonitoring ( this . _element ) ;
212
229
}
230
+
231
+ static ngAcceptInputType_tabIndex : NumberInput ;
213
232
}
214
233
215
234
/**
0 commit comments