Forms

TaylorUI uses react-aria-components to build accessible forms and provides a set of pre-built form elements.

  • Supports client-side and server side validation
  • All form components meet our A11y standards

Create an account

Please enter your full name without any middle names
Please enter a valid email address. Example: test@test.com
Please enter your phone number with the country code. Example: +43
Password must be at least 8 characters long and contain at least one uppercase letter, one lowercase letter, and one number.
Favorite Animal (Required)
Date of Birth (Required)
Please select your date of birth
Preferred Contact Method (Required)
Read our full Terms and Conditions
'use client';
 
import Link from 'next/link';
import { Button } from '@/ui/components/button/button';
import { Checkbox } from '@/ui/components/forms/checkbox';
import { Form } from '@/ui/components/forms/form';
import { useFormAction } from '@/ui/components/forms/hooks/use-form-action';
import { Radio, RadioGroup } from '@/ui/components/forms/radio';
import { Select, SelectItem } from '@/ui/components/forms/select';
import { TextField } from '@/ui/components/forms/text-field';
import {
  FieldErrorSummary,
  FormErrors,
  ServerError,
  validators,
} from '@/ui/components/forms/validation';
import { registerAction } from './actions';
 
export const RegistrationFormExample = () => {
  const form = useFormAction<{
    name: string;
    email: string;
    phone: string;
    password: string;
    favoriteAnimal: string;
    contactMethod: string;
    'terms-and-conditions': boolean;
  }>(registerAction);
 
  return (
    <Form
      action={form.action}
      className="flex max-w-lg flex-col gap-4 rounded-lg border-2 border-gray-200 p-4 shadow-xl"
      validationErrors={form.fieldErrors}
    >
      <h2 className="mb-4 text-3xl font-bold">Create an account</h2>
 
      <FormErrors>
        {/* Error message for things that go wrong on the server */}
        {form.serverError && !form.isPending && (
          <ServerError title="Could not register">
            {form.serverError}
          </ServerError>
        )}
 
        {/* Error message for mistakes the user makes in the form */}
        <FieldErrorSummary
          title="There are errors in your submission"
          subtitle="Please correct your input in these fields:"
          fieldLabels={{
            name: 'Name',
            email: 'Email Address',
            phone: 'Phone Number',
            password: 'Password',
            favoriteAnimal: 'Favorite Animal',
            contactMethod: 'Preferred Contact Method',
            'terms-and-conditions': 'Terms and Conditions',
          }}
        />
      </FormErrors>
 
      <TextField
        id="name"
        name="name"
        label="Name"
        type="text"
        description="Please enter your full name without any middle names"
        defaultValue={form.defaultValues.name}
        autoComplete="name"
        isRequired
        validate={(value) => {
          if (!value) {
            return 'Please enter your name';
          }
        }}
      />
 
      <TextField
        id="email"
        name="email"
        label="Email Address"
        type="email"
        description="Please enter a valid email address. Example: test@test.com"
        defaultValue={form.defaultValues.email}
        autoComplete="email"
        validate={(value) => {
          if (!validators.email(value)) {
            return 'Invalid email address';
          }
        }}
        isRequired
      />
 
      <TextField
        id="phone"
        name="phone"
        label="Phone Number"
        type="tel"
        description="Please enter your phone number with the country code. Example: +43"
        defaultValue={form.defaultValues.phone}
        autoComplete="tel"
      />
 
      <TextField
        id="password"
        name="password"
        label="Password"
        type="password"
        description="Password must be at least 8 characters long and contain at least one
          uppercase letter, one lowercase letter, and one number."
        defaultValue={form.defaultValues.password}
        autoComplete="new-password"
        isRequired
        validate={validatePassword}
      />
 
      <Select
        id="favoriteAnimal"
        name="favoriteAnimal"
        label="Favorite Animal"
        isRequired
        defaultValue={form.defaultValues.favoriteAnimal}
        validate={(value) => {
          if (!value) {
            return 'Please select an animal';
          }
        }}
      >
        {animals.map((animal) => (
          <SelectItem key={animal.id} id={animal.id}>
            {animal.name}
          </SelectItem>
        ))}
      </Select>
 
      <RadioGroup
        id="contactMethod"
        name="contactMethod"
        label="Preferred Contact Method"
        isRequired
        defaultValue={form.defaultValues.contactMethod}
        validate={(value) => {
          console.log('RADIO VALIDATION', value);
          if (!value) {
            return 'Please select a contact method';
          }
          if (value === 'pigeon') {
            return 'Please select a modern contact method';
          }
        }}
        orientation="vertical"
      >
        <Radio value="email">Email</Radio>
        <Radio value="phone">Phone</Radio>
        <Radio value="pigeon">Carrier Pigeon</Radio>
      </RadioGroup>
 
      <Checkbox
        id="terms-and-conditions"
        name="terms-and-conditions"
        value="terms-and-conditions"
        label="I agree to the terms and conditions"
        defaultSelected={!!form.defaultValues['terms-and-conditions']}
        description={
          <>
            Read our full{' '}
            <Link
              href="/terms-and-conditions"
              className="text-primary-500 hover:underline"
            >
              Terms and Conditions
            </Link>
          </>
        }
        isRequired
        validate={(value) => {
          if (!value) {
            return 'Please agree to the terms and conditions';
          }
        }}
        className="pt-2"
      />
 
      <div>
        <Button type="submit">Submit</Button>
      </div>
    </Form>
  );
};