ancoleman/building-forms
Builds form components and data collection interfaces including contact forms, registration flows, checkout processes, surveys, and settings pages. Includes 50+ input types, validation strategies, accessibility patterns (WCAG 2.1), multi-step wizards, and UX best practices. Provides decision trees from data type to component selection, validation timing guidance, and error handling patterns. Use when creating forms, collecting user input, building surveys, implementing validation, designing multi-step workflows, or ensuring form accessibility.
npx skills add https://github.com/ancoleman/ai-design-components --skill building-forms
Build accessible, user-friendly forms with systematic component selection, validation strategies, and UX best practices.
Forms are the primary mechanism for user data input in web applications. This skill provides systematic guidance for:
Triggers:
Common Requests:
The Golden Rule: Data Type → Input Component → Validation Pattern
Start by identifying the data type to collect, then select the appropriate component:
Quick Reference:
For detailed decision tree: See references/decision-tree.md
Recommended Default: On Blur with Progressive Enhancement
Field pristine (never touched): No validation
User typing: No errors shown
On blur (field loses focus): Validate and show errors
After first error: Switch to onChange for that field
On fix: Show success immediately
Validation Modes:
For complete validation guide: See references/validation-concepts.md
Critical Accessibility Patterns:
Labels and Instructions:
<label> or aria-labelKeyboard Navigation:
Error Handling:
aria-describedby)aria-live)ARIA Attributes:
aria-required="true" for required fieldsaria-invalid="true" when validation failsaria-describedby linking to help/error textrole="group" for related inputsaria-live="polite" for validation messagesFor complete accessibility checklist: See references/accessibility-forms.md
Modern Form UX Principles (2024-2025):
For detailed UX patterns: See references/ux-patterns.md
Good Error Message Formula:
Examples:
❌ Bad: "Invalid input"
✅ Good: "Email address must include @ symbol (e.g., [email protected])"
❌ Bad: "Error"
✅ Good: "Password must be at least 8 characters long"
❌ Bad: "Field required"
✅ Good: "Please enter your email address so we can send order confirmation"
Tone Guidelines:
This skill provides universal form concepts above, with language-specific implementations below.
Recommended Stack:
Quick Start:
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import * as z from 'zod';
// Define validation schema
const schema = z.object({
email: z.string().email('Invalid email address'),
password: z.string().min(8, 'Password must be at least 8 characters'),
});
type FormData = z.infer<typeof schema>;
function LoginForm() {
const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
resolver: zodResolver(schema),
mode: 'onBlur', // Validate on blur (recommended)
});
const onSubmit = (data: FormData) => {
console.log(data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<label htmlFor="email">Email</label>
<input id="email" {...register('email')} type="email" />
{errors.email && <span role="alert">{errors.email.message}</span>}
<label htmlFor="password">Password</label>
<input id="password" {...register('password')} type="password" />
{errors.password && <span role="alert">{errors.password.message}</span>}
<button type="submit">Login</button>
</form>
);
}
Detailed JavaScript/React Documentation:
references/javascript/react-hook-form.md - Complete React Hook Form guidereferences/javascript/zod-validation.md - Zod schema validation patternsreferences/javascript/examples/ - Working code examplesRecommended Stack:
Quick Start (FastAPI + Pydantic):
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, EmailStr, Field, validator
app = FastAPI()
# Define validation schema
class LoginForm(BaseModel):
email: EmailStr # Validates email format
password: str = Field(..., min_length=8, description="Password must be at least 8 characters")
@validator('password')
def validate_password_strength(cls, v):
if not any(char.isdigit() for char in v):
raise ValueError('Password must contain at least one number')
if not any(char.isupper() for char in v):
raise ValueError('Password must contain at least one uppercase letter')
return v
@app.post("/api/login")
async def login(form_data: LoginForm):
# Pydantic automatically validates incoming data
# If validation fails, returns 422 with error details
return {"message": "Login successful", "email": form_data.email}
# Example error response (automatic):
# {
# "detail": [
# {
# "loc": ["body", "email"],
# "msg": "value is not a valid email address",
# "type": "value_error.email"
# }
# ]
# }
Detailed Python Documentation:
references/python/pydantic-forms.md - Pydantic validation patternsreferences/python/wtforms.md - WTForms for Flask/Djangoreferences/python/examples/ - Working code examplesPlanned Libraries:
*Rust implementation will be added when needed.*
Planned Libraries:
*Go implementation will be added when needed.*
Text-Based:
Selection:
Date & Time:
Advanced Selection:
Specialized:
Structured Data:
Multi-Step Forms:
Dynamic Forms:
Advanced Patterns:
All form components use the design-tokens skill for visual styling, enabling theme switching (light/dark/high-contrast/custom brands).
Key Token Categories:
See: skills/design-tokens/ for complete theming documentation.
// Basic contact form with validation
// See: references/javascript/examples/basic-form.tsx
// Multi-step registration with password strength
// See: references/javascript/examples/multi-step-wizard.tsx
// Real-time validation with debouncing
// See: references/javascript/examples/inline-validation.tsx
// Dynamic form with conditional fields
// See: references/javascript/examples/conditional-form.tsx
// Mixed input types with autosave
// See: references/javascript/examples/settings-form.tsx
Question: What input should I use?
→ See references/decision-tree.md for complete decision tree
Question: When should I validate?
→ Use on-blur with progressive enhancement (on-change after first error)
→ See references/validation-concepts.md for all strategies
Question: How do I make my form accessible?
→ Use semantic HTML, label all inputs, support keyboard navigation
→ See references/accessibility-forms.md for WCAG 2.1 checklist
Question: How do I handle complex validation?
→ Use schema validation (Zod for TypeScript, Yup for JavaScript)
→ See references/javascript/zod-validation.md for patterns
Question: How do I build a multi-step form?
→ Use state management with progress tracking
→ See references/javascript/examples/multi-step-wizard.tsx
<input>, <select>, <textarea> when possible10. Use design tokens - Consistent styling, theme support
references/decision-tree.md - Complete component selection frameworkreferences/validation-concepts.md - All validation strategies and patternsreferences/accessibility-forms.md - WCAG 2.1 AA compliance checklistreferences/ux-patterns.md - Modern form UX best practicesreferences/javascript/ - JavaScript/React implementation guidesTake ancoleman/building-forms from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.