import {Component, forwardRef, Input, NgZone, ViewChild} from '@angular/core'; import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms'; import {CdkTextareaAutosize} from '@angular/cdk/text-field'; import {take} from 'rxjs/operators'; import {DataCardService} from '../api/data-card.service'; type InputType = 'color'|'date'|'datetime-local'|'email'|'month'|'number'|'password'|'search'|'tel'|'text'|'time'|'url'; export const APP_TEXT_AREA_CONTROL_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TextAreaComponent), multi: true }; @Component({ selector: 'app-text-area', templateUrl: './text-area.component.html', styleUrls: ['./text-area.component.scss'], providers: [APP_TEXT_AREA_CONTROL_VALUE_ACCESSOR], // tslint:disable-next-line:no-host-metadata-property host: { '(mouseenter)': 'onMouseEnter()', '(mouseleave)': 'onMouseLeave()', '(blur)': 'onBlur()', } }) export class TextAreaComponent implements ControlValueAccessor { @Input() type: InputType = 'text'; @Input() label = ''; @Input() notRelevant: boolean|undefined; @Input() name: string|undefined; @Input() minRows: number|undefined; @ViewChild('autosize') autosize: CdkTextareaAutosize|undefined; public innerModel = ''; public disabled = false; public hover = false; private dirtyAble = false; private onChangeCallback: (newValue: string) => any = () => {}; private onTouchedCallback: () => any = () => {}; // tslint:disable-next-line:variable-name constructor(public dataCardService: DataCardService, private _ngZone: NgZone) { this.dataCardService.isDataCardClosed.subscribe(isClosed => this.setDisabledState(isClosed)); } get value(): any { return this.innerModel; } set value(value: any) { if (value !== this.innerModel) { this.innerModel = value; if (this.dirtyAble) { this.onChangeCallback(value); } } } public triggerResize(): void { // Wait for changes to be applied, then trigger textarea resize. this._ngZone.onStable.pipe(take(1)) .subscribe(() => this.autosize?.resizeToFitContent(true)); } onMouseEnter(): void { this.hover = !(this.disabled || this.notRelevant === true); } onMouseLeave(): void { this.hover = false; } // Set touched on 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; } }