Componentes, tablas y UX consistente

Objetivos del capítulo
  • Componer interfaces con Material UI v5.

  • Usar componentes de @backstage/core-components.

  • Crear componentes reusables propios.

Sistema de diseño: una sola carta

Si cada cocinero escribe su propia carta, el cliente se marea. Lo mismo pasa con una IDP: si cada plugin tiene su look & feel, el developer no sabe dónde está. Backstage resuelve esto con un sistema de diseño unificado: Material UI v5 + componentes propios en @backstage/core-components.

Las reglas de oro son:

  1. No importes Material UI directamente sin pasar por el theme. Usa makeStyles con theme.palette para que respete dark mode.

  2. Usa InfoCard como contenedor estándar. Es el plato base sobre el que montar todo.

  3. No mezcles sistemas de diseño de terceros. Si necesitas un componente, escríbelo con Material UI.

Componentes de core-components

@backstage/core-components trae piezas reusables que respetan el theme:

  • InfoCard — tarjeta con título y slot.

  • Table — tabla con ordenación, búsqueda y paginación.

  • SupportButton — botón de soporte (mailto / link).

  • Progress — spinner estándar.

  • EmptyState — vista para listas vacías.

  • Header + HeaderLabel — cabecera de página tipo "ficha de receta".

Un InfoCard con un StatusBadge

Un widget que muestra un servicio y su estado:

Unresolved directive in chapters/cap-10-componentes-y-ux.adoc - include::../../chapters/chapter-10-frontend-components/src/components/InfoCardExample.tsx[tag=info-card-component]

Y el componente StatusBadge:

Unresolved directive in chapters/cap-10-componentes-y-ux.adoc - include::../../chapters/chapter-10-frontend-components/src/components/StatusBadge.tsx[tag=custom-widget]
¿Por qué makeStyles?

makeStyles con theme.palette respeta el theme activo: si el usuario cambia a dark mode, el chip se adapta. Importar colores hardcoded rompe esa consistencia y deja la UI ilegible en dark mode.

Contraste WCAG

Si personalizas colores, valida el contraste mínimo 4.5:1 (WCAG AA). Los colores palette.success.main, warning.main y error.main ya cumplen contraste con sus contrastText. Si inventas una paleta, valida con axe-core o similar.

Composición: de un widget a una página

Un patrón útil es componer varios InfoCard en un grid para construir una página de detalle:

import { Grid, Header, HeaderLabel } from '@backstage/core-components';

<Header title="sazon-api">
  <HeaderLabel label="Owner" value="team-sazon" />
  <HeaderLabel label="Lifecycle" value="production" />
</Header>
<Grid container spacing={2}>
  <Grid item xs={6}><InfoCardExample service="sazon-api" status="healthy" /></Grid>
  <Grid item xs={6}><InfoCardExample service="sazon-worker" status="degraded" /></Grid>
</Grid>
Example 10. Receta del capítulo
  1. Usa InfoCard como contenedor estándar.

  2. Crea widgets propios con makeStyles + theme.

  3. Compón con Grid + Header para páginas de detalle.

  4. Valida el contraste con WCAG AA antes de aceptar un color nuevo.

Resumen

  • El sistema de diseño es Material UI v5 + componentes de core-components.

  • InfoCard y Table son las piezas base para cualquier widget.

  • Componentes custom usan makeStyles + theme.palette para respetar dark mode.

  • Valida el contraste WCAG en cualquier color nuevo.

Glosario del capítulo

makeStyles

API de Material UI v4 para crear hooks de estilos tipados.

theme.palette

Conjunto de colores tematizados (primary, secondary, success, warning, error).

WCAG

Web Content Accessibility Guidelines. Estándar de accesibilidad web.

Grid

Componente de layout responsive de Material UI.

Próximo capítulo

Theming, branding y la carta del menú —personaliza themes.json, logo, favicon y la página principal del portal.