veo-sdk 0.5.5 → 0.5.6

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 { VEO_BLOCK_MIME, attachBlockDropTarget, attachDesignManipulator, createBuilderSession, initBuilderMode, startElementPicker, stopElementPicker } from './chunk-A4RHMCCM.mjs';
2
+ import './chunk-764FSEHS.mjs';
3
+ import './chunk-PTG3BTJE.mjs';
4
+ //# sourceMappingURL=builder-AMCPHL4K.mjs.map
5
+ //# sourceMappingURL=builder-AMCPHL4K.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"builder-O2QHV2DV.mjs"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"builder-AMCPHL4K.mjs"}
package/dist/builder.cjs CHANGED
@@ -522,7 +522,8 @@ function buildButtonBlock(block, doc, callbacks) {
522
522
  btn.textContent = typeof block.text === "string" && block.text ? block.text : "OK";
523
523
  applyBlockStyle(btn, block.style, "button");
524
524
  btn.addEventListener("click", () => {
525
- const action = block.action ?? "dismiss";
525
+ const raw = block.action ?? "dismiss";
526
+ const action = raw === "next" || raw === "url" || raw === "guide" ? raw : "dismiss";
526
527
  const target = action === "url" && typeof block.url === "string" && isSafeUrl(block.url) ? block.url : action === "guide" && typeof block.targetGuideId === "string" && block.targetGuideId ? block.targetGuideId : void 0;
527
528
  const meta = {
528
529
  ...typeof block.id === "string" && block.id ? { buttonId: block.id } : {},
@@ -918,6 +919,35 @@ var GUIDE_STYLES = `
918
919
  animation: veo-fade-in 160ms ease-out;
919
920
  }
920
921
 
922
+ /* \u2500\u2500 Modelo unificado (composite) \u2500\u2500 */
923
+ .veo-composite-overlay {
924
+ position: fixed; inset: 0;
925
+ z-index: ${GUIDE_Z_INDEX};
926
+ pointer-events: none;
927
+ }
928
+ /* Backdrop atenuado (solo centro con backdrop activo). */
929
+ .veo-composite-overlay--dim {
930
+ background: rgba(0, 0, 0, 0.5);
931
+ pointer-events: auto;
932
+ }
933
+ .veo-composite-anchored {
934
+ position: fixed;
935
+ z-index: ${GUIDE_Z_INDEX};
936
+ }
937
+ /* Card gen\xE9rica del modelo unificado. El dise\xF1o (bg/borde/padding/\u2026) lo aplica
938
+ el renderer como estilos inline desde step.design; ac\xE1 van los defaults. */
939
+ .veo-card {
940
+ pointer-events: auto;
941
+ background: var(--veo-bg, #ffffff);
942
+ color: var(--veo-text, #1f2937);
943
+ border-radius: var(--veo-radius, 12px);
944
+ padding: 20px;
945
+ max-width: 90vw;
946
+ box-shadow: var(--veo-shadow, 0 12px 40px rgba(0, 0, 0, 0.18));
947
+ animation: veo-fade-in 160ms ease-out;
948
+ }
949
+ .veo-composite-anchored .veo-card, .veo-composite-overlay .veo-card { position: relative; }
950
+
921
951
  .veo-guide-content {
922
952
  position: relative;
923
953
  display: flex; flex-direction: column;
@@ -1724,6 +1754,182 @@ var BannerRenderer = class extends BaseRenderer {
1724
1754
  function bannerClassOf(position, embedded) {
1725
1755
  return embedded ? "veo-banner veo-banner-embedded" : `veo-banner veo-banner-${position}`;
1726
1756
  }
1757
+ var CompositeRenderer = class extends BaseRenderer {
1758
+ async render(context) {
1759
+ const idx = context.nav?.stepIndex ?? 0;
1760
+ const step = context.guide.guideSteps[idx];
1761
+ if (!step) return;
1762
+ const anchorSelector = step.position === "relative-to-element" || step.presentation === "inline" ? step.anchorSelector?.trim() || void 0 : void 0;
1763
+ let anchor = null;
1764
+ if (anchorSelector) {
1765
+ anchor = await waitForElement(anchorSelector);
1766
+ if (!anchor) return;
1767
+ }
1768
+ const { host, root } = this.createHost();
1769
+ const doc = root.ownerDocument ?? document;
1770
+ const card = doc.createElement("div");
1771
+ card.className = "veo-card";
1772
+ applyCompositeDesign(card, step.design ?? {});
1773
+ const dismiss = (action, meta) => {
1774
+ context.onInteraction({
1775
+ guideId: context.guide.guideId,
1776
+ stepIndex: idx,
1777
+ action,
1778
+ ...meta?.id ? { metadata: { buttonId: meta.id } } : {}
1779
+ });
1780
+ };
1781
+ const synthetic = { blocks: step.blocks ?? [] };
1782
+ for (const node of buildContentNodes(synthetic, doc)) card.appendChild(node);
1783
+ const buttons = (step.blocks ?? []).filter((b) => b.type === "button");
1784
+ if (buttons.length) {
1785
+ const row = doc.createElement("div");
1786
+ row.className = "veo-guide-actions";
1787
+ for (const b of buttons) row.appendChild(this.buildButton(b, doc, context, dismiss));
1788
+ card.appendChild(row);
1789
+ }
1790
+ card.appendChild(
1791
+ createCloseButton(doc, () => {
1792
+ dismiss("dismissed");
1793
+ this.closeOrSkip(context);
1794
+ })
1795
+ );
1796
+ if (step.presentation === "inline" && anchor) {
1797
+ host.style.display = "block";
1798
+ const pos = inlinePosOf(step.inlinePosition);
1799
+ root.appendChild(card);
1800
+ insertHost(anchor, host, pos);
1801
+ this.registerCleanup(keepHostAttached(host, anchorSelector, pos));
1802
+ } else if (step.position === "relative-to-element" && anchor) {
1803
+ const wrapper = doc.createElement("div");
1804
+ wrapper.className = "veo-composite-anchored";
1805
+ wrapper.appendChild(card);
1806
+ root.appendChild(wrapper);
1807
+ this.registerCleanup(await anchorPosition(anchor, wrapper));
1808
+ } else {
1809
+ const overlay = doc.createElement("div");
1810
+ overlay.className = "veo-composite-overlay";
1811
+ if (step.position === "center" && step.design?.backdrop !== false) {
1812
+ overlay.classList.add("veo-composite-overlay--dim");
1813
+ overlay.addEventListener("click", (e) => {
1814
+ if (e.target === overlay) {
1815
+ dismiss("dismissed");
1816
+ this.closeOrSkip(context);
1817
+ }
1818
+ });
1819
+ }
1820
+ applyViewportPosition(card, step.position);
1821
+ overlay.appendChild(card);
1822
+ root.appendChild(overlay);
1823
+ }
1824
+ context.onInteraction({ guideId: context.guide.guideId, stepIndex: idx, action: "shown" });
1825
+ }
1826
+ /** Botón con enrutado de acción (navegación / cierre / url / guía). */
1827
+ buildButton(block, doc, context, emit) {
1828
+ const btn = doc.createElement("button");
1829
+ btn.type = "button";
1830
+ btn.className = "veo-guide-cta";
1831
+ btn.textContent = block.text?.trim() || "OK";
1832
+ btn.addEventListener("click", () => {
1833
+ emit("cta_clicked", block);
1834
+ const nav = context.nav?.callbacks;
1835
+ switch (block.action) {
1836
+ case "next":
1837
+ case "submit-forms":
1838
+ case "submit-forms-advance":
1839
+ if (nav) nav.onNext();
1840
+ else context.onClose();
1841
+ break;
1842
+ case "prev":
1843
+ nav?.onBack();
1844
+ break;
1845
+ case "url":
1846
+ if (typeof block.url === "string" && isSafeUrl(block.url)) {
1847
+ window.open(block.url, "_blank", "noopener,noreferrer");
1848
+ }
1849
+ break;
1850
+ case "guide":
1851
+ if (block.targetGuideId) context.onOpenGuide?.(block.targetGuideId);
1852
+ this.closeOrSkip(context);
1853
+ break;
1854
+ default:
1855
+ this.closeOrSkip(context);
1856
+ }
1857
+ });
1858
+ return btn;
1859
+ }
1860
+ closeOrSkip(context) {
1861
+ if (context.nav?.callbacks) context.nav.callbacks.onSkip();
1862
+ else context.onClose();
1863
+ }
1864
+ };
1865
+ function inlinePosOf(p) {
1866
+ return p === "before" || p === "prepend" || p === "append" ? p : "after";
1867
+ }
1868
+ function applyViewportPosition(card, position) {
1869
+ const s = card.style;
1870
+ s.position = "fixed";
1871
+ const M = "16px";
1872
+ const v = position.includes("top") ? "top" : position.includes("bottom") ? "bottom" : "middle";
1873
+ const h = position.includes("left") ? "left" : position.includes("right") ? "right" : "middle";
1874
+ if (position === "center") {
1875
+ s.top = "50%";
1876
+ s.left = "50%";
1877
+ s.transform = "translate(-50%, -50%)";
1878
+ return;
1879
+ }
1880
+ if (v === "top") s.top = M;
1881
+ else if (v === "bottom") s.bottom = M;
1882
+ else {
1883
+ s.top = "50%";
1884
+ s.transform = "translateY(-50%)";
1885
+ }
1886
+ if (h === "left") s.left = M;
1887
+ else if (h === "right") s.right = M;
1888
+ else {
1889
+ s.left = "50%";
1890
+ s.transform = `${s.transform} translateX(-50%)`.trim();
1891
+ }
1892
+ }
1893
+ async function anchorPosition(anchor, wrapper) {
1894
+ const update = async () => {
1895
+ const { x, y } = await dom.computePosition(anchor, wrapper, {
1896
+ placement: "bottom",
1897
+ strategy: "fixed",
1898
+ middleware: [dom.offset(8), dom.flip(), dom.shift({ padding: 8 })]
1899
+ });
1900
+ wrapper.style.left = `${x}px`;
1901
+ wrapper.style.top = `${y}px`;
1902
+ };
1903
+ await update();
1904
+ const reposition = () => void update();
1905
+ window.addEventListener("scroll", reposition, true);
1906
+ window.addEventListener("resize", reposition);
1907
+ return () => {
1908
+ window.removeEventListener("scroll", reposition, true);
1909
+ window.removeEventListener("resize", reposition);
1910
+ };
1911
+ }
1912
+ function applyCompositeDesign(card, design) {
1913
+ const s = card.style;
1914
+ const px = (v) => typeof v === "number" && Number.isFinite(v) ? `${v}px` : null;
1915
+ const strv = (v) => typeof v === "string" && v ? v : null;
1916
+ if (strv(design.background)) s.background = design.background;
1917
+ if (strv(design.textColor)) s.color = design.textColor;
1918
+ if (px(design.fontSize)) s.fontSize = px(design.fontSize);
1919
+ if (strv(design.fontWeight)) s.fontWeight = design.fontWeight;
1920
+ if (strv(design.align)) s.textAlign = design.align;
1921
+ if (typeof design.lineHeight === "number") s.lineHeight = `${design.lineHeight}%`;
1922
+ if (px(design.radius)) s.borderRadius = px(design.radius);
1923
+ if (px(design.width)) s.width = px(design.width);
1924
+ const bw = px(design.borderWidth);
1925
+ if (bw) s.border = `${bw} solid ${strv(design.borderColor) ?? "#e5e5e5"}`;
1926
+ for (const side of ["Top", "Right", "Bottom", "Left"]) {
1927
+ const p = px(design[`padding${side}`]);
1928
+ if (p) s.setProperty(`padding-${side.toLowerCase()}`, p);
1929
+ const m = px(design[`margin${side}`]);
1930
+ if (m) s.setProperty(`margin-${side.toLowerCase()}`, m);
1931
+ }
1932
+ }
1727
1933
 
1728
1934
  // src/utils/uuid.ts
1729
1935
  function uuidv7() {
@@ -2606,6 +2812,13 @@ var GuidePreviewController = class {
2606
2812
  this.input = input;
2607
2813
  const guide = normalize(input);
2608
2814
  const start = typeof input.startStepIndex === "number" ? input.startStepIndex : 0;
2815
+ if (guide.guideType === "composite") {
2816
+ const s = Math.min(Math.max(0, start), guide.guideSteps.length - 1);
2817
+ const active = guide.guideSteps[s];
2818
+ if (active) guide.guideSteps = [active];
2819
+ const ready2 = this.renderSingleStep(guide);
2820
+ return { close: () => this.close(), ready: ready2, host: () => this.activeHost() };
2821
+ }
2609
2822
  const ready = guide.guideType === "walkthrough" ? this.startWalkthrough(guide, start) : this.renderSingleStep(guide);
2610
2823
  return { close: () => this.close(), ready, host: () => this.activeHost() };
2611
2824
  }
@@ -2785,8 +2998,12 @@ function createSingleStepRenderer(type) {
2785
2998
  return new InlineFormRenderer();
2786
2999
  case "badge":
2787
3000
  return new BadgeRenderer();
3001
+ case "composite":
3002
+ return new CompositeRenderer();
2788
3003
  case "walkthrough":
2789
3004
  return null;
3005
+ default:
3006
+ return null;
2790
3007
  }
2791
3008
  }
2792
3009
  function safeDestroy(renderer) {