Cuánto tardas en montar todos los estados de un botón en Figma?
Si lo haces a mano, ya sabes la respuesta… un rato largo. Duplicar variantes, ajustar el border-radius en cada tamaño, revisar que no se rompa nada.
En este vídeo itero el componente botón del UX fomo Design System añadiendo estados nuevos como el focus y el loading. Lo hago de 2 formas: a mano, como trabajábamos en Figma en 2020, y con Claude Code para ir más rápido y con más consistencia.
Puedes ver todo el proceso en este link de mi mi canal de YouTube. Aquí te cuento lo que hice y por qué tomé cada decisión.

El estado focus a mano
Empiezo con el estado focus, vengo del botón (Button) que dejé montado en el vídeo anterior. Muevo la variante, la renombro a focus, duplico el default y reviso el orden de los estados: default, hover, focus, disabled.
Pero al estado focus le falta algo importante: el «ring», es decir, el indicador que aparece cuando el usuario pulsa la tecla tab y va navegando por la interfaz. Es clave para la accesibilidad, así que no me lo salto.
Lo resuelvo creando un componente muy simple, el FocusIndicator. Un frame con borde (stroke), sin color de fondo. Hago una instancia y la llevo a la variante focus, flotando de forma absoluta a 2 px del botón.
Le doy constraints left-right, top-bottom para que se ajuste al ancho del botón cuando crece o se achica según su contenido.
Ojo que aquí aparece la primera decisión de diseño…
El border-radius del FocusIndicator tiene que acompañar la curva del botón. En la variante md necesito un border-radius de 10 px. Tengo un token de spacing con ese valor, pero su scope está pensado para width, height y demás. No quiero romper ese scope solo por reutilizar el número.
Así que lo pongo a mano.
Llevo el FocusIndicator al resto de variantes y tamaños, ajustando el border-radius en cada una. En la sm, donde el botón tiene border-radius de 6 px, el indicador queda en 8 px y ahí sí tengo un token con ese valor. En las variantes pill uso border-radius full.
Un detalle de consistencia: el color del FocusIndicator no coincidía con el del botón default. Me voy al componente padre y le pongo el mismo color. Ahora son iguales…
La variante secundaria, también a mano
Antes de soltar la IA monto la variante secondary (secundaria).
Creo la propiedad type, con primary como primera variante. Ordeno bien las variantes: type, size, state y shape. Y duplico todo sin perder la selección para que las conexiones del componente se mantengan.
El secondary, como todavía no tengo colores definitivos, lo dejo al contrario: fondo blanco, texto e iconos en el color que el primary tiene de fondo. Pruebo una instancia, le pongo un «Download», y funciona. Las conexiones de prototipado se mantienen porque dupliqué en lugar de crear desde cero.
Ahora sí, vamos a Claude Code
Cambio de escena. Terminal de Claude Code abierta.
Le paso un prompt directo: que analice el componente Button, con el link al archivo de Figma, y que cree 5 variantes nuevas. outline, ghost, success, warning y error.
La máquina inspecciona la estructura del Button, arma su lista de tareas y empieza a montar variante por variante, y después los semánticos.
En minutos tengo 5 variantes que a mano me hubieran llevado bastante más.
Los colores no me convencen, pero eso es normal. Todavía no tenemos la paleta definitiva. Lo que importa es que la estructura está montada y consistente.
Aquí hay un momento que vale la pena… Cuando Claude Code llega a los estados hover de las variantes semánticas, me pregunta cómo tratarlos y me da algunas opciones, yo le digo que use un background menos intenso.
El prompt que utilicé, un poco más pulido, te lo dejo en mi GitHub para que lo puedas usar en tu propio design system.
El estado loading
Último paso…
Le pido a Claude Code que genere un estado loading en todas las variantes.
La idea
- En el estado loading, el leftIcon se reemplaza por una instancia del icono loading.
- Es un icono estático que preparé a mano, pero que cuando esto pase a código usemos componente Spinner girando durante la descarga o el proceso que sea.
Aquí Claude Code no me entiende a la primera… oculta el rightIcon, pone el icono loading en el leftIcon, pero lo muestra también en las demás variantes, y eso no debería ser así .
No pasa nada… corrijo el prompt.
Le digo que deje el icono loading únicamente en el estado loading. Que el resto de estados, en todas las variantes, tengan propiedad boolean e instance swap para el leftIcon, mostrando una instancia del icono genérico, que ahora mismo es un heart-outline.
Esta vez lo hace bien!
El error fue mío.
Antes de promptear debería haber comprobado que las instancias ya tenían la propiedad boolean y el instance swap. Me los apunto para la próxima…
Por el momento nos quedamos aquñi, con el Button con sus estados focus y loading, más las variantes outline, ghost, success, warning y error. Parte a mano, parte con IA.
En el siguiente vídeo seguimos trabajando este y otros componentes, como siempre, a mano y con IA.
Aprende sobre UX/UI + IA, Figma y Product Design
📣 Apúntate a mi newsletter semanal