feat: enhance input component layout with labels and improve styling

This commit is contained in:
2026-06-26 10:18:43 -03:00
parent f1a4f51695
commit 0d46172325
6 changed files with 146 additions and 119 deletions

View File

@@ -45,124 +45,150 @@
<hr class="section-divider" /> <hr class="section-divider" />
<div class="input-grid"> <div class="input-grid">
<div class="input-field">
<label for="search-input">Texto</label>
<app-input <app-input
id="search-input"
type="search" type="search"
placeholder="Buscar producto" placeholder="Buscar producto"
[value]="textValue" [value]="textValue"
[maxlength]="24" [maxlength]="24"
(valueChange)="textValue = $event" (valueChange)="textValue = $event"
> />
Texto </div>
</app-input>
<div class="input-field">
<label for="number-input">Numero</label>
<app-input <app-input
id="number-input"
type="number" type="number"
placeholder="0" placeholder="0"
[value]="numberValue" [value]="numberValue"
(valueChange)="numberValue = $event" (valueChange)="numberValue = $event"
> />
Numero </div>
</app-input>
<div class="input-field">
<label for="email-input">Email</label>
<app-input <app-input
id="email-input"
type="email" type="email"
placeholder="mail@empresa.com" placeholder="mail@empresa.com"
[value]="email" [value]="email"
(valueChange)="email = $event" (valueChange)="email = $event"
> />
Email </div>
</app-input>
<div class="input-field">
<label for="user-input">Usuario</label>
<app-input <app-input
id="user-input"
type="user" type="user"
placeholder="Nombre de usuario" placeholder="Nombre de usuario"
[value]="user" [value]="user"
(valueChange)="user = $event" (valueChange)="user = $event"
> />
Usuario </div>
</app-input>
<div class="input-field">
<label for="password-input">Password</label>
<app-input <app-input
id="password-input"
type="password-toggle" type="password-toggle"
placeholder="********" placeholder="********"
[value]="password" [value]="password"
(valueChange)="password = $event" (valueChange)="password = $event"
> />
Password </div>
</app-input>
<div class="input-field">
<label for="date-input">Fecha</label>
<app-input <app-input
id="date-input"
type="date" type="date"
[value]="date" [value]="date"
(valueChange)="date = $event" (valueChange)="date = $event"
> />
Fecha </div>
</app-input>
<div class="input-field">
<label for="period-input">Periodo</label>
<app-input <app-input
id="period-input"
type="period" type="period"
[value]="period" [value]="period"
(valueChange)="period = $event" (valueChange)="period = $event"
> />
Periodo </div>
</app-input>
<div class="input-field">
<label for="amount-input">Moneda</label>
<app-input <app-input
id="amount-input"
type="currency" type="currency"
placeholder="0" placeholder="0"
[value]="amount" [value]="amount"
(valueChange)="amount = $event" (valueChange)="amount = $event"
> />
Moneda </div>
</app-input>
<div class="input-field">
<label for="percent-input">Porcentaje</label>
<app-input <app-input
id="percent-input"
type="percent" type="percent"
placeholder="0" placeholder="0"
[value]="percent" [value]="percent"
(valueChange)="percent = $event" (valueChange)="percent = $event"
> />
Porcentaje </div>
</app-input>
<div class="input-field">
<label for="disabled-input">Deshabilitado</label>
<app-input <app-input
id="disabled-input"
placeholder="Campo deshabilitado" placeholder="Campo deshabilitado"
[value]="disabledValue" [value]="disabledValue"
[disabled]="true" [disabled]="true"
> />
Deshabilitado </div>
</app-input>
<div class="input-field">
<label for="editable-input">Editable</label>
<app-input <app-input
id="editable-input"
type="editable" type="editable"
[value]="editableValue" [value]="editableValue"
[disabled]="editableDisabled" [disabled]="editableDisabled"
(valueChange)="editableValue = $event" (valueChange)="editableValue = $event"
(disabledChange)="editableDisabled = $event" (disabledChange)="editableDisabled = $event"
> />
Editable </div>
</app-input>
<div class="input-field">
<label for="invalid-input">Invalido</label>
<app-input <app-input
id="invalid-input"
type="email" type="email"
placeholder="mail@empresa.com" placeholder="mail@empresa.com"
[value]="invalidEmail" [value]="invalidEmail"
[invalid]="true" [invalid]="true"
(valueChange)="invalidEmail = $event" (valueChange)="invalidEmail = $event"
> />
Invalido </div>
</app-input>
<div class="file-field"> <div class="file-field">
<div class="input-field">
<label for="file-input">Archivo</label>
<app-input <app-input
id="file-input"
type="file" type="file"
accept=".pdf,.png,.jpg" accept=".pdf,.png,.jpg"
[fileName]="fileName" [fileName]="fileName"
[clearTrigger]="clearTrigger" [clearTrigger]="clearTrigger"
(fileChange)="onFileChange($event)" (fileChange)="onFileChange($event)"
> />
Archivo </div>
</app-input>
<app-button variant="secondary" (click)="clearFile()">Limpiar archivo</app-button> <app-button variant="secondary" (click)="clearFile()">Limpiar archivo</app-button>
</div> </div>

View File

@@ -65,6 +65,11 @@ h1 {
gap: 1rem; gap: 1rem;
} }
.input-field {
display: grid;
gap: 0;
}
.file-field { .file-field {
display: grid; display: grid;
gap: 0.75rem; gap: 0.75rem;

View File

@@ -1,7 +1,3 @@
<label [for]="id" class="input-label">
<ng-content />
</label>
<div <div
class="input-control" class="input-control"
[ngClass]="{ [ngClass]="{
@@ -20,8 +16,8 @@
<input <input
#inputElement #inputElement
[id]="id" [id]="id()"
[name]="id" [name]="id()"
[type]="inputType()" [type]="inputType()"
[ngClass]="inputClasses()" [ngClass]="inputClasses()"
[disabled]="isInputDisabled()" [disabled]="isInputDisabled()"

View File

@@ -4,12 +4,6 @@
padding-bottom: 0 !important; padding-bottom: 0 !important;
} }
.input-label {
display: block;
margin-bottom: 0.375rem;
font-weight: 500;
}
.input-control { .input-control {
position: relative; position: relative;
} }

View File

@@ -66,8 +66,10 @@ export class InputComponent {
private readonly editableDisabled = signal(false); private readonly editableDisabled = signal(false);
private readonly passwordVisible = signal(false); private readonly passwordVisible = signal(false);
private lastClearTrigger = 0; private lastClearTrigger = 0;
private readonly defaultId = `app-input-${globalThis.crypto.randomUUID()}`;
readonly invalid = input(false); readonly invalid = input(false);
readonly id = input(this.defaultId);
readonly placeholder = input(''); readonly placeholder = input('');
readonly value = input<string | number>(''); readonly value = input<string | number>('');
readonly maxlength = input<number | null>(null); readonly maxlength = input<number | null>(null);
@@ -85,8 +87,6 @@ export class InputComponent {
readonly fileChange = output<File | null>(); readonly fileChange = output<File | null>();
readonly visibleChange = output<boolean>(); readonly visibleChange = output<boolean>();
protected readonly id = `app-input-${globalThis.crypto.randomUUID()}`;
protected readonly inputType = computed(() => { protected readonly inputType = computed(() => {
const type = this.type(); const type = this.type();

View File

@@ -10,3 +10,9 @@
:root { :root {
--bs-body-font-family: "Gotham", sans-serif; --bs-body-font-family: "Gotham", sans-serif;
} }
label {
display: block;
margin-bottom: 0.375rem;
font-weight: 500;
}