import { P as PreviewGuideInput } from './guide-preview-C73rKO0u.js'; export { a as PreviewHandle, b as PreviewResult, c as closeGuidePreview, p as previewGuide } from './guide-preview-C73rKO0u.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; /** Título del banner superior. Default en español. */ hint?: string; /** Subtítulo del banner (default: cómo abrir menús con Alt + clic). */ subhint?: 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`, …). */ /** * Estado que el panel (editor) publica para que el SDK pinte el "chrome" del * editor (topbar + fila de pasos) ENCIMA de la app. El panel es la única fuente * de verdad; el chrome solo lo refleja y devuelve `chrome-action`s. */ interface EditorChromeState { guideName: string; /** ISO de creación (null = guía nueva sin guardar). */ createdAt: string | null; steps: Array<{ id: string; label: string; presentation: 'floating' | 'inline'; }>; activeStep: number; /** Qué muestra el panel: ajustes de activación o el paso activo. */ section: 'activation' | 'step' | 'badge' | 'target'; saving: boolean; dirty: boolean; /** * Estado de publicación de la guía, para que el autor vea en la barra si lo * que edita está Activa/Borrador/etc. (sin esto, guardar una guía en borrador * y no verla en la app era un misterio). `tone` elige el color del chip. */ status?: { label: string; tone: 'live' | 'testing' | 'review' | 'draft' | 'paused'; } | null; } /** * Qué está haciendo la preview en la app. El SDK lo publica cada vez que * evalúa un comando `preview` con `honorTrigger`, para que el panel explique * por qué la guía no se ve (retraso, elemento objetivo, otra página, otro * dispositivo) en vez de parecer rota. */ type PreviewStatus = { state: 'shown'; } | { state: 'waiting-delay'; delayMs: number; } | { state: 'waiting-trigger'; trigger: 'on_click' | 'on_hover'; selector: string; } | { state: 'page-mismatch'; pattern: string; } | { state: 'device-mismatch'; devices: 'desktop' | 'mobile'; }; /** Acciones que el usuario dispara en el chrome (barras) y el panel ejecuta. */ type ChromeAction = { action: 'select-activation'; } | { action: 'select-step'; index: number; } | { action: 'add-step'; } | { action: 'save'; exit: boolean; } | { action: 'exit'; } | { action: 'dock'; position: 'top' | 'bottom'; } | { action: 'show-panel'; } | { action: 'preview'; } | { action: 'exit-preview'; }; /** Eventos que la app del cliente envía al dashboard. */ type BuilderEvent = { type: 'ready'; chrome?: boolean; } | { type: 'chrome-action'; payload: ChromeAction; } | { type: 'picked'; payload: PickedElement; } | { type: 'pick-cancelled'; } | { type: 'design-updated'; payload: DesignPatch; } | { type: 'block-dropped'; payload: BlockDropPayload; } | { type: 'preview-status'; payload: PreviewStatus; } | { 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; honorTrigger?: boolean; } | { type: 'block-drag'; phase: 'move' | 'drop' | 'cancel'; x: number; y: number; blockType: string; label?: string; } | { type: 'close-preview'; } | { type: 'teardown'; } | { type: 'editor-state'; state: EditorChromeState; } | { type: 'panel-visibility'; visible: boolean; } | { 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 `