@@ -11,19 +11,23 @@ import {CdkAccordionItem} from '@angular/cdk/accordion';
11
11
import { coerceBooleanProperty } from '@angular/cdk/coercion' ;
12
12
import { UniqueSelectionDispatcher } from '@angular/cdk/collections' ;
13
13
import { TemplatePortal } from '@angular/cdk/portal' ;
14
+ import { DOCUMENT } from '@angular/common' ;
14
15
import {
15
16
AfterContentInit ,
16
17
ChangeDetectionStrategy ,
17
18
ChangeDetectorRef ,
18
19
Component ,
19
20
ContentChild ,
20
21
Directive ,
22
+ ElementRef ,
23
+ Inject ,
21
24
Input ,
22
25
OnChanges ,
23
26
OnDestroy ,
24
27
Optional ,
25
28
SimpleChanges ,
26
29
SkipSelf ,
30
+ ViewChild ,
27
31
ViewContainerRef ,
28
32
ViewEncapsulation ,
29
33
} from '@angular/core' ;
@@ -70,8 +74,13 @@ let uniqueId = 0;
70
74
'[class.mat-expansion-panel-spacing]' : '_hasSpacing()' ,
71
75
}
72
76
} )
73
- export class MatExpansionPanel extends _CdkAccordionItem
74
- implements AfterContentInit , OnChanges , OnDestroy {
77
+ export class MatExpansionPanel extends CdkAccordionItem implements AfterContentInit , OnChanges ,
78
+ OnDestroy {
79
+
80
+ // @breaking -change 8.0.0 Remove `| undefined` from here
81
+ // when the `_document` constructor param is required.
82
+ private _document : Document | undefined ;
83
+
75
84
/** Whether the toggle indicator should be hidden. */
76
85
@Input ( )
77
86
get hideToggle ( ) : boolean {
@@ -91,6 +100,9 @@ export class MatExpansionPanel extends _CdkAccordionItem
91
100
/** Content that will be rendered lazily. */
92
101
@ContentChild ( MatExpansionPanelContent ) _lazyContent : MatExpansionPanelContent ;
93
102
103
+ /** Element containing the panel's user-provided content. */
104
+ @ViewChild ( 'body' ) _body : ElementRef < HTMLElement > ;
105
+
94
106
/** Portal holding the user's content. */
95
107
_portal : TemplatePortal ;
96
108
@@ -100,9 +112,11 @@ export class MatExpansionPanel extends _CdkAccordionItem
100
112
constructor ( @Optional ( ) @SkipSelf ( ) accordion : MatAccordion ,
101
113
_changeDetectorRef : ChangeDetectorRef ,
102
114
_uniqueSelectionDispatcher : UniqueSelectionDispatcher ,
103
- private _viewContainerRef : ViewContainerRef ) {
115
+ private _viewContainerRef : ViewContainerRef ,
116
+ @Inject ( DOCUMENT ) _document ?: any ) {
104
117
super ( accordion , _changeDetectorRef , _uniqueSelectionDispatcher ) ;
105
118
this . accordion = accordion ;
119
+ this . _document = _document ;
106
120
}
107
121
108
122
/** Determines whether the expansion panel should have spacing between it and its siblings. */
@@ -158,6 +172,17 @@ export class MatExpansionPanel extends _CdkAccordionItem
158
172
classList . remove ( cssClass ) ;
159
173
}
160
174
}
175
+
176
+ /** Checks whether the expansion panel's content contains the currently-focused element. */
177
+ _containsFocus ( ) : boolean {
178
+ if ( this . _body && this . _document ) {
179
+ const focusedElement = this . _document . activeElement ;
180
+ const bodyElement = this . _body . nativeElement ;
181
+ return focusedElement === bodyElement || bodyElement . contains ( focusedElement ) ;
182
+ }
183
+
184
+ return false ;
185
+ }
161
186
}
162
187
163
188
@Directive ( {
0 commit comments