Agent skill

form-builder

Build production-ready forms in React/TypeScript. Use when creating contact forms, signup forms, multi-step wizards, or any user input interfaces. Covers React Hook Form patterns, Zod validation, and form state management.

Stars 9
Forks 9

Install this agent skill to your Project

npx add-skill https://github.com/danielmeppiel/corporate-website/tree/main/.github/skills/form-builder

Metadata

Additional technical details for this skill

author
danielmeppiel
version
1.0.0
apm commit
dda98651f55e8fb6a1166a3411c2ae0a5cda5f1e
apm package
danielmeppiel/form-builder
apm version
1.0.0
apm installed at
2025-12-19T12:34:05.033066

SKILL.md

Form Builder Skill

Build accessible, type-safe forms for React applications using industry-standard patterns.

When to Use This Skill

Activate when the user asks to:

  • Create a form (contact, signup, login, checkout, etc.)
  • Add form validation
  • Handle form submissions
  • Build multi-step form wizards
  • Manage form state and loading states

Core Stack

Library Purpose
React Hook Form Form state management, minimal re-renders
Zod TypeScript-first schema validation
React UI components

Quick Start Pattern

Every form follows this structure:

tsx
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';

// 1. Define schema
const schema = z.object({
  email: z.string().email('Invalid email'),
  name: z.string().min(2, 'Name too short'),
});

type FormData = z.infer<typeof schema>;

// 2. Create component
export function MyForm() {
  const {
    register,
    handleSubmit,
    formState: { errors, isSubmitting },
  } = useForm<FormData>({
    resolver: zodResolver(schema),
  });

  // 3. Handle submission
  const onSubmit = async (data: FormData) => {
    await submitToAPI(data);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register('name')} aria-describedby="name-error" />
      {errors.name && <span id="name-error" role="alert">{errors.name.message}</span>}
      
      <input {...register('email')} aria-describedby="email-error" />
      {errors.email && <span id="email-error" role="alert">{errors.email.message}</span>}
      
      <button type="submit" disabled={isSubmitting}>
        {isSubmitting ? 'Sending...' : 'Submit'}
      </button>
    </form>
  );
}

Key Patterns

Validation Timing

  • On blur: Best for most fields. Validates when user leaves field.
  • On change: Use for real-time feedback (password strength).
  • On submit: Always validate on submit as final gate.
tsx
useForm({
  mode: 'onBlur',        // Validate on blur
  reValidateMode: 'onChange', // Re-validate on change after first error
});

Error Display

Always connect errors to inputs for screen readers:

tsx
<input 
  {...register('email')} 
  aria-invalid={!!errors.email}
  aria-describedby={errors.email ? 'email-error' : undefined}
/>
{errors.email && (
  <span id="email-error" role="alert">
    {errors.email.message}
  </span>
)}

Loading States

Disable form during submission, show visual feedback:

tsx
const { formState: { isSubmitting } } = useForm();

<button type="submit" disabled={isSubmitting}>
  {isSubmitting ? 'Sending...' : 'Submit'}
</button>

Server Errors

Handle API errors and display to user:

tsx
const [serverError, setServerError] = useState<string | null>(null);

const onSubmit = async (data: FormData) => {
  setServerError(null);
  try {
    await submitToAPI(data);
  } catch (error) {
    setServerError('Failed to submit. Please try again.');
  }
};

Detailed References

For in-depth patterns, see:

  • React Hook Form patterns - Component structure, registration, controlled inputs
  • Validation patterns - Zod schemas, custom validators, async validation
  • State management - Loading, errors, multi-step forms

Complete Examples

Working implementations:

  • Contact form - Full-featured with all patterns
  • Newsletter signup - Minimal implementation

Common Schemas

Email Field

tsx
z.string().email('Please enter a valid email')

Password with Requirements

tsx
z.string()
  .min(8, 'Password must be at least 8 characters')
  .regex(/[A-Z]/, 'Must contain uppercase letter')
  .regex(/[0-9]/, 'Must contain number')

Phone (Optional)

tsx
z.string()
  .regex(/^\+?[\d\s-()]+$/, 'Invalid phone format')
  .optional()
  .or(z.literal(''))

Checkbox Consent

tsx
z.boolean().refine(val => val === true, 'You must agree to continue')

Dependencies

Install required packages:

bash
npm install react-hook-form @hookform/resolvers zod

Expand your agent's capabilities with these related and highly-rated skills.

Didn't find tool you were looking for?

Be as detailed as possible for better results