1
Contexto y objetivos
Intent: permitir a analistas y managers revisar pedidos con máxima densidad de información y mínima fricción.
Declaración de intención
La DataTable es el núcleo operativo de DataPulse. Usuarios con sesiones de 8-12 h/día necesitan una interfaz predecible, densa y accesible que no interrumpa el flujo de trabajo. Cada regla de este documento existe para maximizar la eficiencia cognitiva sin sacrificar la accesibilidad.
✓ Objetivos
- Renderizar 100-500 filas sin degradación perceptible
- Filtrar pedidos en <2 clicks con filtros inline
- Comunicar 5 estados de pedido sin ambigüedad
- Operable 100% con teclado para usuarios de accesibilidad
- Responsive en tablet ≥768px con scroll horizontal
✗ Fuera de alcance
- Edición inline de celdas (v2)
- Exportación a CSV/Excel (componente aparte)
- Virtualización de filas (umbral >1000 filas)
- Modo móvil <768px (tarjetas alternativas)
2
Tokens y fundamentos de diseño
Usa siempre tokens semánticos — nunca valores hexadecimales en línea.
Paleta de colores
--color-primary
#1677ff
Acciones principales, focus, enlaces
--color-secondary
#8B5CF6
Etiquetas de categoría, destacados
--color-success
#16A34A
Estado Delivered, confirmaciones
--color-warning
#D97706
Estado Processing, alertas
--color-danger
#DC2626
Estado Cancelled, errores
--color-text
#111827
Texto principal (ratio ≥7:1 sobre blanco)
--color-text-secondary
#6b7280
Metadatos, fechas, hints (≥4.5:1)
--color-bg
#f5f6fa
Fondo de página, cabeceras de tabla
Escala tipográfica
| Token | Size | Weight | Uso |
|---|---|---|---|
h1 | 32px | 800 | Títulos de página |
h3 | 20px | 700 | Títulos sección |
body-md | 14px | 400 | Texto de celda |
body-sm | 12px | 400 | Metadatos, fechas |
label | 12px | 700 | Cabeceras |
mono | 13px | 500 | DP-00412 |
Escala de espaciado
4px
8px
12px
16px
24px
32px
Padding celda: 8px 12px (middle density)
Gap filtros: 8px
Padding toolbar: 12px 16px
Margin secciones: 24px o 32px
Gap filtros: 8px
Padding toolbar: 12px 16px
Margin secciones: 24px o 32px
3
Reglas del componente
Anatomía, variantes, estados e interacción del DataTable.
Vista previa — DataTable (estado normal)
| ID | Cliente | Estado | Importe | Fecha | Acciones |
|---|---|---|---|---|---|
| DP-00841 | Marta Solano | Delivered | € 128,50 | 14 jun 2026 | |
| DP-00840 | Carlos Ruiz | Processing | € 345,00 | 13 jun 2026 | |
| DP-00839 | Lucía Fernández | Shipped | € 89,99 | 13 jun 2026 | |
| DP-00838 | Alejandro Moya | Cancelled | € 210,00 | 12 jun 2026 | |
| DP-00837 | Isabel Torres | Pending | € 56,75 | 12 jun 2026 |
Mostrando 1–5 de 842 pedidos
5 / página
‹
1
2
3
…
169
›
Estados del componente
Cargando (loading)
Skeleton rows con animación shimmer. Spinner en toolbar. Filtros bloqueados (disabled).
Vacío (empty)
Sin resultados para "Processing"
Prueba a cambiar los filtros o el rango de fechas.
Error de red
No se pudieron cargar los pedidos
Error de conexión. Los datos pueden estar desactualizados.
Filtro activo
Processing · 83
Reglas de anatomía del componente
-
Toolbar: debe incluir campo de búsqueda (ancho fijo 220px) y filtros de estado en chips. Separación 12px entre buscador y chips.
-
Columna ID: debe usar tipografía monoespaciada
JetBrains Mono 13pxy color--color-primary. Siempre ordenable. Ancho fijo 90px. -
Columna Importe: alineación derecha obligatoria (
text-align: right). Formato europeo:€ 1.234,50. Font-weight 600. Cancelados en--color-danger. -
Status badge: combinar punto de color + etiqueta de texto. Nunca usar solo color. Cada estado mapea a un único token semántico. Rounded-full, padding 2px 8px.
-
Acciones: máximo 2 botones visibles por fila. Acción primaria con estilo
ghost-primary, acción destructiva conghost-danger. Resto en menú contextual. -
Usar iconos solitarios sin tooltip — Hit area mínima 32×32px. Todo ícono de acción must tener
aria-labeldescriptivo. -
Truncar nombre del cliente sin tooltip — Si la celda trunca con ellipsis, debe mostrar el valor completo en tooltip (
ant-tooltip) al hover/focus.
4
Accesibilidad — criterios comprobables
WCAG 2.2 AA. Toda afirmación debe ser testable en code review o herramienta automática.
Regla absoluta: ninguna información se comunica únicamente a través del color. Los status badges combinan punto de color + texto. Los importes cancelados añaden el prefijo "(Cancelado)" para lectores de pantalla.
Navegación por teclado
| Tecla | Acción |
|---|---|
| Tab | Siguiente elemento interactivo |
| Shift+Tab | Elemento anterior |
| Enter / Space | Activar botón / chip de filtro |
| ↑ / ↓ | Navegar filas de la tabla |
| Home / End | Primera / última fila |
| Esc | Cerrar modal de detalle |
| Enter en cabecera | Ordenar columna |
Ratios de contraste (WCAG AA)
- 📐
#111827sobre blanco: ≥ 7:1 (AAA) - 📐
#6b7280sobre blanco: ≥ 4.5:1 (AA) - 📐
#1677ffsobre#e6f4ff: ≥ 4.5:1 ✓ - 📐
#DC2626sobre#fef2f2: ≥ 4.5:1 ✓ - 📐
#16A34Asobre#f0fdf4: ≥ 4.5:1 ✓ - ⚠️
#D97706sobre blanco: = 3.08:1 — usar solo con texto ≥14px Bold - 🔍 Focus ring: 2px sólido
#1677ff+ offset 2px
Semántica HTML / ARIA requerida
-
<table>conrole="grid". Cabeceras<th scope="col">. Filas conrole="row". -
Columna ordenable:
aria-sort="ascending|descending|none"en el<th>activo. Actualizar tras cada click. -
Chips de filtro:
role="radio"agrupados enrole="radiogroup" aria-label="Filtrar por estado". Estado activo conaria-checked="true". -
Estado vacío: contenedor con
role="status" aria-live="polite"para anunciar "Sin resultados" al lector de pantalla. -
Estado de carga:
aria-busy="true"en el contenedor de la tabla mientras carga.aria-label="Cargando pedidos"en el spinner.
5
Contenido y tono — ejemplos
Conciso, orientado a la acción, sin jerga técnica para el usuario final.
Etiquetas de estado
| Estado | Etiqueta UI | Mensaje accesible |
|---|---|---|
| Pending | Pendiente | "Pedido pendiente de confirmación" |
| Processing | En proceso | "Pedido en preparación" |
| Shipped | Enviado | "Pedido enviado al transportista" |
| Delivered | Entregado | "Pedido entregado al cliente" |
| Cancelled | Cancelado | "Pedido cancelado, pendiente reembolso" |
Mensajes de error y vacío
- Error de red: "No se pudieron cargar los pedidos" + [Reintentar]
- Sin resultados (filtro): "Sin resultados para «Processing»" + [Limpiar filtros]
- Sin resultados (búsqueda): "No encontramos pedidos con «DP-999»"
- Timeout (>10s): "La carga está tardando más de lo habitual. [Reintentar] [Continuar esperando]"
- Sin permisos: "No tienes acceso a este pedido. Contacta con tu administrador."
6
Anti-patrones y migraciones
Implementaciones prohibidas con ejemplo de migración al patrón correcto.
✗ No hacer
Color como único indicador de estado
<Tag color="green">Entregado</Tag>
Color sin texto ni ícono. Falla para daltonismo y lectores de pantalla.
✓ Migrar a
Badge con punto + texto + aria
<Badge status="success" text="Entregado" aria-label="Estado: Entregado" />
✗ No hacer
Spacing inconsistente en toolbar
padding: "10px 15px 8px 20px"
Valores arbitrarios fuera de la escala 4/8/12/16/24/32.
✓ Migrar a
Tokens de espaciado del sistema
padding: "12px 16px" /* space-3 space-4 */
✗ No hacer
Acciones sin label accesible
<Button icon={<EditOutlined />} />
Ícono sin texto ni aria-label. Inaccesible con lector de pantalla.
✓ Migrar a
Tooltip + aria-label explícito
<Tooltip title="Ver pedido"><Button icon={...} aria-label="Ver pedido DP-00841" /></Tooltip>
✗ No hacer
Paginación sin anuncio a lector
onClick={fetchPage}
Cambio de contenido silencioso. El usuario de lector no sabe que la tabla cambió.
✓ Migrar a
Live region para anunciar cambio
<div role="status" aria-live="polite">Página 2 de 169 cargada</div>
7
QA Checklist — ejecutable en code review
Todos los ítems deben estar en verde antes de merge a producción.
Tokens y estilo
✓
TokenNingún color hardcoded (#hex) fuera de tokens✓
TokenEspaciados de la escala 4/8/12/16/24/32 únicamente✓
FontFuente monoespaciada en columna ID e importesFontFont-weight 600 en importes positivos, danger en cancelados
✓
Radius4px en chips, celdas botones; 8px en contenedor tabla
Accesibilidad
✓
A11yTabla con role="grid" y th scope="col"✓
A11yFiltros con role="radiogroup" y aria-checkedA11yFocus visible en TODOS los elementos interactivos (2px ring)
A11yaria-live="polite" en región de resultados
✓
A11yaxe-core: 0 errores críticos en CI
Componente y estados
✓
StateEstado loading: skeleton rows + aria-busy="true"✓
StateEstado vacío: ilustración + mensaje + CTA "Limpiar filtros"StateEstado error: mensaje no técnico + botón Reintentar
✓
Sortaria-sort actualizado tras ordenar columnaRespScroll horizontal en tablet ≥768px sin overflow hidden
Contenido
✓
CopyImportes en formato europeo: € 1.234,50✓
CopyFechas en formato "14 jun 2026" (no ISO)CopyNombre truncado tiene tooltip con valor completo
✓
CopyMensajes de error sin stack trace expuesto al usuarioi18nStrings internacionalizables (react-intl ready)