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

27 KiB
Raw Blame History

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:

packages/rdx-ui

Todos los componentes públicos propios del sistema deberán usar el prefijo:

Rdx

Ejemplos:

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:

API → DTO → adapter → Entity → hook → controller → page controller → UI

Separación de responsabilidades:

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:

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

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:

<RdxPageContainer>
  <RdxPageStack>
    <RdxPageHeader />
    <RdxListPageLayout main={...} aside={...} />
  </RdxPageStack>
</RdxPageContainer>

Evitar:

<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:

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:

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:

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:

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:

Una columna por defecto
Ancho máximo centrado
Lateral opcional
No reservar espacio si el lateral no existe
Secciones planas con divisores

Ejemplos:

customers/create
customers/update
suppliers/create
suppliers/update

6.3 Editor complejo

Reglas:

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:

proformas/update
issued-invoices/update, si existiera

6.4 Vista de detalle

Reglas:

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:

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:

max-w-5xl o max-w-6xl

La decisión exacta se centraliza en RdxPageContainer.


8. Foundations visuales

8.1 Espaciado

Escala inicial recomendada:

compact  → 1rem
normal   → 1.5rem
relaxed  → 2rem

Propuesta de uso:

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:

Page title
Page description
Section title
Section description
Field label
Body
Metadata
Numeric value
Status

Referencia inicial:

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:

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:

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:

background
foreground
card
muted
muted-foreground
border
primary
primary-foreground
destructive
destructive-foreground

Se deberán consolidar también tokens para:

success
warning
info

No usar directamente colores físicos cuando exista un token semántico adecuado.

Evitar:

text-green-600
bg-yellow-100
border-blue-300

9. Arquitectura de componentes

9.1 Ubicación

packages/rdx-ui/src/components/

Estructura objetivo progresiva:

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:

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:

RdxPageContainer
RdxPageStack
RdxPageHeader
RdxPageActions
RdxContextPanel
RdxRowActions
RdxEditorPageLayout
RdxPanel
RdxFormGrid
RdxEditorStickyFooter

Candidatos posteriores a validar con pantallas piloto reales:

RdxResponsivePageGrid
RdxListPageLayout

También deberán evaluarse y adaptar, no necesariamente reescribir:

PageHeader
PageFormHeader
RightPanel
DataTable

No se implementarán todavía:

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.
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.
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;
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.
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.
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:

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.
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.
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

Acción principal → cabecera
Acciones frecuentes → visibles en fila
Acciones infrecuentes → overflow
Acciones destructivas → overflow por defecto

Orden recomendado:

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

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

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

Desktop → ancho máximo centrado
Mobile → una columna

14.3 Editor complejo

Desktop → main + aside
Tablet/móvil → aside debajo de main
Footer sticky → debe respetar safe areas

14.4 Detalle

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:

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:

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:

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:

/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:

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:

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:

Testing Library
Vitest

19. Plan de implementación

Fase 0 — Documentación y UI Kit base

Crear o mantener sincronizados:

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:

RdxPageContainer
RdxPageStack
RdxPageHeader
RdxPageActions

Fase 2 — Piloto proformas/list

Aplicar foundations sin rediseño funcional.

Objetivos:

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:

RdxResponsivePageGrid
RdxListPageLayout

Validar con:

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:

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:

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:

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:

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:

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

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:

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.