import { ChangeDetectionStrategy, Component, forwardRef, input } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; export type InputSize = 'sm' | 'md' | 'lg'; export type InputState = 'default' | 'error' | 'success'; @Component({ selector: 'app-input', standalone: true, templateUrl: './input.component.html', styleUrl: './input.component.scss', changeDetection: ChangeDetectionStrategy.OnPush, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => InputComponent), multi: true } ], host: { '[class.app-input-host--full-width]': 'fullWidth()' } }) export class InputComponent implements ControlValueAccessor { readonly type = input<'text' | 'email' | 'password' | 'number' | 'search' | 'tel' | 'url'>('text'); readonly size = input('md'); readonly state = input('default'); readonly placeholder = input(''); readonly disabled = input(false); readonly fullWidth = input(false); readonly ariaLabel = input(null); protected value: string | number = ''; protected isDisabled = false; private onChange: (value: string | number) => void = () => {}; private onTouched: () => void = () => {}; writeValue(value: string | number): void { this.value = value ?? ''; } registerOnChange(fn: (value: string | number) => void): void { this.onChange = fn; } registerOnTouched(fn: () => void): void { this.onTouched = fn; } setDisabledState(isDisabled: boolean): void { this.isDisabled = isDisabled; } protected handleInput(event: Event): void { const target = event.target as HTMLInputElement; this.value = target.value; this.onChange(this.value); } protected handleBlur(): void { this.onTouched(); } }