diff --git a/src/app/features/componentes-test/pages/reutilizables-test-page/reutilizables-test-page.component.html b/src/app/features/componentes-test/pages/reutilizables-test-page/reutilizables-test-page.component.html index 0b18909..8598ef8 100644 --- a/src/app/features/componentes-test/pages/reutilizables-test-page/reutilizables-test-page.component.html +++ b/src/app/features/componentes-test/pages/reutilizables-test-page/reutilizables-test-page.component.html @@ -74,7 +74,7 @@ } + @if (type() === 'password-toggle') { + + } + @if (type() === 'file') { {{ resolvedFileName() || 'Sin archivo...' }} diff --git a/src/app/shared/components/input/input.component.scss b/src/app/shared/components/input/input.component.scss index 27746b2..aa80ab0 100644 --- a/src/app/shared/components/input/input.component.scss +++ b/src/app/shared/components/input/input.component.scss @@ -43,6 +43,10 @@ padding-right: 2.5rem; } +.input-with-action-icon { + padding-right: 2.5rem; +} + input[type='file'].form-control { padding-right: 1rem; color: transparent; @@ -100,7 +104,8 @@ input[type='file'].form-control { } } -.input-control-editable { +.input-control-editable, +.input-control-password-toggle { .input-icon { position: absolute; right: 0.875rem; diff --git a/src/app/shared/components/input/input.component.ts b/src/app/shared/components/input/input.component.ts index a290775..40cd038 100644 --- a/src/app/shared/components/input/input.component.ts +++ b/src/app/shared/components/input/input.component.ts @@ -18,6 +18,7 @@ export type AppInputType = | 'number' | 'email' | 'password' + | 'password-toggle' | 'currency' | 'percent' | 'date' @@ -32,6 +33,7 @@ const INPUT_TYPES = new Set([ 'number', 'email', 'password', + 'password-toggle', 'currency', 'percent', 'date', @@ -60,6 +62,7 @@ export class InputComponent { private readonly inputElement = viewChild>('inputElement'); private readonly selectedFileName = signal(''); private readonly editableDisabled = signal(false); + private readonly passwordVisible = signal(false); private lastClearTrigger = 0; readonly invalid = input(false); @@ -70,6 +73,7 @@ export class InputComponent { readonly fileName = input(''); readonly clearTrigger = input(0); readonly disabled = input(false); + readonly visible = input(null); readonly type = input(DEFAULT_TYPE, { transform: normalizeType }); @@ -77,12 +81,17 @@ export class InputComponent { readonly disabledChange = output(); readonly valueChange = output(); readonly fileChange = output(); + readonly visibleChange = output(); protected readonly id = `app-input-${globalThis.crypto.randomUUID()}`; protected readonly inputType = computed(() => { const type = this.type(); + if (type === 'password-toggle') { + return this.isPasswordVisible() ? 'text' : 'password'; + } + if (type === 'search' || type === 'currency' || type === 'percent' || type === 'editable') { return 'text'; } @@ -100,7 +109,8 @@ export class InputComponent { 'input-with-search-icon': this.type() === 'search', 'input-with-prefix': this.type() === 'currency', 'input-with-suffix': this.type() === 'percent', - 'input-with-icon': this.type() === 'editable' + 'input-with-icon': this.type() === 'editable', + 'input-with-action-icon': this.type() === 'password-toggle' })); protected readonly isInputDisabled = computed(() => @@ -111,6 +121,11 @@ export class InputComponent { () => this.type() === 'editable' && !this.editableDisabled() ); + protected readonly isPasswordVisible = computed(() => { + const visible = this.visible(); + return visible === null ? this.passwordVisible() : visible; + }); + protected readonly resolvedFileName = computed( () => this.selectedFileName() || this.fileName() || '' ); @@ -163,6 +178,20 @@ export class InputComponent { this.disabledChange.emit(nextState); } + protected togglePasswordVisibility(): void { + if (this.type() !== 'password-toggle' || this.disabled()) { + return; + } + + const nextState = !this.isPasswordVisible(); + + if (this.visible() === null) { + this.passwordVisible.set(nextState); + } + + this.visibleChange.emit(nextState); + } + private clearFileInput(): void { this.inputElement()?.nativeElement && (this.inputElement()!.nativeElement.value = ''); this.selectedFileName.set('');