Saltar al contenido
Lección 10 de 22

Patrones de Frontend con IA

14 min read

Pensar en componentes

Toda interfaz moderna se construye a partir de componentes — piezas pequenas y reutilizables que se ensamblan como bloques de construccion. Una barra de navegacion es un componente. Un boton es un componente. Una tarjeta que muestra el perfil de un usuario es un componente. Incluso el layout completo de una pagina es un componente hecho de componentes mas pequenos.

Este modelo mental es tu arma secreta al trabajar con IA. En lugar de pedir una pagina completa de una sola vez, divides la interfaz en piezas y describes cada una. La IA las construye individualmente, y tu las compones en algo mas grande.

Atomic Design para Vibe Coders

El atomic design de Brad Frost nos da un vocabulario muy util:

  • Atoms — las piezas mas pequenas: botones, inputs, labels, iconos, badges
  • Molecules — grupos pequenos de atoms: una barra de busqueda (input + boton), un campo de formulario (label + input + mensaje de error)
  • Organisms — grupos complejos: una barra de navegacion, una seccion hero, una tabla de precios
  • Templates — layouts a nivel de pagina 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. Asi 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. Construiras mas rapido y obtendras resultados de mayor calidad que pidiendo todo de una sola vez.

Describir componentes a la IA

Mientras mejor sea tu descripcion, mejor sera el resultado. Compara estos dos prompts:

Vago: "Hazme un componente card."

Especifico: "Crea un componente de tarjeta de caracteristica con un icono en la parte superior (usando iconos de Lucide React), un titulo en texto semibold, una descripcion de dos lineas 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 libreria de iconos. Esta es la forma del vibe coding — piensas en lo que quieres, lo describes claramente, y la IA se encarga de la implementacion.

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 mas efectiva.

Componentes funcionales y Props

Cada componente de React es una funcion 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 que hacer con eso.

Children y composicion

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 patron de composicion — construir interfaces complejas anidando componentes simples. Cuando le dices a la IA "crea un componente Card wrapper que acepte children", genera exactamente este patron.

Renderizado condicional

A veces quieres mostrar u ocultar elementos basandote en datos:

function UserGreeting({ user }: { user: User | null }) {
  return (
    <div>
      {user ? (
        <p>Bienvenido de nuevo, {user.name}!</p>
      ) : (
        <button>Iniciar Sesion</button>
      )}
    </div>
  )
}

Patron de prompt: "Muestra el nombre del usuario si esta logueado, de lo contrario muestra un boton de inicio de sesion." La IA traduce tu intencion en renderizado condicional automaticamente.

Curso intensivo de Tailwind CSS

Tailwind CSS es el enfoque de estilos mas 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 diseno. Aqui estan las clases que veras con mas 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)

Tipografia: 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 → movil (todos los tamanos)
  • sm: → 640px en adelante
  • md: → 768px en adelante
  • lg: → 1024px en adelante
  • xl: → 1280px en adelante
  • 2xl: → 1536px en adelante

Modo oscuro

El prefijo dark: de Tailwind aplica estilos cuando el modo oscuro esta 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 anadira 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 maximo" → 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 mas comunes que vas a construir. Para cada uno, mostrare el prompt que usarias y el tipo de resultado que obtendras.

Secciones Hero

El hero es lo primero que ven los visitantes. Establece el tono.

Prompt: "Crea una seccion hero con un fondo de gradiente de blue-600 a purple-600, texto blanco centrado con un encabezado grande, un parrafo de subtitulo, y dos botones CTA — uno blanco solido y uno con borde. Hazlo responsivo con mas 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 caracteristicas

Las grillas de caracteristicas muestran las capacidades de tu producto. El patron es una grilla de tarjetas, cada una con un icono, titulo y descripcion.

Prompt: "Crea una grilla de caracteristicas de 3 columnas con 6 tarjetas. Cada tarjeta tiene un contenedor de icono con color, un titulo en negritas y una descripcion. La grilla debe apilarse en 1 columna en movil 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 mas dificiles de lograr bien. Asi es como les das prompt:

Prompt: "Crea una seccion de precios con 3 niveles: Gratis, Pro ($19/mes) y Enterprise (precio personalizado). El plan Pro debe estar resaltado como 'Mas Popular' con un borde de color y un badge. Cada plan muestra una lista de caracteristicas con checkmarks. Agrega un boton 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 seccion de testimonios con 3 tarjetas de testimonio. Cada tarjeta tiene una cita en texto italico, el avatar de la persona (usa un placeholder), su nombre, cargo y empresa. Agrega decoraciones de comillas."

Barras de navegacion

La navegacion es critica y necesita funcionar en todos los tamanos de pantalla.

Prompt: "Crea una navbar responsiva con un logo a la izquierda, enlaces de navegacion en el centro (ocultos en movil) y un boton CTA a la derecha. En movil, muestra un menu hamburguesa que alterna un menu desplegable con todos los enlaces. Usa estado de React para el toggle del menu movil."

