@@ -19,7 +19,9 @@ import {
19
19
ContentChild ,
20
20
Directive ,
21
21
EventEmitter ,
22
+ ElementRef ,
22
23
Input ,
24
+ Inject ,
23
25
OnChanges ,
24
26
OnDestroy ,
25
27
Optional ,
@@ -28,7 +30,9 @@ import {
28
30
SkipSelf ,
29
31
ViewContainerRef ,
30
32
ViewEncapsulation ,
33
+ ViewChild ,
31
34
} from '@angular/core' ;
35
+ import { DOCUMENT } from '@angular/common' ;
32
36
import { Subject } from 'rxjs' ;
33
37
import { filter , startWith , take } from 'rxjs/operators' ;
34
38
import { MatAccordion } from './accordion' ;
@@ -72,8 +76,13 @@ let uniqueId = 0;
72
76
'[class.mat-expansion-panel-spacing]' : '_hasSpacing()' ,
73
77
}
74
78
} )
75
- export class MatExpansionPanel extends _CdkAccordionItem
76
- implements AfterContentInit , OnChanges , OnDestroy {
79
+ export class MatExpansionPanel extends CdkAccordionItem implements AfterContentInit , OnChanges ,
80
+ OnDestroy {
81
+
82
+ // @breaking -change 8.0.0 Remove `| undefined` from here
83
+ // when the `_document` constructor param is required.
84
+ private _document : Document | undefined ;
85
+
77
86
/** Whether the toggle indicator should be hidden. */
78
87
@Input ( )
79
88
get hideToggle ( ) : boolean {
@@ -99,6 +108,9 @@ export class MatExpansionPanel extends _CdkAccordionItem
99
108
/** Content that will be rendered lazily. */
100
109
@ContentChild ( MatExpansionPanelContent ) _lazyContent : MatExpansionPanelContent ;
101
110
111
+ /** Element containing the panel's user-provided content. */
112
+ @ViewChild ( 'body' ) _body : ElementRef < HTMLElement > ;
113
+
102
114
/** Portal holding the user's content. */
103
115
_portal : TemplatePortal ;
104
116
@@ -108,9 +120,11 @@ export class MatExpansionPanel extends _CdkAccordionItem
108
120
constructor ( @Optional ( ) @SkipSelf ( ) accordion : MatAccordion ,
109
121
_changeDetectorRef : ChangeDetectorRef ,
110
122
_uniqueSelectionDispatcher : UniqueSelectionDispatcher ,
111
- private _viewContainerRef : ViewContainerRef ) {
123
+ private _viewContainerRef : ViewContainerRef ,
124
+ @Inject ( DOCUMENT ) _document ?: any ) {
112
125
super ( accordion , _changeDetectorRef , _uniqueSelectionDispatcher ) ;
113
126
this . accordion = accordion ;
127
+ this . _document = _document ;
114
128
}
115
129
116
130
/** Determines whether the expansion panel should have spacing between it and its siblings. */
@@ -174,6 +188,17 @@ export class MatExpansionPanel extends _CdkAccordionItem
174
188
this . afterCollapse . emit ( ) ;
175
189
}
176
190
}
191
+
192
+ /** Checks whether the expansion panel's content contains the currently-focused element. */
193
+ _containsFocus ( ) : boolean {
194
+ if ( this . _body && this . _document ) {
195
+ const focusedElement = this . _document . activeElement ;
196
+ const bodyElement = this . _body . nativeElement ;
197
+ return focusedElement === bodyElement || bodyElement . contains ( focusedElement ) ;
198
+ }
199
+
200
+ return false ;
201
+ }
177
202
}
178
203
179
204
@Directive ( {
0 commit comments