Form Validation

Pattern canonico per costruire form Qoovex comprensibili, recuperabili e accessibili usando le primitive già adottate nel prodotto.

Quando usarlo

Usa questa composizione per ogni form operativo o di account che valida dati prima o dopo il submit. Sirio documenta il contratto già presente nei form reali: non introduce un form builder, una nuova sorgente di errori o una seconda astrazione sopra il design system.

Contratto del campo

Ogni parte ha un compito preciso. Descrizione ed errore sono facoltativi, la label no.

Label
È sempre visibile e collegata al controllo tramite htmlFor e id. Il placeholder resta soltanto un esempio.
Controllo
Mantiene name, tipo, autocomplete e semantica nativa o della primitiva canonica.
Descrizione
Compare solo quando chiarisce contenuto, formato o conseguenza del campo.
Errore locale
Segue il controllo, usa linguaggio umano e viene incluso nel suo aria-describedby.

Specimen interattivi

Gli esempi coprono campo normale, descrizione, errore locale, più errori, invio in corso, successo ed errore generale. Sono dimostrativi e non inviano dati.

Stati del singolo campo

Label, descrizione ed errore hanno responsabilità distinte e ID stabili.

La nota sarà visibile alle persone coinvolte nel lavoro.

Inserisci un indirizzo email valido.

Form completo

Invia il form vuoto per verificare gli errori locali e il focus sul primo campo invalido.

Inserisci solo le informazioni necessarie per comprendere la richiesta.

Se selezionata, la chiusura resta sospesa finché la richiesta è aperta.

Flusso di validazione

Il mapping degli errori resta vicino alla mutation reale; la composizione visuale resta comune.

  1. Mantieni lo stato del form e impedisci un secondo invio anche prima del re-render di pending.
  2. Mappa gli errori attribuibili ai campi, mostra un solo FieldError per controllo e imposta aria-invalid.
  3. Collega descrizione ed errore concatenando i rispettivi ID in aria-describedby.
  4. Dopo una risposta fallita porta il focus al primo controllo invalido visibile, seguendo l’ordine del form.
  5. Mostra un errore generale soltanto quando il problema non appartiene a un campo e non spostare arbitrariamente il focus.
  6. Durante l’invio usa aria-busy, controlli disabilitati e un solo messaggio di stato; dopo il successo comunica l’esito senza sottrarre il focus.

Controlli canonici

Componi Field,Label,FieldDescription eFieldError con input,textarea,select e checkbox esistenti.

I controlli composti legacy che non espongono ancora un contratto completo per ID, ref o messaggi locali non sono specimen canonici di questo pattern: vanno valutati separatamente prima di usarli in nuovi form.

Responsive e accessibilità

La tastiera, il focus e gli annunci fanno parte del comportamento del form, non sono decorazioni successive.

  • Input e textarea usano label native associate; select e checkbox mantengono la stessa relazione accessibile tramite le primitive canoniche.
  • L’errore non dipende dal colore: testo specifico, aria-invalid e associazione al controllo comunicano insieme lo stato.
  • FieldError fornisce l’annuncio urgente del singolo errore. Non aggiungere un secondo role=alert attorno allo stesso messaggio.
  • Pending e successo usano un solo role=status per cambiamento; lo spinner decorativo va nascosto se il testo annuncia già l’attesa.
  • Il focus resta visibile e segue l’ordine DOM. Non usare tabIndex positivi né autofocus aggressivo dopo successo o errore generale.
  • Su viewport stretti label, descrizioni, errori e azioni vanno a capo senza separarsi dal controllo a cui appartengono.

Errori da evitare

Questi anti-pattern rendono il recupero ambiguo anche quando la validazione tecnica è corretta.

  • Usare il placeholder come unica label o come istruzione permanente.
  • Mostrare tutti gli errori soltanto in cima al form, lontano dai controlli coinvolti.
  • Comunicare l’errore soltanto con colore, bordo o icona.
  • Perdere il focus dopo il submit o spostarlo quando non aiuta il recupero.
  • Renderizzare label senza htmlFor/id corrispondenti o riutilizzare lo stesso ID.
  • Mostrare nomi di proprietà backend, codici o messaggi raw ricevuti dal server.
  • Annunciare lo stesso errore con più live region o usare role=alert per ogni feedback non urgente.