FactuGES_ERP/docs/frontend/UI/visual-system-design.md
David 3d2ce8b981 feat: add page layouts documentation and visual system design for Rdx UI components
- Introduced `page-layouts.md` to outline approved page patterns for progressive adoption.
- Created `visual-system-design.md` to consolidate visual, architectural, and adoption decisions for a uniform UI/UX system in the ERP frontend.
- Added `RdxEditorActionBar` component for managing action bars in editor screens.
- Implemented `RdxPanel` component for grouping related content with optional headers and actions.
2026-09-04 11:07:59 +02:00

1226 lines
27 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Frontend ERP — Sistema visual Rdx para páginas y patrones UI/UX
## 1. Estado
**DISEÑO APROBADO PARA IMPLEMENTACIÓN PROGRESIVA**
Este documento consolida las decisiones visuales, arquitectónicas y de adopción para construir un sistema UI/UX uniforme en el frontend del ERP.
El sistema se implementará dentro de:
```txt
packages/rdx-ui
```
Todos los componentes públicos propios del sistema deberán usar el prefijo:
```txt
Rdx
```
Ejemplos:
```txt
RdxPageContainer
RdxPageHeader
RdxPageActions
RdxContextPanel
RdxRowActions
RdxListPageLayout
RdxEditorPageLayout
RdxPanel
RdxFormGrid
RdxEditorStickyFooter
RdxDetailPageLayout
```
El prefijo distingue los componentes propios de la aplicación frente a primitives de terceros como Shadcn/UI y evita colisiones de naming.
---
## 2. Contexto
El frontend ERP está basado en:
- React 19
- TypeScript estricto
- Shadcn/UI
- Tailwind CSS v4
- React Hook Form
- TanStack Query
- TanStack Table
- React Router
La arquitectura general mantiene el flujo:
```txt
API → DTO → adapter → Entity → hook → controller → page controller → UI
```
Separación de responsabilidades:
```txt
shared/api → transporte remoto
shared/adapters → DTO → Entity
shared/hooks → React Query y entities
controllers → orquestación del caso de uso
page controllers → composición e integración externa
Page → wiring y composición
UI → render puro
```
El sistema visual Rdx debe respetar estrictamente esta arquitectura.
---
## 3. Objetivo
Crear un estándar visual y estructural común para los principales tipos de pantalla del ERP:
```txt
Listados
Vistas de detalle
Pantallas de creación
Pantallas de edición
```
El sistema debe unificar:
- márgenes;
- padding;
- separación entre elementos;
- anchuras;
- jerarquía tipográfica;
- disposición de acciones;
- iconografía;
- estados visuales;
- superficies;
- responsive;
- accesibilidad;
- soporte claro/oscuro;
- documentación y ejemplos interactivos.
El objetivo no es crear un framework CRUD universal, sino una biblioteca pequeña de primitives y composiciones visuales explícitas.
---
## 4. Principios rectores
### 4.1 Claridad antes que abstracción
```txt
Primero claridad local.
Después repetición real.
Solo entonces abstraer.
```
No se crearán componentes genéricos sin evidencia suficiente de repetición.
### 4.2 UI pura
Los componentes Rdx no deben conocer:
- React Query;
- DTOs;
- APIs;
- controllers;
- routing;
- permisos de negocio;
- estados de dominio;
- errores de transporte.
Deben recibir props ya preparadas.
### 4.3 Composición, no configuración excesiva
Preferir:
```tsx
<RdxPageContainer>
<RdxPageStack>
<RdxPageHeader />
<RdxListPageLayout main={...} aside={...} />
</RdxPageStack>
</RdxPageContainer>
```
Evitar:
```tsx
<RdxCrudPage
entity="customers"
filters={...}
permissions={...}
routing={...}
query={...}
/>
```
### 4.4 Diseño compacto y ordenado
La interfaz debe:
- evitar espacio vacío que no aporte jerarquía;
- mantener alta densidad informativa;
- conservar suficiente separación para lectura;
- evitar ruido visual;
- evitar card dentro de card;
- usar superficies solo cuando tengan una función clara.
### 4.5 Tema claro y oscuro desde el inicio
Todo componente debe diseñarse y validarse en:
```txt
Tema claro
Tema oscuro
```
No se aceptará una implementación diseñada solo para tema claro y corregida posteriormente.
---
## 5. Referencias visuales
### 5.1 Pantalla de referencia principal
La pantalla de listado de proformas es la referencia visual inicial para:
- densidad;
- toolbar;
- espaciado;
- jerarquía de acciones;
- tratamiento de tabla;
- iconografía;
- filtros;
- composición general.
Ruta:
```txt
modules/customer-invoices/src/web/proformas/list
```
Estado de adopción a 6 de agosto de 2026:
- primera pantalla piloto migrada a `RdxPageContainer`, `RdxPageStack`, `RdxPageHeader` y `RdxPageActions`;
- se ha sustituido el header legacy solo en la Page de listado, sin tocar controllers, grid, filtros, panel lateral ni dialogs;
- el piloto confirma que las foundations actuales cubren la geometría exterior de la página sin justificar todavía `RdxListPageLayout`, `RdxResponsivePageGrid` ni `RdxContextPanel`.
- segundo piloto migrado en `modules/customers/src/web/list` con el mismo perímetro de cambio;
- ambos listados confirman la reutilización de container, stack, header y CTA principal, pero todavía no justifican abstraer la geometría interior del listado;
- los dos paneles contextuales reales confirman una separación válida entre `RightPanel` como primitive de superficie y `RdxContextPanel` como composición visual contextual.
### 5.2 Pantallas de contraste
Se usarán además:
```txt
modules/customers/src/web/list
modules/customers/src/web/create
modules/customers/src/web/update
modules/customers/src/web/view
modules/customer-invoices/src/web/proformas/create
modules/customer-invoices/src/web/proformas/update
modules/customer-invoices/src/web/proformas/detail
```
Estas pantallas permiten validar listados, editor simple, editor complejo y detalle.
---
## 6. Tipos de pantalla
## 6.1 Listados
Reglas:
```txt
Anchura completa
Toolbar compacta
Tabla densa
Acción principal en cabecera
Panel lateral opcional
Paginación integrada
Estados vacíos y errores consistentes
```
El listado no debe estar obligado a usar filtros, panel lateral o tabs.
## 6.2 Editor simple
Reglas:
```txt
Una columna por defecto
Ancho máximo centrado
Lateral opcional
No reservar espacio si el lateral no existe
Secciones planas con divisores
```
Ejemplos:
```txt
customers/create
customers/update
suppliers/create
suppliers/update
```
## 6.3 Editor complejo
Reglas:
```txt
Todo el ancho disponible
Main flexible
Lateral derecho permitido como región estructural estándar
Footer sticky cuando exista scroll significativo
Paneles laterales para resumen, configuración o contexto
```
Ejemplos:
```txt
proformas/update
issued-invoices/update, si existiera
```
## 6.4 Vista de detalle
Reglas:
```txt
Anchura wide o full
Main + lateral opcional
Lateral para metadata, actividad, resumen o acciones
Patrón label/value consistente
```
---
## 7. Política de anchuras
Se define el siguiente contrato inicial:
```ts
export type RdxPageWidth = "full" | "wide" | "content";
```
### `full`
Uso:
- listados;
- editores complejos;
- tablas;
- pantallas documentales.
### `wide`
Uso:
- vistas de detalle;
- pantallas con mucha información sin necesidad de ocupar todo el viewport.
### `content`
Uso:
- formularios y editores simples.
Referencia inicial:
```txt
max-w-5xl o max-w-6xl
```
La decisión exacta se centraliza en `RdxPageContainer`.
---
## 8. Foundations visuales
## 8.1 Espaciado
Escala inicial recomendada:
```txt
compact → 1rem
normal → 1.5rem
relaxed → 2rem
```
Propuesta de uso:
```txt
Page padding mobile: 1rem
Page padding desktop: 1.5rem
Main block gap: 1.5rem
Section internal gap: 1rem
Form grid horizontal: 1.5rem
Form grid vertical: 1.25rem
Compact element gap: 0.5–0.75rem
```
No se fija `gap-12` como foundation global.
## 8.2 Tipografía
Funciones tipográficas:
```txt
Page title
Page description
Section title
Section description
Field label
Body
Metadata
Numeric value
Status
```
Referencia inicial:
```txt
Page title: text-2xl font-semibold tracking-tight
Page description: text-sm text-muted-foreground
Section title: text-base font-semibold
Section description: text-sm text-muted-foreground
Metadata label: text-xs font-medium text-muted-foreground
Numeric value: font-medium tabular-nums
```
## 8.3 Superficies
Política:
```txt
Contenido principal → plano
Secciones → divisores y spacing
Aside → paneles permitidos
Tabla compleja → superficie independiente permitida
Notices → superficie semántica
Cards → excepción, no default
```
## 8.4 Bordes y radios
Reglas:
- evitar border en cada bloque;
- preferir `border-b` o `Separator` entre secciones;
- reservar radios para paneles o superficies independientes;
- los radios hijos no deben exceder los radios del contenedor padre.
## 8.5 Sombras
Reglas:
```txt
Página y secciones → sin sombra
Panel contextual → sombra suave opcional
Header/footer sticky → borde como primera opción
```
Las sombras deben ser mínimas.
## 8.6 Color
Usar tokens semánticos:
```txt
background
foreground
card
muted
muted-foreground
border
primary
primary-foreground
destructive
destructive-foreground
```
Se deberán consolidar también tokens para:
```txt
success
warning
info
```
No usar directamente colores físicos cuando exista un token semántico adecuado.
Evitar:
```txt
text-green-600
bg-yellow-100
border-blue-300
```
---
## 9. Arquitectura de componentes
## 9.1 Ubicación
```txt
packages/rdx-ui/src/components/
```
Estructura objetivo progresiva:
```txt
components/
├── layout/
├── page-states/
├── list-page/
├── detail-page/
├── editor-page/
├── form/
└── right-panel/
```
No es obligatorio crear toda la estructura desde la primera fase.
## 9.2 Naming
Todos los componentes públicos propios usan `Rdx`.
Ejemplo:
```ts
export interface RdxPageHeaderProps {
// ...
}
export const RdxPageHeader = ({
// ...
}: RdxPageHeaderProps) => {
// ...
};
```
No es obligatorio usar `Rdx` en:
- helpers internos;
- tipos privados;
- variantes locales;
- tokens CSS.
---
## 10. Foundations implementadas y siguientes candidatos
Fase 1 implementada:
```txt
RdxPageContainer
RdxPageStack
RdxPageHeader
RdxPageActions
RdxContextPanel
RdxRowActions
RdxEditorPageLayout
RdxPanel
RdxFormGrid
RdxEditorStickyFooter
```
Candidatos posteriores a validar con pantallas piloto reales:
```txt
RdxResponsivePageGrid
RdxListPageLayout
```
También deberán evaluarse y adaptar, no necesariamente reescribir:
```txt
PageHeader
PageFormHeader
RightPanel
DataTable
```
No se implementarán todavía:
```txt
RdxDetailPageLayout
RdxDetailField
RdxNotice
RdxEmptyState
```
Estos componentes se diseñarán en fases posteriores con pantallas piloto específicas.
---
## 11. Contratos iniciales
## 11.1 `RdxPageContainer`
Responsabilidad:
- ancho;
- padding exterior;
- centrado;
- comportamiento responsive.
```ts
export interface RdxPageContainerProps {
children: React.ReactNode;
width?: RdxPageWidth;
className?: string;
}
```
No debe gestionar ritmo vertical.
## 11.2 `RdxPageStack`
Responsabilidad:
- separación vertical entre bloques principales.
```ts
export type RdxPageStackSpacing = "compact" | "default" | "relaxed";
export interface RdxPageStackProps {
children: React.ReactNode;
spacing?: RdxPageStackSpacing;
className?: string;
}
```
## 11.3 `RdxPageHeader`
Responsabilidad:
- título;
- descripción;
- leading opcional;
- metadata opcional;
- acciones;
```ts
export interface RdxPageHeaderProps {
title: React.ReactNode;
description?: React.ReactNode;
leading?: React.ReactNode;
metadata?: React.ReactNode;
actions?: React.ReactNode;
className?: string;
}
```
No debe conocer routing.
## 11.4 `RdxPageActions`
Responsabilidad:
- agrupar acciones;
- diferenciar primarias, secundarias y overflow;
- resolver layout responsive.
```ts
export interface RdxPageActionsProps {
primary?: React.ReactNode;
secondary?: React.ReactNode;
overflow?: React.ReactNode;
className?: string;
}
```
No debe decidir permisos ni disponibilidad.
## 11.5 `RdxResponsivePageGrid`
Responsabilidad:
- layout `main + aside`;
- stacking responsive;
- ancho limitado del aside.
```ts
export type RdxPageAsideWidth = "sm" | "md" | "lg";
export type RdxPageAsideBehavior = "static" | "sticky";
export interface RdxResponsivePageGridProps {
main: React.ReactNode;
aside?: React.ReactNode;
asideWidth?: RdxPageAsideWidth;
asideBehavior?: RdxPageAsideBehavior;
className?: string;
mainClassName?: string;
asideClassName?: string;
}
```
Reglas:
```txt
Desktop → main + aside
Tablet/móvil → aside debajo de main
Sin aside → no reservar espacio
Sticky → variante explícita
```
## 11.6 `RdxListPageLayout`
Responsabilidad:
- geometría del área de listado;
- composición `main + aside`.
```ts
export interface RdxListPageLayoutProps {
main: React.ReactNode;
aside?: React.ReactNode;
className?: string;
}
```
No debe conocer:
- DataTable;
- búsqueda;
- filtros;
- selección;
- React Query;
- estado remoto;
- dominio.
## 11.7 `RdxRowActions`
Responsabilidad:
- renderizar acciones visibles;
- renderizar acciones overflow;
- representar disabled y destructive;
- ofrecer tooltips y labels accesibles.
```ts
export interface RdxRowAction {
id: string;
label: string;
icon: React.ReactNode;
onSelect: () => void;
disabled?: boolean;
disabledReason?: string;
destructive?: boolean;
}
export interface RdxRowActionsProps {
primaryActions?: RdxRowAction[];
overflowActions?: RdxRowAction[];
overflowLabel: string;
className?: string;
}
```
El componente no decide qué acciones existen.
La UI solo renderiza; el consumidor conserva permisos, labels, disabled reasons y callbacks.
---
## 12. Política de acciones
## 12.1 Listados
```txt
Acción principal → cabecera
Acciones frecuentes → visibles en fila
Acciones infrecuentes → overflow
Acciones destructivas → overflow por defecto
```
Orden recomendado:
```txt
Ver
Editar
Más acciones
```
## 12.2 Formularios cortos
Acciones en cabecera o al final del formulario.
## 12.3 Formularios largos
Acciones principales en footer sticky.
## 12.4 Editores complejos
```txt
Cabecera → navegación, estado y acciones documentales
Footer sticky → cancelar, guardar y submit principal
```
La ubicación depende de la distancia real del usuario a la acción primaria, no solo del tipo CRUD.
---
## 13. Política de iconos
Catálogo inicial:
| Acción | Icono recomendado |
|---|---|
| Ver | `Eye` |
| Editar | `Pencil` |
| Crear | `Plus` |
| Eliminar | `Trash2` |
| Descargar | `Download` |
| Imprimir | `Printer` |
| Duplicar | `Copy` |
| Más acciones | `Ellipsis` |
| Volver | `ArrowLeft` |
| Guardar | `Save` |
| Filtrar | `ListFilter` |
| Buscar | `Search` |
| Configurar columnas | `Columns3` |
| Cerrar | `X` |
Reglas:
- iconos con tamaño consistente;
- botón solo icono con `aria-label`;
- tooltip cuando la acción no sea inequívoca;
- no usar iconos diferentes para la misma acción sin justificación.
---
## 14. Responsive
## 14.1 Listados
```txt
Desktop → toolbar horizontal y tabla completa
Tablet → filtros colapsables cuando sea necesario
Mobile → scroll horizontal o adaptación específica
```
No se implementará todavía una vista móvil universal de cards para tablas.
## 14.2 Editor simple
```txt
Desktop → ancho máximo centrado
Mobile → una columna
```
## 14.3 Editor complejo
```txt
Desktop → main + aside
Tablet/móvil → aside debajo de main
Footer sticky → debe respetar safe areas
```
## 14.4 Detalle
```txt
Desktop → main + aside opcional
Tablet/móvil → aside debajo de main
```
---
## 15. Accesibilidad
Reglas obligatorias:
- un único `h1` por página;
- jerarquía correcta de headings;
- botones reales para acciones;
- links reales para navegación;
- foco visible;
- botones de icono con `aria-label`;
- estados no representados solo mediante color;
- `type="button"` en botones internos de formularios;
- targets táctiles suficientes;
- tooltips accesibles;
- dialogs con restauración de foco;
- loading que conserve el significado de la acción;
- acciones disabled con explicación cuando sea útil.
---
## 16. Reutilización de componentes existentes
Antes de crear un componente nuevo se debe comparar su contrato con:
```txt
modules/core/src/web/components/page-header.tsx
modules/core/src/web/components/form/form-actions/page-form-header.tsx
modules/core/src/web/components/page-error-state.tsx
modules/core/src/web/components/error-alert.tsx
packages/rdx-ui/src/components/right-panel/right-panel.tsx
packages/rdx-ui/src/components/datatable/data-table.tsx
packages/rdx-ui/src/components/form/form-section-card.tsx
packages/rdx-ui/src/components/form/form-section-grid.tsx
```
Proceso obligatorio:
```txt
1. Definir contrato objetivo Rdx.
2. Comparar con componente existente.
3. Adaptar si es viable.
4. Exportar con naming Rdx.
5. Mantener alias temporal si hay consumidores.
6. Migrar progresivamente.
7. Retirar alias cuando no se use.
```
No se harán renombrados globales sin estrategia de compatibilidad.
---
## 17. Documentación
## 17.1 Markdown
Ubicación canónica:
```txt
packages/rdx-ui/docs/
├── visual-system-design.md
├── foundations.md
├── page-layouts.md
└── contributing-ui.md
```
## 17.2 UI Kit interactivo
Se creará una ruta interna:
```txt
/development/ui-kit
```
El UI Kit debe mostrar:
- foundations;
- componentes aislados;
- variantes;
- estados;
- tema claro y oscuro;
- comportamiento responsive;
- composiciones completas;
- ejemplos correctos;
- anti-patterns relevantes.
Ejemplos completos mínimos:
```txt
Listado
Detalle
Editor simple
Editor complejo
Error
Vacío
Loading
```
## 17.3 Regla de sincronización
Todo cambio que afecte a API pública, comportamiento o apariencia debe actualizar en la misma intervención:
```txt
1. implementación;
2. documentación Markdown;
3. UI Kit interactivo;
4. tests aplicables.
```
Un cambio se considera incompleto si alguno de estos recursos queda desactualizado.
---
## 18. Testing
Los tests deben centrarse en comportamiento:
- render de slots;
- variantes;
- accesibilidad;
- acciones disabled;
- overflow;
- responsive inferible por clases;
- ausencia de columna aside cuando no se proporciona;
- compatibilidad con tema.
No testear detalles internos irrelevantes.
Herramientas:
```txt
Testing Library
Vitest
```
---
## 19. Plan de implementación
## Fase 0 — Documentación y UI Kit base
Crear o mantener sincronizados:
```txt
packages/rdx-ui/docs/visual-system-design.md
packages/rdx-ui/docs/foundations.md
packages/rdx-ui/docs/page-layouts.md
packages/rdx-ui/docs/contributing-ui.md
```
Crear la infraestructura mínima de `/development/ui-kit`.
## Fase 1 — Foundations de página
Implementar:
```txt
RdxPageContainer
RdxPageStack
RdxPageHeader
RdxPageActions
```
## Fase 2 — Piloto `proformas/list`
Aplicar foundations sin rediseño funcional.
Objetivos:
```txt
Misma funcionalidad
Misma densidad
Menos clases estructurales locales
Contrato reusable validado
```
Resultado observado:
- `RdxPageContainer` absorbe el padding exterior de página y evita mantener `p-6` local;
- `RdxPageStack` absorbe el ritmo vertical principal y evita mantener `space-y-6` local;
- `RdxPageHeader` cubre la cabecera de listado con composición directa;
- `RdxPageActions` cubre correctamente una acción primaria única;
- el layout interno del listado sigue necesitando composición específica local mientras no se compare este piloto con `customers/list`.
## Fase 3 — Layout de listado y panel
Implementar:
```txt
RdxResponsivePageGrid
RdxListPageLayout
```
Validar con:
```txt
proformas/list
customers/list
```
Estado tras comparar ambos pilotos:
- `RdxListPageLayout`: prematuro;
- `RdxResponsivePageGrid`: prematuro en listados que dependen de `ResizablePanelGroup`;
- `RdxContextPanel`: candidato confirmado para una fase específica sobre `RightPanel`, `CustomerSummaryPanel` y `ProformaSummaryPanel`.
## Fase 4 — Panel contextual
Normalizar:
```txt
RightPanel
RdxContextPanel
CustomerSummaryPanel
ProformaSummaryPanel
```
Resultado esperado:
- `RightPanel` mantiene la superficie lateral reusable;
- `RdxContextPanel` concentra cabecera, cierre, jerarquía y footer contextual;
- no existe doble header;
- no existe doble cierre;
- no existe doble sombra.
## Fase 5 — Acciones de fila
Implementar `RdxRowActions` tomando proformas como referencia.
Resultado observado a 6 de agosto de 2026:
- `RdxRowActions` ya existe en `packages/rdx-ui` y se exporta públicamente;
- `proformas/list` y `customers/list` consumen el mismo contrato visual;
- las acciones destructivas quedan en overflow;
- el consumidor sigue decidiendo permisos, estado, callbacks y razones de disabled;
- en `customers/list` se ha corregido el bug que renderizaba delete cuando no existía `onDeleteClick`.
## Fase 6 — Editor simple
Usar `customers/update` como piloto para:
```txt
RdxEditorPageLayout
RdxPanel
RdxFormGrid
```
Resultado observado a 6 de agosto de 2026:
- `RdxEditorPageLayout` absorbe el ancho centrado y el padding interior del editor simple;
- `RdxPanel` sustituye en `customers/update` el uso sistemático de `FormSectionCard` cuando la superficie no necesita card;
- `RdxFormGrid` consolida la retícula ya existente sin mover lógica de formulario fuera del consumidor;
- `PageFormHeader` se mantiene sin cambios funcionales;
- queda pendiente validar visualmente si el header sticky full-width se percibe demasiado separado del ancho centrado del editor.
## Fase 7 — Confirmación de editor simple
Validar el mismo patrón en:
```txt
customers/create
```
Resultado observado a 6 de agosto de 2026:
- `customers/create` reutiliza `RdxEditorPageLayout`, `RdxPanel` y `RdxFormGrid` sin requerir nuevas primitives;
- create y update comparten shell, header legacy, superficie editable única y secciones planas internas;
- las diferencias reales quedan en defaults, submit y wiring del controller, no en la composición visual;
- `PageFormHeader` sigue siendo funcionalmente suficiente, aunque se mantiene una deuda visual menor por su anchura full-width frente al contenido centrado.
## Fase 8 — Editor complejo
Usar `proformas/update` como piloto para:
```txt
main + aside
sticky footer
totales
acciones según scroll
```
Resultado observado a 10 de agosto de 2026:
- `proformas/update` valida `RdxEditorPageLayout` con `complexity="complex"` a ancho completo, `main` flexible y `aside` estructural aproximado de `22rem`;
- el `main` concentra la única superficie editable real del documento y el bloque de líneas mantiene su layout propio;
- el `aside` conserva únicamente controles secundarios ya presentes en la pantalla, sin convertirlo en `RightPanel` ni mover allí los totales;
- el footer sticky de totales se mantiene como dominio visual y económico de Proformas;
- `RdxEditorStickyFooter` queda justificado para combinar en una única superficie sticky la región de totales/contexto y las acciones `Cancelar` / `Guardar`;
- `PageFormHeader` queda reducido a navegación y contexto solo en `proformas/update`, sin cambio global del componente legacy;
- `RdxPanel` y `RdxFormGrid` siguen siendo válidos para bloques de campos, pero no deben forzar el layout del editor de líneas ni el footer de totales.
## Fase 8 — Detalle
Usar primero `proformas/detail` y después `customers/view`.
---
## 20. Anti-patterns prohibidos
No crear:
```txt
RdxCrudPage
RdxCrudEditor
RdxGenericEntityPage
RdxUniversalToolbar
RdxFormSectionEngine
GenericPageFactory
```
No hacer:
- routing dentro de `packages/rdx-ui`;
- React Query dentro de componentes Rdx;
- interpretación de `ApiClientError` en UI;
- permisos dentro de `RdxRowActions`;
- hardcodes de dominio;
- colors físicos cuando exista token semántico;
- megacomponentes configurables;
- migraciones globales sin alias temporal;
- abstracciones genéricas antes de validarlas en varias pantallas.
---
## 21. Evidencia de pilotos de listado
### DECISIÓN_CONFIRMADA
- `RdxPageContainer` resuelve de forma estable el padding exterior y la anchura de `proformas/list` y `customers/list`.
- `RdxPageStack` resuelve el ritmo vertical principal entre cabecera, error inline y contenido.
- `RdxPageHeader` sustituye correctamente al `PageHeader` legacy en ambos listados sin conocer navegación.
- `RdxPageActions` cubre la CTA principal de cabecera en ambos pilotos sin necesidad de variantes adicionales.
- `RightPanel` es suficiente como primitive de superficie lateral y no debe renombrarse globalmente.
- `RdxContextPanel` está justificado como composición visual común sobre `RightPanel`.
- `RdxRowActions` está justificado para normalizar icon buttons, overflow, disabled reason y destructivas en tablas.
- `RdxEditorPageLayout`, `RdxPanel` y `RdxFormGrid` quedan confirmados tras migrar `customers/update` y `customers/create`.
- `RdxEditorPageLayout` también es apto para `proformas/update` cuando el `aside` contiene bloques secundarios ya existentes y el `main` conserva la única superficie editable.
- `RdxPanel` soporta tanto secciones planas de formulario como grupos secundarios del `aside` sin volver a `Card` por defecto.
- `RdxFormGrid` queda confirmado para campos en editores complejos, pero no debe envolver tablas o editores de líneas.
- `RdxEditorStickyFooter` está justificado para el patrón de editor complejo con una sola zona inferior persistente y sin duplicidad de acciones con el header.
### DECISIÓN_PROVISIONAL
- La extracción de una Page View pura es útil cuando reduce wiring y facilita tests sin controllers reales, pero no debe convertirse todavía en convención global.
- El patrón `main + aside` existe en ambos listados, pero hoy depende de `ResizablePanelGroup`, tamaños y apertura específicos de cada pantalla.
- El contrato final del footer contextual puede seguir afinándose cuando aparezcan paneles con resúmenes o acciones más heterogéneas.
- `RdxEditorPageLayout` ya cubre el editor simple, pero la convivencia visual con `PageFormHeader` debe seguir validándose antes de tocar el header legacy.
- la densidad final de la sticky zone inferior en móvil sigue requiriendo validación visual manual en múltiples resoluciones y tema oscuro.
### NO_ABSTRAER_TODAVÍA
- `RdxListPageLayout`: la geometría exterior ya queda resuelta por `RdxPageContainer`, `RdxPageStack` y la propia Page.
- `RdxResponsivePageGrid`: no encaja todavía como abstracción para listados con resize persistente.
- layouts superiores de listado mientras `ResizablePanelGroup` siga gobernando el split real.
- un layout superior específico de editor complejo mientras `RdxEditorPageLayout` + `RdxEditorStickyFooter` sigan cubriendo la geometría exterior.
---
## 22. Criterios de aceptación
La fase inicial se considerará correcta si:
- `packages/rdx-ui` contiene los primeros componentes Rdx;
- los contratos son puramente visuales;
- no existe dependencia de routing, datos o dominio;
- `proformas/list` puede adoptarlos sin perder comportamiento;
- la documentación Markdown está actualizada;
- el UI Kit muestra los componentes y sus variantes;
- tema claro y oscuro están validados;
- los tests aplicables pasan;
- no se ha creado un framework CRUD;
- las clases estructurales repetidas disminuyen;
- la Page sigue componiendo y haciendo wiring explícito.
---
## 23. Regla mental final
```txt
Rdx define geometría, jerarquía y comportamiento visual.
La Page compone.
Los controllers orquestan.
La UI no interpreta dominio ni transporte.
```
Y como criterio de calidad:
```txt
Si una abstracción ahorra pocas líneas pero empeora la lectura, no se usa.
Si un componente necesita conocer el caso de uso, no pertenece a rdx-ui.
Si un cambio visual no actualiza documentación y UI Kit, está incompleto.
```