Saltar al contenido
Development

Seis correcciones pequeñas de UX en una sola sesión

Por Victor Da Luz
sveltetauriuxdev-loggreenhouse

Después de el rediseño de navegación, el backlog tenía una serie de correcciones pequeñas y bien especificadas de UI/UX de la misma revisión, del tipo donde la corrección ya está detallada en el issue y no queda ninguna decisión de diseño por tomar. Elegí seis de ellas en orden de tamaño y recorrí el ciclo completo para cada una: rama, implementación, verificación contra la app real corriendo, merge, cierre. Sin pausas entre ellas, cada una resultó ser tan acotada como parecía al empezar.

La lista

Límites de layout para pantallas ultra anchas: la grilla de zonas del dashboard no tenía max-width, así que en un monitor ancho todo se estiraba de borde a borde. Lo limité a 110rem, centrado. Timestamps de contacto que respetan el idioma: formatTouchTime llamaba a toLocaleString(), que sigue el idioma del sistema operativo, no la configuración de idioma propia de la app, una interfaz en portugués en una Mac en inglés mostraba fechas en inglés. Cambié a Intl.DateTimeFormat(getLocale(), ...). Emojis a SVG: la marca y el indicador de racha eran emojis, que se renderizan como al sistema operativo se le ocurra y no toman color de los tokens de diseño. Reemplacé ambos por SVGs de trazo en línea que coinciden con el resto del set de íconos. Errores descartables más carga diferida: los banners de error de acción no tenían forma de descartarlos salvo disparando otra acción, y cada entrada de vista mostraba una tarjeta de carga incluso para fetches que terminan en menos de 50ms. Agregué un botón de cerrar a los banners, y puse cada tarjeta de carga detrás de un temporizador de 150ms para que los fetches rápidos simplemente se actualicen en el lugar. Hero de primer uso: un vault recién creado mostraba tres líneas pasivas de “todavía no hay nada acá” y nada más. Agregué un estado de primer uso apropiado, una oración más un botón de Capturar más grande, que solo aparece cuando el vault está genuinamente vacío (no solo temporalmente bajo).

Y una pasada de textos con un error de redundancia real: siete correcciones pequeñas de redacción (títulos de diálogo que no coincidían con sus disparadores, una etiqueta de botón con un paréntesis innecesario, un ambiguo “6m” que se leía como seis meses al lado de “300d”). La interesante: la tarjeta de un ítem guardado o liberado mostraba la misma palabra tres veces, el nombre de la etapa del pipeline, un chip “Dormant 20d,” y una insignia “Dormant,” todo en una sola fila. Lo arreglé para que la insignia solo aparezca cuando no hay duración para poner en el chip.

Qué hizo que este lote avanzara rápido de verdad

Cada una de estas tenía un único criterio de aceptación inequívoco incorporado en el texto del issue, “usar Intl.DateTimeFormat en vez de toLocaleString,” “limitar a max-width: 110rem.” Ninguna necesitaba una decisión de diseño. Esa es la diferencia entre una corrección que toma quince minutos y una que necesita una conversación antes, la redundancia de la insignia fue lo más parecido a una decisión de criterio en todo el lote, y aun así se resolvió con limpieza una vez que rastreé con exactitud qué combinación de chip más insignia estaba mostrando la misma palabra dos veces.

Lo único que señalaría desde el punto de vista del proceso: varias de estas tocaron componentes compartidos (la lógica de insignias de ItemCard, el patrón de estado de carga duplicado en cuatro componentes de vista) donde un cambio para arreglar una cosa tiene efectos de segundo orden sobre pruebas que ya existían. El hero de primer uso, por ejemplo, agregó un segundo botón “Capture an idea” que coexiste con el de la barra superior, lo que rompió seis pruebas sin relación que buscaban ese botón por nombre asumiendo que siempre habría una sola coincidencia. Nada de eso apareció como riesgo de diseño al empezar; solo sale a la superficie una vez que se corre la suite de verdad y se lee qué se rompe.

Resultado

Las seis se fusionaron a main, CI en verde en todo momento, 166 pruebas de frontend pasando (frente a 158 antes de este lote, cada corrección que introdujo comportamiento nuevo recibió una prueba que demuestra ese comportamiento, no solo demostrar que las pruebas viejas siguen pasando).

Lecturas relacionadas

Development

Toast y deshacer para la acción de vault de Greenhouse

La primera superficie de feedback transitorio de la app, la regla de aria-live que hace que un toast renderizado condicionalmente quede sin anunciar en silencio, y un prop que queda desactualizado apenas se renombra algo.

Leer
Development

Un dashboard que dejó de decir la hora

Un bloque $derived que leyó Date.now() exactamente una vez, una medianoche que significaba cosas distintas para el frontend y para el motor en Rust, y la oración gramaticalmente rota que lo demostró.

Leer