AvesraAvesrabeta

Field Error

Displays validation error messages for form fields

Import

import { AvFieldErrorComponent } from '@avesra/angular';

Usage

The FieldError component displays validation error messages for form fields. Bind [visible] to your invalid condition to show or hide it with a smooth transition.

import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AvFieldErrorComponent, AvInputComponent, AvLabelComponent } from '@avesra/angular';

@Component({
  selector: 'app-field-error-basic-demo',
  imports: [FormsModule, AvFieldErrorComponent, AvInputComponent, AvLabelComponent],
  host: { class: 'flex w-64 flex-col gap-1' },
  template: `<label av-label for="username">Username</label>
      <input
        av-input
        id="username"
        placeholder="Enter username"
        [(ngModel)]="username"
        [invalid]="isInvalid"
      />
      <p av-field-error [visible]="isInvalid">Username must be at least 3 characters</p>`,
})
export class FieldErrorBasicDemo {
  username = 'jr';

  get isInvalid(): boolean {
    return this.username.length > 0 && this.username.length < 3;
  }
}

Basic Validation

Drive visibility from your own validation logic and mark the input [invalid] when the field fails.

import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AvFieldErrorComponent, AvInputComponent, AvLabelComponent } from '@avesra/angular';

@Component({
  selector: 'app-field-error-basic-validation-demo',
  imports: [FormsModule, AvFieldErrorComponent, AvInputComponent, AvLabelComponent],
  host: { class: 'flex w-64 flex-col gap-1' },
  template: `<label av-label for="email">Email</label>
      <input
        av-input
        id="email"
        type="email"
        placeholder="you&#64;example.com"
        [(ngModel)]="email"
        [invalid]="isInvalid"
      />
      <p av-field-error [visible]="isInvalid">Email must include &#64; symbol</p>`,
})
export class FieldErrorBasicValidationDemo {
  email = 'invalid-email';

  get isInvalid(): boolean {
    return this.email.length > 0 && !this.email.includes('@');
  }
}

Dynamic Messages

Interpolate the error text so the message updates as the user types.

import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AvFieldErrorComponent, AvInputComponent, AvLabelComponent } from '@avesra/angular';

@Component({
  selector: 'app-field-error-dynamic-messages-demo',
  imports: [FormsModule, AvFieldErrorComponent, AvInputComponent, AvLabelComponent],
  host: { class: 'flex w-64 flex-col gap-1' },
  template: `<label av-label for="password">Password</label>
      <input
        av-input
        id="password"
        type="password"
        placeholder="Enter password"
        [(ngModel)]="password"
        [invalid]="isInvalid"
      />
      <p av-field-error [visible]="isInvalid">{{ errorMessage }}</p>`,
})
export class FieldErrorDynamicMessagesDemo {
  password = 'abc';

  get isInvalid(): boolean {
    return this.password.length > 0 && this.password.length < 8;
  }

  get errorMessage(): string {
    if (this.password.length === 0) {
      return '';
    }
    if (this.password.length < 4) {
      return 'Password is too short';
    }
    if (this.password.length < 8) {
      return `Need ${8 - this.password.length} more characters`;
    }
    return '';
  }
}

Multiple Error Messages

Project multiple messages inside a single av-field-error when several rules fail at once.

import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AvFieldErrorComponent, AvInputComponent, AvLabelComponent } from '@avesra/angular';

@Component({
  selector: 'app-field-error-multiple-errors-demo',
  imports: [FormsModule, AvFieldErrorComponent, AvInputComponent, AvLabelComponent],
  host: { class: 'flex w-64 flex-col gap-1' },
  template: `<label av-label for="username-multi">Username</label>
      <input
        av-input
        id="username-multi"
        placeholder="Choose a username"
        [(ngModel)]="username"
        [invalid]="hasErrors"
      />
      <p av-field-error [visible]="hasErrors">
        @for (error of errors; track error) {
          <span class="block">{{ error }}</span>
        }
      </p>`,
})
export class FieldErrorMultipleErrorsDemo {
  username = 'ab!';

  get errors(): string[] {
    const next: string[] = [];
    if (this.username.length > 0 && this.username.length < 3) {
      next.push('Must be at least 3 characters');
    }
    if (this.username.length > 0 && !/^[a-zA-Z0-9_]*$/.test(this.username)) {
      next.push('Only letters, numbers, and underscores allowed');
    }
    return next;
  }

  get hasErrors(): boolean {
    return this.errors.length > 0;
  }
}

Styling

CSS Classes

Avesra uses BEM-style classes for predictable customization. Override them in @layer components or pass utility classes directly.

  • .av-field-error — Base error styles with danger color
  • [data-visible="true"] — Visible state with height and opacity transition

Inside checkbox, switch, and radio items, field error styles are overridden to stack below the label like description text without collapsible height animation.

Accessibility

Field Error ensures validation feedback is accessible by:

  • Using role="alert" and aria-live="polite" for screen reader announcement
  • Controlling visibility via the visible input — bind it to your invalid condition
  • Showing and hiding visually with [data-visible="true"]
  • Optionally associating the error with a control yourself using an id on the error and aria-describedby on the input

API

PropTypeDefaultDescription
visiblebooleantrueControls visibility and expand/collapse animation.

Made with ❤ by SyntaxHertz. Open source and available on GitHub.