Esto genera un componente con useState para el menu movil, 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 (caracteristicas, precios, docs), Recursos (guias, API, comunidad) y Legal (privacidad, terminos, cookies). Agrega iconos de redes sociales en la parte inferior con una linea de copyright."

Formularios y validacion

Los formularios son donde los usuarios interactuan 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 boton de enviar. Agrega validacion del lado del cliente — nombre requerido, email debe tener formato valido, mensaje debe tener al menos 20 caracteres. Muestra mensajes de error debajo de cada campo en texto rojo. Deshabilita el boton de envio mientras se esta 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 patron es: estado controlado para errores, validacion en el handler de envio, y retroalimentacion visual para el usuario.

Modales y dialogos

Los modales son overlays que demandan la atencion 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 boton de cerrar en el header. Agrega una animacion 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 detras)
  • Usar role="dialog" y aria-modal="true"

Si usas una libreria de componentes como shadcn/ui, obtienes todo esto gratis. Mas sobre eso en un momento.

Diseno responsivo con prompts

Mobile-first significa que disenas para pantallas pequenas primero, y luego agregas complejidad para las mas grandes. Al darle prompts a la IA, se explicito sobre los breakpoints:

Patron de prompt: "En movil, apila todo verticalmente con ancho completo. En tablet (md), cambia a una grilla de 2 columnas. En desktop (lg), usa 3 columnas con mas padding horizontal."

Tambien puedes pedirle a la IA que ajuste componentes existentes:

  • "Haz esta seccion hero responsiva — texto mas grande y mas padding en desktop"
  • "En movil, convierte esta lista horizontal de caracteristicas en una pila vertical"
  • "Oculta el sidebar en movil y muestra una barra de navegacion inferior en su lugar"

Probar layouts responsivos es simple: redimensiona tu navegador o usa la emulacion de dispositivos de las dev tools. Cuando algo se ve mal en un tamano especifico, 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 transicion 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 transicion comunes: transition-all, transition-colors, transition-transform, transition-opacity, duration-200, duration-300, ease-in-out.

Utilidades de animacion de Tailwind

Tailwind viene con algunas animaciones incorporadas:

  • animate-spin — spinners de carga
  • animate-ping — puntos de notificacion
  • animate-pulse — estados de carga skeleton
  • animate-bounce — elementos que llaman la atencion

Basicos de Framer Motion

Para animaciones complejas, Framer Motion es la libreria 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 animacion de fade-in-up a cada tarjeta de caracteristica usando Framer Motion. Escalona las animaciones para que cada tarjeta aparezca 0.1 segundos despues de la anterior."

La IA maneja bien Framer Motion porque la API es declarativa — describes los estados de la animacion, no la mecanica.

Implementacion de modo oscuro

El modo oscuro es esperado en las apps modernas. Aqui esta el enfoque de implementacion mas limpio.

El patron de toggle

  1. Almacena la preferencia en localStorage y respeta la preferencia del sistema como valor por defecto
  2. Agrega o elimina una clase dark en el elemento <html>
  3. 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 eleccion en localStorage, y agrega variantes dark: a todos los componentes."

Librerias de componentes vs. personalizado

No siempre necesitas construir desde cero. Las librerias de componentes te dan componentes accesibles y probados listos para usar.

shadcn/ui

shadcn/ui es la libreria mas amigable para la IA porque copia los componentes en tu proyecto como archivos reales que puedes personalizar. No es una dependencia — es una coleccion 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 dialogo y estiliza el contenido con Tailwind."

Headless UI y Radix

Estas librerias proporcionan comportamiento sin estilos. Obtienes dropdowns, modales y menus accesibles que tu estilizas. Perfecto cuando quieres control total sobre la apariencia.

Cuando usar que

  • shadcn/ui — cuando quieres valores por defecto hermosos con facil personalizacion. Lo mejor para la mayoria de proyectos.
  • Headless UI / Radix — cuando necesitas primitivas accesibles pero quieres control completo de estilos.
  • Personalizado — cuando necesitas algo verdaderamente unico o cuando las librerias no cubren tu caso de uso.

Prompt de decision: "Estoy construyendo un dashboard con modales, dropdowns y tablas de datos. Deberia usar una libreria de componentes?" La IA normalmente recomendara shadcn/ui para este caso de uso — y es la eleccion correcta.

Que sigue

Ahora tienes el kit de herramientas de frontend para construir cualquier UI con IA. Sabes como pensar en componentes, describir layouts y estilos, construir disenos responsivos, y elegir las herramientas adecuadas para el trabajo.

Pero un frontend hermoso necesita un backend que lo alimente. En la siguiente leccion, nos sumergiremos en el desarrollo backend y de APIs — construyendo logica del lado del servidor, rutas de API, validacion de datos y manejo de errores. Aprenderas como decirle a la IA que construya el servidor que alimenta tu frontend con datos reales.