/* istanbul ignore file - Design system demo page covered by e2e tests */ /** * Form Patterns Demo * Interactive demonstrations of form patterns with validation * Access: /dev/forms */ 'use client'; import { useState } from 'react'; import { Link } from '@/lib/i18n/routing'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { z } from 'zod'; import { CheckCircle2, Loader2 } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { DevBreadcrumbs } from '@/components/dev/DevBreadcrumbs'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Textarea } from '@/components/ui/textarea'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { Badge } from '@/components/ui/badge'; import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'; import { Example, ExampleSection } from '@/components/dev/Example'; import { BeforeAfter } from '@/components/dev/BeforeAfter'; // Example schemas const loginSchema = z.object({ email: z.string().email('Invalid email address'), password: z.string().min(8, 'Password must be at least 8 characters'), }); const contactSchema = z.object({ name: z.string().min(1, 'Name is required'), email: z.string().email('Invalid email address'), message: z.string().min(10, 'Message must be at least 10 characters'), category: z.string().min(1, 'Please select a category'), }); type LoginForm = z.infer; type ContactForm = z.infer; export default function FormsPage() { const [isSubmitting, setIsSubmitting] = useState(false); const [submitSuccess, setSubmitSuccess] = useState(false); // Login form const { register: registerLogin, handleSubmit: handleSubmitLogin, formState: { errors: errorsLogin }, } = useForm({ resolver: zodResolver(loginSchema), }); // Contact form const { register: registerContact, handleSubmit: handleSubmitContact, formState: { errors: errorsContact }, setValue: setValueContact, } = useForm({ resolver: zodResolver(contactSchema), }); const onSubmitLogin = async (data: LoginForm) => { setIsSubmitting(true); setSubmitSuccess(false); // Simulate API call await new Promise((resolve) => setTimeout(resolve, 1500)); if (process.env.NODE_ENV === 'development') { console.log('Login form data:', data); } setIsSubmitting(false); setSubmitSuccess(true); }; const onSubmitContact = async (data: ContactForm) => { setIsSubmitting(true); setSubmitSuccess(false); // Simulate API call await new Promise((resolve) => setTimeout(resolve, 1500)); if (process.env.NODE_ENV === 'development') { console.log('Contact form data:', data); } setIsSubmitting(false); setSubmitSuccess(true); }; return (
{/* Breadcrumbs */} {/* Content */}
{/* Introduction */}

Complete form implementations using react-hook-form for state management and Zod for validation. Includes error handling, loading states, and accessibility features.

react-hook-form Zod Validation ARIA
{/* Basic Form */}
{errors.email && (

{errors.email.message}

)}
`} >
{/* Email */}
{errorsLogin.email && ( )}
{/* Password */}
{errorsLogin.password && ( )}
{/* Submit */} {/* Success Message */} {submitSuccess && ( Success! Form submitted successfully. )}
{/* Complete Form */} {/* Input field */}
{errors.name &&

{errors.name.message}

}
{/* Textarea field */}