1+ import { DOCUMENT } from '@angular/common' ;
12import {
23 AfterContentInit ,
34 AfterViewInit ,
45 booleanAttribute ,
56 ChangeDetectorRef ,
67 Component ,
78 ContentChild ,
9+ DestroyRef ,
810 Directive ,
911 ElementRef ,
1012 EventEmitter ,
1113 forwardRef ,
1214 HostBinding ,
1315 HostListener ,
16+ inject ,
1417 Inject ,
1518 Input ,
1619 NgZone ,
1720 OnChanges ,
1821 OnDestroy ,
1922 OnInit ,
20- Optional ,
2123 Output ,
2224 Renderer2 ,
25+ signal ,
2326 SimpleChanges
2427} from '@angular/core' ;
25- import { DOCUMENT } from '@angular/common ' ;
28+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop ' ;
2629import { Subscription } from 'rxjs' ;
2730import { filter } from 'rxjs/operators' ;
2831
@@ -42,12 +45,11 @@ export abstract class DropdownToken {}
4245 standalone : true
4346} )
4447export class DropdownToggleDirective implements AfterViewInit {
45-
46- constructor (
47- public elementRef : ElementRef ,
48- private dropdownService : DropdownService ,
49- @Optional ( ) public dropdown ?: DropdownToken
50- ) { }
48+ // injections
49+ readonly #destroyRef = inject ( DestroyRef ) ;
50+ public readonly elementRef = inject ( ElementRef ) ;
51+ #dropdownService = inject ( DropdownService ) ;
52+ public dropdown = inject ( DropdownToken , { optional : true } ) ;
5153
5254 /**
5355 * Toggle the disabled state for the toggler.
@@ -70,7 +72,8 @@ export class DropdownToggleDirective implements AfterViewInit {
7072 @Input ( ) caret = true ;
7173
7274 /**
73- * Create split button dropdowns with virtually the same markup as single button dropdowns, but with the addition of `.dropdown-toggle-split` class for proper spacing around the dropdown caret.
75+ * Create split button dropdowns with virtually the same markup as single button dropdowns,
76+ * but with the addition of `.dropdown-toggle-split` class for proper spacing around the dropdown caret.
7477 * @type boolean
7578 * @default false
7679 */
@@ -85,16 +88,29 @@ export class DropdownToggleDirective implements AfterViewInit {
8588 } ;
8689 }
8790
91+ #ariaExpanded = signal ( false ) ;
92+
93+ @HostBinding ( 'attr.aria-expanded' )
94+ get ariaExpanded ( ) {
95+ return this . #ariaExpanded( ) ;
96+ }
97+
8898 @HostListener ( 'click' , [ '$event' ] )
8999 public onClick ( $event : MouseEvent ) : void {
90100 $event . preventDefault ( ) ;
91- ! this . disabled && this . dropdownService . toggle ( { visible : 'toggle' , dropdown : this . dropdown } ) ;
101+ ! this . disabled && this . # dropdownService. toggle ( { visible : 'toggle' , dropdown : this . dropdown } ) ;
92102 }
93103
94104 ngAfterViewInit ( ) : void {
95105 if ( this . dropdownComponent ) {
96106 this . dropdown = this . dropdownComponent ;
97- this . dropdownService = this . dropdownComponent ?. dropdownService ;
107+ this . #dropdownService = this . dropdownComponent ?. dropdownService ;
108+ }
109+ if ( this . dropdown ) {
110+ const dropdown = < DropdownComponent > this . dropdown ;
111+ dropdown ?. visibleChange ?. pipe ( takeUntilDestroyed ( this . #destroyRef) ) . subscribe ( ( visible ) => {
112+ this . #ariaExpanded. set ( visible ) ;
113+ } ) ;
98114 }
99115 }
100116}
@@ -109,7 +125,6 @@ export class DropdownToggleDirective implements AfterViewInit {
109125 hostDirectives : [ { directive : ThemeDirective , inputs : [ 'dark' ] } ]
110126} )
111127export class DropdownComponent implements AfterContentInit , OnChanges , OnDestroy , OnInit {
112-
113128 constructor (
114129 @Inject ( DOCUMENT ) private document : Document ,
115130 private elementRef : ElementRef ,
@@ -136,7 +151,8 @@ export class DropdownComponent implements AfterContentInit, OnChanges, OnDestroy
136151 @Input ( ) direction ?: 'center' | 'dropup' | 'dropup-center' | 'dropend' | 'dropstart' ;
137152
138153 /**
139- * Describes the placement of your component after Popper.js has applied all the modifiers that may have flipped or altered the originally provided placement property.
154+ * Describes the placement of your component after Popper.js has applied all the modifiers
155+ * that may have flipped or altered the originally provided placement property.
140156 * @type Placement
141157 */
142158 @Input ( ) placement : Placement = 'bottom-start' ;
@@ -155,7 +171,7 @@ export class DropdownComponent implements AfterContentInit, OnChanges, OnDestroy
155171 @Input ( )
156172 set popperOptions ( value : Partial < Options > ) {
157173 this . _popperOptions = { ...this . _popperOptions , ...value } ;
158- } ;
174+ }
159175
160176 get popperOptions ( ) : Partial < Options > {
161177 let placement = this . placement ;
@@ -237,12 +253,10 @@ export class DropdownComponent implements AfterContentInit, OnChanges, OnDestroy
237253 @HostBinding ( 'class' )
238254 get hostClasses ( ) : any {
239255 return {
240- dropdown :
241- ( this . variant === 'dropdown' || this . variant === 'nav-item' ) &&
242- ! this . direction ,
256+ dropdown : ( this . variant === 'dropdown' || this . variant === 'nav-item' ) && ! this . direction ,
243257 [ `${ this . direction } ` ] : ! ! this . direction ,
244258 [ `${ this . variant } ` ] : ! ! this . variant ,
245- ' dropup' : this . direction === 'dropup' || this . direction === 'dropup-center' ,
259+ dropup : this . direction === 'dropup' || this . direction === 'dropup-center' ,
246260 show : this . visible
247261 } ;
248262 }
@@ -262,16 +276,15 @@ export class DropdownComponent implements AfterContentInit, OnChanges, OnDestroy
262276
263277 dropdownStateSubscribe ( subscribe : boolean = true ) : void {
264278 if ( subscribe ) {
265- this . dropdownStateSubscription =
266- this . dropdownService . dropdownState$ . pipe (
279+ this . dropdownStateSubscription = this . dropdownService . dropdownState$
280+ . pipe (
267281 filter ( ( state ) => {
268282 return this === state . dropdown ;
269283 } )
270- ) . subscribe ( ( state ) => {
284+ )
285+ . subscribe ( ( state ) => {
271286 if ( 'visible' in state ) {
272- state ?. visible === 'toggle'
273- ? this . toggleDropdown ( )
274- : ( this . visible = state . visible ) ;
287+ state ?. visible === 'toggle' ? this . toggleDropdown ( ) : ( this . visible = state . visible ) ;
275288 }
276289 } ) ;
277290 } else {
0 commit comments