6
6
* found in the LICENSE file at https://angular.dev/license
7
7
*/
8
8
9
- import { contentChild , Directive , inject } from '@angular/core' ;
9
+ import {
10
+ afterRenderEffect ,
11
+ contentChild ,
12
+ Directive ,
13
+ ElementRef ,
14
+ inject ,
15
+ input ,
16
+ model ,
17
+ signal ,
18
+ WritableSignal ,
19
+ } from '@angular/core' ;
10
20
import { DeferredContent , DeferredContentAware } from '@angular/cdk-experimental/deferred-content' ;
21
+ import { ComboboxPattern , ComboboxPopupControls } from '../ui-patterns' ;
11
22
12
23
@Directive ( {
13
24
selector : '[cdkCombobox]' ,
@@ -18,25 +29,75 @@ import {DeferredContent, DeferredContentAware} from '@angular/cdk-experimental/d
18
29
inputs : [ 'preserveContent' ] ,
19
30
} ,
20
31
] ,
32
+ host : {
33
+ '[attr.data-expanded]' : 'pattern.expanded()' ,
34
+ '(input)' : 'pattern.onInput($event)' ,
35
+ '(keydown)' : 'pattern.onKeydown($event)' ,
36
+ '(pointerup)' : 'pattern.onPointerup($event)' ,
37
+ '(focusin)' : 'pattern.onFocusIn()' ,
38
+ '(focusout)' : 'pattern.onFocusOut($event)' ,
39
+ } ,
21
40
} )
22
- export class CdkCombobox {
41
+ export class CdkCombobox < V > {
42
+ /** The element that the combobox is attached to. */
43
+ private readonly _elementRef = inject ( ElementRef ) ;
44
+
23
45
/** The DeferredContentAware host directive. */
24
46
private readonly _deferredContentAware = inject ( DeferredContentAware , { optional : true } ) ;
25
47
26
48
/** The combobox popup. */
27
- readonly popup = contentChild ( CdkComboboxPopup ) ;
49
+ readonly popup = contentChild < CdkComboboxPopup < V > > ( CdkComboboxPopup ) ;
50
+
51
+ /** The filter mode for the combobox. */
52
+ filterMode = input < 'manual' | 'auto-select' | 'highlight' > ( 'manual' ) ;
53
+
54
+ /** Whether the combobox is focused. */
55
+ readonly isFocused = signal ( false ) ;
56
+
57
+ /** The values of the current selected items. */
58
+ value = model < V | undefined > ( undefined ) ;
59
+
60
+ /** The combobox ui pattern. */
61
+ readonly pattern = new ComboboxPattern < any , V > ( {
62
+ ...this ,
63
+ inputEl : signal ( undefined ) ,
64
+ containerEl : signal ( undefined ) ,
65
+ popupControls : ( ) => this . popup ( ) ?. actions ( ) ,
66
+ } ) ;
28
67
29
68
constructor ( ) {
30
- this . _deferredContentAware ?. contentVisible . set ( true ) ;
69
+ ( this . pattern . inputs . containerEl as WritableSignal < HTMLElement > ) . set (
70
+ this . _elementRef . nativeElement ,
71
+ ) ;
72
+
73
+ afterRenderEffect ( ( ) => {
74
+ this . _deferredContentAware ?. contentVisible . set ( this . pattern . isFocused ( ) ) ;
75
+ } ) ;
31
76
}
32
77
}
33
78
34
79
@Directive ( {
35
80
selector : 'input[cdkComboboxInput]' ,
36
81
exportAs : 'cdkComboboxInput' ,
37
- host : { 'role' : 'combobox' } ,
82
+ host : {
83
+ 'role' : 'combobox' ,
84
+ '[attr.aria-expanded]' : 'combobox.pattern.expanded()' ,
85
+ '[attr.aria-activedescendant]' : 'combobox.pattern.activedescendant()' ,
86
+ } ,
38
87
} )
39
- export class CdkComboboxInput { }
88
+ export class CdkComboboxInput {
89
+ /** The element that the combobox is attached to. */
90
+ private readonly _elementRef = inject ( ElementRef ) ;
91
+
92
+ /** The combobox that the input belongs to. */
93
+ readonly combobox = inject ( CdkCombobox ) ;
94
+
95
+ constructor ( ) {
96
+ ( this . combobox . pattern . inputs . inputEl as WritableSignal < HTMLInputElement > ) . set (
97
+ this . _elementRef . nativeElement ,
98
+ ) ;
99
+ }
100
+ }
40
101
41
102
@Directive ( {
42
103
selector : 'ng-template[cdkComboboxPopupContent]' ,
@@ -49,7 +110,10 @@ export class CdkComboboxPopupContent {}
49
110
selector : '[cdkComboboxPopup]' ,
50
111
exportAs : 'cdkComboboxPopup' ,
51
112
} )
52
- export class CdkComboboxPopup {
113
+ export class CdkComboboxPopup < V > {
53
114
/** The combobox that the popup belongs to. */
54
- readonly combobox = inject ( CdkCombobox , { optional : true } ) ;
115
+ readonly combobox = inject < CdkCombobox < V > > ( CdkCombobox , { optional : true } ) ;
116
+
117
+ /** The actions that the combobox can perform on the popup. */
118
+ readonly actions = signal < ComboboxPopupControls < any , V > | undefined > ( undefined ) ;
55
119
}
0 commit comments