Standard vertical layout with label above the control.
Horizontal Layout
Horizontal layout with label beside the control.
Compact Layout
Compact spacing for tighter layouts.
States
Default State
Normal state with no validation.
Error State
Error state with error message.
Success State
Success state with success message.
Warning State
Warning state with warning message.
Info State
Info state with informational message.
Disabled State
Disabled field with disabled styling.
Required and Optional Fields
Required Field
Field marked as required with asterisk.
Optional Field
Field marked as optional with (optional) text.
Input Types
Text Input
Email Input
Number Input
Textarea
Select
Checkbox Group
Character Count
With Character Counter
Shows character count with maximum limit.
Hint Text
With Hint
Additional helpful information with icon.
Reactive Form Integration
Form with Validation
Form fields with Angular reactive form validation.
Form Status: {{ validationForm.status }}
Form Valid: {{ validationForm.valid }}
Form Touched: {{ validationForm.touched }}
Form Dirty: {{ validationForm.dirty }}
Usage Example
{{ codeExample }}
`,
styleUrl: './form-field-demo.component.scss'
})
export class FormFieldDemoComponent implements OnInit {
sizes = ['sm', 'md', 'lg'] as const;
characterCountText = '';
validationForm = new FormGroup({
name: new FormControl('', [Validators.required, Validators.minLength(2)]),
email: new FormControl('', [Validators.required, Validators.email]),
password: new FormControl('', [Validators.required, Validators.minLength(8)]),
age: new FormControl('', [Validators.min(18), Validators.max(100)]),
website: new FormControl('', [this.urlValidator]),
bio: new FormControl('', [Validators.maxLength(200)])
});
validationMessages = {
required: 'This field is required',
email: 'Please enter a valid email address',
minlength: 'This field is too short',
maxlength: 'This field is too long',
min: 'Value is too low',
max: 'Value is too high',
url: 'Please enter a valid URL',
custom: 'Custom validation error'
};
readonly codeExample = `import { FormFieldComponent } from 'ui-essentials';
// Basic usage
// With validation messages
// Horizontal layout
// Custom states
`;
ngOnInit(): void {
// Watch form changes for demo purposes
this.validationForm.valueChanges.subscribe(() => {
// Update demo display if needed
});
}
updateCharacterCount(event: Event): void {
const input = event.target as HTMLInputElement;
this.characterCountText = input.value;
}
isFieldInvalid(fieldName: string): boolean {
const field = this.validationForm.get(fieldName);
return field ? field.invalid && (field.dirty || field.touched) : false;
}
isFieldValid(fieldName: string): boolean {
const field = this.validationForm.get(fieldName);
return field ? field.valid && field.value && (field.dirty || field.touched) : false;
}
getFieldValue(fieldName: string): any {
return this.validationForm.get(fieldName)?.value;
}
markAllTouched(): void {
this.validationForm.markAllAsTouched();
}
resetValidationForm(): void {
this.validationForm.reset();
Object.keys(this.validationForm.controls).forEach(key => {
this.validationForm.get(key)?.setErrors(null);
});
}
fillSampleData(): void {
this.validationForm.patchValue({
name: 'John Doe',
email: 'john.doe@example.com',
password: 'SecurePass123!',
age: "30",
website: 'https://johndoe.com',
bio: 'Software developer with 10 years of experience in web development.'
});
this.validationForm.markAllAsTouched();
}
// Custom URL validator
private urlValidator(control: AbstractControl): ValidationErrors | null {
if (!control.value) return null;
try {
new URL(control.value);
return null;
} catch {
return { url: true };
}
}
}