Back to components

Form Field

zyra-form-field

Field wrappers that align labels, hints, and validation copy into a more polished form system.

Component preview

Explore the available states and the real library behavior for this component.

zyra-form-field + zyra-input

CVAAngular Forms

Smart wrapper + pure CVA input — Reactive & Template Forms

Controls
type
appearance
size
hint
successHint
features
prefixIcon
suffixIcon
maxLength
Architecture

zyra-form-field — label, hint, icons, counter

zyra-input — pure CVA, no chrome

Use zyra-input standalone inside toolbars, tables etc.

Live Preview outlinemdtext
This is a hint message
valid: false touched: false dirty: false
Generated Code
<zyra-form-field
  label="Email"
  hint="We'll never share it"
  successHint="Valid email"
  appearance="outline"
>
  <zyra-input type="text" formControlName="email" />
</zyra-form-field>

// Component:
readonly appIcons = appIcons;
form = new FormGroup({
  email: new FormControl('', [Validators.required, Validators.email])
});
Event Log 0
Interact with the input above to see events
Appearances 3 variants
appearance="outline"
outline style input
appearance="filled"
filled style input
appearance="underline"
underline style input
Real World Forms Reactive Forms
Login
Welcome back
We'll never share your email
At least 8 characters
✗ Has errors
Register
Create your account
Min 2 characters
Min 10 digits
Min 8 chars + uppercase + number + symbol
✗ Has errors
Profile Settings
Update your info
Min 3 chars, no spaces
Must start with https://
Max 160 characters
0 / 160
✓ Form valid
All Validators Blur each to trigger
Validators.required
Leave empty and blur
Validators.email
Try: notanemail
Validators.minLength(6)
Try: abc
Validators.maxLength(10)
Try more than 10 chars
0 / 10
Validators.min(18)
Try: 15
Validators.max(100)
Try: 150
Validators.pattern
6 digits only. Try: abc123
Custom validator
No spaces. Try: hello world
zyra-input Standalone No zyra-form-field needed
Search bar
🔍
Inside a table cell
Row 1
Row 2
Row 3

Copy-paste example

Drop this into your Angular standalone component and it works out of the box.

form-field.demo.ts
import { Component } from '@angular/core';
import { ZyraFormField, ZyraInput } from 'zyra-ng-ui';

@Component({
  selector: 'app-demo-form-field',
  standalone: true,
  imports: [ZyraFormField, ZyraInput],
  template: `
    <zyra-form-field
      label="Email"
      hint="We'll only use this for account updates."
    >
      <zyra-input
        type="email"
        placeholder="name@company.com"
      />
    </zyra-form-field>
  `,
})
export class DemoFormFieldComponent {}

Variants

All the visual modes and states available for this component.

with label

Visible label above the field

with hint

Helper text below the field

with error

Error message replacing the hint on invalid state

with prefix icon

Icon decorating the start of the wrapped input

API

All inputs and configuration options for zyra-form-field.

PropTypeDefaultDescription
labelstring-Visible label text linked to the child input
hintstring-Helper text shown below the input
errorstring-Error text; replaces hint when set
size'sm' | 'md' | 'lg''md'Passes size down to child input
prefixIconIconDefinition-Icon shown inside the field leading edge
clearButtonbooleanfalseShows a clear x button in the field

Accessibility

Built to meet WCAG 2.0 AA. These notes cover the key ARIA, keyboard, and interaction behaviours.

  • label is automatically linked to the child input via htmlFor/id pairing
  • hint and error text are linked via aria-describedby on the input
  • When error is set, the child input receives aria-invalid="true"