veo-sdk 0.3.7 → 0.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,5 @@
1
+ export { createBuilderSession, initBuilderMode, startElementPicker, stopElementPicker } from './chunk-3YRVJRBF.mjs';
2
+ import './chunk-S522B64R.mjs';
3
+ import './chunk-PTG3BTJE.mjs';
4
+ //# sourceMappingURL=builder-AGU5EM3C.mjs.map
5
+ //# sourceMappingURL=builder-AGU5EM3C.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"builder-7MBMYL26.mjs"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"builder-AGU5EM3C.mjs"}
package/dist/builder.cjs CHANGED
@@ -207,11 +207,17 @@ function renderBlocks(container, blocks, doc, callbacks) {
207
207
  if (block?.type === "button") {
208
208
  const actions = doc.createElement("div");
209
209
  actions.className = "veo-guide-actions";
210
+ let rowAlign;
210
211
  while (i < blocks.length && blocks[i]?.type === "button") {
211
212
  const btnBlock = blocks[i];
213
+ if (!rowAlign) {
214
+ const a = btnBlock.style?.align;
215
+ if (a === "left" || a === "center" || a === "right") rowAlign = a;
216
+ }
212
217
  actions.appendChild(buildButtonBlock(btnBlock, doc, callbacks));
213
218
  i++;
214
219
  }
220
+ if (rowAlign) actions.style.justifyContent = BLOCK_ALIGN_SELF[rowAlign];
215
221
  container.appendChild(actions);
216
222
  continue;
217
223
  }
@@ -276,7 +282,7 @@ function applyBlockStyle(el, style, kind) {
276
282
  const align = typeof s.align === "string" ? s.align : null;
277
283
  if (align && (align === "left" || align === "center" || align === "right")) {
278
284
  if (kind === "text") el.style.textAlign = align;
279
- else el.style.alignSelf = BLOCK_ALIGN_SELF[align];
285
+ else if (kind === "image") el.style.alignSelf = BLOCK_ALIGN_SELF[align];
280
286
  }
281
287
  if (kind !== "image" && typeof s.color === "string") el.style.color = s.color;
282
288
  if (kind === "text" && typeof s.fontSize === "number" && Number.isFinite(s.fontSize)) {
@@ -614,6 +620,12 @@ var GUIDE_STYLES = `
614
620
  position: relative;
615
621
  display: flex; flex-direction: column;
616
622
  }
623
+ /* Reserva espacio para la \u2715 (esquina sup. derecha) SOLO en el primer bloque:
624
+ as\xED el texto alineado a la derecha no queda tapado por el bot\xF3n de cerrar. */
625
+ .veo-guide-content > .veo-guide-title:first-child,
626
+ .veo-guide-content > .veo-guide-text:first-child {
627
+ padding-right: 20px;
628
+ }
617
629
  .veo-guide-image {
618
630
  display: block;
619
631
  width: var(--veo-image-width, 100%);
@@ -780,21 +792,6 @@ var GUIDE_STYLES = `
780
792
  background: transparent;
781
793
  color-scheme: normal;
782
794
  }
783
- /*
784
- * X de cerrar de las gu\xEDas custom: el HTML del cliente vive en un iframe
785
- * sandbox, as\xED que el bot\xF3n lo pone el host POR ENCIMA del iframe. Con fondo
786
- * propio para ser visible sobre cualquier contenido.
787
- */
788
- .veo-custom-close {
789
- position: absolute; top: 6px; right: 6px; z-index: 1;
790
- width: 22px; height: 22px; padding: 0;
791
- display: flex; align-items: center; justify-content: center;
792
- font-size: 16px; line-height: 1; color: #6b7280;
793
- background: rgba(255, 255, 255, 0.92);
794
- border: 1px solid rgba(0, 0, 0, 0.08); border-radius: 50%;
795
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.14); cursor: pointer;
796
- }
797
- .veo-custom-close:hover { color: #111827; }
798
795
 
799
796
  @keyframes veo-fade-in { from { opacity: 0; } to { opacity: 1; } }
800
797
  @keyframes veo-slide-up {
@@ -968,7 +965,8 @@ function mountCustomFrame(doc, step, context, opts) {
968
965
  const token = uuidv7();
969
966
  const wantsTailwind = step.style?.tailwind === true;
970
967
  iframe.srcdoc = buildSrcdoc(step.html ?? "", step.css ?? "", step.js ?? "", token, {
971
- tokens: collectHostTokens(),
968
+ hostCss: collectHostStyles(),
969
+ htmlAttrs: hostHtmlAttrs(),
972
970
  tailwind: wantsTailwind
973
971
  });
974
972
  const close = () => context.onClose();
@@ -1019,25 +1017,40 @@ function mountCustomFrame(doc, step, context, opts) {
1019
1017
  function toCssSize(value) {
1020
1018
  return typeof value === "number" ? `${value}px` : value;
1021
1019
  }
1022
- function collectHostTokens() {
1023
- if (typeof window === "undefined" || typeof document === "undefined") return "";
1020
+ var MAX_HOST_CSS = 800 * 1024;
1021
+ function collectHostStyles() {
1022
+ if (typeof document === "undefined") return "";
1023
+ let out = "";
1024
1024
  try {
1025
- const rootStyle = getComputedStyle(document.documentElement);
1026
- const decls = [];
1027
- const seen = /* @__PURE__ */ new Set();
1028
- for (let i = 0; i < rootStyle.length && decls.length < 400; i++) {
1029
- const name = rootStyle.item(i);
1030
- if (!name.startsWith("--") || seen.has(name)) continue;
1031
- seen.add(name);
1032
- const value = rootStyle.getPropertyValue(name).trim();
1033
- if (!value || value.length > 200 || /[<>{}]/.test(value)) continue;
1034
- decls.push(`${name}:${value}`);
1025
+ for (const sheet of Array.from(document.styleSheets)) {
1026
+ let rules = null;
1027
+ try {
1028
+ rules = sheet.cssRules;
1029
+ } catch {
1030
+ continue;
1031
+ }
1032
+ if (!rules) continue;
1033
+ for (const rule of Array.from(rules)) {
1034
+ out += `${rule.cssText}
1035
+ `;
1036
+ if (out.length > MAX_HOST_CSS) return out;
1037
+ }
1035
1038
  }
1036
- const bodyFont = getComputedStyle(document.body).fontFamily;
1037
- if (bodyFont && bodyFont.length <= 200 && !/[<>{}]/.test(bodyFont)) {
1038
- decls.push(`--veo-host-font:${bodyFont}`);
1039
+ } catch {
1040
+ return out;
1041
+ }
1042
+ return out;
1043
+ }
1044
+ function hostHtmlAttrs() {
1045
+ if (typeof document === "undefined") return "";
1046
+ try {
1047
+ const el = document.documentElement;
1048
+ const attrs = [];
1049
+ for (const name of ["class", "style", "data-theme", "data-mode", "data-color-mode"]) {
1050
+ const v = el.getAttribute(name);
1051
+ if (v && v.length <= 1e3 && !/["<>]/.test(v)) attrs.push(`${name}="${v}"`);
1039
1052
  }
1040
- return decls.length ? `:root{${decls.join(";")}}` : "";
1053
+ return attrs.join(" ");
1041
1054
  } catch {
1042
1055
  return "";
1043
1056
  }
@@ -1047,9 +1060,13 @@ function isRecord(value) {
1047
1060
  }
1048
1061
  function buildSrcdoc(html, css, js, token, opts) {
1049
1062
  const bridge = `(function(){var T=${JSON.stringify(token)};function P(m){m.__veo=T;parent.postMessage(m,'*');}window.veo={dismiss:function(){P({type:'dismiss'});},cta:function(u){P({type:'cta',url:u});},track:function(n,p){P({type:'track',name:n,props:p||{}});},navigate:function(u){P({type:'navigate',url:u});}};document.addEventListener('click',function(e){var a=e.target&&e.target.closest?e.target.closest('a[href]'):null;if(!a)return;var h=a.getAttribute('href');if(!h||h.charAt(0)==='#'||/^(javascript|mailto|tel):/i.test(h))return;e.preventDefault();if(a.target==='_blank'){P({type:'cta',url:a.href,close:false});}else{P({type:'navigate',url:h});}},true);function H(){P({type:'resize',height:Math.ceil(document.documentElement.scrollHeight)});}window.addEventListener('load',H);try{if(typeof ResizeObserver!=='undefined'){new ResizeObserver(H).observe(document.documentElement);}}catch(e){}})();`;
1050
- const tokensStyle = opts.tokens ? `<style>${escapeClosing(opts.tokens, "style")}</style>` : "";
1063
+ const hostStyle = opts.hostCss ? `<style>${escapeClosing(opts.hostCss, "style")}</style>` : "";
1051
1064
  const tailwind = opts.tailwind ? '<script src="https://cdn.tailwindcss.com"></script>' : "";
1052
- return '<!DOCTYPE html><html><head><meta charset="utf-8"><style>html,body{margin:0;padding:0;background:transparent;font-family:var(--veo-host-font,system-ui,sans-serif);}</style>' + tokensStyle + tailwind + `<style>${escapeClosing(css, "style")}</style></head><body>${html}<script>${bridge}</script>` + (js ? `<script>${escapeClosing(js, "script")}</script>` : "") + "</body></html>";
1065
+ return (
1066
+ // Orden: base → CSS del host (utilidades+clases propias+:root) → reset
1067
+ // flotante (fondo transparente, sin márgenes) → Tailwind → CSS del autor (gana).
1068
+ `<!DOCTYPE html><html ${opts.htmlAttrs}><head><meta charset="utf-8"><style>html,body{margin:0;padding:0;}body{font-family:system-ui,-apple-system,sans-serif;}</style>` + hostStyle + "<style>html,body{margin:0!important;padding:0!important;background:transparent!important;}</style>" + tailwind + `<style>${escapeClosing(css, "style")}</style></head><body>${html}<script>${bridge}</script>` + (js ? `<script>${escapeClosing(js, "script")}</script>` : "") + "</body></html>"
1069
+ );
1053
1070
  }
1054
1071
  function escapeClosing(code, tag) {
1055
1072
  const rx = tag === "script" ? /<\/script/gi : /<\/style/gi;
@@ -1082,20 +1099,6 @@ var CustomRenderer = class extends BaseRenderer {
1082
1099
  });
1083
1100
  this.registerCleanup(cleanup);
1084
1101
  wrapper.appendChild(iframe);
1085
- wrapper.appendChild(
1086
- createCloseButton(
1087
- doc,
1088
- () => {
1089
- context.onInteraction({
1090
- guideId: context.guide.guideId,
1091
- stepIndex: 0,
1092
- action: "dismissed"
1093
- });
1094
- context.onClose();
1095
- },
1096
- "veo-custom-close"
1097
- )
1098
- );
1099
1102
  root.appendChild(wrapper);
1100
1103
  if (placement.mode === "floating") {
1101
1104
  applyFloatingPosition(wrapper, placement);
@@ -1497,20 +1500,6 @@ var InlineCustomRenderer = class extends BaseRenderer {
1497
1500
  const { iframe, cleanup } = mountCustomFrame(doc, step, context, { width: "100%" });
1498
1501
  this.registerCleanup(cleanup);
1499
1502
  wrapper.appendChild(iframe);
1500
- wrapper.appendChild(
1501
- createCloseButton(
1502
- doc,
1503
- () => {
1504
- context.onInteraction({
1505
- guideId: context.guide.guideId,
1506
- stepIndex: 0,
1507
- action: "dismissed"
1508
- });
1509
- context.onClose();
1510
- },
1511
- "veo-custom-close"
1512
- )
1513
- );
1514
1503
  root.appendChild(wrapper);
1515
1504
  context.onInteraction({ guideId: context.guide.guideId, stepIndex: 0, action: "shown" });
1516
1505
  }
@@ -1648,6 +1637,8 @@ var TooltipRenderer = class extends BaseRenderer {
1648
1637
  if (typeof selector !== "string" || selector.length === 0) return;
1649
1638
  const anchor = await waitForElement(selector);
1650
1639
  if (!anchor) return;
1640
+ const rawSide = step.style?.tooltipPlacement;
1641
+ const side = rawSide === "top" || rawSide === "left" || rawSide === "right" ? rawSide : "bottom";
1651
1642
  const { root } = this.createHost();
1652
1643
  this.applyDesign(step.style);
1653
1644
  const ownerDocument = root.ownerDocument ?? document;
@@ -1675,7 +1666,7 @@ var TooltipRenderer = class extends BaseRenderer {
1675
1666
  root.appendChild(tooltip);
1676
1667
  const updatePosition = async () => {
1677
1668
  const { x, y, placement, middlewareData } = await dom.computePosition(anchor, tooltip, {
1678
- placement: "bottom",
1669
+ placement: side,
1679
1670
  middleware: [dom.offset(10), dom.flip(), dom.shift({ padding: 8 }), dom.arrow({ element: arrowEl })]
1680
1671
  });
1681
1672
  tooltip.style.left = `${x}px`;
@@ -1707,6 +1698,8 @@ var WalkthroughRenderer = class extends BaseRenderer {
1707
1698
  if (typeof selector !== "string" || selector.length === 0) return false;
1708
1699
  const anchor = await waitForElement(selector, WALKTHROUGH_STEP_SELECTOR_TIMEOUT_MS);
1709
1700
  if (!anchor) return false;
1701
+ const rawSide = step.style?.tooltipPlacement;
1702
+ const side = rawSide === "top" || rawSide === "left" || rawSide === "right" ? rawSide : "bottom";
1710
1703
  const { root } = this.createHost();
1711
1704
  this.applyDesign(step.style);
1712
1705
  const ownerDocument = root.ownerDocument ?? document;
@@ -1726,7 +1719,7 @@ var WalkthroughRenderer = class extends BaseRenderer {
1726
1719
  root.appendChild(tooltip);
1727
1720
  const updatePosition = async () => {
1728
1721
  const { x, y, placement, middlewareData } = await dom.computePosition(anchor, tooltip, {
1729
- placement: "bottom",
1722
+ placement: side,
1730
1723
  middleware: [dom.offset(10), dom.flip(), dom.shift({ padding: 8 }), dom.arrow({ element: arrowEl })]
1731
1724
  });
1732
1725
  tooltip.style.left = `${x}px`;