import { booleanAttribute, Directive, input, model, signal } from '@angular/core'; import { AbstractControl, ValidationErrors } from '@angular/forms'; import type { DisabledReason, FormValueControl, ValidationError, WithOptionalFieldTree, } from '@angular/forms/signals'; const numberInput = (value: unknown) => { if (value === '' || value === null || value === undefined) { return undefined; } return Number(value); }; @Directive() export class BaseInput implements FormValueControl { id = input(''); label = input(''); class = input(''); icon = input(''); name = input(''); required = input(false, { transform: booleanAttribute }); disabled = input(false, { transform: booleanAttribute }); readonly = input(false, { transform: booleanAttribute }); hidden = input(false, { transform: booleanAttribute }); invalid = input(false, { transform: booleanAttribute }); pending = input(false, { transform: booleanAttribute }); dirty = input(false, { transform: booleanAttribute }); maxLength = input(undefined, { transform: numberInput }); minLength = input(undefined, { transform: numberInput }); min = input(undefined, { transform: numberInput }); max = input(undefined, { transform: numberInput }); pattern = input([]); disabledReasons = input[]>([]); errors = input([]); touched = model(false); value = model({} as T); private readonly legacyControl = signal(null); private readonly legacyErrors = signal(null); readonly defaultClasses = 'text-black border-primary border-2 rounded focus:border-primary focus:ring-primary'; get feedbackState() { return this.legacyControl() ?? this.invalid(); } get displayErrors() { const errors = this.errors(); return errors.length > 0 ? errors : this.legacyErrors(); } isDisabled() { return this.disabled(); } onInput(event: Event) { const target = event.target as HTMLInputElement | HTMLSelectElement; const value = target.value as T; this.value.set(value); } onBlur() { this.touched.set(true); } setLegacyFormState(control: AbstractControl | null) { this.legacyControl.set(control); this.legacyErrors.set(control?.errors ?? null); } }