diff --git a/projects/components/src/color-picker/color-picker.component.scss b/projects/components/src/color-picker/color-picker.component.scss
index 27f4a2327..57fe290da 100644
--- a/projects/components/src/color-picker/color-picker.component.scss
+++ b/projects/components/src/color-picker/color-picker.component.scss
@@ -17,6 +17,10 @@
border: 2px solid $blue-4;
}
}
+
+ .add-icon {
+ cursor: pointer;
+ }
}
.container {
diff --git a/projects/components/src/color-picker/color-picker.component.ts b/projects/components/src/color-picker/color-picker.component.ts
index 7c3c1244e..343cfbe8f 100644
--- a/projects/components/src/color-picker/color-picker.component.ts
+++ b/projects/components/src/color-picker/color-picker.component.ts
@@ -1,5 +1,5 @@
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
-import { NG_VALUE_ACCESSOR } from '@angular/forms';
+import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { IconType } from '@hypertrace/assets-library';
import { Color } from '@hypertrace/common';
import { IconSize } from '../icon/icon-size';
@@ -37,7 +37,7 @@ import { IconSize } from '../icon/icon-size';
`
})
-export class ColorPickerComponent {
+export class ColorPickerComponent implements ControlValueAccessor {
@Input()
public selected?: string;
diff --git a/projects/components/src/combo-box/combo-box.component.ts b/projects/components/src/combo-box/combo-box.component.ts
index 77d05fa38..04305ec3e 100644
--- a/projects/components/src/combo-box/combo-box.component.ts
+++ b/projects/components/src/combo-box/combo-box.component.ts
@@ -13,9 +13,10 @@ import {
ViewChild,
ViewChildren
} from '@angular/core';
+import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { IconType } from '@hypertrace/assets-library';
import { DomElementScrollIntoViewService, isNonEmptyString, TypedSimpleChanges } from '@hypertrace/common';
-import { isNil } from 'lodash-es';
+import { isEmpty, isNil } from 'lodash-es';
import { IconSize } from '../icon/icon-size';
import { PopoverRef } from '../popover/popover-ref';
import { PopoverComponent } from '../popover/popover.component';
@@ -25,6 +26,13 @@ import { ComboBoxMode, ComboBoxOption, ComboBoxResult } from './combo-box-api';
selector: 'ht-combo-box',
styleUrls: ['./combo-box.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
+ providers: [
+ {
+ provide: NG_VALUE_ACCESSOR,
+ multi: true,
+ useExisting: ComboBoxComponent
+ }
+ ],
template: `
@@ -113,7 +121,7 @@ import { ComboBoxMode, ComboBoxOption, ComboBoxResult } from './combo-box-api';
`
})
-export class ComboBoxComponent implements AfterViewInit, OnChanges, OnDestroy {
+export class ComboBoxComponent implements AfterViewInit, OnChanges, OnDestroy, ControlValueAccessor {
@Input()
public mode?: ComboBoxMode = ComboBoxMode.Input;
@@ -176,6 +184,9 @@ export class ComboBoxComponent implements AfterViewInit, OnChan
public createOption?: ComboBoxOption;
+ private propagateControlValueChange?: (value: string | undefined) => void;
+ private propagateControlValueChangeOnTouch?: (value: string | undefined) => void;
+
public constructor(
private readonly changeDetectorRef: ChangeDetectorRef,
private readonly scrollIntoViewService: DomElementScrollIntoViewService
@@ -204,10 +215,9 @@ export class ComboBoxComponent implements AfterViewInit, OnChan
}
private setFilteredOptions(searchText?: string): void {
- this.filteredOptions =
- searchText === undefined
- ? this.options ?? []
- : (this.options ?? []).filter(option => option.text.toLowerCase().includes(searchText.toLowerCase()));
+ this.filteredOptions = isEmpty(searchText)
+ ? this.options ?? []
+ : (this.options ?? []).filter(option => option.text.toLowerCase().includes(searchText!.toLowerCase()));
this.createOption = this.isShowCreateOption(searchText) ? this.buildCreateOption(searchText) : undefined;
this.setHighlightedOptionIndex();
}
@@ -227,6 +237,7 @@ export class ComboBoxComponent implements AfterViewInit, OnChan
this.measureText();
this.setHighlightedOptionIndex();
this.textChange.emit(this.text);
+ this.propagateValueChangeToFormControl(this.text);
}
}
@@ -405,4 +416,21 @@ export class ComboBoxComponent implements AfterViewInit, OnChan
this.changeDetectorRef.markForCheck(); // Yes, required
});
}
+
+ private propagateValueChangeToFormControl(value?: string): void {
+ this.propagateControlValueChange?.(value);
+ this.propagateControlValueChangeOnTouch?.(value);
+ }
+
+ public writeValue(text?: string): void {
+ this.text = text;
+ }
+
+ public registerOnChange(onChange: (value?: string) => void): void {
+ this.propagateControlValueChange = onChange;
+ }
+
+ public registerOnTouched(onTouch: (value?: string) => void): void {
+ this.propagateControlValueChangeOnTouch = onTouch;
+ }
}