- Removed outdated documents on screen design and editor layout audit. - Added comprehensive documentation on frontend architecture, UI patterns, and UI system. - Established clear guidelines for component usage, routing, and layout structures. - Enhanced accessibility and responsiveness standards across UI components. - Defined testing protocols and anti-patterns to maintain code quality and consistency.
186 lines
7.0 KiB
Markdown
186 lines
7.0 KiB
Markdown
# Sistema UI Rdx
|
|
|
|
> **Propósito:** explicar qué foundations y componentes visuales existen. Este documento, junto con [Arquitectura frontend](./frontend-architecture.md) y [UI patterns](./ui-patterns.md), forma la fuente de verdad (SSOT) de frontend/UI.
|
|
|
|
## 1. Principios
|
|
|
|
- Claridad antes que abstracción.
|
|
- UI pura: recibe datos preparados y emite eventos.
|
|
- Composición antes que configuración extensa.
|
|
- KISS: no existe un framework CRUD genérico.
|
|
- Tema claro y oscuro desde el inicio.
|
|
- Accesibilidad y densidad informativa.
|
|
- Tokens semánticos en lugar de colores físicos.
|
|
|
|
## 2. Responsabilidad de `rdx-ui`
|
|
|
|
`packages/rdx-ui` contiene foundations y composiciones visuales reutilizables. No conoce React Query, routing, DTOs, entidades de dominio, controllers, permisos, casos de uso ni errores de transporte. El consumidor decide contenido, acciones, orden, labels y estados disabled.
|
|
|
|
Los componentes públicos propios usan prefijo `Rdx`, API pequeña, props explícitas y `className` solo como escape controlado.
|
|
|
|
## 3. Arquitectura visual
|
|
|
|
```text
|
|
AppMain
|
|
└── RdxPageFrame
|
|
├── header
|
|
│ ├── RdxPageHeader
|
|
│ └── RdxEditorHeader
|
|
├── content (scroll principal)
|
|
│ └── RdxPageContainer
|
|
│ ├── RdxPageStack
|
|
│ └── RdxEditorLayout
|
|
└── footer opcional
|
|
└── RdxEditorActionBar
|
|
```
|
|
|
|
Cada nivel tiene una sola responsabilidad. No se reconstruye viewport, anchura y scroll en componentes de página.
|
|
|
|
## 4. Foundations
|
|
|
|
### Espaciado y anchura
|
|
|
|
`RdxPageContainer` controla ancho, centrado y padding:
|
|
|
|
| Propiedad | Resultado |
|
|
| --- | --- |
|
|
| padding móvil | `px-4 py-4` |
|
|
| padding desktop | `md:px-6 md:py-6` |
|
|
| `width="full"` | ancho completo |
|
|
| `width="wide"` | centrado, `max-w-screen-2xl` |
|
|
| `width="content"` | centrado, `max-w-5xl` |
|
|
|
|
`padding="none"` elimina únicamente su padding. El container no controla altura ni scroll.
|
|
|
|
`RdxPageStack` establece el ritmo vertical:
|
|
|
|
| Spacing | Gap |
|
|
| --- | --- |
|
|
| `compact` | 4 |
|
|
| `default` | 6 |
|
|
| `relaxed` | 8 |
|
|
|
|
### Tema
|
|
|
|
Se usan tokens como `bg-background`, `text-foreground`, `bg-muted`, `text-muted-foreground`, `border-border`, `bg-primary` y `bg-destructive`. El color nunca es el único indicador de estado. Toda foundation nueva debe verificarse en light y dark.
|
|
|
|
## 5. Componentes públicos
|
|
|
|
### `RdxPageFrame`
|
|
|
|
Compone header, contenido y footer y es propietario del scroll principal. No conoce routing, queries, width, formularios ni negocio.
|
|
|
|
```tsx
|
|
<RdxPageFrame
|
|
header={<RdxEditorHeader title={title} />}
|
|
footer={<RdxEditorActionBar primary={saveButton} />}
|
|
>
|
|
<RdxPageContainer width="content">{content}</RdxPageContainer>
|
|
</RdxPageFrame>
|
|
```
|
|
|
|
`contentClassName="overflow-hidden"` se reserva para layouts especializados con panes y scrolls internos.
|
|
|
|
### Headers
|
|
|
|
`RdxPageHeader` es la cabecera editorial estándar. Presenta `title`, `description`, `leading`, `metadata`, `actions` y contenido opcional.
|
|
|
|
`RdxEditorHeader` es la cabecera compacta fullscreen. Presenta `title`, retorno mediante `onBack`/`backLabel`, `status`, `actions` y contenido contextual opcional.
|
|
|
|
Ninguno usa `sticky` para seleccionar una variante. El frame coloca el header fuera del scroll.
|
|
|
|
### `RdxPageActions`
|
|
|
|
Ordena regiones `secondary`, `primary` y `overflow`. No decide qué acciones existen ni sus permisos.
|
|
|
|
### `RdxEditorLayout`
|
|
|
|
Distribuye main y un `aside` opcional. No controla width, padding ni scroll. Sin aside no reserva una columna. En desktop, el aside usa `22rem`; en anchos menores se apila.
|
|
|
|
El aside aloja contexto secundario, metadata o configuración auxiliar. No se mueven campos allí solo por estética.
|
|
|
|
### `RdxEditorActionBar`
|
|
|
|
Compone `leading`, `status`, `secondary` y `primary`. El patrón normal la coloca en `RdxPageFrame.footer`, fuera del scroll. La capacidad `sticky` solo se usa si la barra vive justificadamente dentro de un área scrollable.
|
|
|
|
### `RdxPanel`
|
|
|
|
Agrupa una sección con título, descripción, icono, acciones y contenido:
|
|
|
|
- `variant="plain"`: sección plana con divisor; valor predeterminado.
|
|
- `variant="card"`: superficie independiente.
|
|
|
|
### `RdxFormGrid`
|
|
|
|
Proporciona la retícula de campos. No conoce React Hook Form ni debe envolver tablas, line editors o layouts especializados.
|
|
|
|
### `RdxRowActions`
|
|
|
|
Renderiza acciones primarias y overflow. El consumidor decide acciones, orden, navegación, `disabledReason` y destructividad. Las destructivas van en overflow por defecto.
|
|
|
|
### `RdxContextPanel`
|
|
|
|
Compone cabecera, cierre, body y footer de un panel contextual. La geometría redimensionable y el contenido de dominio permanecen en el consumidor.
|
|
|
|
## 6. Scroll y viewport
|
|
|
|
Regla canónica:
|
|
|
|
```text
|
|
AppMain (espacio disponible, sin scroll)
|
|
└── RdxPageFrame
|
|
└── content: overflow-y-auto
|
|
```
|
|
|
|
Una Page no debe usar `fixed inset-0`, `h-screen`, `h-dvh`, `overflow-y-auto` ni `overflow-auto` para reconstruir viewport o scroll principal.
|
|
|
|
Excepción: un detalle documental puede configurar el contenido del frame con `overflow-hidden` y delegar scroll interno a document panes o inspectors. Dialogs, sheets, drawers, overlays, viewers y paneles internos también pueden necesitar posicionamiento o scroll propios.
|
|
|
|
## 7. Superficies
|
|
|
|
- El contenido principal es plano por defecto.
|
|
- Las secciones se separan con spacing y divisores.
|
|
- Una card es una excepción, no el envoltorio automático de cada sección.
|
|
- El aside puede usar cards cuando necesita una superficie independiente.
|
|
- Tablas y editores de líneas conservan su layout funcional.
|
|
- Evitar card dentro de card y sombras acumuladas.
|
|
|
|
## 8. Responsive y accesibilidad
|
|
|
|
- Las columnas se apilan antes de producir overflow horizontal.
|
|
- Todo contenedor flexible susceptible de truncado usa `min-w-0`.
|
|
- Botones de icono tienen nombre accesible y foco visible.
|
|
- No se crean `div` clicables.
|
|
- El orden DOM debe ser coherente con lectura y teclado.
|
|
- Los iconos decorativos usan `aria-hidden`.
|
|
- Estados no dependen exclusivamente del color.
|
|
|
|
## 9. UI Kit
|
|
|
|
`/development/ui-kit` muestra las foundations públicas vigentes y sirve para revisar tema, responsive y composición. No es una especificación alternativa: debe mantenerse sincronizado con implementación, este documento y tests.
|
|
|
|
## 10. Testing
|
|
|
|
Los componentes públicos se prueban por comportamiento y contrato observable. No se fijan clases Tailwind salvo cuando expresan una responsabilidad estructural esencial, como el ownership de scroll o la ausencia de una columna aside.
|
|
|
|
Cada cambio de API pública debe actualizar conjuntamente:
|
|
|
|
1. implementación;
|
|
2. documentación;
|
|
3. UI Kit;
|
|
4. tests aplicables.
|
|
|
|
## 11. Anti-patterns
|
|
|
|
- Variantes genéricas `simple`/`complex` para mezclar width y geometría.
|
|
- Layouts CRUD universales.
|
|
- Scroll principal fuera de `RdxPageFrame`.
|
|
- Padding duplicado entre shell, container y superficie.
|
|
- Routing, permisos o queries dentro de `rdx-ui`.
|
|
- Acciones completas duplicadas en header y footer.
|
|
- Cards por sección sin necesidad funcional.
|
|
- Colores físicos o color como única señal.
|
|
|
|
Las recetas para construir páginas concretas están en [UI patterns](./ui-patterns.md).
|
|
|