import { P as PreviewGuideInput } from './guide-preview-XUnTmzUO.js'; export { a as PreviewHandle, b as PreviewResult, c as closeGuidePreview, p as previewGuide } from './guide-preview-XUnTmzUO.js'; /** Dónde soltó el autor un bloque nuevo. */ interface BlockDropPayload { stepIndex: number; /** Tipo de bloque arrastrado (title/text/button/image — lo valida el panel). */ blockType: string; /** Índice del bloque ANTES del cual insertar; `null` = al final. */ beforeIndex: number | null; } /** * Manipulación DIRECTA del diseño en modo editor: arrastrar la tarjeta de una * modal para posicionarla, redimensionarla desde bordes/esquinas, y arrastrar * un banner para alternar top/bottom. Vive en el bundle builder (veo-builder.js) * — el runtime de guías no carga nada de esto. * * Funciona como DECORATOR: se adjunta DESPUÉS del render sobre el shadow root * abierto del host de la guía (no toca los renderers). Durante el gesto aplica * las variables CSS localmente (feedback a 60fps, sin postMessage); al soltar * (`pointerup`) emite UN `onCommit(patch)` con los valores finales, que el * builder-mode postea al panel como `design-updated`. El panel actualiza su * estado y re-manda `preview` — que entra por el update in-place con las * MISMAS variables → no hay loop ni parpadeo. * * Geometría del modal (ver styles.ts): la card usa `left: posX%` + * `translate(-posX%)`, o sea `cardLeft = posX * (viewportW - cardW)` → * `posX = cardLeft / (viewportW - cardW)`. Mismo modelo que serializa el * dashboard (`style.posX/posY` en 0..1) y consume `applyDesignVars`. */ /** Merge superficial sobre `step.style` del paso activo (lo aplica el panel). */ interface DesignPatch { stepIndex: number; style: { posX?: number; posY?: number; width?: number; height?: number; position?: 'top' | 'bottom'; }; } /** * Element picker — el "inspeccionar" del navegador, pero del SDK. Corre * DENTRO de la app del cliente (no en el dashboard: son orígenes distintos * y el dashboard no puede leer el DOM de la app). Resalta el elemento bajo * el cursor, muestra su selector + dimensiones, y al hacer click captura un * selector CSS estable reutilizando `buildSelectorPath` del autocapture. * * Es la base del builder no-code: el dashboard abre la app del cliente en * modo builder, el usuario "pincha" un elemento y el selector resultante se * usa como ancla de un tooltip/walkthrough. El puente con el dashboard * (postMessage) es la fase siguiente; aquí exponemos el primitivo * `startElementPicker(onPick)`. * * No usa `innerHTML` — todo por `textContent`/DOM, igual que los renderers. */ /** Datos del elemento elegido que se entregan al caller. */ interface PickedElement { /** Selector CSS estable con ancestros (lo que se guarda como ancla). */ selector: string; /** Selector corto solo del elemento (tag + id/atributo/clases). */ shortSelector: string; tag: string; id: string | null; classes: string[]; text: string; rect: { x: number; y: number; width: number; height: number; }; } interface ElementPickerOptions { /** Llamado al hacer click en un elemento. El picker se cierra tras esto. */ onPick: (picked: PickedElement) => void; /** Llamado al cancelar (Esc). El picker se cierra. */ onCancel?: () => void; /** Niveles de ancestros del selector. Default 5 (igual que autocapture). */ maxAncestors?: number; /** Texto del banner superior. Default en español. */ hint?: string; } interface ElementPickerHandle { /** Cierra el picker sin elegir nada. Idempotente. */ stop(): void; } /** * Inicia el modo de selección de elementos (inspector). Resalta lo que está * bajo el cursor y, al hacer click, entrega un selector CSS estable. * Devuelve un handle con `stop()`. Iniciar otro picker cierra el anterior. * * @example * ```ts * import { startElementPicker } from '@veo/sdk'; * * const picker = startElementPicker({ * onPick: ({ selector }) => console.log('elegido:', selector), * onCancel: () => console.log('cancelado'), * }); * // picker.stop() para abortar manualmente. * ``` */ declare function startElementPicker(options: ElementPickerOptions): ElementPickerHandle; /** Cierra el picker activo, si lo hay. Idempotente. */ declare function stopElementPicker(): void; /** * Contrato de mensajes del puente builder (app del cliente ↔ dashboard). * Ambos lados validan `event.origin` y que `token` coincida antes de actuar. * * Flujo: * 1. El dashboard abre la app con `?veoBuilder=&veoBuilderOrigin=`. * 2. La app (veo-builder.js) postea `ready` a la ventana que la abrió. * 3. El dashboard manda comandos (`start-picker`, `preview`, …). * 4. La app responde con eventos (`picked`, `pick-cancelled`, …). */ /** Eventos que la app del cliente envía al dashboard. */ type BuilderEvent = { type: 'ready'; } | { type: 'picked'; payload: PickedElement; } | { type: 'pick-cancelled'; } | { type: 'design-updated'; payload: DesignPatch; } | { type: 'block-dropped'; payload: BlockDropPayload; } | { type: 'closed'; }; /** Comandos que el dashboard/panel envía a la app del cliente. */ type BuilderCommand = { type: 'start-picker'; maxAncestors?: number; hint?: string; } | { type: 'stop-picker'; } | { type: 'preview'; guide: PreviewGuideInput; editable?: boolean; } | { type: 'block-drag'; phase: 'move' | 'drop' | 'cancel'; x: number; y: number; blockType: string; label?: string; } | { type: 'close-preview'; } | { type: 'teardown'; } | { type: 'panel-ready'; }; /** * Lado APP del puente builder. Corre dentro de la app del cliente (vía * veo-builder.js). Si el contexto trae `?veoBuilder=`, se conecta con el * editor de Veo, atiende comandos y devuelve el elemento elegido. * * Dos transportes: * - **iframe/popup** (`resolveTarget` = opener/parent): el dashboard es la * ventana principal y embebe/abre la app; le hablamos a esa ventana. * - **panel inyectado** (`ctx.panel`): la app es top-level (login real) y NOSOTROS * inyectamos el panel del editor encima (iframe al dashboard); le hablamos a * ese iframe. Es el modo sin adaptación por app. * * Seguridad: solo acepta mensajes cuyo `origin` coincida con el del dashboard * (`veoBuilderOrigin` / `document.referrer`) y cuyo `token` coincida. */ interface BuilderModeHandle { /** Desconecta el puente y limpia picker/preview/panel. */ teardown(): void; } /** * Inicializa el modo builder si hay contexto (URL o persistido). Devuelve un * handle, o `null` si no estamos en modo builder o no hay canal con el editor. * Es seguro llamarla siempre. */ declare function initBuilderMode(): BuilderModeHandle | null; interface BuilderSessionOptions { /** URL de la app del cliente a abrir en modo builder. */ appUrl: string; /** Token de la sesión (idealmente emitido/firmado por el backend). */ token: string; /** Origen al que la app debe responder. Default: `location.origin`. */ dashboardOrigin?: string; /** La app está lista y escuchando comandos. */ onReady?: () => void; /** El usuario eligió un elemento. */ onPicked?: (picked: PickedElement) => void; /** El usuario canceló la selección (Esc). */ onCancelled?: () => void; /** La app cerró el modo builder (o el popup se cerró). */ onClosed?: () => void; /** * Si se pasa, la app se embebe en este `