Form

Building forms with Angular Reactive Forms and validation using Zod or class-validator.

Preview Code
This is your public display name. We'll never share your email.
Interactive

Features

  • Composable form components.
  • Form field component for building accessible forms.
  • Form validation using Angular validators or Zod.
  • Accessible error messages.
  • Form submission handling.

Installation

Install the component from your command line.

Angular CLInpmpnpmyarnbun
Bash
ng g @ng-cn/core:c form

Anatomy

Import all parts and piece them together.

Typescript
import {
  Form,
  FormField,
  FormItem,
  FormLabel,
  FormControl,
  FormDescription,
  FormMessage
} from '@/ui/form';
Html
<Form [form]="form">
  <FormField name="fieldName">
    <FormItem>
      <FormLabel />
      <FormControl>
        <!-- Input component -->
      </FormControl>
      <FormDescription />
      <FormMessage />
    </FormItem>
  </FormField>
</Form>

API Reference

Form

The form wrapper component that provides context.

PropTypeDefault
form *FormGroup
The Angular FormGroup instance.
class string
Additional CSS classes to apply.

FormField

Wraps a form field and provides context for validation.

PropTypeDefault
name *string
The name of the field in the form.

FormItem

Container for form field components.

PropTypeDefault
class string
Additional CSS classes to apply.

FormLabel

The label for the form field.

PropTypeDefault
class string
Additional CSS classes to apply.

Data Attributes

AttributeValues
[data-invalid]Present when field has errors

FormControl

Wraps the actual input component.

FormDescription

Help text for the form field.

PropTypeDefault
class string
Additional CSS classes to apply.

FormMessage

Displays validation error messages.

PropTypeDefault
class string
Additional CSS classes to apply.

Data Attributes

AttributeValues
[data-state]"error" | "valid"

Examples

Basic

A simple form with validation.

Html
// In your component:
form = new FormGroup({
  username: new FormControl('', [Validators.required, Validators.minLength(2)]),
});

onSubmit() {
  if (this.form.valid) {
    console.log(this.form.value);
  }
}

// In template:
<Form [form]="form" (ngSubmit)="onSubmit()">
  <FormField name="username">
    <FormItem>
      <FormLabel>Username</FormLabel>
      <FormControl>
        <Input formControlName="username" placeholder="shadcn" />
      </FormControl>
      <FormDescription>
        This is your public display name.
      </FormDescription>
      <FormMessage />
    </FormItem>
  </FormField>
  <Button type="submit">Submit</Button>
</Form>

With select

Using select within a form.

Html
<Form [form]="form">
  <FormField name="email">
    <FormItem>
      <FormLabel>Email</FormLabel>
      <Select formControlName="email">
        <FormControl>
          <SelectTrigger>
            <SelectValue placeholder="Select a verified email" />
          </SelectTrigger>
        </FormControl>
        <SelectContent>
          <SelectItem value="m@example.com">m&#64;example.com</SelectItem>
          <SelectItem value="m@google.com">m&#64;google.com</SelectItem>
        </SelectContent>
      </Select>
      <FormDescription>
        You can manage email addresses in your settings.
      </FormDescription>
      <FormMessage />
    </FormItem>
  </FormField>
</Form>

With textarea

Multi-line input in a form.

Html
<Form [form]="form">
  <FormField name="bio">
    <FormItem>
      <FormLabel>Bio</FormLabel>
      <FormControl>
        <Textarea
          formControlName="bio"
          placeholder="Tell us a little bit about yourself"
          class="resize-none"
        />
      </FormControl>
      <FormDescription>
        You can &#64;mention other users and organizations.
      </FormDescription>
      <FormMessage />
    </FormItem>
  </FormField>
</Form>

With checkbox

Boolean field with checkbox.

Html
<Form [form]="form">
  <FormField name="marketing">
    <FormItem class="flex flex-row items-start space-x-3 space-y-0">
      <FormControl>
        <Checkbox formControlName="marketing" />
      </FormControl>
      <div class="space-y-1 leading-none">
        <FormLabel>
          Receive marketing emails
        </FormLabel>
        <FormDescription>
          We'll send you updates about new features.
        </FormDescription>
      </div>
    </FormItem>
  </FormField>
</Form>

Accessibility

Adheres to the Form validation pattern .

Keyboard Interactions

KeyDescription
Tab Moves focus between form fields.
Enter Submits the form when focus is on the submit button.