Comment créer des formulaires accessibles avec ShadCN UI

Créer des formulaires à la fois fonctionnels et accessibles peut s’avérer complexe. Entre la gestion d’état, la validation et l’implémentation des attributs ARIA appropriés, les développeurs passent souvent d’innombrables heures sur ce qui devrait être des tâches simples. ShadCN UI, combiné à React Hook Form et Zod, offre une solution puissante qui simplifie la création de formulaires tout en respectant les standards d’accessibilité.
Cet article démontre comment construire des formulaires accessibles avec ShadCN UI, intégrer ShadCN UI React Hook Form pour la gestion d’état, et implémenter des modèles de validation ShadCN UI Zod qui resteront pertinents pendant des années.
Points clés à retenir
- ShadCN UI gère automatiquement les attributs ARIA et les modèles d’accessibilité grâce à son système de formulaires composables
- L’intégration de React Hook Form fournit une gestion d’état efficace avec un minimum de re-rendus
- La validation de schéma Zod assure une validation de formulaire type-safe avec des messages d’erreur clairs
- Les composants intégrés gèrent les associations d’étiquettes, les annonces d’erreurs et la navigation au clavier
Comprendre l’architecture des formulaires ShadCN UI
ShadCN UI fournit un système de formulaires composables construit sur React Hook Form et les primitives Radix UI. L’architecture suit un modèle cohérent :
<Form>
<FormField
control={form.control}
name="fieldName"
render={({ field }) => (
<FormItem>
<FormLabel>Field Label</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormDescription>Helper text</FormDescription>
<FormMessage />
</FormItem>
)}
/>
</Form>
Cette structure gère automatiquement :
- La génération d’ID uniques en utilisant
React.useId()
- Les attributs
aria-describedby
etaria-invalid
appropriés - Les associations de messages d’erreur
- Les relations étiquette-champ de saisie
Configuration des formulaires accessibles avec ShadCN UI
D’abord, installez les composants nécessaires :
npx shadcn@latest add form input textarea checkbox label
Cette commande installe les composants ShadCN UI ainsi que les dépendances React Hook Form et Zod.
Création d’un schéma de formulaire de base
Définissez la structure de votre formulaire en utilisant Zod pour une validation type-safe :
import { z } from "zod"
const formSchema = z.object({
name: z.string().min(2, "Name must be at least 2 characters"),
email: z.string().email("Invalid email address"),
message: z.string().min(10, "Message must be at least 10 characters"),
terms: z.boolean().refine((val) => val === true, {
message: "You must accept the terms"
})
})
type FormData = z.infer<typeof formSchema>
Implémentation du composant de formulaire
Voici comment construire un formulaire de contact accessible en utilisant l’intégration ShadCN UI React Hook Form :
import { useForm } from "react-hook-form"
import { zodResolver } from "@hookform/resolvers/zod"
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, FormDescription } from "@/components/ui/form"
import { Input } from "@/components/ui/input"
import { Textarea } from "@/components/ui/textarea"
import { Checkbox } from "@/components/ui/checkbox"
import { Button } from "@/components/ui/button"
export function ContactForm() {
const form = useForm<FormData>({
resolver: zodResolver(formSchema),
defaultValues: {
name: "",
email: "",
message: "",
terms: false
}
})
function onSubmit(data: FormData) {
console.log(data)
}
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
<FormField
control={form.control}
name="name"
render={({ field }) => (
<FormItem>
<FormLabel>Name</FormLabel>
<FormControl>
<Input placeholder="John Doe" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormLabel>Email</FormLabel>
<FormControl>
<Input type="email" placeholder="john@example.com" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="message"
render={({ field }) => (
<FormItem>
<FormLabel>Message</FormLabel>
<FormControl>
<Textarea
placeholder="Your message here..."
className="resize-none"
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="terms"
render={({ field }) => (
<FormItem className="flex flex-row items-start space-x-3 space-y-0">
<FormControl>
<Checkbox
checked={field.value}
onCheckedChange={field.onChange}
/>
</FormControl>
<div className="space-y-1 leading-none">
<FormLabel>
Accept terms and conditions
</FormLabel>
</div>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit">Submit</Button>
</form>
</Form>
)
}
Discover how at OpenReplay.com.
Fonctionnalités d’accessibilité intégrées
Les composants de formulaire de ShadCN UI implémentent automatiquement des modèles d’accessibilité cruciaux :
- Étiquetage approprié : Le composant
FormLabel
utilise l’attributhtmlFor
pour s’associer aux contrôles de formulaire - Annonces d’erreurs : Les composants
FormMessage
sont liés viaaria-describedby
- États invalides : Les champs reçoivent automatiquement
aria-invalid="true"
lorsque la validation échoue - Navigation au clavier : Tous les composants supportent les interactions clavier standard
Modèles de validation avancés
Implémentez des scénarios de validation ShadCN UI Zod complexes :
const advancedSchema = z.object({
password: z.string()
.min(8, "Password must be at least 8 characters")
.regex(/[A-Z]/, "Password must contain at least one uppercase letter")
.regex(/[a-z]/, "Password must contain at least one lowercase letter")
.regex(/[0-9]/, "Password must contain at least one number"),
confirmPassword: z.string()
}).refine((data) => data.password === data.confirmPassword, {
message: "Passwords don't match",
path: ["confirmPassword"]
})
Bonnes pratiques pour des formulaires accessibles
- Utilisez toujours des étiquettes : Chaque champ de saisie nécessite une étiquette visible pour les utilisateurs de lecteurs d’écran
- Fournissez des messages d’erreur clairs : Soyez spécifique sur ce qui s’est mal passé et comment le corriger
- Regroupez les champs associés : Utilisez
fieldset
etlegend
pour les regroupements logiques - Testez avec le clavier : Assurez-vous que toutes les interactions fonctionnent sans souris
- Validez à la soumission : Évitez la validation inline agressive qui interrompt les utilisateurs
Conclusion
ShadCN UI transforme le développement de formulaires en combinant la puissance de la gestion d’état de React Hook Form avec la validation type-safe de Zod, tout en maintenant l’accessibilité comme principe fondamental. L’architecture des composants garantit que chaque formulaire que vous construisez respecte les standards WCAG sans nécessiter une gestion manuelle des attributs ARIA.
En suivant ces modèles, vous créez des formulaires qui fonctionnent pour tout le monde—indépendamment de leurs capacités ou technologies d’assistance. La beauté de cette approche réside dans sa simplicité : les formulaires accessibles deviennent la norme, pas une réflexion après coup.
FAQ
Bien que techniquement possible, les composants de formulaire de ShadCN UI sont conçus pour fonctionner avec React Hook Form. Les utiliser sans cela signifie perdre la validation automatique, la gestion d'état et les fonctionnalités d'accessibilité qui rendent la bibliothèque précieuse.
ShadCN UI génère automatiquement des ID uniques, associe les étiquettes aux champs de saisie via les attributs htmlFor, lie les messages d'erreur via aria-describedby, et définit aria-invalid lors d'erreurs de validation. Tous les composants supportent la navigation au clavier par défaut.
La validation Zod s'exécute uniquement quand nécessaire, typiquement lors des événements blur ou submit. L'impact sur les performances est minimal car React Hook Form empêche les re-rendus inutiles. Pour les formulaires avec des centaines de champs, considérez l'utilisation de la validation au niveau des champs plutôt qu'au niveau du schéma.
Gain Debugging Superpowers
Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.