1226 lines
27 KiB
Markdown
1226 lines
27 KiB
Markdown
|
|
# 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
|
|||
|
|
RdxEditorSection
|
|||
|
|
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
|
|||
|
|
RdxEditorSection
|
|||
|
|
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
|
|||
|
|
RdxEditorSection
|
|||
|
|
RdxFormGrid
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Resultado observado a 6 de agosto de 2026:
|
|||
|
|
|
|||
|
|
- `RdxEditorPageLayout` absorbe el ancho centrado y el padding interior del editor simple;
|
|||
|
|
- `RdxEditorSection` 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`, `RdxEditorSection` 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;
|
|||
|
|
- `RdxEditorSection` 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`, `RdxEditorSection` 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.
|
|||
|
|
- `RdxEditorSection` 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.
|
|||
|
|
```
|