Files
design_system/docs/interactive-tools.md
2026-08-12 03:44:07 -06:00

6.0 KiB

Herramientas interactivas

Estado: primera versión funcional. Este documento conserva el contexto necesario para extender DsSortableList y DsLogicTree sin cambiar accidentalmente sus contratos públicos.

Principios compartidos

  • Los modelos son serializables y no contienen referencias DOM ni estado interno de Vue.
  • Cada elemento o nodo necesita un id estable y único.
  • Las actualizaciones reemplazan arreglos y nodos en lugar de mutar los objetos recibidos.
  • La interacción con puntero siempre debe tener una alternativa de teclado.
  • La lógica de negocio, persistencia y traducción a consultas pertenece a la aplicación consumidora o a adaptadores independientes.
  • Cualquier ampliación debe actualizar tipos, API pública, pruebas, playground y documentación.

DsSortableList

Contrato actual

Recibe v-model<DsSortableItem[]>. Cada elemento contiene:

interface DsSortableItem {
  id: string;
  label: string;
  description?: string;
  disabled?: boolean;
}

El usuario puede arrastrar un elemento o utilizar los botones subir/bajar. Cada cambio reemplaza el arreglo y emite:

interface DsSortableChange {
  item: DsSortableItem;
  from: number;
  to: number;
}

El slot predeterminado puede personalizar la representación, pero id y label continúan formando parte del contrato porque se utilizan para identidad y nombres accesibles.

Decisiones

  • Se usa drag-and-drop nativo del navegador para mantener pequeña la primera versión y evitar una dependencia runtime.
  • Los botones subir/bajar son la alternativa accesible y también permiten operar la lista en pantallas táctiles.
  • La nueva posición se anuncia mediante una región status.
  • Un elemento disabled no puede iniciar un movimiento.

Limitaciones conocidas

  • Solo reordena elementos dentro de una misma lista.
  • No tiene gesto táctil de arrastre; en móvil se usan los botones.
  • No ofrece clonación, selección múltiple, grupos ni zonas de descarte.
  • El destino corresponde al elemento sobre el que se suelta; todavía no existe un indicador entre filas.
  • No administra persistencia ni historial para deshacer/rehacer.

Próximas extensiones

  1. Mejorar el indicador de inserción antes/después de una fila.
  2. Evaluar Pointer Events para arrastre táctil sin eliminar la alternativa por botones.
  3. Diseñar drag-and-drop entre listas. Antes de implementarlo hay que definir sourceListId, targetListId, copia frente a movimiento y el evento público resultante.
  4. Añadir soporte opcional para deshacer/rehacer como composable independiente.
  5. Incorporar pruebas visuales y de interacción en navegadores reales.

DsLogicTree

Contrato actual

Recibe v-model<DsLogicGroup>. El árbol utiliza una unión discriminada:

type DsLogicNode = DsLogicCondition | DsLogicGroup;

interface DsLogicGroup {
  id: string;
  type: "group";
  operator: "and" | "or";
  children: DsLogicNode[];
}

interface DsLogicCondition {
  id: string;
  type: "condition";
  field: string;
  comparison: string;
  value: string;
}

fields y comparisons usan opciones { label, value, disabled? }. La prop labels permite adaptar todos los textos del editor y readonly conserva la estructura sin permitir cambios. Cada edición actualiza el v-model y emite change con el árbol completo.

El render recursivo vive en DsLogicTreeNode.vue, que es una implementación interna y no forma parte de la API pública.

Decisiones

  • AND y OR se almacenan como and y or; los textos visibles son configurables.
  • Las condiciones usan cadenas para que la primera versión sea neutral respecto al dominio.
  • Los nodos nuevos reciben UUID y los nodos proporcionados por el consumidor deben conservar IDs estables.
  • El árbol solamente describe reglas. No evalúa condiciones ni genera SQL, JSON Logic u otra sintaxis.
  • Los controles nativos mantienen nombres accesibles y el anidamiento se representa con listas y grupos.

Limitaciones conocidas

  • Todos los valores se editan como texto, sin tipos number, boolean, fecha o selección múltiple.
  • No existe validación de campos vacíos, operadores incompatibles o grupos sin condiciones.
  • Los nodos no pueden reordenarse ni moverse entre grupos.
  • No hay operadores unarios como is-empty ni condiciones que omitan value.
  • No se muestran resúmenes en lenguaje natural.
  • No se incluye un evaluador ni adaptadores para backends.

Próximas extensiones

  1. Añadir validación sin cambiar el modelo serializable; los errores deben asociarse al control correspondiente.
  2. Diseñar definiciones de campo tipadas con un valueType y opciones de valor. Hay que conservar compatibilidad con el esquema actual o introducir el cambio en una versión mayor.
  3. Permitir comparadores que no requieran valor y editores personalizados mediante slots.
  4. Reordenar condiciones y mover nodos entre grupos reutilizando un contrato de drag-and-drop estable.
  5. Crear adaptadores separados para evaluar el árbol o convertirlo a formatos como JSON Logic. Estos adaptadores no deben acoplar el componente visual a un backend.
  6. Añadir colapsado de grupos, resumen legible y deshacer/rehacer cuando el árbol crezca.

Checklist para futuras sesiones

Antes de modificar estas herramientas:

  1. Revisa este documento, src/types.ts y las pruebas de tests/data-tools.test.ts.
  2. Decide si el cambio es compatible con los modelos actuales y documenta cualquier migración.
  3. Conserva una alternativa completa al arrastre para teclado y tecnologías asistivas.
  4. Añade el caso nuevo al playground en ?section=tools.
  5. Actualiza docs/components.md si cambia la API pública.
  6. Ejecuta npm run check y npm run test:coverage.

Fuera de alcance actual

  • Ejecución de reglas contra datos reales.
  • Generación directa de SQL o llamadas a APIs.
  • Colaboración en tiempo real.
  • Persistencia automática.
  • Un editor visual de flujos con nodos y conexiones libres.

Estas capacidades requieren contratos y análisis de seguridad propios; no deben incorporarse como comportamiento implícito de los componentes visuales.