UI & Canvas Interaction Standards
Overview
Estandardización de interacción en Generate: menús contextuales, drawers, modales y comportamiento de canvas.
1. Componentes UI Base
1.1 ConfirmModal
Uso: Acciones destructivas (eliminar, resetear).
<ConfirmModal
title="Eliminar servicio"
message="Esta acción no se puede deshacer."
confirmLabel="Eliminar"
confirmIcon="bi-trash3"
danger={true}
onConfirm={() => deleteService(id)}
onCancel={() => {}}
/>
Props:
title: string- Título del modalmessage: string- Descripción de la acciónconfirmLabel?: string- Label del botón confirmar (default: "Confirmar")cancelLabel?: string- Label del botón cancelar (default: "Cancelar")confirmIcon?: string- Icono Bootstrap en confirmardanger?: boolean- Si true, usa color de peligroonConfirm: () => voidonCancel: () => void
1.2 TableFormModal
Uso: Formularios de creación/edición de entidades.
<TableFormModal
config={{
title: "New Table",
subtitle: "Create a DBML table",
fields: [
{
id: "name",
label: "Table name",
type: "text",
value: "",
placeholder: "users",
required: true,
},
{
id: "note",
label: "Note",
type: "textarea",
value: "",
placeholder: "Description",
},
{
id: "color",
label: "Header color",
type: "text",
value: "",
placeholder: "#ff6a7f",
},
],
onSubmit: (vals) => {
/* handle */
},
onCancel: () => {},
}}
onClose={() => setModal(null)}
/>
Field types: text, textarea, select, checkbox
1.3 PromptModal
Uso: Entrada de texto rápida (renombrar, nombre courts).
<PromptModal
title="Rename module"
initialValue="currentName"
label="Module name"
placeholder="Enter name..."
onConfirm={(val) => rename(val)}
onCancel={() => {}}
/>
1.4 SelectModal
Uso: Selección de una opción de lista.
<SelectModal
title="Select service type"
options={[
{ id: "backend", label: "Backend" },
{ id: "frontend", label: "Frontend" },
{ id: "database", label: "Database" },
]}
onSelect={(id) => setType(id)}
onCancel={() => {}}
/>
1.5 ActionMenu (Context Menu)
Ubicación: ContextMenus.tsx
Menús contextuales unificados para canvas:
| Menu ID | Uso |
|---|---|
table-actions-menu |
DBML table actions |
relation-actions-menu |
DBML relation actions |
arch-node-actions-menu |
Architecture service node |
arch-link-actions-menu |
Architecture connection |
arch-canvas-actions-menu |
Architecture canvas (background) |
appsflows-node-actions-menu |
Apps Flows screen node |
appsflows-link-actions-menu |
Apps Flows connection |
appsflows-canvas-actions-menu |
Apps Flows canvas (background) |
Comportamiento:
- Click derecho abre menú en posición del cursor
- Click fuera cierra todos los menús
- Escape cierra menús
- Cada acción dispatchea un CustomEvent
2. Canvas Views — 5 Vistas
2.1 Architecture (System View)
Archivo: ArchitectureDiagram.tsx
Interacciones:
- Click en nodo: selecciona servicio, abre sidebar de propiedades
- Click derecho en nodo: abre
arch-node-actions-menu - Click derecho en link: abre
arch-link-actions-menu - Click derecho en canvas: abre
arch-canvas-actions-menu - Drag nodo: actualiza posición (guarda en store)
Estados de nodo:
- Default: borde sutil, fondo claro
- Hover: borde accent, sombra
- Selected: borde accent sólido, fondo con tint
- Disabled: opacidad 50%
Keyboard shortcuts:
Delete: eliminar nodo/link seleccionadoEscape: deseleccionar
2.2 YAML Diagram
Archivo: YamlDiagram.tsx
Interacciones:
- Muestra módulos como nodos conectados a servicio owner
- Click en módulo: abre editor YAML con contenido
- Hover: highlight de conexiones
Estados:
- Empty: "No YAML modules" con CTA para crear
- Module nodes: muestran nombre y endpoint count
2.3 DBML / ER Diagram
Archivo: ERDiagram.tsx
Interacciones:
- Click en tabla: selecciona, muestra campos
- Click derecho en tabla:
table-actions-menu - Click derecho en relación:
relation-actions-menu - Drag tabla: reposiciona
Estados de tabla:
- Default: header con color configurable
- Hover: elevación sutil
- Selected: borde accent, spotlight
- Referenced: badge de FK
Keyboard shortcuts:
Delete: eliminar tabla/relaciónEscape: deseleccionarCtrl+F: abrir búsqueda
2.4 Apps Flows
Archivo: ArchitectureDiagram.tsx (view="flows")
Interacciones:
- Click en screen node: selecciona pantalla
- Click derecho en screen:
appsflows-node-actions-menu - Click derecho en link:
appsflows-link-actions-menu - Click derecho en canvas:
appsflows-canvas-actions-menu - Drag: actualiza posición
Nodos:
- Screen nodes: rectangles con nombre
- Links: flechas con label de transición
2.5 Taskboard Organigram
Archivo: TaskboardOrganigram.tsx
Interacciones:
- Drag nodes: reorganizar organigrama
- Zoom/pan con scroll
- Fit to view button
Estados:
- Empty: mensaje + CTA para añadir primer nodo
- Node hover: highlight
- Node selected: accent border
3. Empty States
Cada vista debe tener empty state consistente:
<div className="canvas-empty-state">
<i className="bi bi-diagram-3" />
<h3>No items yet</h3>
<p>Description of what to do next</p>
<button onClick={handleCreate}>
<i className="bi bi-plus" /> Create first item
</button>
</div>
Estilos en diagram.css:
.canvas-empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
color: var(--text-muted);
gap: 12px;
}
.canvas-empty-state i {
font-size: 48px;
opacity: 0.5;
}
.canvas-empty-state h3 {
margin: 0;
color: var(--text-primary);
}
.canvas-empty-state p {
margin: 0;
font-size: 13px;
}
4. Design Tokens
Spacing
4px— micro gap8px— compact12px— default16px— comfortable24px— spacious32px— section
Border Radius
4px— inputs, chips6px— buttons, small cards8px— cards, panels10px— modals, dropdowns12px— large modals
Colors (CSS variables)
--accent— primary action (coral #ff6a7f)--primary— secondary (blue #3b82f6)--success— success state (green)--warning— warning (amber)--danger— danger (red)--text-primary— main text--text-secondary— muted text--text-muted— disabled/hint--bg-primary— main background--bg-secondary— elevated surface--bg-tertiary— hover state--border— borders
Typography
- Font: system-ui stack
- Headings: 18px/600, 16px/600
- Body: 14px/400
- Small: 12px/400
- Micro: 11px/400
5. Interaction Patterns
Modal/Drawer Lifecycle
- Apertura: fade-in + scale animation
- Focus primer input o botón
- Escape/Click fuera cierra (si no hay form activo)
- Submit: deshabilita botón, muestra loading
- Error: muestra mensaje inline
- Success: cierra y callback
Context Menu Lifecycle
- Right-click captura posición
- Menu aparece en posición (clamped a viewport)
- Click en acción ejecuta y cierra
- Click fuera cierra
Form Validation
- Required: asterisco rojo en label
- Error: mensaje debajo del campo en
--danger - Success: check verde cuando aplica
6. Accessibility
- Todos los modales:
role="dialog",aria-modal="true" - Focus trap dentro del modal
- Escape cierra modal
- Enter submits (si no hay textarea con Enter)
- Color no es único medio de estado
7. Anti-Patterns (NO USAR)
// ❌ MAL - alert nativo
window.alert('Error')
// ✅ BIEN - toast o modal
toast.error('Error al guardar')
// ❌ MAL - confirm nativo
if (window.confirm('Delete?')) deleteItem()
// ✅ BIEN - ConfirmModal
<ConfirmModal title="Delete" message="..." onConfirm={deleteItem} onCancel={() => {}}/>
// ❌ MAL - prompt nativo
const name = window.prompt('Name:', 'default')
// ✅ BIEN - PromptModal
<PromptModal title="Name" initialValue="default" onConfirm={setName} onCancel={() => {}}/>
8. Archivos Clave
| Archivo | Uso |
|---|---|
src/components/app/modals/ConfirmModal.tsx |
Confirmation dialogs |
src/components/app/modals/TableFormModal.tsx |
Entity forms |
src/components/app/modals/PromptModals.tsx |
Quick input |
src/components/app/ContextMenus.tsx |
All context menus |
src/components/app/Toast.tsx |
Notifications |
src/styles/modals.css |
Modal styles |
src/styles/diagram.css |
Context menu + empty states |
src/stores/appStore.ts |
UI state (modals, overlays) |