import { ChangeDetectionStrategy , ChangeDetectorRef , Component , ElementRef , HostListener , Input , Optional , Self , ViewEncapsulation , } from '@angular/core' ; import { ControlValueAccessor , FormGroupDirective , NgControl } from '@angular/forms' ; import { FormFieldControl } from '../form-field/form-field-control' ; import { MenuItem } from './menu-item' ; let uniqueId = 0 ; example @ Component ( { selector : 'gd-select-menu' , templateUrl : './select-menu.component.html' , styleUrls : [ './select-menu.component.scss' ] , changeDetection : ChangeDetectionStrategy . OnPush , encapsulation : ViewEncapsulation . None , host : { 'class' : 'SelectMenu' , '[attr.id]' : 'id' , '[attr.tabindex]' : 'disabled ? null : 0' , '[class.SelectMenu--disabled]' : 'disabled' , } , providers : [ { provide : FormFieldControl , useExisting : SelectMenuComponent , } , ] , } ) export class SelectMenuComponent extends FormFieldControl implements ControlValueAccessor { @ Input ( ) placeholder : string = '' ; @ Input ( ) convertFn : ( value : any ) => MenuItem ; private onChange : ( value : any ) => void ; private onTouch : ( ) => void ; constructor ( @ Self ( ) @ Optional ( ) public ngControl , @ Optional ( ) parentForm , public elementRef , private changeDetectorRef ) { super ( ) ; if ( this . ngControl ) { this . ngControl . valueAccessor = this ; } } private _item : MenuItem | null = null ; get item ( ) : MenuItem { if ( this . _item && this . convertFn ) { return this . convertFn ( this . _item ) ; } else { return this . _item ; } } private _id : string = `gd-select-menu-${ uniqueId ++ }` ; @ Input ( ) get id ( ) { return this . _id ; } set id ( value ) { this . _id = value ; } private _disabled : boolean = false ; @ Input ( ) get disabled ( ) { return this . _disabled ; } set disabled ( value ) { this . _disabled = value ; } get isEmptyValue ( ) : boolean { return ! this . _item ; } writeValue ( obj ) { this . _item = obj ; this . changeDetectorRef . markForCheck ( ) ; } registerOnChange ( fn ) { this . onChange = fn ; } registerOnTouched ( fn ) { this . onTouch = fn ; } setDisabledState ( isDisabled ) { this . _disabled = isDisabled ; this . changeDetectorRef . markForCheck ( ) ; } @ HostListener ( 'focus' ) private handleFocus ( ) { this . focused = true ; } @ HostListener ( 'blur' ) private handleBlur ( ) { this . focused = false ; } }