11import {
22 AfterContentInit ,
3+ AfterViewInit ,
34 ChangeDetectorRef ,
45 Component ,
56 ContentChild ,
@@ -20,20 +21,41 @@ import {
2021import { DOCUMENT } from '@angular/common' ;
2122import { BooleanInput , coerceBooleanProperty } from '@angular/cdk/coercion' ;
2223import { Subscription } from 'rxjs' ;
24+
2325import { createPopper , Instance , Options , Placement } from '@popperjs/core' ;
2426
2527import { DropdownService } from '../dropdown.service' ;
2628import { DropdownMenuDirective } from '../dropdown-menu/dropdown-menu.directive' ;
2729
2830@Directive ( {
2931 selector : '[cDropdownToggle]' ,
30- exportAs : 'cDropdownToggle' ,
32+ exportAs : 'cDropdownToggle'
3133} )
32- export class DropdownToggleDirective {
34+ export class DropdownToggleDirective implements AfterViewInit {
3335
3436 static ngAcceptInputType_split : BooleanInput ;
3537 static ngAcceptInputType_popper : BooleanInput ;
3638
39+ constructor (
40+ public elementRef : ElementRef ,
41+ private dropdownService : DropdownService ,
42+ @Optional ( ) public dropdown ?: DropdownComponent
43+ ) { }
44+
45+ /**
46+ * Toggle the disabled state for the toggler.
47+ * @type DropdownComponent | undefined
48+ * @default undefined
49+ */
50+ @Input ( ) dropdownComponent ?: DropdownComponent ;
51+
52+ /**
53+ * Disables the toggler.
54+ * @type boolean
55+ * @default false
56+ */
57+ @Input ( ) disabled ?: boolean = false ;
58+
3759 /**
3860 * Enables pseudo element caret on toggler.
3961 * @type boolean
@@ -53,24 +75,26 @@ export class DropdownToggleDirective {
5375 }
5476 private _split = false ;
5577
56- constructor (
57- public elementRef : ElementRef ,
58- private dropdownService : DropdownService ,
59- @Optional ( ) public dropdown ?: DropdownComponent
60- ) { }
61-
6278 @HostBinding ( 'class' )
6379 get hostClasses ( ) : any {
6480 return {
6581 'dropdown-toggle' : this . caret ,
6682 'dropdown-toggle-split' : this . split ,
83+ disabled : this . disabled
6784 } ;
6885 }
6986
7087 @HostListener ( 'click' , [ '$event' ] )
7188 public onClick ( $event : MouseEvent ) : void {
7289 $event . preventDefault ( ) ;
73- this . dropdownService . toggle ( { visible : 'toggle' , dropdown : this . dropdown } ) ;
90+ ! this . disabled && this . dropdownService . toggle ( { visible : 'toggle' , dropdown : this . dropdown } ) ;
91+ }
92+
93+ ngAfterViewInit ( ) : void {
94+ if ( this . dropdownComponent ) {
95+ this . dropdown = this . dropdownComponent ;
96+ this . dropdownService = this . dropdownComponent ?. dropdownService ;
97+ }
7498 }
7599}
76100
@@ -79,7 +103,7 @@ export class DropdownToggleDirective {
79103 template : '<ng-content></ng-content>' ,
80104 styleUrls : [ './dropdown.component.scss' ] ,
81105 exportAs : 'cDropdown' ,
82- providers : [ DropdownService ] ,
106+ providers : [ DropdownService ]
83107} )
84108export class DropdownComponent implements AfterContentInit , OnDestroy , OnInit {
85109
@@ -164,7 +188,6 @@ export class DropdownComponent implements AfterContentInit, OnDestroy, OnInit {
164188 this . _popperOptions = { ...this . _popperOptions , placement : placement } ;
165189 return this . _popperOptions ;
166190 }
167-
168191 private _popperOptions : Partial < Options > = {
169192 placement : this . placement ,
170193 modifiers : [ ] ,
@@ -196,7 +219,7 @@ export class DropdownComponent implements AfterContentInit, OnDestroy, OnInit {
196219
197220 @Output ( ) visibleChange : EventEmitter < boolean > = new EventEmitter < boolean > ( ) ;
198221
199- dropdownContext = { $implicit : this . visible } ;
222+ dropdownContext = { $implicit : this . visible } ;
200223 @ContentChild ( DropdownToggleDirective ) _toggler ! : DropdownToggleDirective ;
201224 @ContentChild ( DropdownMenuDirective ) _menu ! : DropdownMenuDirective ;
202225
@@ -212,7 +235,7 @@ export class DropdownComponent implements AfterContentInit, OnDestroy, OnInit {
212235 private renderer : Renderer2 ,
213236 private ngZone : NgZone ,
214237 private changeDetectorRef : ChangeDetectorRef ,
215- private dropdownService : DropdownService
238+ public dropdownService : DropdownService
216239 ) { }
217240
218241 @HostBinding ( 'class' )
@@ -225,14 +248,14 @@ export class DropdownComponent implements AfterContentInit, OnDestroy, OnInit {
225248 'btn-group' : this . variant === 'btn-group' ,
226249 'nav-item' : this . variant === 'nav-item' ,
227250 'input-group' : this . variant === 'input-group' ,
228- show : this . visible ,
251+ show : this . visible
229252 } ;
230253 }
231254
232255 // todo: find better solution
233256 @HostBinding ( 'style' )
234257 get hostStyle ( ) : any {
235- return this . variant === 'input-group' ? { display : 'contents' } : { } ;
258+ return this . variant === 'input-group' ? { display : 'contents' } : { } ;
236259 }
237260
238261 private clickedTarget ! : HTMLElement ;
@@ -287,7 +310,7 @@ export class DropdownComponent implements AfterContentInit, OnDestroy, OnInit {
287310 }
288311
289312 setVisibleState ( value : boolean ) : void {
290- this . dropdownService . toggle ( { visible : value , dropdown : this } ) ;
313+ this . dropdownService . toggle ( { visible : value , dropdown : this } ) ;
291314 }
292315
293316 // todo: turn off popper in navbar-nav
@@ -301,7 +324,7 @@ export class DropdownComponent implements AfterContentInit, OnDestroy, OnInit {
301324 this . popperInstance = createPopper (
302325 this . _toggler . elementRef . nativeElement ,
303326 this . _menu . elementRef . nativeElement ,
304- { ...this . popperOptions }
327+ { ...this . popperOptions }
305328 ) ;
306329 }
307330 this . ngZone . run ( ( ) => {
@@ -331,13 +354,13 @@ export class DropdownComponent implements AfterContentInit, OnDestroy, OnInit {
331354 return ;
332355 }
333356 if ( this . clickedTarget === target && this . autoClose === 'inside' ) {
334- this . setVisibleState ( false ) ;
335- return ;
336- }
357+ this . setVisibleState ( false ) ;
358+ return ;
359+ }
337360 if ( this . clickedTarget !== target && this . autoClose === 'outside' ) {
338- this . setVisibleState ( false ) ;
339- return ;
340- }
361+ this . setVisibleState ( false ) ;
362+ return ;
363+ }
341364 } )
342365 ) ;
343366 this . listeners . push (
0 commit comments