Claude-skill-registry form-validator-generator
Generate comprehensive form validation logic for React forms with TypeScript. Use when creating signup/login forms, input validation, or user data collection. Includes email regex, password strength, required fields, and error handling.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/form-validator-generator" ~/.claude/skills/majiayu000-claude-skill-registry-form-validator-generator && rm -rf "$T"
manifest:
skills/data/form-validator-generator/SKILL.mdsource content
Form Validator Generator
Generate TypeScript validation logic for React forms with comprehensive error handling.
When to Use
Use this skill when:
- Creating signup or signin forms
- Building forms with multiple fields
- Need client-side validation before submission
- Implementing user input validation
- Creating questionnaires or surveys
Instructions
Step 1: Identify Form Fields
Determine which fields need validation:
- Email addresses
- Passwords (with strength requirements)
- Names (trim whitespace)
- Phone numbers
- Dropdowns/selects (required selections)
- Text areas
- Custom fields
Step 2: Generate Validation Function
Create a TypeScript validation function:
const validateForm = (): boolean => { const errors: Record<string, string> = {}; // Add validation logic for each field setValidationErrors(errors); return Object.keys(errors).length === 0; };
Step 3: Implement Field-Specific Validation
Add rules for each field type:
Email Validation:
if (!formData.email.trim()) { errors.email = "Email is required"; } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.email)) { errors.email = "Please enter a valid email address"; }
Password Validation:
if (!formData.password) { errors.password = "Password is required"; } else if (formData.password.length < 8) { errors.password = "Password must be at least 8 characters"; }
Password Confirmation:
if (formData.password !== formData.confirmPassword) { errors.confirmPassword = "Passwords do not match"; }
Required Field:
if (!formData.name.trim()) { errors.name = "Name is required"; }
Required Select:
if (!formData.softwareExperience) { errors.softwareExperience = "Please select your experience level"; }
Step 4: Add Real-time Validation
Clear errors as user types:
const handleChange = (field: string, value: string) => { setFormData((prev) => ({ ...prev, [field]: value })); // Clear validation error for this field if (validationErrors[field]) { setValidationErrors((prev) => { const newErrors = { ...prev }; delete newErrors[field]; return newErrors; }); } };
Step 5: Display Validation Errors
Show errors in UI:
<input type="email" value={formData.email} onChange={(e) => handleChange("email", e.target.value)} className={validationErrors.email ? styles.error : ""} />; { validationErrors.email && ( <span className={styles.errorMessage}>{validationErrors.email}</span> ); }
Complete Example: Signup Form Validation
import { useState } from "react"; interface SignupFormData { name: string; email: string; password: string; confirmPassword: string; softwareExperience: string; aiMlFamiliarity: string; } export default function SignupForm() { const [formData, setFormData] = useState<SignupFormData>({ name: "", email: "", password: "", confirmPassword: "", softwareExperience: "", aiMlFamiliarity: "", }); const [validationErrors, setValidationErrors] = useState< Record<string, string> >({}); const validateForm = (): boolean => { const errors: Record<string, string> = {}; // Name validation if (!formData.name.trim()) { errors.name = "Name is required"; } // Email validation if (!formData.email.trim()) { errors.email = "Email is required"; } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.email)) { errors.email = "Please enter a valid email address"; } // Password validation if (!formData.password) { errors.password = "Password is required"; } else if (formData.password.length < 8) { errors.password = "Password must be at least 8 characters"; } // Password confirmation if (formData.password !== formData.confirmPassword) { errors.confirmPassword = "Passwords do not match"; } // Required select fields if (!formData.softwareExperience) { errors.softwareExperience = "Please select your experience level"; } if (!formData.aiMlFamiliarity) { errors.aiMlFamiliarity = "Please select your AI/ML familiarity"; } setValidationErrors(errors); return Object.keys(errors).length === 0; }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!validateForm()) { return; } // Proceed with form submission }; return <form onSubmit={handleSubmit}>{/* Form fields */}</form>; }
Validation Rules Library
Email Patterns
// Basic email /^[^\s@]+@[^\s@]+\.[^\s@]+$/ // Strict email (RFC 5322) /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/
Password Strength
// At least 8 characters password.length >= 8 // Contains uppercase /[A-Z]/.test(password) // Contains number /\d/.test(password) // Contains special character /[!@#$%^&*(),.?":{}|<>]/.test(password)
Phone Numbers
// US phone number /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/ // International format /^\+?[1-9]\d{1,14}$/
URLs
// Basic URL /^https?:\/\/.+/ // Strict URL /^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)$/
Error Message Best Practices
- Be Specific: "Email is required" not "Invalid input"
- Be Helpful: "Password must be at least 8 characters" not "Bad password"
- Be Consistent: Use same tone/style across all messages
- Be Positive: "Please enter your email" not "You forgot email"
TypeScript Types
// Validation errors type ValidationErrors = Record<string, string>; // Form data interface FormData { [key: string]: string | number | boolean; } // Validation rules type ValidationRule = (value: any) => string | null; // Field config interface FieldConfig { required?: boolean; pattern?: RegExp; minLength?: number; maxLength?: number; custom?: ValidationRule; }
Accessibility Considerations
- Link error messages to inputs with
aria-describedby - Use
on fields with errorsaria-invalid - Ensure error messages are screen-reader friendly
- Don't rely solely on color to indicate errors
<input type="email" id="email" aria-invalid={!!validationErrors.email} aria-describedby={validationErrors.email ? "email-error" : undefined} />; { validationErrors.email && ( <span id="email-error" role="alert"> {validationErrors.email} </span> ); }