Skip to content

Commit

Permalink
feat: wr-input component research
Browse files Browse the repository at this point in the history
  • Loading branch information
yumagulov-azat committed Dec 17, 2024
1 parent 3430624 commit 69dc7a0
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 134 deletions.
1 change: 0 additions & 1 deletion projects/lib/input/input-types.ts

This file was deleted.

12 changes: 1 addition & 11 deletions projects/lib/input/input.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,7 @@
</div>
}

<input
class="wr-input__native"
[type]="type"
[placeholder]="placeholder"
[readonly]="readonly"
[disabled]="isDisabled()"
[ngModel]="inputValue()"
(ngModelChange)="writeValue($event)"
(focus)="isFocused.set(true)"
(blur)="isFocused.set(false)"
/>
<ng-content></ng-content>

@if (passwordIcons) {
<div class="wr-input-icon" [class.wr-input-icon--disabled]="isDisabled()" (click)="onPasswordVisibilityChange()">
Expand Down
69 changes: 53 additions & 16 deletions projects/lib/input/input.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@

import { coerceBooleanProperty } from '@angular/cdk/coercion';
import {
AfterContentInit,
booleanAttribute,
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
ContentChild,
ElementRef,
forwardRef,
HostBinding,
inject,
Expand All @@ -26,8 +29,6 @@ import { WrAbstractBase } from 'ngwr/cdk';
import { SafeAny } from 'ngwr/cdk/types';
import { provideWrIcons, eye, eyeOff, WrIconModule } from 'ngwr/icon';

import { WrInputType } from './input-types';

/**
* NGWR input component.
*
Expand All @@ -50,14 +51,17 @@ import { WrInputType } from './input-types';
},
],
})
export class WrInputComponent extends WrAbstractBase implements ControlValueAccessor {
@Input() placeholder = '';
export class WrInputComponent extends WrAbstractBase implements ControlValueAccessor, AfterContentInit {
@Input() prefix: string | null = null;
@Input() suffix: string | null = null;
@Input({ transform: booleanAttribute }) rounded = false;
@Input({ transform: booleanAttribute }) passwordIcons = false;
@Input({ transform: booleanAttribute }) readonly = false;
@Input() type: WrInputType = 'text';

@ContentChild('input') private inputRefFromTemplate?: ElementRef<HTMLInputElement>;

private get inputElement(): HTMLInputElement {
return this.inputRefFromTemplate?.nativeElement || this.elementRef.nativeElement.querySelector('input');
}

@HostBinding('class')
get elClasses(): SafeAny {
Expand All @@ -77,10 +81,41 @@ export class WrInputComponent extends WrAbstractBase implements ControlValueAcce
protected value?: string;

private readonly cdr = inject(ChangeDetectorRef);
private readonly elementRef = inject(ElementRef);

protected readonly eyeOn = signal(true);
protected readonly isFocused = signal(false);
protected readonly isDisabled = signal(false);

ngAfterContentInit(): void {
if (this.inputElement) {
this.setupInputElement();
} else {
console.error('No input element found in wr-input component');
}
}

private setupInputElement(): void {
const input = this.inputElement;
input.classList.add('wr-input__native');

input.addEventListener('focus', () => {
this.isFocused.set(true);
this.cdr.markForCheck();
});

input.addEventListener('blur', () => {
this.isFocused.set(false);
this.onTouch();
this.cdr.markForCheck();
});

input.addEventListener('input', event => {
const value = (event.target as HTMLInputElement).value;
this.onChange(value);
});
}

onChange: (value: string) => void = noop;
onTouch: () => void = noop;

Expand All @@ -94,22 +129,24 @@ export class WrInputComponent extends WrAbstractBase implements ControlValueAcce

setDisabledState(isDisabled: boolean): void {
this.isDisabled.set(coerceBooleanProperty(isDisabled));

if (this.inputElement) {
this.inputElement.disabled = isDisabled;
}
}

writeValue(value: string): void {
this.value = value;
this.onChange(value);
this.inputValue.set(value);
if (this.inputElement) {
this.inputElement.value = value ?? '';
}
this.cdr.markForCheck();
}

onPasswordVisibilityChange(): void {
if (this.type === 'password') {
this.type = 'text';
this.eyeOn.set(false);
} else {
this.type = 'password';
this.eyeOn.set(true);
}
if (!this.inputElement) return;

const newType = this.inputElement.type === 'password' ? 'text' : 'password';
this.inputElement.type = newType;
this.eyeOn.set(newType === 'password');
}
}
1 change: 0 additions & 1 deletion projects/lib/input/public-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,5 @@
* found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
*/

export * from './input-types';
export * from './input.component';
export * from './input.module';
Loading

0 comments on commit 69dc7a0

Please sign in to comment.