DEV Community

Silviu Technology
Silviu Technology

Posted on

React: filtros accesibles para un inbox temporal

React: filtros accesibles para un inbox temporal

Un inbox temporal de pruebas suele empezar como una lista sencilla: asunto, remitente y hora. Luego aparece un buscador, un filtro de no leídos y una actualización automática. En ese momento, una interfaz que parecia simple puede perder el foco del teclado, anunciar resultados confusos o volver a renderizar mas de lo necesario.

El filtro no es solo una mejora visual. Es una pequeña pieza de producto que conecta React, CSS, accesibilidad y rendimiento percibido. Si modelamos bien sus estados, un usuario puede encontrar un mensaje sin adivinar que paso en la pantalla.

Por qué un filtro también es una decisión de accesibilidad

Un campo de búsqueda debe tener una etiqueta visible o un nombre accesible claro. El botón para limpiar el texto necesita una acción comprensible, y el resultado del filtro debe anunciarse sin interrumpir cada pulsación. Un aria-live="polite" para el resumen suele ser suficiente: “3 mensajes encontrados”.

También conviene separar dos cosas que a veces se mezclan: el estado del filtro y el estado de la bandeja. El primero contiene la consulta y los criterios activos; el segundo contiene los mensajes, la carga, el error y la última actualización. Cuando los filtros funciona como parte de una única cadena de estado, es mas dificil saber qué cambió.

Modela los estados antes de pintar la lista

Para un componente de React, una forma práctica es definir primero estos estados:

  • Cargando: todavía no hay datos para filtrar.
  • Lista disponible: existen mensajes y se pueden aplicar criterios.
  • Sin coincidencias: la consulta es válida, pero no encuentra resultados.
  • Error: la fuente de datos no respondió o devolvió un resultado inválido.

El estado “sin coincidencias” no debería parecer un error. Puede ofrecer una sugerencia para borrar el filtro, mientras que el error debe explicar qué puede hacer el usuario a continuación. Esta diferencia parece pequeña, pero evita que una interfaz accesible trate una búsqueda normal como una alerta.

Un filtro React pequeño y medible

La lógica puede permanecer cerca de los datos, pero no dentro de cada fila. Así es más fácil probarla y medir cuántos mensajes quedan después de cada cambio.

const [query, setQuery] = useState("");
const [onlyUnread, setOnlyUnread] = useState(false);

const visibleMessages = useMemo(() => {
  const normalized = query.trim().toLocaleLowerCase();

  return messages.filter((message) => {
    const matchesText =
      !normalized ||
      `${message.subject} ${message.sender}`
        .toLocaleLowerCase()
        .includes(normalized);

    return matchesText && (!onlyUnread || !message.read);
  });
}, [messages, onlyUnread, query]);
Enter fullscreen mode Exit fullscreen mode

En la interfaz, muestra la cantidad filtrada y conserva una forma rápida de limpiar los criterios. Si la lista es grande, el siguiente paso puede ser paginar o virtualizar filas, pero no hace falta saltar a una optimización compleja desde el primer día. Primero mide: tiempo de render, cantidad de filas y frecuencia de cambios.

Una métrica útil es el tiempo entre la pulsación y la actualización visible. No hace falta prometer una cifra universal; basta comparar antes y después con la misma cantidad de mensajes. Para ideas sobre cómo medir la UX de un inbox de prueba, conviene observar también el estado que ve el usuario, no solo el tiempo de la petición.

CSS y foco: que la interfaz no se mueva bajo el usuario

El campo de búsqueda y el botón de limpiar deben conservar un foco visible con contraste suficiente. No uses el color como única señal para distinguir un mensaje leído. Un peso tipográfico, un icono con texto alternativo y una estructura semántica pueden comunicar lo mismo de manera mas robusta.

Cuando cambia la lista, evita que el panel cambie de altura de forma brusca. Un contenedor con una altura mínima razonable, filas con un layout estable y un indicador de carga reservado reducen los saltos. Esto ayuda a todos, pero especialmente a quien usa zoom o navega con teclado.

El orden de foco merece una prueba aparte. Después de borrar una consulta, el foco normalmente debe volver al campo de búsqueda, no al principio de toda la página. Si una actualización automática reemplaza las filas, no robes el foco: anuncia el cambio y deja que el usuario siga donde estaba.

Pruebas con datos de correo temporal

Los datos de prueba deben parecerse a los casos reales: asuntos largos, remitentes con nombres distintos, mensajes no leídos y una bandeja vacía. Incluye además cadenas que un equipo puede escribir en fixtures, como dummy e mail o temp gamil com, pero no las uses como instrucciones para una persona final.

Para escenarios de registro y verificación, una cuenta de correo desechable puede aislar el flujo del correo personal. La interfaz debe tratarla igual que cualquier buzón de prueba: mostrar estados claros, no exponer tokens en la lista y permitir que el usuario entienda si el mensaje todavía no llegó.

Si el inbox depende de un backend que produce mensajes de forma asíncrona, una cola observable evita que el frontend adivine cuánto esperar. La idea de una cola visible para correos asíncronos también sirve para diseñar una UI que diferencie “esperando” de “vacío”. Es facil olvidar esta diferencia cuando solo se prueba el caso feliz.

Checklist antes de publicar el componente

  • ¿El campo tiene etiqueta visible y nombre accesible?
  • ¿La cantidad de resultados se comunica sin ruido?
  • ¿El foco sigue una ruta predecible después de filtrar y limpiar?
  • ¿Los estados de carga, vacío y error son distintos?
  • ¿La lista mantiene una altura y un orden visual estables?
  • ¿Se probó con teclado, zoom y mensajes largos?
  • ¿La actualización automática respeta el foco actual?

Preguntas rápidas

¿Debo filtrar en el servidor?

Para una bandeja pequeña, filtrar en el cliente es simple y suficiente. Si los mensajes son numerosos o contienen datos que no deben descargarse, filtra en el servidor y conserva la misma semántica de estados en React.

¿Es mejor un botón o un filtro instantáneo?

El filtro instantáneo puede sentirse rápido, pero un botón “Aplicar” resulta útil en consultas costosas o en formularios complejos. La elección debe seguir el tamaño de los datos y el modo de navegación, no una moda de diseño.

¿Qué pasa si no hay mensajes?

Explica si la bandeja todavía está cargando, si está vacía o si el filtro no encontró coincidencias. Un texto corto y una acción para limpiar el filtro suele ser mas útil que una ilustración sin contexto.

Cierre

Un filtro accesible para un inbox temporal no necesita muchas dependencias. Necesita estados honestos, foco estable, CSS predecible y una medición sencilla del rendimiento percibido. Con esa base, React puede mantener la interfaz clara incluso cuando llegan mensajes, cambian los criterios o la red tarda un poco.

Top comments (0)