Input
Primitive single-line text input. Apply av-input to a native <input> element. Accepts standard HTML attributes and implements ControlValueAccessor for Angular forms.
Import
import { AvInputComponent } from '@avesra/angular'; For labels, descriptions, and validation errors, compose with av-label, av-description, and av-field-error. For form-level validation and submission, see Form.
Usage
import { Component } from '@angular/core';
import { AvInputComponent } from '@avesra/angular';
@Component({
selector: 'app-input-basic-demo',
imports: [AvInputComponent],
host: { class: 'flex w-full items-center justify-center' },
template: `<input
av-input
class="w-64"
type="text"
placeholder="Enter your name"
aria-label="Name"
/>`,
})
export class InputBasicDemo {}Anatomy
Input uses the av-input attribute selector on a native <input> element. Compose with shared label and error primitives as needed.
<label av-label for="name">Name</label>
<input av-input id="name" type="text" placeholder="Enter your name" />
<p av-description>Your public display name.</p>
<p av-field-error [visible]="false">Name is required</p>Variants
The Input component supports two visual variants:
primary(default) — Standard styling with shadow, suitable for most use casessecondary— Lower emphasis variant without shadow, suitable for use in Surface components
import { Component } from '@angular/core';
import { AvInputComponent } from '@avesra/angular';
@Component({
selector: 'app-input-variants-demo',
imports: [AvInputComponent],
host: { class: 'flex w-full max-w-[240px] flex-col gap-2' },
template: `<input av-input full-width placeholder="Primary input" variant="primary" />
<input av-input full-width placeholder="Secondary input" variant="secondary" />`,
})
export class InputVariantsDemo {}In Surface
When used inside a Surface component, use variant="secondary" to apply the lower emphasis variant suitable for surface backgrounds.
import { Component } from '@angular/core';
import { AvInputComponent, AvSurfaceComponent } from '@avesra/angular';
@Component({
selector: 'app-input-on-surface-demo',
imports: [AvInputComponent, AvSurfaceComponent],
host: { class: 'flex w-full items-center justify-center' },
template: `<div
av-surface
class="flex h-[180px] w-[280px] items-center justify-center rounded-3xl p-4"
>
<input
av-input
class="w-full"
placeholder="Your name"
variant="secondary"
aria-label="Name"
/>
</div>`,
})
export class InputOnSurfaceDemo {}Full Width
Set full-width to expand the input to its container width.
import { Component } from '@angular/core';
import { AvInputComponent } from '@avesra/angular';
@Component({
selector: 'app-input-full-width-demo',
imports: [AvInputComponent],
host: { class: 'w-full max-w-[400px]' },
template: `<input av-input full-width placeholder="Full width input" aria-label="Full width" />`,
})
export class InputFullWidthDemo {}Input Types
Use the native type attribute for email, password, number, and other HTML input types. Pair with av-label via matching for and id.
import { Component } from '@angular/core';
import { AvInputComponent, AvLabelComponent } from '@avesra/angular';
@Component({
selector: 'app-input-input-types-demo',
imports: [AvInputComponent, AvLabelComponent],
host: { class: 'flex w-full max-w-xs flex-col gap-4' },
template: `<div class="flex flex-col gap-1">
<label av-label for="input-type-email">Email</label>
<input
av-input
id="input-type-email"
type="email"
placeholder="jane@example.com"
/>
</div>
<div class="flex flex-col gap-1">
<label av-label for="input-type-number">Age</label>
<input
av-input
id="input-type-number"
type="number"
min="0"
placeholder="30"
/>
</div>
<div class="flex flex-col gap-1">
<label av-label for="input-type-password">Password</label>
<input
av-input
id="input-type-password"
type="password"
placeholder="••••••••"
/>
</div>`,
})
export class InputInputTypesDemo {}Controlled
Bind the value with [(ngModel)] (requires FormsModule) or formControlName / [formControl] with ReactiveFormsModule.
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AvInputComponent } from '@avesra/angular';
@Component({
selector: 'app-input-controlled-demo',
imports: [FormsModule, AvInputComponent],
host: { class: 'flex w-full max-w-xs flex-col gap-2' },
template: `<input
av-input
class="w-full"
type="text"
placeholder="domain"
aria-label="Domain"
[(ngModel)]="value"
/>
<span class="px-1 text-sm text-muted">https://{{ value || 'your-domain' }}</span>`,
})
export class InputControlledDemo {
value = 'avesra.dev';
}Styling
Passing Tailwind CSS classes
Pass utility classes on the host <input>, or compose with av-label for labeled fields.
import { Component } from '@angular/core';
import { AvInputComponent, AvLabelComponent } from '@avesra/angular';
@Component({
selector: 'app-input-custom-styling-demo',
imports: [AvInputComponent, AvLabelComponent],
host: { class: 'flex w-full max-w-sm justify-center' },
template: `<div class="flex flex-col gap-2">
<label av-label for="custom-input">Project name</label>
<input
av-input
id="custom-input"
class="rounded-xl border border-border/70 bg-surface px-4 py-2 text-sm shadow-sm"
placeholder="New web app"
/>
</div>`,
})
export class InputCustomStylingDemo {}Customizing the component classes
The base class .av-input powers every instance. Override it once with @layer components.
@layer components {
.av-input {
@apply rounded-lg border border-border bg-surface px-4 py-2 text-sm shadow-sm transition-colors;
&:hover,
&[data-hovered="true"] {
@apply bg-surface-secondary border-border/80;
}
&:focus-visible,
&[data-focus-visible="true"] {
@apply border-accent ring-2 ring-accent/20;
}
&[data-invalid="true"] {
@apply border-danger bg-danger-soft text-danger;
}
}
}CSS Classes
.av-input— Native input element styling.av-input--primary— Primary visual variant.av-input--secondary— Secondary visual variant.av-input--full-width— Full-width layout
Interactive States
- Hover:
:hoveror[data-hovered="true"] - Focus Visible:
:focus-visibleor[data-focus-visible="true"] - Invalid:
[data-invalid="true"](also syncs witharia-invalid) - Disabled:
:disabledor[data-disabled="true"] - Read Only: native
readonly/[aria-readonly="true"]
API
Input accepts all standard HTML <input> attributes plus the following Angular inputs. Use [(ngModel)] or reactive forms via ControlValueAccessor. For field-level validation UI, compose with av-label, av-description, av-field-error, and optionally Form.
| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'primary' | 'secondary' | 'primary' | Visual variant. primary is the default style with shadow. secondary is a lower emphasis variant without shadow, suitable for use in surfaces. |
full-width | boolean | false | Whether the input should take full width of its container. |
disabled | boolean | false | Disables the input. |
invalid | boolean | false | Marks the input as invalid and sets aria-invalid / data-invalid. |
ngModel / formControlName | string | — | Bound value via ControlValueAccessor. Use FormsModule (ngModel) or ReactiveFormsModule. |
type | string | 'text' | Native input type (text, email, password, number, etc.). |
placeholder | string | — | Placeholder text. |
name | string | — | Name for form submission. |
readonly | boolean | false | Native read-only attribute. |
required | boolean | false | Native required attribute for HTML validation. |