Formularios
Patrones para construir formularios accesibles y consistentes.
Estructura base
<form onSubmit={handleSubmit} className="space-y-6">
{/* Campos agrupados */}
<div className="grid gap-4 sm:grid-cols-2">
<Input label="Nombre *" placeholder="Tu nombre" required />
<Input label="Email *" placeholder="tu@email.com" type="email" required />
</div>
{/* Campo de texto largo */}
<div className="space-y-2">
<label className="block text-sm font-medium text-zinc-300">
Mensaje *
</label>
<textarea
className="w-full rounded-xl border border-zinc-700 bg-zinc-900
px-4 py-3 text-sm text-white placeholder:text-zinc-500
focus:border-blue-500 focus:outline-none focus:ring-2
focus:ring-blue-500/20 min-h-[120px] resize-y"
placeholder="Describe tu proyecto..."
required
/>
</div>
{/* Submit */}
<Button type="submit" variant="primary" size="lg" className="w-full sm:w-auto">
Enviar mensaje
</Button>
</form>Validación
Mostrar errores inline debajo del campo. Cambiar el borde a rojo. Usar role="alert" para accesibilidad.
// Usar el prop 'error' del componente Input
<Input
label="Email"
placeholder="tu@email.com"
error={errors.email?.message} // react-hook-form compatible
/>
// El componente maneja automáticamente:
// ✓ aria-invalid="true"
// ✓ aria-describedby apuntando al mensaje
// ✓ Borde rojo + ring rojo
// ✓ Mensaje con role="alert"Select
<div className="space-y-2">
<label className="block text-sm font-medium text-zinc-300">
Tipo de proyecto
</label>
<select className="flex h-11 w-full rounded-xl border border-zinc-700
bg-zinc-900 px-4 py-2 text-sm text-white
focus:border-blue-500 focus:outline-none focus:ring-2
focus:ring-blue-500/20 appearance-none"
>
<option value="">Selecciona una opción</option>
<option value="web">Aplicación Web</option>
<option value="mobile">App Móvil</option>
<option value="saas">Plataforma SaaS</option>
</select>
</div>Lineamientos
- • Siempre usar
labelvisible — nunca solo placeholder - • Marcar campos obligatorios con asterisco (*) en el label
- • Mostrar errores solo después del primer submit o blur
- • Usar
autocompleteen campos comunes (email, name, tel) - • Agrupar campos relacionados en grids de 2 columnas en desktop
- • Botón de submit siempre al final, con estado loading al enviar