8.3 KiB
8.3 KiB
Page Layouts Rdx
Estado
Este documento describe los patrones conceptuales de página aprobados para adopción progresiva.
El documento canónico de contexto global es:
Listado
RdxPageContainer
└── RdxPageStack
├── RdxPageHeader
├── notices opcionales
└── contenido del listado
Reglas:
- anchura por defecto
full; - acciones principales en cabecera;
- acciones de fila frecuentes visibles y acciones destructivas en overflow mediante
RdxRowActions; - panel contextual solo cuando aporte contexto real;
- la composición del listado no debe acoplarse a React Query, routing ni dominio.
Ejemplo de integración real validado en proformas/list y customers/list:
<RdxPageContainer width="full">
<RdxPageStack spacing="default">
<RdxPageHeader
title={title}
description={description}
actions={<RdxPageActions primary={primaryAction} />}
/>
{notice}
{content}
</RdxPageStack>
{dialogs}
</RdxPageContainer>
Aclaraciones:
RdxPageContainerresuelve el padding exterior y la anchura de página;RdxPageStackresuelve el ritmo vertical principal entre cabecera, aviso y contenido;RdxPageHeaderno conoce navegación ni callbacks de React Router;- la tabla, los filtros, los panels, los dialogs y los controllers permanecen fuera de las foundations;
RdxRowActionspuede vivir dentro de las columnas de tabla, pero recibe acciones ya decididas por el consumidor;- en ambos pilotos el panel contextual sigue viviendo en composición local mediante
ResizablePanelGroup; - no documentar todavía
RdxListPageLayoutniRdxResponsivePageGridmientras el resize y la apertura del aside dependan del caso de uso.
Evidencia de pilotos de listado
DECISIÓN_CONFIRMADA
Container + Stack + Header + Actions cubren la capa exterior del listado.
DECISIÓN_PROVISIONAL
La Page puede extraer una vista pura si mejora el test y reduce wiring.
NO_ABSTRAER_TODAVÍA
main + aside redimensionable
shell específico del panel contextual
toolbars
Listado con panel contextual
ResizablePanelGroup
├── main
└── RightPanel
└── RdxContextPanel
Reglas:
ResizablePanelGroupgestiona la geometría, el resize y la persistencia local del split;RightPanelgestiona la superficie lateral, la altura y el overflow base;RdxContextPanelgestiona cabecera, cierre, body y footer visual del panel;- el contenido interno del panel sigue siendo específico del dominio;
- no documentar todavía un layout genérico de listado a partir de este patrón.
Editor simple
scroll container
└── RdxEditorPageLayout complexity="simple"
└── form stack
├── RdxEditorSection
├── RdxEditorSection
└── ...
Reglas:
- las rutas cuya tarea principal sea crear, editar o configurar mediante un formulario focalizado deben entrar por el shell
app-fullscreen; - listados, dashboards, detalle y navegación de settings mantienen
app-sidebarsalvo necesidad funcional explícita; RdxEditorPageLayoutresuelve padding interior, ancho centrado ymin-w-0;- el editor simple puede apoyarse en una única superficie contenedora para diferenciar la página del área editable, sin volver a cards por sección;
RdxEditorSectionexpresa jerarquía por defecto con spacing y divisor inferior;RdxFormGridmantiene la retícula del formulario sin conocer RHF ni dominio;- priorizar lectura y velocidad de escaneo;
- usar secciones planas con espacio o divisores;
- reservar sticky footer solo cuando el scroll lo justifique.
Ejemplo validado en customers/update, customers/create y /account:
<AppFullscreenLayout>
<PageFormHeader backLabel={backLabel} onBack={onBack} title={title} />
<div className="flex-1 overflow-y-auto">
<RdxEditorPageLayout complexity="simple">
<div className="flex min-w-0 flex-col gap-6">
{notice}
<form className="flex min-w-0 flex-col gap-6">
<RdxEditorSection title={title} description={description}>
<RdxFormGrid>{fields}</RdxFormGrid>
</RdxEditorSection>
</form>
</div>
</RdxEditorPageLayout>
</div>
</AppFullscreenLayout>
Deuda registrada:
PageFormHeadersigue siendo full-width mientras el contenido del editor queda centrado enmax-w-5xl;- no modificar todavía el header legacy sin validación visual manual real.
Evidencia adicional de create/update:
DECISIÓN_CONFIRMADA
ambos flujos reutilizan el mismo layout, superficie y secciones.
ESPECÍFICO
defaults iniciales
wiring de submit
feedback de error
navegación de retorno concreta
Candidatos explícitos para auditoría posterior:
customers/createcustomers/update/accountproformas/update
Editor complejo
shell
├── PageFormHeader
├── scroll container
│ └── RdxEditorPageLayout complexity="complex"
│ ├── main
│ │ └── única superficie editable
│ │ ├── RdxEditorSection
│ │ ├── RdxEditorSection
│ │ ├── bloque de líneas con layout propio
│ │ └── ...
│ └── aside
│ └── controles secundarios o contexto de apoyo
└── RdxEditorStickyFooter
├── summary/context region
└── action region
Reglas:
RdxEditorPageLayoutresuelve padding exterior,min-w-0y la geometríamain + aside;- el
maindebe alojar los campos editables y sus bloques funcionales; - el
asidedebe reservarse para metadata, configuración o contexto de apoyo ya existente en la pantalla; - el
asidedel editor complejo usa una geometría aproximadaminmax(0, 1fr) 22remen desktop y se apila debajo delmaincuando no hay ancho suficiente; - no mover campos editables al
asidesolo por estética si eso empeora el flujo; - no mover los totales al
aside; - los bloques con layout interno propio, como una tabla de líneas, no deben forzarse dentro de
RdxFormGrid; RdxEditorStickyFooterresuelve una única superficie sticky con una región contextual flexible y una región de acciones;- los totales siguen perteneciendo al dominio de Proformas aunque se rendericen dentro de la región contextual del footer;
PageFormHeaderpuede seguir existiendo, pero no debe duplicarGuardaryCancelarcuando el footer sticky ya los contiene.
Ejemplo validado en proformas/update:
<div className="fixed inset-0 flex flex-col overflow-hidden">
<PageFormHeader />
<div className="flex min-h-0 flex-1 flex-col bg-muted/20">
<div className="min-h-0 flex-1 overflow-y-auto">
{notice}
<RdxEditorPageLayout
complexity="complex"
aside={aside}
>
<div className="rounded-2xl border border-border bg-background px-4 py-4 shadow-xs md:px-6 md:py-6">
<form className="flex min-w-0 flex-col gap-6">
<RdxEditorSection title={documentTitle}>
<RdxFormGrid>{documentFields}</RdxFormGrid>
</RdxEditorSection>
{lineEditor}
</form>
</div>
</RdxEditorPageLayout>
</div>
<RdxEditorStickyFooter
leading={<TotalsSummary />}
secondary={cancelButton}
primary={saveButton}
status={status}
/>
</div>
</div>
Evidencia del piloto:
DECISIÓN_CONFIRMADA
main contiene la única superficie editable
aside contiene bloques secundarios ya existentes del editor
la sticky zone inferior pasa a una única superficie visual
los totales permanecen como dominio de Proformas dentro de la región contextual
las acciones principales comparten el mismo footer sin una segunda franja
RdxFormGrid se mantiene solo para campos
DECISIÓN_PROVISIONAL
visual exacta del header legacy frente al ancho full del editor complejo
NO_ABSTRAER_TODAVÍA
layout específico del bloque de líneas
layout específico del footer de totales
Detalle
width="wide" o "full"
main + aside opcional
aside para metadata, actividad, resumen o acciones
Reglas:
- mantener patrón consistente de label/value;
- usar aside solo cuando el contenido realmente gane claridad;
- no implementar todavía
RdxDetailPageLayouten esta fase.