1
+ import { DOCUMENT } from '@angular/common' ;
1
2
import {
2
3
AfterContentInit ,
3
4
AfterViewInit ,
4
5
booleanAttribute ,
5
6
ChangeDetectorRef ,
6
7
Component ,
7
8
ContentChild ,
9
+ DestroyRef ,
8
10
Directive ,
9
11
ElementRef ,
10
12
EventEmitter ,
11
13
forwardRef ,
12
14
HostBinding ,
13
15
HostListener ,
16
+ inject ,
14
17
Inject ,
15
18
Input ,
16
19
NgZone ,
17
20
OnChanges ,
18
21
OnDestroy ,
19
22
OnInit ,
20
- Optional ,
21
23
Output ,
22
24
Renderer2 ,
25
+ signal ,
23
26
SimpleChanges
24
27
} from '@angular/core' ;
25
- import { DOCUMENT } from '@angular/common ' ;
28
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop ' ;
26
29
import { Subscription } from 'rxjs' ;
27
30
import { filter } from 'rxjs/operators' ;
28
31
@@ -42,12 +45,11 @@ export abstract class DropdownToken {}
42
45
standalone : true
43
46
} )
44
47
export 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 } ) ;
51
53
52
54
/**
53
55
* Toggle the disabled state for the toggler.
@@ -70,7 +72,8 @@ export class DropdownToggleDirective implements AfterViewInit {
70
72
@Input ( ) caret = true ;
71
73
72
74
/**
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.
74
77
* @type boolean
75
78
* @default false
76
79
*/
@@ -85,16 +88,29 @@ export class DropdownToggleDirective implements AfterViewInit {
85
88
} ;
86
89
}
87
90
91
+ #ariaExpanded = signal ( false ) ;
92
+
93
+ @HostBinding ( 'attr.aria-expanded' )
94
+ get ariaExpanded ( ) {
95
+ return this . #ariaExpanded( ) ;
96
+ }
97
+
88
98
@HostListener ( 'click' , [ '$event' ] )
89
99
public onClick ( $event : MouseEvent ) : void {
90
100
$event . preventDefault ( ) ;
91
- ! this . disabled && this . dropdownService . toggle ( { visible : 'toggle' , dropdown : this . dropdown } ) ;
101
+ ! this . disabled && this . # dropdownService. toggle ( { visible : 'toggle' , dropdown : this . dropdown } ) ;
92
102
}
93
103
94
104
ngAfterViewInit ( ) : void {
95
105
if ( this . dropdownComponent ) {
96
106
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
+ } ) ;
98
114
}
99
115
}
100
116
}
@@ -109,7 +125,6 @@ export class DropdownToggleDirective implements AfterViewInit {
109
125
hostDirectives : [ { directive : ThemeDirective , inputs : [ 'dark' ] } ]
110
126
} )
111
127
export class DropdownComponent implements AfterContentInit , OnChanges , OnDestroy , OnInit {
112
-
113
128
constructor (
114
129
@Inject ( DOCUMENT ) private document : Document ,
115
130
private elementRef : ElementRef ,
@@ -136,7 +151,8 @@ export class DropdownComponent implements AfterContentInit, OnChanges, OnDestroy
136
151
@Input ( ) direction ?: 'center' | 'dropup' | 'dropup-center' | 'dropend' | 'dropstart' ;
137
152
138
153
/**
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.
140
156
* @type Placement
141
157
*/
142
158
@Input ( ) placement : Placement = 'bottom-start' ;
@@ -155,7 +171,7 @@ export class DropdownComponent implements AfterContentInit, OnChanges, OnDestroy
155
171
@Input ( )
156
172
set popperOptions ( value : Partial < Options > ) {
157
173
this . _popperOptions = { ...this . _popperOptions , ...value } ;
158
- } ;
174
+ }
159
175
160
176
get popperOptions ( ) : Partial < Options > {
161
177
let placement = this . placement ;
@@ -237,12 +253,10 @@ export class DropdownComponent implements AfterContentInit, OnChanges, OnDestroy
237
253
@HostBinding ( 'class' )
238
254
get hostClasses ( ) : any {
239
255
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 ,
243
257
[ `${ this . direction } ` ] : ! ! this . direction ,
244
258
[ `${ this . variant } ` ] : ! ! this . variant ,
245
- ' dropup' : this . direction === 'dropup' || this . direction === 'dropup-center' ,
259
+ dropup : this . direction === 'dropup' || this . direction === 'dropup-center' ,
246
260
show : this . visible
247
261
} ;
248
262
}
@@ -262,16 +276,15 @@ export class DropdownComponent implements AfterContentInit, OnChanges, OnDestroy
262
276
263
277
dropdownStateSubscribe ( subscribe : boolean = true ) : void {
264
278
if ( subscribe ) {
265
- this . dropdownStateSubscription =
266
- this . dropdownService . dropdownState$ . pipe (
279
+ this . dropdownStateSubscription = this . dropdownService . dropdownState$
280
+ . pipe (
267
281
filter ( ( state ) => {
268
282
return this === state . dropdown ;
269
283
} )
270
- ) . subscribe ( ( state ) => {
284
+ )
285
+ . subscribe ( ( state ) => {
271
286
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 ) ;
275
288
}
276
289
} ) ;
277
290
} else {
0 commit comments