/
TestEntry
/
mt-app
Обзор
Документация
Войти
/
TestEntry
/
mt-app
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
projects/ui-kit/src/lib/input/mt-kit-input.component.ts
127 строк
3 KB
PontiyPirat
refactor: drop Angular Material; migrate wishlist to @ui-kit
02 май 2026, 22:33
02 май 2026, 22:33
11abf99
Код
Авторство
О чём код?
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, forwardRef, inject, input, output, } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; @Component({ selector: 'mt-kit-input', standalone: true, template: ` <label class="mt-kit-input__root" [class.mt-kit-input__root--disabled]="isDisabled"> @if (label()) { <span class="mt-kit-input__label">{{ label() }}</span> } @if (rows() >= 2) { <textarea class="mt-kit-input__control mt-kit-input__control--textarea" [disabled]="isDisabled" [placeholder]="placeholder()" [attr.rows]="rows()" [value]="value" (input)="onTextareaInput($event)" (blur)="onBlur()" (keydown)="keydown.emit($event)" ></textarea> } @else { <input class="mt-kit-input__control" [type]="inputType()" [disabled]="isDisabled" [placeholder]="placeholder()" [attr.autocomplete]="autocomplete() || null" [value]="value" (input)="onInput($event)" (blur)="onBlur()" (keydown)="keydown.emit($event)" /> } </label> `, styleUrl: './mt-kit-input.component.scss', changeDetection: ChangeDetectionStrategy.OnPush, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MtKitInputComponent), multi: true, }, ], }) export class MtKitInputComponent implements ControlValueAccessor { readonly label = input(''); readonly placeholder = input(''); readonly inputType = input<'text' | 'email' | 'password' | 'number' | 'url'>('text'); readonly autocomplete = input(''); /** When >= 2, renders a textarea instead of a single-line input. */ readonly rows = input(0, { transform: (v: unknown) => Number(v) || 0 }); readonly keydown = output<KeyboardEvent>(); value = ''; isDisabled = false; private onChange: (value: string | number | null) => void = () => {}; private onTouched: () => void = () => {}; private readonly cdr = inject(ChangeDetectorRef); writeValue(value: string | number | null): void { if (value === null || value === undefined) { this.value = ''; } else { this.value = String(value); } this.mark(); } registerOnChange(fn: (value: string | number | null) => void): void { this.onChange = fn; } registerOnTouched(fn: () => void): void { this.onTouched = fn; } setDisabledState(isDisabled: boolean): void { this.isDisabled = isDisabled; this.mark(); } onInput(event: Event): void { const el = event.target as HTMLInputElement; this.value = el.value; this.emitFromSingleLine(el.value); } onTextareaInput(event: Event): void { const el = event.target as HTMLTextAreaElement; this.value = el.value; this.onChange(el.value); } onBlur(): void { this.onTouched(); } private emitFromSingleLine(raw: string): void { if (this.inputType() === 'number') { if (raw.trim() === '') { this.onChange(null); return; } const n = Number(raw); this.onChange(Number.isNaN(n) ? null : n); return; } this.onChange(raw); } private mark(): void { this.cdr.markForCheck(); } }