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; + } }