import {Component, forwardRef, HostListener, Input} from '@angular/core'; import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms'; type InputType = 'color' | 'date' | 'datetime-local' | 'email' | 'month' | 'number' | 'password' | 'search' | 'tel' | 'text' | 'time' | 'url'; export const APP_INPUT_CONTROL_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MaskableInputComponent), multi: true }; @Component({ selector: 'app-maskable-input', templateUrl: './maskable-input.component.html', styleUrls: ['./maskable-input.component.scss'], providers: [APP_INPUT_CONTROL_VALUE_ACCESSOR], }) export class MaskableInputComponent implements ControlValueAccessor { @Input() type: InputType = 'text'; @Input() label = ''; @Input() notRelevant: boolean | undefined; @Input() mask: string | undefined; public innerModel = ''; public disabled = false; public hover = false; private dirtyAble = false; private onChangeCallback: (newValue: string) => any = () => {}; private onTouchedCallback: () => any = () => {}; constructor() { } get value(): any { return this.innerModel; } set value(value: any) { if (value !== this.innerModel) { this.innerModel = value; if (this.dirtyAble) { this.onChangeCallback(value); } } } @HostListener('mouseenter') onMouseEnter(): void { this.hover = !(this.disabled || this.notRelevant === true); } @HostListener('mouseleave') onMouseLeave(): void { this.hover = false; } // Set touched on blur @HostListener('blur') onBlur(): void { this.onTouchedCallback(); } registerOnChange(fn: any): void { this.onChangeCallback = fn; } registerOnTouched(fn: any): void { this.onTouchedCallback = fn; } setDisabledState(isDisabled: boolean): void { this.disabled = isDisabled; } writeValue(newValue: any): void { this.value = newValue; } public makeDirtyAble(): void { this.dirtyAble = true; } }