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 modal
  • message: string - Descripción de la acción
  • confirmLabel?: string - Label del botón confirmar (default: "Confirmar")
  • cancelLabel?: string - Label del botón cancelar (default: "Cancelar")
  • confirmIcon?: string - Icono Bootstrap en confirmar
  • danger?: boolean - Si true, usa color de peligro
  • onConfirm: () => void
  • onCancel: () => 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 seleccionado
  • Escape: 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ón
  • Escape: deseleccionar
  • Ctrl+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 gap
  • 8px — compact
  • 12px — default
  • 16px — comfortable
  • 24px — spacious
  • 32px — section

Border Radius

  • 4px — inputs, chips
  • 6px — buttons, small cards
  • 8px — cards, panels
  • 10px — modals, dropdowns
  • 12px — 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

  1. Apertura: fade-in + scale animation
  2. Focus primer input o botón
  3. Escape/Click fuera cierra (si no hay form activo)
  4. Submit: deshabilita botón, muestra loading
  5. Error: muestra mensaje inline
  6. Success: cierra y callback

Context Menu Lifecycle

  1. Right-click captura posición
  2. Menu aparece en posición (clamped a viewport)
  3. Click en acción ejecuta y cierra
  4. 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)