veo-sdk 0.5.3 → 0.5.5

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-XPB4DL2Y.mjs';
2
+ import './chunk-JPA46JBS.mjs';
3
+ import './chunk-PTG3BTJE.mjs';
4
+ //# sourceMappingURL=builder-O2QHV2DV.mjs.map
5
+ //# sourceMappingURL=builder-O2QHV2DV.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"builder-QNMXYF4U.mjs"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"builder-O2QHV2DV.mjs"}
package/dist/builder.cjs CHANGED
@@ -2,6 +2,112 @@
2
2
 
3
3
  var dom = require('@floating-ui/dom');
4
4
 
5
+ // src/plugins/builder/block-drop-target.ts
6
+ var VEO_BLOCK_MIME = "application/x-veo-block";
7
+ function attachBlockDropTarget(options) {
8
+ const { host, stepIndex, onDrop } = options;
9
+ const doc = host.ownerDocument;
10
+ let line = null;
11
+ let spot = null;
12
+ const contentEl = () => host.shadowRoot?.querySelector(".veo-guide-content") ?? null;
13
+ const blockChildren = (container) => Array.from(container.children).filter(
14
+ (el) => el instanceof HTMLElement && el.dataset.veoIdx !== void 0
15
+ );
16
+ const hideLine = () => {
17
+ line?.remove();
18
+ line = null;
19
+ spot = null;
20
+ };
21
+ const showLine = (at) => {
22
+ if (!line) {
23
+ line = doc.createElement("div");
24
+ line.style.cssText = "position:fixed;height:3px;border-radius:2px;background:#FF5B35;box-shadow:0 0 0 1px rgba(255,255,255,0.65);pointer-events:none;z-index:2147483647;";
25
+ host.shadowRoot?.appendChild(line);
26
+ }
27
+ line.style.left = `${at.rect.left + 4}px`;
28
+ line.style.width = `${Math.max(0, at.rect.width - 8)}px`;
29
+ line.style.top = `${at.y - 1.5}px`;
30
+ };
31
+ const isBlockDrag = (event) => {
32
+ const types = event.dataTransfer?.types;
33
+ return !!types && Array.from(types).includes(VEO_BLOCK_MIME);
34
+ };
35
+ const NEAR_PX = 48;
36
+ const locate = (clientY) => {
37
+ const container = contentEl();
38
+ if (!container) return null;
39
+ const rect = container.getBoundingClientRect();
40
+ const kids = blockChildren(container);
41
+ let beforeIndex = null;
42
+ let y = kids.length === 0 ? rect.top + rect.height / 2 : 0;
43
+ for (const kid of kids) {
44
+ const r = kid.getBoundingClientRect();
45
+ if (clientY < r.top + r.height / 2) {
46
+ const idx = Number(kid.dataset.veoIdx);
47
+ beforeIndex = Number.isFinite(idx) ? idx : null;
48
+ y = r.top;
49
+ break;
50
+ }
51
+ y = r.bottom;
52
+ }
53
+ return { beforeIndex, y, rect };
54
+ };
55
+ const overContent = (x, y, rect) => x >= rect.left - NEAR_PX && x <= rect.right + NEAR_PX && y >= rect.top - NEAR_PX && y <= rect.bottom + NEAR_PX;
56
+ const hoverAt = (x, y) => {
57
+ const at = locate(y);
58
+ if (!at || !overContent(x, y, at.rect)) {
59
+ hideLine();
60
+ return false;
61
+ }
62
+ spot = at;
63
+ showLine(at);
64
+ return true;
65
+ };
66
+ const dropAt = (x, y) => {
67
+ const at = locate(y);
68
+ hideLine();
69
+ if (!at || !overContent(x, y, at.rect)) return null;
70
+ return { beforeIndex: at.beforeIndex };
71
+ };
72
+ const onDragOver = (event) => {
73
+ if (!isBlockDrag(event)) return;
74
+ const at = locate(event.clientY);
75
+ if (!at) return;
76
+ event.preventDefault();
77
+ if (event.dataTransfer) event.dataTransfer.dropEffect = "copy";
78
+ spot = at;
79
+ showLine(at);
80
+ };
81
+ const onDropEvent = (event) => {
82
+ if (!isBlockDrag(event)) return;
83
+ event.preventDefault();
84
+ const blockType = event.dataTransfer?.getData(VEO_BLOCK_MIME) ?? "";
85
+ const at = spot ?? locate(event.clientY);
86
+ hideLine();
87
+ if (!blockType || !at) return;
88
+ onDrop({ stepIndex, blockType, beforeIndex: at.beforeIndex });
89
+ };
90
+ const onDragLeave = (event) => {
91
+ const to = event.relatedTarget;
92
+ if (to instanceof Node && (to === host || host.contains(to))) return;
93
+ hideLine();
94
+ };
95
+ host.addEventListener("dragover", onDragOver);
96
+ host.addEventListener("drop", onDropEvent);
97
+ host.addEventListener("dragleave", onDragLeave);
98
+ return {
99
+ hoverAt,
100
+ dropAt,
101
+ cancelHover: hideLine,
102
+ detach() {
103
+ host.removeEventListener("dragover", onDragOver);
104
+ host.removeEventListener("drop", onDropEvent);
105
+ host.removeEventListener("dragleave", onDragLeave);
106
+ hideLine();
107
+ }
108
+ };
109
+ }
110
+
5
111
  // src/utils/safe-env.ts
