@@ -13,9 +13,10 @@ import {
1313 ViewChild ,
1414 ViewChildren
1515} from '@angular/core' ;
16+ import { ControlValueAccessor , NG_VALUE_ACCESSOR } from '@angular/forms' ;
1617import { IconType } from '@hypertrace/assets-library' ;
1718import { DomElementScrollIntoViewService , isNonEmptyString , TypedSimpleChanges } from '@hypertrace/common' ;
18- import { isNil } from 'lodash-es' ;
19+ import { isEmpty , isNil } from 'lodash-es' ;
1920import { IconSize } from '../icon/icon-size' ;
2021import { PopoverRef } from '../popover/popover-ref' ;
2122import { PopoverComponent } from '../popover/popover.component' ;
@@ -25,6 +26,13 @@ import { ComboBoxMode, ComboBoxOption, ComboBoxResult } from './combo-box-api';
2526 selector : 'ht-combo-box' ,
2627 styleUrls : [ './combo-box.component.scss' ] ,
2728 changeDetection : ChangeDetectionStrategy . OnPush ,
29+ providers : [
30+ {
31+ provide : NG_VALUE_ACCESSOR ,
32+ multi : true ,
33+ useExisting : ComboBoxComponent
34+ }
35+ ] ,
2836 template : `
2937 <ht-popover (popoverOpen)="this.onPopoverOpen($event)" (popoverClose)="this.onPopoverClose()" class="combo-box">
3038 <ht-popover-trigger>
@@ -113,7 +121,7 @@ import { ComboBoxMode, ComboBoxOption, ComboBoxResult } from './combo-box-api';
113121 </ht-popover>
114122 `
115123} )
116- export class ComboBoxComponent < TValue = string > implements AfterViewInit , OnChanges , OnDestroy {
124+ export class ComboBoxComponent < TValue = string > implements AfterViewInit , OnChanges , OnDestroy , ControlValueAccessor {
117125 @Input ( )
118126 public mode ?: ComboBoxMode = ComboBoxMode . Input ;
119127
@@ -176,6 +184,9 @@ export class ComboBoxComponent<TValue = string> implements AfterViewInit, OnChan
176184
177185 public createOption ?: ComboBoxOption < TValue > ;
178186
187+ private propagateControlValueChange ?: ( value : string | undefined ) => void ;
188+ private propagateControlValueChangeOnTouch ?: ( value : string | undefined ) => void ;
189+
179190 public constructor (
180191 private readonly changeDetectorRef : ChangeDetectorRef ,
181192 private readonly scrollIntoViewService : DomElementScrollIntoViewService
@@ -204,10 +215,9 @@ export class ComboBoxComponent<TValue = string> implements AfterViewInit, OnChan
204215 }
205216
206217 private setFilteredOptions ( searchText ?: string ) : void {
207- this . filteredOptions =
208- searchText === undefined
209- ? this . options ?? [ ]
210- : ( this . options ?? [ ] ) . filter ( option => option . text . toLowerCase ( ) . includes ( searchText . toLowerCase ( ) ) ) ;
218+ this . filteredOptions = isEmpty ( searchText )
219+ ? this . options ?? [ ]
220+ : ( this . options ?? [ ] ) . filter ( option => option . text . toLowerCase ( ) . includes ( searchText ! . toLowerCase ( ) ) ) ;
211221 this . createOption = this . isShowCreateOption ( searchText ) ? this . buildCreateOption ( searchText ) : undefined ;
212222 this . setHighlightedOptionIndex ( ) ;
213223 }
@@ -227,6 +237,7 @@ export class ComboBoxComponent<TValue = string> implements AfterViewInit, OnChan
227237 this . measureText ( ) ;
228238 this . setHighlightedOptionIndex ( ) ;
229239 this . textChange . emit ( this . text ) ;
240+ this . propagateValueChangeToFormControl ( this . text ) ;
230241 }
231242 }
232243
@@ -405,4 +416,21 @@ export class ComboBoxComponent<TValue = string> implements AfterViewInit, OnChan
405416 this . changeDetectorRef . markForCheck ( ) ; // Yes, required
406417 } ) ;
407418 }
419+
420+ private propagateValueChangeToFormControl ( value ?: string ) : void {
421+ this . propagateControlValueChange ?.( value ) ;
422+ this . propagateControlValueChangeOnTouch ?.( value ) ;
423+ }
424+
425+ public writeValue ( text ?: string ) : void {
426+ this . text = text ;
427+ }
428+
429+ public registerOnChange ( onChange : ( value ?: string ) => void ) : void {
430+ this . propagateControlValueChange = onChange ;
431+ }
432+
433+ public registerOnTouched ( onTouch : ( value ?: string ) => void ) : void {
434+ this . propagateControlValueChangeOnTouch = onTouch ;
435+ }
408436}
0 commit comments