@@ -21,6 +21,7 @@ import {
21
21
} from '@angular/core' ;
22
22
import { DOCUMENT } from '@angular/common' ;
23
23
import { BooleanInput , coerceBooleanProperty } from '@angular/cdk/coercion' ;
24
+ import { FocusMonitor } from '@angular/cdk/a11y' ;
24
25
import { Subscription } from 'rxjs' ;
25
26
26
27
import { createPopper , Instance , Options , Placement } from '@popperjs/core' ;
@@ -33,7 +34,7 @@ export abstract class DropdownToken {}
33
34
34
35
@Directive ( {
35
36
selector : '[cDropdownToggle]' ,
36
- providers : [ { provide : DropdownToken , useExisting : forwardRef ( ( ) => DropdownComponent ) } ] ,
37
+ providers : [ { provide : DropdownToken , useExisting : forwardRef ( ( ) => DropdownComponent ) } ] ,
37
38
exportAs : 'cDropdownToggle'
38
39
} )
39
40
export class DropdownToggleDirective implements AfterViewInit {
@@ -75,9 +76,11 @@ export class DropdownToggleDirective implements AfterViewInit {
75
76
set split ( value : boolean ) {
76
77
this . _split = coerceBooleanProperty ( value ) ;
77
78
}
79
+
78
80
get split ( ) : boolean {
79
81
return this . _split ;
80
82
}
83
+
81
84
private _split = false ;
82
85
83
86
@HostBinding ( 'class' )
@@ -132,9 +135,11 @@ export class DropdownComponent implements AfterContentInit, OnDestroy, OnInit {
132
135
set dark ( value : boolean ) {
133
136
this . _dark = coerceBooleanProperty ( value ) ;
134
137
} ;
138
+
135
139
get dark ( ) {
136
140
return this . _dark ;
137
141
}
142
+
138
143
private _dark = false ;
139
144
140
145
/**
@@ -158,9 +163,11 @@ export class DropdownComponent implements AfterContentInit, OnDestroy, OnInit {
158
163
set popper ( value : boolean ) {
159
164
this . _popper = coerceBooleanProperty ( value ) ;
160
165
}
166
+
161
167
get popper ( ) : boolean {
162
168
return this . _popper ;
163
169
}
170
+
164
171
private _popper = true ;
165
172
166
173
/**
@@ -171,6 +178,7 @@ export class DropdownComponent implements AfterContentInit, OnDestroy, OnInit {
171
178
set popperOptions ( value : Partial < Options > ) {
172
179
this . _popperOptions = { ...this . _popperOptions , ...value } ;
173
180
} ;
181
+
174
182
get popperOptions ( ) : Partial < Options > {
175
183
let placement = this . placement ;
176
184
switch ( this . direction ) {
@@ -201,14 +209,15 @@ export class DropdownComponent implements AfterContentInit, OnDestroy, OnInit {
201
209
this . _popperOptions = { ...this . _popperOptions , placement : placement } ;
202
210
return this . _popperOptions ;
203
211
}
212
+
204
213
private _popperOptions : Partial < Options > = {
205
214
placement : this . placement ,
206
215
modifiers : [ ] ,
207
216
strategy : 'absolute'
208
217
} ;
209
218
210
219
/**
211
- * Set the dropdown variant to an btn-group, dropdown, input-group, and nav-item.
220
+ * Set the dropdown variant to a btn-group, dropdown, input-group, and nav-item.
212
221
*/
213
222
@Input ( ) variant ?: 'btn-group' | 'dropdown' | 'input-group' | 'nav-item' = 'dropdown' ;
214
223
@@ -225,9 +234,11 @@ export class DropdownComponent implements AfterContentInit, OnDestroy, OnInit {
225
234
_value ? this . createPopperInstance ( ) : this . destroyPopperInstance ( ) ;
226
235
this . visibleChange . emit ( _value ) ;
227
236
}
237
+
228
238
get visible ( ) : boolean {
229
239
return this . _visible ;
230
240
}
241
+
231
242
private _visible = false ;
232
243
233
244
@Output ( ) visibleChange : EventEmitter < boolean > = new EventEmitter < boolean > ( ) ;
@@ -243,11 +254,12 @@ export class DropdownComponent implements AfterContentInit, OnDestroy, OnInit {
243
254
private listeners : ( ( ) => void ) [ ] = [ ] ;
244
255
245
256
constructor (
246
- @Inject ( DOCUMENT ) private document : any ,
257
+ @Inject ( DOCUMENT ) private document : Document ,
247
258
private elementRef : ElementRef ,
248
259
private renderer : Renderer2 ,
249
260
private ngZone : NgZone ,
250
261
private changeDetectorRef : ChangeDetectorRef ,
262
+ private focusMonitor : FocusMonitor ,
251
263
public dropdownService : DropdownService
252
264
) { }
253
265
@@ -259,7 +271,7 @@ export class DropdownComponent implements AfterContentInit, OnDestroy, OnInit {
259
271
! this . direction ,
260
272
[ `${ this . direction } ` ] : ! ! this . direction ,
261
273
[ `${ this . variant } ` ] : ! ! this . variant ,
262
- 'dropup' : this . direction === 'dropup' || this . direction === 'dropup-center' ,
274
+ 'dropup' : this . direction === 'dropup' || this . direction === 'dropup-center' ,
263
275
show : this . visible
264
276
} ;
265
277
}
@@ -308,6 +320,14 @@ export class DropdownComponent implements AfterContentInit, OnDestroy, OnInit {
308
320
if ( this . variant === 'nav-item' ) {
309
321
this . renderer . addClass ( this . _toggler . elementRef . nativeElement , 'nav-link' ) ;
310
322
}
323
+ this . focusMonitor . monitor ( this . elementRef , true ) . subscribe ( origin => {
324
+ this . ngZone . run ( ( ) => {
325
+ if ( ( ! origin ) && ( this . autoClose === true || this . autoClose === 'outside' ) ) {
326
+ this . setVisibleState ( false ) ;
327
+ this . changeDetectorRef . markForCheck ( ) ;
328
+ }
329
+ } ) ;
330
+ } ) ;
311
331
}
312
332
313
333
ngOnInit ( ) : void {
@@ -316,6 +336,7 @@ export class DropdownComponent implements AfterContentInit, OnDestroy, OnInit {
316
336
}
317
337
318
338
ngOnDestroy ( ) : void {
339
+ this . focusMonitor ?. stopMonitoring ( this . elementRef ) ;
319
340
this . clearListeners ( ) ;
320
341
this . dropdownStateSubscribe ( false ) ;
321
342
this . destroyPopperInstance ( ) ;
@@ -341,6 +362,7 @@ export class DropdownComponent implements AfterContentInit, OnDestroy, OnInit {
341
362
}
342
363
this . ngZone . run ( ( ) => {
343
364
this . setListeners ( ) ;
365
+ this . changeDetectorRef . markForCheck ( ) ;
344
366
this . changeDetectorRef . detectChanges ( ) ;
345
367
} ) ;
346
368
} ) ;
0 commit comments