Patrones de Frontend con IA
Pensar en componentes
Toda interfaz moderna se construye a partir de componentes — piezas pequeñas y reutilizables que se ensamblan como bloques de construcción. Una barra de navegación es un componente. Un botón es un componente. Una tarjeta que muestra el perfil de un usuario es un componente. Incluso el layout completo de una página es un componente hecho de componentes más pequeños.
Este modelo mental es tu arma secreta al trabajar con IA. En lugar de pedir una página completa de una sola vez, divides la interfaz en piezas y describes cada una. La IA las construye individualmente, y tú las compones en algo más grande.
Atomic Design para Vibe Coders
El atomic design de Brad Frost nos da un vocabulario muy útil:
- Atoms — las piezas más pequeñas: botones, inputs, labels, iconos, badges
- Molecules — grupos pequeños de atoms: una barra de búsqueda (input + botón), un campo de formulario (label + input + mensaje de error)
- Organisms — grupos complejos: una barra de navegación, una sección hero, una tabla de precios
- Templates — layouts a nivel de página que organizan organisms en una estructura
- Pages — templates llenos con contenido real
Cuando le das prompts a la IA, normalmente trabajas a nivel de molecule y organism. Así es como funciona el pensamiento:
"Construyeme una tabla de precios" → organism (buen alcance de prompt)
"Construyeme una tarjeta de precio" → molecule (aun mas enfocado)
"Construyeme un boton" → atom (a veces util para establecer variantes)
El punto ideal es describir un organism a la vez y luego componerlos. Construirás más rápido y obtendrás resultados de mayor calidad que pidiendo todo de una sola vez.
Describir componentes a la IA
Mientras mejor sea tu descripción, mejor será el resultado. Compara estos dos prompts:
Vago: "Hazme un componente card."
Específico: "Crea un componente de tarjeta de característica con un icono en la parte superior (usando iconos de Lucide React), un título en texto semibold, una descripción de dos líneas en gris atenuado, y un borde sutil con esquinas redondeadas. La tarjeta debe tener un efecto hover que la eleve ligeramente con una sombra."
El segundo prompt le da a la IA todo lo que necesita: estructura, detalles de estilo, comportamiento e incluso la librería de iconos. Esta es la forma del vibe coding — piensas en lo que quieres, lo describes claramente, y la IA se encarga de la implementación.
Patrones de componentes React para Vibe Coders
No necesitas dominar la sintaxis de React para hacer vibe coding. Pero entender los patrones principales te ayuda a leer lo que genera la IA y a describir lo que quieres de manera más efectiva.
Componentes funcionales y Props
Cada componente de React es una función que retorna JSX (sintaxis similar a HTML). Los props son las entradas del componente:
function FeatureCard({ icon, title, description }: {
icon: React.ReactNode
title: string
description: string
}) {
return (
<div className="p-6 border rounded-xl hover:shadow-lg transition-shadow">
<div className="mb-4 text-blue-500">{icon}</div>
<h3 className="text-lg font-semibold mb-2">{title}</h3>
<p className="text-gray-600">{description}</p>
</div>
)
}
Al darle un prompt a la IA, puedes decir: "Crea un componente FeatureCard que acepte icon, title y description como props." La IA sabe qué hacer con eso.
Children y composición
El prop children permite que los componentes envuelvan a otros componentes:
function Card({ children }: { children: React.ReactNode }) {
return (
<div className="p-6 border rounded-xl shadow-sm">
{children}
</div>
)
}
// Uso
<Card>
<h3>Cualquier contenido va aqui</h3>
<p>El Card solo provee el estilo del contenedor</p>
</Card>
Este es el patrón de composición — construir interfaces complejas anidando componentes simples. Cuando le dices a la IA "crea un componente Card wrapper que acepte children", genera exactamente este patrón.
Renderizado condicional
A veces quieres mostrar u ocultar elementos basándote en datos:
function UserGreeting({ user }: { user: User | null }) {
return (
<div>
{user ? (
<p>Bienvenido de nuevo, {user.name}!</p>
) : (
<button>Iniciar Sesion</button>
)}
</div>
)
}
Patrón de prompt: "Muestra el nombre del usuario si está logueado, de lo contrario muestra un botón de inicio de sesión." La IA traduce tu intención en renderizado condicional automáticamente.
Curso intensivo de Tailwind CSS
Tailwind CSS es el enfoque de estilos más amigable para la IA porque es descriptivo. En lugar de escribir CSS en archivos separados, aplicas clases de utilidad directamente a tus elementos HTML.
El enfoque utility-first
CSS tradicional:
.card {
padding: 1.5rem;
border-radius: 0.75rem;
background-color: white;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
Equivalente en Tailwind:
<div class="p-6 rounded-xl bg-white shadow-sm">
Cada clase de Tailwind hace una sola cosa. Las compones para crear cualquier diseño. Aquí están las clases que verás con más frecuencia:
Layout: flex, grid, grid-cols-3, gap-4, items-center, justify-between, w-full, max-w-7xl, mx-auto
Espaciado: p-4 (padding), m-4 (margin), px-6 (padding horizontal), py-3 (padding vertical), space-y-4 (espacio vertical entre hijos)
Tipografía: text-lg, text-2xl, font-bold, font-semibold, text-gray-600, text-center, leading-relaxed
Colores: bg-blue-500, text-white, border-gray-200, bg-gradient-to-r, from-blue-600, to-purple-600
Efectos: shadow-md, rounded-lg, opacity-75, hover:shadow-lg, transition-all
Prefijos responsivos
Tailwind es mobile-first. Las clases sin prefijo aplican a todas las pantallas. Las clases con prefijo aplican a partir de ese breakpoint:
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
- Sin prefijo → móvil (todos los tamaños)
sm:→ 640px en adelantemd:→ 768px en adelantelg:→ 1024px en adelantexl:→ 1280px en adelante2xl:→ 1536px en adelante
Modo oscuro
El prefijo dark: de Tailwind aplica estilos cuando el modo oscuro está activo:
<div class="bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100">
Al darle un prompt a la IA, simplemente di "agrega soporte de modo oscuro" y añadirá variantes dark: a las clases apropiadas.
Describir estilos de Tailwind a la IA
No necesitas memorizar clases. Describe lo que quieres visualmente:
- "Una tarjeta con padding generoso, esquinas redondeadas y una sombra sutil" →
p-6 rounded-xl shadow-sm - "Fondo con gradiente azul de izquierda a derecha" →
bg-gradient-to-r from-blue-600 to-blue-800 - "Centrar todo horizontalmente con un ancho máximo" →
max-w-7xl mx-auto
La IA traduce tu lenguaje visual a clases de Tailwind. Ese es todo el punto.
Construyendo secciones de UI completas
Recorramos los patrones de UI más comunes que vas a construir. Para cada uno, mostraré el prompt que usarías y el tipo de resultado que obtendrás.
Secciones Hero
El hero es lo primero que ven los visitantes. Establece el tono.
Prompt: "Crea una sección hero con un fondo de gradiente de blue-600 a purple-600, texto blanco centrado con un encabezado grande, un párrafo de subtítulo, y dos botones CTA — uno blanco sólido y uno con borde. Hazlo responsivo con más padding en pantallas grandes."
function Hero() {
return (
<section className="bg-gradient-to-r from-blue-600 to-purple-600 py-20 md:py-32 px-4">
<div className="max-w-4xl mx-auto text-center">
<h1 className="text-4xl md:text-6xl font-bold text-white mb-6">
Construye mas rapido con IA
</h1>
<p className="text-lg md:text-xl text-blue-100 mb-10 max-w-2xl mx-auto">
Lanza apps de produccion en dias, no meses. Deja que la IA maneje el
codigo mientras tu te enfocas en el producto.
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<button className="px-8 py-3 bg-white text-blue-600 rounded-lg font-semibold hover:bg-blue-50 transition-colors">
Empieza Gratis
</button>
<button className="px-8 py-3 border-2 border-white text-white rounded-lg font-semibold hover:bg-white/10 transition-colors">
Ver Demo
</button>
</div>
</div>
</section>
)
}
Grillas de características
Las grillas de características muestran las capacidades de tu producto. El patrón es una grilla de tarjetas, cada una con un icono, título y descripción.
Prompt: "Crea una grilla de características de 3 columnas con 6 tarjetas. Cada tarjeta tiene un contenedor de icono con color, un título en negritas y una descripción. La grilla debe apilarse en 1 columna en móvil y 2 en tablet."
Esto genera una grilla responsiva usando grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 con tarjetas individuales dentro.
Tablas de precios
Las tablas de precios son uno de los patrones de UI más difíciles de lograr bien. Así es como les das prompt:
Prompt: "Crea una sección de precios con 3 niveles: Gratis, Pro ($19/mes) y Enterprise (precio personalizado). El plan Pro debe estar resaltado como 'Más Popular' con un borde de color y un badge. Cada plan muestra una lista de características con checkmarks. Agrega un botón CTA en la parte inferior de cada tarjeta."
El detalle clave es resaltar el plan popular — la IA maneja esto con estilos condicionales, normalmente un borde de color y un badge flotante.
Testimonios
Prompt: "Crea una sección de testimonios con 3 tarjetas de testimonio. Cada tarjeta tiene una cita en texto itálico, el avatar de la persona (usa un placeholder), su nombre, cargo y empresa. Agrega decoraciones de comillas."
Barras de navegación
La navegación es crítica y necesita funcionar en todos los tamaños de pantalla.
Prompt: "Crea una navbar responsiva con un logo a la izquierda, enlaces de navegación en el centro (ocultos en móvil) y un botón CTA a la derecha. En móvil, muestra un menú hamburguesa que alterna un menú desplegable con todos los enlaces. Usa estado de React para el toggle del menú móvil."
Esto genera un componente con useState para el menú móvil, un icono hamburguesa que alterna la visibilidad, y clases responsivas para mostrar/ocultar elementos.
Footers
Prompt: "Crea un footer con 4 columnas: Empresa (acerca de, blog, carreras), Producto (características, precios, docs), Recursos (guías, API, comunidad) y Legal (privacidad, términos, cookies). Agrega iconos de redes sociales en la parte inferior con una línea de copyright."
Formularios y validación
Los formularios son donde los usuarios interactúan con tu app. Hacerlos bien importa tanto para la UX como para la integridad de los datos.
Prompt: "Crea un formulario de contacto con campos de nombre, email y mensaje, y un botón de enviar. Agrega validación del lado del cliente — nombre requerido, email debe tener formato válido, mensaje debe tener al menos 20 caracteres. Muestra mensajes de error debajo de cada campo en texto rojo. Deshabilita el botón de envío mientras se está enviando."
function ContactForm() {
const [errors, setErrors] = useState<Record<string, string>>({})
const [isSubmitting, setIsSubmitting] = useState(false)
async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault()
const formData = new FormData(e.currentTarget)
const newErrors: Record<string, string> = {}
if (!formData.get("name")) newErrors.name = "El nombre es requerido"
if (!formData.get("email")?.toString().includes("@"))
newErrors.email = "Se requiere un email valido"
if ((formData.get("message")?.toString().length ?? 0) < 20)
newErrors.message = "El mensaje debe tener al menos 20 caracteres"
if (Object.keys(newErrors).length > 0) {
setErrors(newErrors)
return
}
setIsSubmitting(true)
// Enviar al API...
setIsSubmitting(false)
}
return (
<form onSubmit={handleSubmit} className="space-y-4 max-w-md mx-auto">
<div>
<label className="block text-sm font-medium mb-1">Nombre</label>
<input name="name" className="w-full px-4 py-2 border rounded-lg" />
{errors.name && <p className="text-red-500 text-sm mt-1">{errors.name}</p>}
</div>
{/* Similar para email y mensaje */}
<button
type="submit"
disabled={isSubmitting}
className="w-full py-2 bg-blue-600 text-white rounded-lg disabled:opacity-50"
>
{isSubmitting ? "Enviando..." : "Enviar Mensaje"}
</button>
</form>
)
}
El patrón es: estado controlado para errores, validación en el handler de envío, y retroalimentación visual para el usuario.
Modales y diálogos
Los modales son overlays que demandan la atención del usuario. Son comunes para confirmaciones, formularios y vistas de detalle.
Prompt: "Crea un componente Modal reutilizable que tome props isOpen, onClose, title y children. Debe tener un backdrop semi-transparente, centrar el modal vertical y horizontalmente, cerrarse al hacer clic en el backdrop o presionar Escape, e incluir un botón de cerrar en el header. Agrega una animación de fade-in."
Detalles clave de accesibilidad para mencionar en tus prompts:
- Cerrar al presionar la tecla Escape
- Cerrar al hacer clic en el backdrop
- Atrapar el foco dentro del modal (para que Tab no vaya a elementos detrás)
- Usar
role="dialog"yaria-modal="true"
Si usas una librería de componentes como shadcn/ui, obtienes todo esto gratis. Más sobre eso en un momento.
Diseño responsivo con prompts
Mobile-first significa que diseñas para pantallas pequeñas primero, y luego agregas complejidad para las más grandes. Al darle prompts a la IA, sé explícito sobre los breakpoints:
Patrón de prompt: "En móvil, apila todo verticalmente con ancho completo. En tablet (md), cambia a una grilla de 2 columnas. En desktop (lg), usa 3 columnas con más padding horizontal."
También puedes pedirle a la IA que ajuste componentes existentes:
- "Haz esta sección hero responsiva — texto más grande y más padding en desktop"
- "En móvil, convierte esta lista horizontal de características en una pila vertical"
- "Oculta el sidebar en móvil y muestra una barra de navegación inferior en su lugar"
Probar layouts responsivos es simple: redimensiona tu navegador o usa la emulación de dispositivos de las dev tools. Cuando algo se ve mal en un tamaño específico, dile a la IA: "Las tarjetas de precios se superponen en tablet. Corrige los breakpoints de la grilla."
Animaciones y transiciones
Las animaciones sutiles hacen que tu interfaz se sienta pulida y viva.
Transiciones CSS con Tailwind
Tailwind tiene utilidades de transición incorporadas:
<button class="bg-blue-500 hover:bg-blue-600 transition-colors duration-200">
Pasa el cursor
</button>
<div class="hover:scale-105 transition-transform duration-300">
Tarjeta que escala al pasar el cursor
</div>
Clases de transición comunes: transition-all, transition-colors, transition-transform, transition-opacity, duration-200, duration-300, ease-in-out.
Utilidades de animación de Tailwind
Tailwind viene con algunas animaciones incorporadas:
animate-spin— spinners de cargaanimate-ping— puntos de notificaciónanimate-pulse— estados de carga skeletonanimate-bounce— elementos que llaman la atención
Básicos de Framer Motion
Para animaciones complejas, Framer Motion es la librería de referencia en React:
import { motion } from "framer-motion"
function FadeInCard({ children }: { children: React.ReactNode }) {
return (
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
>
{children}
</motion.div>
)
}
Prompt: "Agrega una animación de fade-in-up a cada tarjeta de característica usando Framer Motion. Escalona las animaciones para que cada tarjeta aparezca 0.1 segundos después de la anterior."
La IA maneja bien Framer Motion porque la API es declarativa — describes los estados de la animación, no la mecánica.
Implementación de modo oscuro
El modo oscuro es esperado en las apps modernas. Aquí está el enfoque de implementación más limpio.
El patrón de toggle
- Almacena la preferencia en
localStoragey respeta la preferencia del sistema como valor por defecto - Agrega o elimina una clase
darken el elemento<html> - Usa el prefijo
dark:de Tailwind para todos los estilos de modo oscuro
function ThemeToggle() {
const [isDark, setIsDark] = useState(false)
useEffect(() => {
const stored = localStorage.getItem("theme")
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches
const dark = stored === "dark" || (!stored && prefersDark)
setIsDark(dark)
document.documentElement.classList.toggle("dark", dark)
}, [])
function toggle() {
const newDark = !isDark
setIsDark(newDark)
document.documentElement.classList.toggle("dark", newDark)
localStorage.setItem("theme", newDark ? "dark" : "light")
}
return (
<button onClick={toggle} className="p-2 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-700">
{isDark ? "☀️" : "🌙"}
</button>
)
}
Prompt: "Agrega soporte de modo oscuro a toda la app. Detecta la preferencia del sistema, permite toggle manual, persiste la elección en localStorage, y agrega variantes dark: a todos los componentes."
Librerías de componentes vs. personalizado
No siempre necesitas construir desde cero. Las librerías de componentes te dan componentes accesibles y probados listos para usar.
shadcn/ui
shadcn/ui es la librería más amigable para la IA porque copia los componentes en tu proyecto como archivos reales que puedes personalizar. No es una dependencia — es una colección de componentes copy-paste construidos sobre Radix UI y Tailwind.
npx shadcn@latest add button dialog card
Prompt: "Usa shadcn/ui para el componente de diálogo y estiliza el contenido con Tailwind."
Headless UI y Radix
Estas librerías proporcionan comportamiento sin estilos. Obtienes dropdowns, modales y menús accesibles que tú estilizas. Perfecto cuando quieres control total sobre la apariencia.
Cuándo usar qué
- shadcn/ui — cuando quieres valores por defecto hermosos con fácil personalización. Lo mejor para la mayoría de proyectos.
- Headless UI / Radix — cuando necesitas primitivas accesibles pero quieres control completo de estilos.
- Personalizado — cuando necesitas algo verdaderamente único o cuando las librerías no cubren tu caso de uso.
Prompt de decisión: "Estoy construyendo un dashboard con modales, dropdowns y tablas de datos. ¿Debería usar una librería de componentes?" La IA normalmente recomendará shadcn/ui para este caso de uso — y es la elección correcta.
Qué sigue
Ahora tienes el kit de herramientas de frontend para construir cualquier UI con IA. Sabes cómo pensar en componentes, describir layouts y estilos, construir diseños responsivos, y elegir las herramientas adecuadas para el trabajo.
Pero un frontend hermoso necesita un backend que lo alimente. En la siguiente lección, nos sumergiremos en el desarrollo backend y de APIs — construyendo lógica del lado del servidor, rutas de API, validación de datos y manejo de errores. Aprenderás cómo decirle a la IA que construya el servidor que alimenta tu frontend con datos reales.