6
112
  function hasWindow() {
7
113
  return typeof window !== "undefined";
@@ -268,7 +374,15 @@ function buildStepContent(step, doc, callbacks) {
268
374
  function buildContentNodes(step, doc) {
269
375
  const blocks = normalizeBlocks(step);
270
376
  if (blocks) {
271
- return blocks.filter((b) => b.type !== "button").map((b) => buildContentBlock(b, doc)).filter((n) => n !== null);
377
+ const nodes2 = [];
378
+ for (const { block, idx } of blocks) {
379
+ if (block.type === "button") continue;
380
+ const node = buildContentBlock(block, doc);
381
+ if (!node) continue;
382
+ node.dataset.veoIdx = String(idx);
383
+ nodes2.push(node);
384
+ }
385
+ return nodes2;
272
386
  }
273
387
  const nodes = [];
274
388
  if (typeof step.imageUrl === "string" && step.imageUrl && isSafeUrl(step.imageUrl)) {
@@ -330,7 +444,8 @@ function renderLegacyStep(container, step, doc, callbacks) {
330
444
  }
331
445
  function normalizeBlocks(step) {
332
446
  if (!Array.isArray(step.blocks) || step.blocks.length === 0) return null;
333
- const valid = step.blocks.filter((b) => {
447
+ const valid = step.blocks.map((block, idx) => ({ block, idx })).filter((entry) => {
448
+ const b = entry.block;
334
449
  if (!b || typeof b !== "object") return false;
335
450
  if (b.type === "image") return typeof b.url === "string" && isSafeUrl(b.url);
336
451
  return b.type === "title" || b.type === "text" || b.type === "button";
@@ -340,13 +455,14 @@ function normalizeBlocks(step) {
340
455
  function renderBlocks(container, blocks, doc, callbacks) {
341
456
  let i = 0;
342
457
  while (i < blocks.length) {
343
- const block = blocks[i];
344
- if (block?.type === "button") {
458
+ const entry = blocks[i];
459
+ if (entry?.block.type === "button") {
345
460
  const actions = doc.createElement("div");
346
461
  actions.className = "veo-guide-actions";
462
+ actions.dataset.veoIdx = String(entry.idx);
347
463
  let rowAlign;
348
- while (i < blocks.length && blocks[i]?.type === "button") {
349
- const btnBlock = blocks[i];
464
+ while (i < blocks.length && blocks[i]?.block.type === "button") {
465
+ const btnBlock = blocks[i].block;
350
466
  if (!rowAlign) {
351
467
  const a = btnBlock.style?.align;
352
468
  if (a === "left" || a === "center" || a === "right") rowAlign = a;
@@ -358,8 +474,11 @@ function renderBlocks(container, blocks, doc, callbacks) {
358
474
  container.appendChild(actions);
359
475
  continue;
360
476
  }
361
- const node = buildContentBlock(block, doc);
362
- if (node) container.appendChild(node);
477
+ const node = entry ? buildContentBlock(entry.block, doc) : null;
478
+ if (node && entry) {
479
+ node.dataset.veoIdx = String(entry.idx);
480
+ container.appendChild(node);
481
+ }
363
482
  i++;
364
483
  }
365
484
  }
@@ -2689,7 +2808,7 @@ var MIN_H = 320;
2689
2808
  var MARGIN = 16;
2690
2809
  function injectBuilderPanel(opts) {
2691
2810
  if (!hasWindow() || !hasDocument()) {
2692
- return { target: () => null, teardown: () => {
2811
+ return { target: () => null, frameRect: () => null, teardown: () => {
2693
2812
  } };
2694
2813
  }
2695
2814
  const panelUrl = buildPanelUrl(opts);
@@ -2806,6 +2925,7 @@ function injectBuilderPanel(opts) {
2806
2925
  });
2807
2926
  return {
2808
2927
  target: () => popped && !popped.closed ? popped : iframe.contentWindow,
2928
+ frameRect: () => popped && !popped.closed ? null : iframe.getBoundingClientRect(),
2809
2929
  teardown: () => {
2810
2930
  stopPoll();
2811
2931
  if (popped && !popped.closed) popped.close();
@@ -3389,6 +3509,9 @@ function initBuilderMode() {
3389
3509
  let panel = null;
3390
3510
  let staticTarget = null;
3391
3511
  let manipulator = null;
3512
+ let dropTarget = null;
3513
+ let dragGhost = null;
3514
+ let previewStepIndex = 0;
3392
3515
  let pendingPreview = null;
3393
3516
  const getTarget = () => panel ? panel.target() : staticTarget;
3394
3517
  const post = (event) => {
@@ -3397,6 +3520,9 @@ function initBuilderMode() {
3397
3520
  const applyPreview = (cmd) => {
3398
3521
  manipulator?.detach();
3399
3522
  manipulator = null;
3523
+ dropTarget?.detach();
3524
+ dropTarget = null;
3525
+ previewStepIndex = cmd.guide.startStepIndex ?? 0;
3400
3526
  const handle = previewGuide(cmd.guide);
3401
3527
  if (!cmd.editable) return;
3402
3528
  void handle.ready.then((result) => {
@@ -3415,8 +3541,54 @@ function initBuilderMode() {
3415
3541
  applyPreview(queued);
3416
3542
  }
3417
3543
  });
3544
+ dropTarget = attachBlockDropTarget({
3545
+ host,
3546
+ stepIndex: cmd.guide.startStepIndex ?? 0,
3547
+ onDrop: (payload) => post({ type: "block-dropped", payload })
3548
+ });
3418
3549
  });
3419
3550
  };
3551
+ const hideDragGhost = () => {
3552
+ dragGhost?.remove();
3553
+ dragGhost = null;
3554
+ };
3555
+ const moveDragGhost = (x, y, label) => {
3556
+ if (!dragGhost) {
3557
+ dragGhost = document.createElement("div");
3558
+ dragGhost.style.cssText = "position:fixed;padding:4px 10px;border-radius:999px;background:#1c1917;color:#fff;font:12px/1.4 system-ui,sans-serif;box-shadow:0 4px 14px rgba(0,0,0,0.35);border:1px solid rgba(255,255,255,0.25);pointer-events:none;z-index:2147483647;";
3559
+ document.body.appendChild(dragGhost);
3560
+ }
3561
+ dragGhost.textContent = label;
3562
+ dragGhost.style.left = `${x + 14}px`;
3563
+ dragGhost.style.top = `${y + 12}px`;
3564
+ };
3565
+ const handleBlockDrag = (cmd) => {
3566
+ const rect = panel?.frameRect();
3567
+ if (!rect || !dropTarget) {
3568
+ if (cmd.phase !== "move") hideDragGhost();
3569
+ dropTarget?.cancelHover();
3570
+ return;
3571
+ }
3572
+ const x = rect.left + cmd.x;
3573
+ const y = rect.top + cmd.y;
3574
+ if (cmd.phase === "move") {
3575
+ moveDragGhost(x, y, cmd.label || cmd.blockType);
3576
+ dropTarget.hoverAt(x, y);
3577
+ return;
3578
+ }
3579
+ hideDragGhost();
3580
+ if (cmd.phase === "cancel") {
3581
+ dropTarget.cancelHover();
3582
+ return;
3583
+ }
3584
+ const spotAt = dropTarget.dropAt(x, y);
3585
+ if (spotAt) {
3586
+ post({
3587
+ type: "block-dropped",
3588
+ payload: { stepIndex: previewStepIndex, blockType: cmd.blockType, ...spotAt }
3589
+ });
3590
+ }
3591
+ };
3420
3592
  const handleCommand = (cmd) => {
3421
3593
  switch (cmd.type) {
3422
3594
  case "panel-ready":
@@ -3446,9 +3618,15 @@ function initBuilderMode() {
3446
3618
  if (manipulator?.isDragging()) pendingPreview = cmd;
3447
3619
  else applyPreview(cmd);
3448
3620
  break;
3621
+ case "block-drag":
3622
+ handleBlockDrag(cmd);
3623
+ break;
3449
3624
  case "close-preview":
3450
3625
  manipulator?.detach();
3451
3626
  manipulator = null;
3627
+ dropTarget?.detach();
3628
+ dropTarget = null;
3629
+ hideDragGhost();
3452
3630
  pendingPreview = null;
3453
3631
  closeGuidePreview();
3454
3632
  break;
@@ -3471,6 +3649,9 @@ function initBuilderMode() {
3471
3649
  picker = null;
3472
3650
  manipulator?.detach();
3473
3651
  manipulator = null;
3652
+ dropTarget?.detach();
3653
+ dropTarget = null;
3654
+ hideDragGhost();
3474
3655
  pendingPreview = null;
3475
3656
  closeGuidePreview();
3476
3657
  post({ type: "closed" });