Form
Wrapper component for form validation and submission handling. Apply av-form to a native <form> element.
Import
import { AvFormComponent } from '@avesra/angular';Usage
Compose fields with av-label, av-input, av-description, and av-field-error. Handle submit with the native (submit) event and set aria-label or aria-labelledby for accessibility.
import { Component, signal } from '@angular/core';
import {
AvButtonComponent,
AvDescriptionComponent,
AvFieldErrorComponent,
AvFormComponent,
AvInputComponent,
AvLabelComponent,
} from '@avesra/angular';
@Component({
selector: 'app-form-basic-demo',
imports: [
AvFormComponent,
AvLabelComponent,
AvInputComponent,
AvDescriptionComponent,
AvFieldErrorComponent,
AvButtonComponent,
],
host: { class: 'w-full max-w-96' },
template: `<form
av-form
class="flex w-full flex-col gap-4"
aria-label="Sign in"
(submit)="onSubmit($event)"
>
<div class="flex flex-col gap-1">
<label av-label for="form-email" required>Email</label>
<input
av-input
full-width
id="form-email"
name="email"
type="email"
placeholder="john@example.com"
required
[invalid]="emailError()"
(input)="onEmailInput($event)"
/>
<p av-field-error [visible]="emailError()">Please enter a valid email address</p>
</div>
<div class="flex flex-col gap-1">
<label av-label for="form-password" required>Password</label>
<input
av-input
full-width
id="form-password"
name="password"
type="password"
placeholder="Enter your password"
required
minlength="8"
[invalid]="passwordError()"
(input)="onPasswordInput($event)"
/>
<p av-description>
Must be at least 8 characters with 1 uppercase and 1 number
</p>
<p av-field-error [visible]="passwordError()">
{{ passwordMessage() }}
</p>
</div>
<div class="flex gap-2">
<button av-button type="submit">Submit</button>
<button av-button type="reset" variant="secondary">Reset</button>
</div>
</form>`,
})
export class FormBasicDemo {
readonly emailError = signal(false);
readonly passwordError = signal(false);
readonly passwordMessage = signal('Password must be at least 8 characters');
onEmailInput(event: Event): void {
const value = (event.target as HTMLInputElement).value;
const isValid = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(value);
this.emailError.set(value.length > 0 && !isValid);
}
onPasswordInput(event: Event): void {
const value = (event.target as HTMLInputElement).value;
if (value.length === 0) {
this.passwordError.set(false);
return;
}
if (value.length < 8) {
this.passwordMessage.set('Password must be at least 8 characters');
this.passwordError.set(true);
return;
}
if (!/[A-Z]/.test(value)) {
this.passwordMessage.set('Password must contain at least one uppercase letter');
this.passwordError.set(true);
return;
}
if (!/[0-9]/.test(value)) {
this.passwordMessage.set('Password must contain at least one number');
this.passwordError.set(true);
return;
}
this.passwordError.set(false);
}
onSubmit(event: Event): void {
event.preventDefault();
const form = event.target as HTMLFormElement;
const formData = new FormData(form);
const data: Record<string, string> = {};
formData.forEach((value, key) => {
data[key] = value.toString();
});
alert(`Form submitted with: ${JSON.stringify(data, null, 2)}`);
}
}Anatomy
Import the Form parts and compose them with attribute selectors on native elements.
<form av-form aria-label="Example form" (submit)="onSubmit($event)">
<!-- Form fields go here -->
<button av-button type="submit">Submit</button>
<button av-button type="reset" variant="secondary">Reset</button>
</form>Styling
Passing Tailwind CSS classes
Pass utility classes on the host <form> and child field elements, or override BEM classes in @layer components.
import { Component } from '@angular/core';
import {
AvButtonComponent,
AvFieldErrorComponent,
AvFormComponent,
AvInputComponent,
AvLabelComponent,
} from '@avesra/angular';
@Component({
selector: 'app-form-custom-styling-demo',
imports: [
AvFormComponent,
AvLabelComponent,
AvInputComponent,
AvFieldErrorComponent,
AvButtonComponent,
],
host: { class: 'w-full max-w-md' },
template: `<form
av-form
class="w-full max-w-md space-y-4 rounded-lg border border-border bg-surface p-6"
aria-label="Newsletter signup"
(submit)="onSubmit($event)"
>
<div class="flex flex-col gap-1">
<label av-label class="text-sm font-medium" for="form-styled-email">Email</label>
<input
av-input
full-width
class="rounded-full"
id="form-styled-email"
name="email"
type="email"
placeholder="Enter your email"
required
/>
<p av-field-error class="text-xs" [visible]="false">Please enter a valid email address</p>
</div>
<button av-button full-width type="submit">Submit</button>
</form>`,
})
export class FormCustomStylingDemo {
onSubmit(event: Event): void {
event.preventDefault();
}
}CSS Classes
Form is a semantic wrapper with no default layout. Use these selectors for hooks:
.av-form— Root form element[data-slot="form"]— Slot attribute on the host
API
Form wraps a native <form> and provides validation behavior plus shared error context for descendant fields.
| Prop | Type | Default | Description |
|---|---|---|---|
action | string | — | The URL to submit the form data to. |
method | 'get' | 'post' | — | The HTTP method to use when submitting the form. |
enctype | 'application/x-www-form-urlencoded' | 'multipart/form-data' | 'text/plain' | — | The encoding type for form data submission. |
target | '_self' | '_blank' | '_parent' | '_top' | — | Where to display the response after submitting the form. |
novalidate | boolean | false | Disables native browser validation. |
aria-label | string | — | Accessibility label for the form landmark. |
aria-labelledby | string | — | ID of the element that labels the form. Creates a form landmark when provided. |
validationBehavior | 'native' | 'aria' | 'native' | Whether to use native HTML validation or ARIA validation. 'native' blocks form submission; 'aria' displays errors in realtime. |
validationErrors | Record<string, string | string[]> | {} | Server-side validation errors mapped by field name. Displayed immediately and cleared when the user modifies the field. |
Form Validation
Form integrates with HTML and Avesra field validation:
- Use built-in HTML5 validation attributes (
required,minlength,pattern, etc.) - Drive custom validation with signals and bind
[invalid]on inputs - Display errors with
av-field-error - Handle submission after validation with the native
(submit)event - Provide server-side errors via the
validationErrorsinput, keyed by field name
Validation Behavior
The validationBehavior input controls how validation is displayed:
native(default) — Uses native HTML validation and blocks form submission on errors. The first invalid field is focused automatically.aria— Uses ARIA attributes for validation, displays errors in realtime as the user types, and does not block submission.
Set novalidate to disable native browser validation UI when you want full control via ARIA and av-field-error.
Form Submission
Forms can be submitted in several ways:
- Traditional submission — Set the
actionandmethodinputs to submit to a URL - JavaScript handling — Use the
(submit)event to process form data - FormData API — Access form data with
FormDatain your submit handler
Example with FormData:
onSubmit(event: Event): void {
event.preventDefault();
const form = event.target as HTMLFormElement;
const formData = new FormData(form);
const data = Object.fromEntries(formData);
console.log('Form data:', data);
}Integration with Form Fields
Form works with Avesra form field components and shared primitives:
- Input / Textarea — Text inputs with labels and validation
- Checkbox / Checkbox Group — Boolean and multi-select controls
- Radio / Radio Group — Single selection from multiple options
- Switch / Switch Group — Toggle controls
- Select — Collapsible option lists
- Fieldset — Grouped fields with legend and actions
- Button — Submit and reset actions
Compose with shared av-label, av-description, and av-field-error. Field components pick up Form context for validation behavior and server errors when placed inside av-form.
Accessibility
Form uses a native <form> element and provides:
- Native
<form>element semantics - Form landmark creation with
aria-labeloraria-labelledby - Automatic focus management on the first invalid field during native validation
- ARIA validation attributes when using
validationBehavior="aria"