@wix/astro 0.2.13 → 0.2.15

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.
Files changed (80) hide show
  1. package/dist/components/TailwindEditor/EditorPanel.d.ts +11 -0
  2. package/dist/components/TailwindEditor/EditorPanel.js +86 -0
  3. package/dist/components/TailwindEditor/dev-toolbar-app.d.ts +14 -0
  4. package/dist/components/TailwindEditor/dev-toolbar-app.js +39 -0
  5. package/dist/components/TailwindEditor/dev-toolbar.d.ts +13 -0
  6. package/dist/components/TailwindEditor/dev-toolbar.js +547 -0
  7. package/dist/components/TailwindEditor/index.d.ts +5 -0
  8. package/dist/components/TailwindEditor/index.js +155 -0
  9. package/dist/components/TailwindEditor/integration.d.ts +3 -0
  10. package/dist/components/TailwindEditor/integration.js +18 -0
  11. package/dist/components/TailwindEditor/types.d.ts +35 -0
  12. package/dist/components/TailwindEditor/types.js +2 -0
  13. package/dist/components/TailwindEditor/utils.d.ts +22 -0
  14. package/dist/components/TailwindEditor/utils.js +234 -0
  15. package/dist/components/login-helpers/bi-header-generator.d.ts +11 -0
  16. package/dist/components/login-helpers/bi-header-generator.js +18 -0
  17. package/dist/components/login-helpers/iframeUtils.d.ts +4 -0
  18. package/dist/components/login-helpers/iframeUtils.js +44 -0
  19. package/dist/components/login-helpers/login-helpers.d.ts +39 -0
  20. package/dist/components/login-helpers/login-helpers.js +117 -0
  21. package/dist/dev-toolbar/Editor/EditorPanel.d.ts +14 -0
  22. package/dist/dev-toolbar/Editor/EditorPanel.js +1273 -0
  23. package/dist/dev-toolbar/Editor/classes.d.ts +12 -0
  24. package/dist/dev-toolbar/Editor/classes.js +271 -0
  25. package/dist/dev-toolbar/Editor/dnd.d.ts +34 -0
  26. package/dist/dev-toolbar/Editor/dnd.js +1161 -0
  27. package/dist/dev-toolbar/Editor/index.d.ts +5 -0
  28. package/dist/dev-toolbar/Editor/index.js +136 -0
  29. package/dist/dev-toolbar/Editor/types.d.ts +42 -0
  30. package/dist/dev-toolbar/Editor/types.js +2 -0
  31. package/dist/dev-toolbar/agent-chat.d.ts +14 -0
  32. package/dist/dev-toolbar/agent-chat.js +362 -0
  33. package/dist/dev-toolbar/ai-agent-server.d.ts +1 -0
  34. package/dist/dev-toolbar/ai-agent-server.js +174 -0
  35. package/dist/dev-toolbar/ai-agent.d.ts +2 -0
  36. package/dist/dev-toolbar/ai-agent.js +171 -0
  37. package/dist/dev-toolbar/api-key-form.d.ts +7 -0
  38. package/dist/dev-toolbar/api-key-form.js +138 -0
  39. package/dist/dev-toolbar/astro-toolbar.d.ts +1156 -0
  40. package/dist/dev-toolbar/astro-toolbar.js +29 -0
  41. package/dist/dev-toolbar/editor.d.ts +2 -0
  42. package/dist/dev-toolbar/editor.js +19 -0
  43. package/dist/integration.d.ts +3 -1
  44. package/dist/integration.js +41 -10
  45. package/dist/routes/auth/callback.js +1 -1
  46. package/dist/src/auth-context.d.ts +5 -0
  47. package/dist/src/auth-context.js +3 -0
  48. package/dist/src/client.d.ts +15 -0
  49. package/dist/src/client.js +17 -0
  50. package/dist/src/entrypoints/server.d.ts +13 -0
  51. package/dist/src/entrypoints/server.js +37 -0
  52. package/dist/src/index.d.ts +5 -0
  53. package/dist/src/index.js +5 -0
  54. package/dist/src/integration.d.ts +8 -0
  55. package/dist/src/integration.js +229 -0
  56. package/dist/src/loaders/blog.d.ts +2 -0
  57. package/dist/src/loaders/blog.js +49 -0
  58. package/dist/src/loaders/index.d.ts +2 -0
  59. package/dist/src/loaders/index.js +3 -0
  60. package/dist/src/middleware.d.ts +2 -0
  61. package/dist/src/middleware.js +90 -0
  62. package/dist/src/routes/auth/callback.d.ts +3 -0
  63. package/dist/src/routes/auth/callback.js +53 -0
  64. package/dist/src/routes/auth/constants.d.ts +5 -0
  65. package/dist/src/routes/auth/constants.js +6 -0
  66. package/dist/src/routes/auth/login.d.ts +3 -0
  67. package/dist/src/routes/auth/login.js +27 -0
  68. package/dist/src/routes/auth/logout-callback.d.ts +3 -0
  69. package/dist/src/routes/auth/logout-callback.js +10 -0
  70. package/dist/src/routes/auth/logout.d.ts +3 -0
  71. package/dist/src/routes/auth/logout.js +11 -0
  72. package/dist/src/routes/auth/runtime.d.ts +5 -0
  73. package/dist/src/routes/auth/runtime.js +8 -0
  74. package/dist/src/runtime.d.ts +2 -0
  75. package/dist/src/runtime.js +9 -0
  76. package/dist/src/vite-plugins/sdk-context.d.ts +4 -0
  77. package/dist/src/vite-plugins/sdk-context.js +68 -0
  78. package/dist/vite-plugins/sdk-context.d.ts +3 -1
  79. package/dist/vite-plugins/sdk-context.js +51 -70
  80. package/package.json +6 -3
@@ -0,0 +1,1161 @@
1
+ import { useDragLoader } from "../../hooks/use-loader-context.js";
2
+ import React from "react";
3
+ // Store the loader functions for global access
4
+ let showDragLoader = null;
5
+ let hideDragLoader = null;
6
+ // Hook to initialize the loader functions
7
+ export function useDragLoaderInit() {
8
+ const { showDragLoader: show, hideDragLoader: hide } = useDragLoader();
9
+ // Update the global references
10
+ showDragLoader = show;
11
+ hideDragLoader = hide;
12
+ }
13
+ // Constants
14
+ var EditorAttributes;
15
+ (function (EditorAttributes) {
16
+ EditorAttributes["DATA_PICASSO_DRAGGING"] = "data-picasso-dragging";
17
+ EditorAttributes["DATA_PICASSO_DRAG_SAVED_STYLE"] = "data-picasso-drag-saved-style";
18
+ EditorAttributes["DATA_PICASSO_DRAG_DIRECTION"] = "data-picasso-drag-direction";
19
+ EditorAttributes["DATA_PICASSO_DRAG_START_POSITION"] = "data-picasso-drag-start-position";
20
+ EditorAttributes["DATA_PICASSO_ORIGINAL_PARENT"] = "data-picasso-original-parent";
21
+ })(EditorAttributes || (EditorAttributes = {}));
22
+ // Add this near the top with other constants
23
+ const VALID_DROP_TARGET_CLASS = "picasso-valid-drop-target";
24
+ const INVALID_DROP_TARGET_CLASS = "picasso-invalid-drop-target";
25
+ // Store component move instructions internally
26
+ let componentMoveInstructions = [];
27
+ // Function to create a component move instruction
28
+ function createComponentMoveChange(component, sourceFile, fromLine, toLine, parentNode, parentId, toFile, originalParentNode, originalParentId) {
29
+ // Create the base instruction
30
+ const instruction = {
31
+ type: "componentMove",
32
+ timestamp: new Date().toISOString(),
33
+ component,
34
+ toLine,
35
+ parentNode,
36
+ parentId,
37
+ originalParentNode,
38
+ originalParentId
39
+ };
40
+ // For cross-file moves, add toFile property
41
+ if (toFile && toFile !== sourceFile) {
42
+ // Use type assertion to add toFile to the instruction
43
+ // This works around TypeScript errors if the types.tsx update hasn't been picked up
44
+ instruction.toFile = toFile;
45
+ }
46
+ return {
47
+ file: sourceFile,
48
+ line: fromLine,
49
+ instruction,
50
+ };
51
+ }
52
+ // Function to add a component move change to the list
53
+ function addComponentMoveChange(change) {
54
+ componentMoveInstructions.push(change);
55
+ console.log("Component move change added:", change);
56
+ }
57
+ // Export a function to get all component move changes
58
+ export function getComponentMoveChanges() {
59
+ return [...componentMoveInstructions];
60
+ }
61
+ // Export a function to clear component move changes
62
+ export function clearComponentMoveChanges() {
63
+ componentMoveInstructions = [];
64
+ }
65
+ // Helper functions
66
+ function elementFromDomId(domId) {
67
+ return document.getElementById(domId);
68
+ }
69
+ function calculateMouseOffset(el, mouseX, mouseY) {
70
+ const rect = el.getBoundingClientRect();
71
+ return {
72
+ x: mouseX - rect.left,
73
+ y: mouseY - rect.top,
74
+ };
75
+ }
76
+ function isValidHtmlElement(node) {
77
+ return node instanceof HTMLElement;
78
+ }
79
+ function createStub(el) {
80
+ const stub = document.createElement("div");
81
+ stub.id = "drag-stub";
82
+ stub.style.height = `${el.offsetHeight}px`;
83
+ stub.style.width = `${el.offsetWidth}px`;
84
+ stub.style.background = "#e0e0e0";
85
+ stub.style.border = "2px dashed #aaa";
86
+ stub.style.borderRadius = "4px";
87
+ // Insert stub before the element being dragged
88
+ if (el.parentElement) {
89
+ el.parentElement.insertBefore(stub, el);
90
+ }
91
+ }
92
+ // Add a variable to track the last insertion point to prevent jitter
93
+ let lastInsertionTarget = null;
94
+ let lastUpdateTime = 0;
95
+ const JITTER_THRESHOLD_PX = 20; // Minimum distance in pixels to trigger a change
96
+ const DEBOUNCE_DELAY = 150; // Minimum delay between updates in milliseconds
97
+ // Add variables to track last position for smooth movement
98
+ let lastDragX = 0;
99
+ let lastDragY = 0;
100
+ const MOVEMENT_SMOOTHING = 0.5; // Higher = less smoothing but more responsive
101
+ // Add a variable to store the last stable insertion index
102
+ let lastStableIndex = -1;
103
+ let stablePositionCount = 0;
104
+ const STABILITY_THRESHOLD = 3; // Number of consistent positions before committing
105
+ function moveStub(el, x, y) {
106
+ const stub = document.getElementById("drag-stub");
107
+ if (!stub)
108
+ return;
109
+ // Check if we're over a different container
110
+ const dropTarget = getDropTargetAt(x, y, el);
111
+ // If no drop target found, use the original parent
112
+ const originalParentId = el.getAttribute(EditorAttributes.DATA_PICASSO_ORIGINAL_PARENT);
113
+ const originalParent = originalParentId ? document.getElementById(originalParentId) : null;
114
+ const currentParent = stub.parentElement;
115
+ // Determine which container to use (drop target or original parent)
116
+ let targetContainer = dropTarget || (originalParent || el.parentElement);
117
+ // CRITICAL SAFETY CHECK: Never allow the stub to be its own container
118
+ // This prevents "Failed to execute 'appendChild' on 'Node': The new child element contains the parent" error
119
+ if (targetContainer === stub) {
120
+ console.error("Prevented circular reference: stub trying to append to itself");
121
+ targetContainer = originalParent || el.parentElement;
122
+ // If we still have an invalid container, abort the operation
123
+ if (!targetContainer || targetContainer === stub) {
124
+ console.error("Cannot find valid container for stub, aborting drag operation");
125
+ removeStub();
126
+ endAllDrag();
127
+ return;
128
+ }
129
+ }
130
+ // Additional safety check to prevent circular references:
131
+ // 1. Ensure target container is not null
132
+ // 2. Ensure it's not the element itself
133
+ // 3. Ensure it's not a descendant of the element
134
+ if (!targetContainer ||
135
+ targetContainer === el ||
136
+ isChildOf(targetContainer, el)) {
137
+ console.warn("Prevented potential circular reference in moveStub");
138
+ // Fall back to the original parent as a safe option
139
+ targetContainer = originalParent || el.parentElement;
140
+ // If we still have an invalid container, abort the operation
141
+ if (!targetContainer || targetContainer === el || isChildOf(targetContainer, el)) {
142
+ console.error("Cannot find valid container for stub, aborting drag operation");
143
+ removeStub();
144
+ endAllDrag();
145
+ return;
146
+ }
147
+ }
148
+ // If the stub isn't already in the target container, move it
149
+ if (targetContainer && currentParent !== targetContainer) {
150
+ // Remove stub from current parent
151
+ if (currentParent) {
152
+ currentParent.removeChild(stub);
153
+ }
154
+ // One more safety check before appending
155
+ try {
156
+ // Add to new container
157
+ targetContainer.appendChild(stub);
158
+ console.log("Moved stub to new container:", targetContainer.tagName, targetContainer.id);
159
+ // Reset stability tracking when container changes
160
+ lastStableIndex = -1;
161
+ stablePositionCount = 0;
162
+ // Update immediately without delay
163
+ lastUpdateTime = 0;
164
+ }
165
+ catch (e) {
166
+ console.error("Error moving stub to new container:", e);
167
+ // If we encounter an error, clean up and end the drag
168
+ removeStub();
169
+ endAllDrag();
170
+ return;
171
+ }
172
+ }
173
+ // If no valid container found, don't proceed
174
+ if (!targetContainer)
175
+ return;
176
+ // Now position within the container
177
+ const children = Array.from(targetContainer.children).filter((child) => isValidHtmlElement(child) && child !== el && child !== stub);
178
+ // If no children to compare, stub is already in the right place
179
+ if (children.length === 0)
180
+ return;
181
+ // Throttle updates to prevent jitter
182
+ const now = Date.now();
183
+ if (now - lastUpdateTime < DEBOUNCE_DELAY) {
184
+ return;
185
+ }
186
+ // Get layout direction
187
+ const direction = getDisplayDirection(targetContainer);
188
+ // Sort children based on their position in the document
189
+ children.sort((a, b) => {
190
+ const aRect = a.getBoundingClientRect();
191
+ const bRect = b.getBoundingClientRect();
192
+ if (direction === "row") {
193
+ return aRect.left - bRect.left; // Sort by X for row
194
+ }
195
+ else {
196
+ return aRect.top - bRect.top; // Sort by Y for column
197
+ }
198
+ });
199
+ // Find insertion point
200
+ let insertBefore = null;
201
+ let currentInsertionIndex = -1;
202
+ for (let i = 0; i < children.length; i++) {
203
+ const child = children[i];
204
+ const rect = child.getBoundingClientRect();
205
+ if (direction === "row") {
206
+ // For row layout, compare X position
207
+ if (x < rect.left + rect.width / 2) {
208
+ insertBefore = child;
209
+ currentInsertionIndex = i;
210
+ break;
211
+ }
212
+ }
213
+ else {
214
+ // For column layout, compare Y position
215
+ if (y < rect.top + rect.height / 2) {
216
+ insertBefore = child;
217
+ currentInsertionIndex = i;
218
+ break;
219
+ }
220
+ }
221
+ }
222
+ // If we didn't find an insertion point, we would insert at the end
223
+ if (insertBefore === null) {
224
+ currentInsertionIndex = children.length;
225
+ }
226
+ // Stability check - only commit position changes when they've been stable for a few checks
227
+ if (currentInsertionIndex === lastStableIndex) {
228
+ stablePositionCount++;
229
+ }
230
+ else {
231
+ lastStableIndex = currentInsertionIndex;
232
+ stablePositionCount = 1;
233
+ }
234
+ // Only update if position has been stable for a while or if it's far from the last position
235
+ let needsUpdate = false;
236
+ if (stablePositionCount >= STABILITY_THRESHOLD) {
237
+ needsUpdate = true;
238
+ }
239
+ else if (insertBefore &&
240
+ lastInsertionTarget &&
241
+ insertBefore !== lastInsertionTarget) {
242
+ // Check if the distance between old and new position is significant
243
+ const insertRect = insertBefore.getBoundingClientRect();
244
+ const lastRect = lastInsertionTarget.getBoundingClientRect();
245
+ const distance = direction === "row"
246
+ ? Math.abs(insertRect.left - lastRect.left)
247
+ : Math.abs(insertRect.top - lastRect.top);
248
+ needsUpdate = distance > JITTER_THRESHOLD_PX * 2;
249
+ }
250
+ else if (insertBefore === null && lastInsertionTarget === null) {
251
+ // Both null, check if stub is already at the end
252
+ const isAtEnd = stub.nextElementSibling === null;
253
+ needsUpdate = !isAtEnd;
254
+ }
255
+ else if (insertBefore !== lastInsertionTarget) {
256
+ // One is null and the other isn't, definitely an update
257
+ needsUpdate = true;
258
+ }
259
+ // Only update the DOM if necessary
260
+ if (needsUpdate) {
261
+ // Move stub to the determined position
262
+ if (insertBefore) {
263
+ // Check if we'd be moving to the same place
264
+ if (stub.nextElementSibling !== insertBefore) {
265
+ console.log("Moving stub before element:", insertBefore.tagName);
266
+ targetContainer.insertBefore(stub, insertBefore);
267
+ }
268
+ }
269
+ else {
270
+ // If no insert point found, append to the end
271
+ if (stub.nextElementSibling !== null) {
272
+ console.log("Moving stub to end of container");
273
+ targetContainer.appendChild(stub);
274
+ }
275
+ }
276
+ // Log the achieved position
277
+ const allChildren = Array.from(targetContainer.children);
278
+ const stubPosition = allChildren.indexOf(stub);
279
+ console.log("Stub now at position", stubPosition, "of", allChildren.length);
280
+ // Update tracking variables
281
+ lastInsertionTarget = insertBefore;
282
+ lastUpdateTime = now;
283
+ }
284
+ }
285
+ // Reset the tracking variables when drag ends
286
+ function removeStub() {
287
+ const stub = document.getElementById("drag-stub");
288
+ if (stub)
289
+ stub.remove();
290
+ // Reset tracking variables
291
+ lastInsertionTarget = null;
292
+ lastUpdateTime = 0;
293
+ lastStableIndex = -1;
294
+ stablePositionCount = 0;
295
+ }
296
+ function getCurrentStubIndex(parent, draggingEl) {
297
+ const stub = document.getElementById("drag-stub");
298
+ if (!stub)
299
+ return -1;
300
+ // The stub might be in a different parent now
301
+ const stubParent = stub.parentElement;
302
+ if (!stubParent)
303
+ return -1;
304
+ // Get all children of the stub's parent, excluding the dragging element
305
+ const childrenWithoutDraggingEl = Array.from(stubParent.children).filter((child) => isValidHtmlElement(child) && child !== draggingEl);
306
+ // Find the index of the stub in this filtered list
307
+ const stubIndex = childrenWithoutDraggingEl.indexOf(stub);
308
+ // Debug logging
309
+ console.log("Stub parent:", stubParent.tagName, stubParent.id);
310
+ console.log("Filtered children length:", childrenWithoutDraggingEl.length);
311
+ console.log("Stub found at filtered index:", stubIndex);
312
+ return stubIndex;
313
+ }
314
+ function restoreElementStyle(el) {
315
+ const savedStyleStr = el.getAttribute(EditorAttributes.DATA_PICASSO_DRAG_SAVED_STYLE);
316
+ if (!savedStyleStr)
317
+ return;
318
+ try {
319
+ const savedStyle = JSON.parse(savedStyleStr);
320
+ for (const [key, value] of Object.entries(savedStyle)) {
321
+ if (value) {
322
+ el.style[key] = value;
323
+ }
324
+ else {
325
+ el.style[key] = "";
326
+ }
327
+ }
328
+ // Ensure these critical styles are explicitly reset
329
+ el.style.zIndex = "";
330
+ el.style.opacity = "";
331
+ el.style.pointerEvents = "";
332
+ el.style.boxShadow = "";
333
+ el.style.transition = "";
334
+ }
335
+ catch (e) {
336
+ console.error("Error restoring element style:", e);
337
+ }
338
+ }
339
+ function getOrAssignDomId(el) {
340
+ if (el.id)
341
+ return el.id;
342
+ const newId = `picasso-element-${Math.random().toString(36).substr(2, 9)}`;
343
+ el.id = newId;
344
+ return newId;
345
+ }
346
+ function getDomElement(el, deep = true) {
347
+ return {
348
+ type: el.tagName.toLowerCase(),
349
+ id: getOrAssignDomId(el),
350
+ };
351
+ }
352
+ function getDisplayDirection(parent) {
353
+ const style = window.getComputedStyle(parent);
354
+ if (style.display === "flex" || style.display === "inline-flex") {
355
+ // Check for row or row-reverse
356
+ if (style.flexDirection === "row" ||
357
+ style.flexDirection === "row-reverse") {
358
+ return "row";
359
+ }
360
+ // All other flex directions (column, column-reverse) are treated as column
361
+ }
362
+ // Default to column for non-flex containers or column flex
363
+ return "column";
364
+ }
365
+ // Add a helper for direction-aware positioning
366
+ function getPositionInDirection(element, parent) {
367
+ const direction = getDisplayDirection(parent);
368
+ const rect = element.getBoundingClientRect();
369
+ const siblings = Array.from(parent.children).filter((child) => isValidHtmlElement(child) && child !== element);
370
+ // Sort siblings based on their position
371
+ return {
372
+ before: siblings.filter((sibling) => {
373
+ const sibRect = sibling.getBoundingClientRect();
374
+ return direction === "row"
375
+ ? sibRect.left < rect.left // For row direction, compare X position
376
+ : sibRect.top < rect.top; // For column direction, compare Y position
377
+ }),
378
+ after: siblings.filter((sibling) => {
379
+ const sibRect = sibling.getBoundingClientRect();
380
+ return direction === "row"
381
+ ? sibRect.left >= rect.left // For row direction, compare X position
382
+ : sibRect.top >= rect.top; // For column direction, compare Y position
383
+ }),
384
+ };
385
+ }
386
+ // Find the closest draggable element (with data-source attribute)
387
+ function findDraggableElement(el) {
388
+ // Check if current element has data-source
389
+ if (el.hasAttribute("data-source")) {
390
+ return el;
391
+ }
392
+ // Find closest parent with data-source
393
+ let current = el;
394
+ while (current && current !== document.body) {
395
+ if (current.hasAttribute("data-source")) {
396
+ return current;
397
+ }
398
+ current = current.parentElement;
399
+ }
400
+ return null;
401
+ }
402
+ // Hook implementation
403
+ export function ButtonBar({ el, onHighlight, showDragOnly = false, dragButtonClassNames }) {
404
+ // Add duplicate button click handler
405
+ async function onDuplicate(e) {
406
+ e.preventDefault();
407
+ e.stopPropagation();
408
+ // Find the draggable element (element with data-source or closest parent with it)
409
+ const draggableEl = findDraggableElement(el);
410
+ if (draggableEl) {
411
+ // Get the source location from the data-source attribute
412
+ const source = draggableEl.getAttribute("data-source") ||
413
+ draggableEl.getAttribute("data-source-main");
414
+ if (source) {
415
+ const [sourceFile, line] = source.split(":");
416
+ try {
417
+ // Send duplication change to the API
418
+ const response = await fetch("http://localhost:3000/api/chat/canvas/change", {
419
+ method: "POST",
420
+ headers: {
421
+ "Content-Type": "application/json",
422
+ },
423
+ body: JSON.stringify([
424
+ {
425
+ file: sourceFile,
426
+ line: parseInt(line),
427
+ instruction: {
428
+ type: "duplicate_element",
429
+ },
430
+ },
431
+ ]),
432
+ });
433
+ if (!response.ok) {
434
+ throw new Error(`HTTP error! status: ${response.status}`);
435
+ }
436
+ }
437
+ catch (error) {
438
+ console.error("Error duplicating element:", error);
439
+ }
440
+ }
441
+ }
442
+ }
443
+ // Add delete button click handler
444
+ async function onDelete(e) {
445
+ e.preventDefault();
446
+ e.stopPropagation();
447
+ // Find the draggable element (element with data-source or closest parent with it)
448
+ const draggableEl = findDraggableElement(el);
449
+ if (draggableEl) {
450
+ // Get the source location from the data-source attribute
451
+ const source = draggableEl.getAttribute("data-source") ||
452
+ draggableEl.getAttribute("data-source-main");
453
+ if (source) {
454
+ const [sourceFile, line] = source.split(":");
455
+ try {
456
+ // Send deletion change to the API
457
+ const response = await fetch("http://localhost:3000/api/chat/canvas/change", {
458
+ method: "POST",
459
+ headers: {
460
+ "Content-Type": "application/json",
461
+ },
462
+ body: JSON.stringify([
463
+ {
464
+ file: sourceFile,
465
+ line: parseInt(line),
466
+ instruction: {
467
+ type: "delete_element",
468
+ },
469
+ },
470
+ ]),
471
+ });
472
+ if (!response.ok) {
473
+ throw new Error(`HTTP error! status: ${response.status}`);
474
+ }
475
+ }
476
+ catch (error) {
477
+ console.error("Error deleting element:", error);
478
+ }
479
+ }
480
+ }
481
+ }
482
+ let startX = 0;
483
+ let startY = 0;
484
+ let isDragging = false;
485
+ let mouseOffsetX = 0;
486
+ let mouseOffsetY = 0;
487
+ function onDrag(e) {
488
+ e.preventDefault();
489
+ e.stopPropagation();
490
+ // Find the draggable element (element with data-source or closest parent with it)
491
+ const draggableEl = findDraggableElement(el);
492
+ // If no draggable element found, do nothing
493
+ if (!draggableEl) {
494
+ console.warn("No draggable element found with data-source attribute");
495
+ return;
496
+ }
497
+ // Ensure element has ID for dragging
498
+ getOrAssignDomId(draggableEl);
499
+ // Store the initial mouse position
500
+ startX = e.clientX;
501
+ startY = e.clientY;
502
+ // Calculate mouse offset relative to the element for more accurate dragging
503
+ const rect = draggableEl.getBoundingClientRect();
504
+ mouseOffsetX = startX - rect.left;
505
+ mouseOffsetY = startY - rect.top;
506
+ // Store the mouse offset on the element for later use
507
+ // Store the mouse offset on the element for later use
508
+ draggableEl.dataset["picassoDragMouseOffset"] = JSON.stringify({
509
+ x: mouseOffsetX,
510
+ y: mouseOffsetY,
511
+ });
512
+ isDragging = true;
513
+ // Start the drag operation
514
+ startDrag(draggableEl.id);
515
+ const handleMove = (moveEvent) => {
516
+ if (!isDragging)
517
+ return;
518
+ const currentX = moveEvent.clientX;
519
+ const currentY = moveEvent.clientY;
520
+ // Pass the current mouse coordinates for positioning
521
+ drag(draggableEl.id, currentX, currentY);
522
+ };
523
+ const handleUp = async () => {
524
+ if (!isDragging)
525
+ return;
526
+ isDragging = false;
527
+ // Reset element label position to "absolute" to prepare for recalculation
528
+ const elementLabel = document.querySelector('.element-label');
529
+ if (elementLabel) {
530
+ elementLabel.style.position = "absolute";
531
+ }
532
+ const result = endDrag(draggableEl.id);
533
+ if (result && result.parent && result.child && result.newIndex !== -1) {
534
+ const parentEl = elementFromDomId(result.parent.id);
535
+ const childEl = elementFromDomId(result.child.id);
536
+ if (parentEl && childEl) {
537
+ const children = Array.from(parentEl.children);
538
+ const currentIndex = children.indexOf(childEl);
539
+ // Only move if needed
540
+ if (currentIndex !== result.newIndex) {
541
+ console.log("Moving element from index", currentIndex, "to", result.newIndex);
542
+ // Get all children without the element we're moving
543
+ const filteredChildren = Array.from(parentEl.children).filter((child) => child !== childEl);
544
+ // If the target index is at the end, we simply append
545
+ if (result.newIndex >= filteredChildren.length) {
546
+ console.log("Appending element to the end");
547
+ parentEl.appendChild(childEl);
548
+ }
549
+ else {
550
+ // Otherwise, we need to insert before the element at the target index
551
+ // in the filtered list (which doesn't include the element we're moving)
552
+ const targetNode = filteredChildren[result.newIndex];
553
+ console.log("Inserting element before", targetNode.tagName);
554
+ parentEl.insertBefore(childEl, targetNode);
555
+ }
556
+ // Make sure the element is correctly positioned and selectable again
557
+ childEl.style.position =
558
+ childEl.style.position === "static"
559
+ ? "relative"
560
+ : childEl.style.position;
561
+ childEl.style.pointerEvents = "";
562
+ const sourceFile = result.sourceFile;
563
+ const fromLine = result.fromLine;
564
+ // Get the target element's data-source to determine the correct toLine
565
+ let toLine = fromLine; // Default fallback
566
+ let targetFile = sourceFile; // Default to the same file for intra-file movement
567
+ // Get the actual element at the new position
568
+ const filteredChildren = Array.from(parentEl.children).filter((child) => child !== childEl);
569
+ if (result.newIndex < filteredChildren.length) {
570
+ // Get the element we're inserting before
571
+ const targetElement = filteredChildren[result.newIndex];
572
+ const targetSource = targetElement.getAttribute("data-source");
573
+ if (targetSource) {
574
+ const [targetSourceFile, targetLineStr] = targetSource.split(":");
575
+ targetFile = targetSourceFile; // Set the target file from the element we're inserting before
576
+ toLine = parseInt(targetLineStr, 10);
577
+ }
578
+ }
579
+ else if (filteredChildren.length > 0) {
580
+ // If we're appending at the end, get the last element's line + 1
581
+ const lastElement = filteredChildren[filteredChildren.length - 1];
582
+ const lastSource = lastElement.getAttribute("data-source");
583
+ if (lastSource) {
584
+ const [lastSourceFile, lastLineStr] = lastSource.split(":");
585
+ targetFile = lastSourceFile; // Set the target file from the last element
586
+ toLine = parseInt(lastLineStr, 10) + 1;
587
+ }
588
+ }
589
+ else {
590
+ // If there are no other children, try to get file info from the parent
591
+ const parentSource = parentEl.getAttribute("data-source");
592
+ if (parentSource) {
593
+ const [parentSourceFile] = parentSource.split(":");
594
+ targetFile = parentSourceFile; // Use the parent's file
595
+ toLine = 1; // Default to line 1 if we can't determine
596
+ }
597
+ }
598
+ // Check if this is a cross-file move
599
+ const isCrossFileMove = targetFile !== sourceFile;
600
+ // Create and add a component move change
601
+ const moveChange = createComponentMoveChange(result.child.type, sourceFile, fromLine, toLine, result.parent.type, result.parent.id, isCrossFileMove ? targetFile : undefined);
602
+ // Add the change
603
+ addComponentMoveChange(moveChange);
604
+ // Apply the change immediately instead of waiting for save button
605
+ try {
606
+ // Get all move changes
607
+ const moveChanges = getComponentMoveChanges();
608
+ if (moveChanges.length > 0) {
609
+ // Show the loader before applying changes
610
+ if (showDragLoader) {
611
+ showDragLoader("Applying change...");
612
+ }
613
+ // Send the changes to the API
614
+ const response = await fetch("http://localhost:3000/api/chat/canvas/change", {
615
+ method: "POST",
616
+ headers: {
617
+ "Content-Type": "application/json",
618
+ },
619
+ body: JSON.stringify(moveChanges),
620
+ });
621
+ if (!response.ok) {
622
+ console.error("Error applying drag changes:", response.status, response.statusText);
623
+ // Hide loader on error
624
+ if (hideDragLoader) {
625
+ hideDragLoader();
626
+ }
627
+ throw new Error(`HTTP error! status: ${response.status}`);
628
+ }
629
+ await response.json();
630
+ // Clear the move changes since they've been applied
631
+ clearComponentMoveChanges();
632
+ // Note: Don't hide the loader here
633
+ // The HMR detection will handle hiding the loader and reloading the page
634
+ }
635
+ }
636
+ catch (error) {
637
+ console.error("Error applying drag changes:", error);
638
+ // Hide loader on error
639
+ if (hideDragLoader) {
640
+ hideDragLoader();
641
+ }
642
+ }
643
+ // Log the move
644
+ console.log(`Component ${result.child.type} moved ${isCrossFileMove ? `from ${sourceFile} to ${targetFile}` : `in ${sourceFile}`} from line ${fromLine} to line ${toLine}`);
645
+ // Re-highlight the element to restore selection UI
646
+ if (onHighlight) {
647
+ // Slight delay to ensure DOM is updated
648
+ setTimeout(() => {
649
+ onHighlight(childEl);
650
+ // Explicitly update the element label position
651
+ const elementLabel = document.querySelector('.element-label');
652
+ if (elementLabel) {
653
+ const rect = childEl.getBoundingClientRect();
654
+ elementLabel.style.position = "absolute";
655
+ elementLabel.style.left = `${window.scrollX + rect.left}px`;
656
+ elementLabel.style.top = `${window.scrollY + rect.top - 20}px`;
657
+ elementLabel.style.zIndex = "";
658
+ }
659
+ }, 10);
660
+ }
661
+ }
662
+ }
663
+ }
664
+ // Clean up the stored data
665
+ delete draggableEl.dataset["picassoDragMouseOffset"];
666
+ document.removeEventListener("mousemove", handleMove);
667
+ document.removeEventListener("mouseup", handleUp);
668
+ };
669
+ document.addEventListener("mousemove", handleMove);
670
+ document.addEventListener("mouseup", handleUp);
671
+ }
672
+ return (React.createElement(React.Fragment, null,
673
+ React.createElement("button", { className: `drag-button`, onMouseDown: onDrag },
674
+ React.createElement("i", { className: dragButtonClassNames })),
675
+ !showDragOnly && (React.createElement(React.Fragment, null,
676
+ React.createElement("button", { className: "duplicate-button", onClick: onDuplicate }, "Duplicate"),
677
+ React.createElement("button", { className: "delete-button", onClick: onDelete }, "Delete")))));
678
+ }
679
+ // Add function to update visual indicators
680
+ function updateDropTargetVisuals(draggingElement) {
681
+ // Only proceed if the element is bound
682
+ const isBound = draggingElement.getAttribute('data-binding-same-as-rendering-component') === 'true';
683
+ if (!isBound) {
684
+ return;
685
+ }
686
+ // Get the rendering component value of the dragging element
687
+ const draggingRendering = draggingElement.getAttribute('data-picasso-rendering-comp');
688
+ // Get all potential drop targets
689
+ const allDropTargets = findValidDropTargets();
690
+ // First, clear any existing visual indicators
691
+ clearDropTargetVisuals();
692
+ // Only highlight valid drop targets
693
+ allDropTargets.forEach(target => {
694
+ const targetRendering = target.getAttribute('data-picasso-rendering-comp');
695
+ // Only add visual indicator for compatible targets
696
+ if (draggingRendering === targetRendering) {
697
+ target.classList.add(VALID_DROP_TARGET_CLASS);
698
+ }
699
+ });
700
+ }
701
+ // Add function to clean up visuals
702
+ function clearDropTargetVisuals() {
703
+ // Remove visual indicators from all elements
704
+ document.querySelectorAll(`.${VALID_DROP_TARGET_CLASS}, .${INVALID_DROP_TARGET_CLASS}`).forEach(el => {
705
+ el.classList.remove(VALID_DROP_TARGET_CLASS, INVALID_DROP_TARGET_CLASS);
706
+ });
707
+ }
708
+ // Modify startDrag to allow panel elements
709
+ export function startDrag(domId) {
710
+ const el = elementFromDomId(domId);
711
+ if (!el) {
712
+ console.warn(`Start drag element not found: ${domId}`);
713
+ return null;
714
+ }
715
+ /* // Allow panel elements to be dragged without edit mode
716
+ if (!isFromPanel(el)) {
717
+ // Keep existing edit mode check for non-panel elements
718
+ const isEditMode = document.documentElement.hasAttribute('data-picasso-edit');
719
+ if (!isEditMode) {
720
+ console.warn('Not in edit mode');
721
+ return null;
722
+ }
723
+ } */
724
+ const parent = el.parentElement;
725
+ if (!parent) {
726
+ console.warn("Start drag parent not found");
727
+ return null;
728
+ }
729
+ // Store the original parent for reference
730
+ el.setAttribute(EditorAttributes.DATA_PICASSO_ORIGINAL_PARENT, getOrAssignDomId(parent));
731
+ const htmlChildren = Array.from(parent.children).filter(isValidHtmlElement);
732
+ const originalIndex = htmlChildren.indexOf(el);
733
+ prepareElementForDragging(el);
734
+ createStub(el);
735
+ // Store the element's initial position and dimensions for reference
736
+ const rect = el.getBoundingClientRect();
737
+ const pos = {
738
+ left: rect.left + window.scrollX,
739
+ top: rect.top + window.scrollY,
740
+ width: rect.width,
741
+ height: rect.height,
742
+ };
743
+ el.setAttribute(EditorAttributes.DATA_PICASSO_DRAG_START_POSITION, JSON.stringify(pos));
744
+ // Add visual indicators if element is bound
745
+ updateDropTargetVisuals(el);
746
+ return originalIndex;
747
+ }
748
+ // Add panel element handling to drag function
749
+ export function drag(domId, x, y) {
750
+ const el = elementFromDomId(domId);
751
+ if (!el) {
752
+ console.warn("Dragging element not found");
753
+ return;
754
+ }
755
+ // Special handling for panel elements
756
+ /*if (isFromPanel(el)) {
757
+ el.style.position = "fixed";
758
+ el.style.pointerEvents = "none";
759
+ el.style.zIndex = "9999";
760
+ el.style.opacity = "0.8";
761
+ el.style.boxShadow = "0 5px 10px rgba(0,0,0,0.2)";
762
+ el.style.left = `${x}px`;
763
+ el.style.top = `${y}px`;
764
+ moveStub(el, x, y);
765
+ return;
766
+ }*/
767
+ try {
768
+ // Visual styling for dragged element
769
+ const styles = window.getComputedStyle(el);
770
+ // Get the stored mouse offset
771
+ let offsetX = 20, offsetY = 20; // Default offsets
772
+ try {
773
+ const dragData = el.dataset["picassoDragMouseOffset"];
774
+ if (dragData) {
775
+ const mouseOffset = JSON.parse(dragData);
776
+ offsetX = mouseOffset.x || offsetX;
777
+ offsetY = mouseOffset.y || offsetY;
778
+ }
779
+ }
780
+ catch (e) {
781
+ console.error("Error parsing drag data:", e);
782
+ }
783
+ // Position the element precisely at the mouse position with offset
784
+ el.style.left = `${x - offsetX}px`;
785
+ el.style.top = `${y - offsetY}px`;
786
+ el.style.width = styles.width;
787
+ el.style.height = styles.height;
788
+ el.style.position = "fixed";
789
+ el.style.pointerEvents = "none";
790
+ el.style.zIndex = "9999";
791
+ el.style.opacity = "0.8";
792
+ el.style.boxShadow = "0 5px 10px rgba(0,0,0,0.2)";
793
+ // Remove transition to ensure instant response
794
+ el.style.transition = "";
795
+ // Update the element-label position if it exists
796
+ const elementLabel = document.querySelector('.element-label');
797
+ if (elementLabel && el.dataset["selected"] === "true") {
798
+ elementLabel.style.left = `${x - offsetX}px`;
799
+ elementLabel.style.top = `${Math.max(0, y - offsetY - 20)}px`;
800
+ elementLabel.style.position = "fixed";
801
+ elementLabel.style.zIndex = "10000"; // Ensure it's above the dragged element
802
+ }
803
+ // Calculate smoothed positions for stub positioning only
804
+ let smoothX = x;
805
+ let smoothY = y;
806
+ // Apply smoothing only for stub positioning to reduce jitter
807
+ if (lastDragX !== 0 || lastDragY !== 0) {
808
+ smoothX = x * MOVEMENT_SMOOTHING + lastDragX * (1 - MOVEMENT_SMOOTHING);
809
+ smoothY = y * MOVEMENT_SMOOTHING + lastDragY * (1 - MOVEMENT_SMOOTHING);
810
+ }
811
+ // Update last positions
812
+ lastDragX = smoothX;
813
+ lastDragY = smoothY;
814
+ // Try to move the stub - wrap in try/catch to prevent errors from crashing the app
815
+ try {
816
+ moveStub(el, smoothX, smoothY);
817
+ }
818
+ catch (e) {
819
+ console.error("Error moving stub:", e);
820
+ // Clean up and abort drag if there's an error
821
+ removeStub();
822
+ cleanUpElementAfterDragging(el);
823
+ }
824
+ // Update visual indicators if element is bound
825
+ updateDropTargetVisuals(el);
826
+ }
827
+ catch (error) {
828
+ console.error("Error in drag function:", error);
829
+ // Clean up and abort if anything goes wrong
830
+ endAllDrag();
831
+ }
832
+ }
833
+ // Modify endDrag and endAllDrag to clean up visuals
834
+ export function endDrag(domId) {
835
+ // Clear visual indicators
836
+ clearDropTargetVisuals();
837
+ // Reset smoothing variables
838
+ lastDragX = 0;
839
+ lastDragY = 0;
840
+ const el = elementFromDomId(domId);
841
+ if (!el) {
842
+ console.warn("End drag element not found");
843
+ endAllDrag();
844
+ return null;
845
+ }
846
+ // Remove transition before cleanup to prevent visual glitches
847
+ if (el.style.transition) {
848
+ el.style.transition = "";
849
+ }
850
+ // Get the original parent ID
851
+ const originalParentId = el.getAttribute(EditorAttributes.DATA_PICASSO_ORIGINAL_PARENT);
852
+ const originalParent = originalParentId ? elementFromDomId(originalParentId) : null;
853
+ // Get the stub
854
+ const stub = document.getElementById("drag-stub");
855
+ if (!stub) {
856
+ console.warn("Stub not found");
857
+ cleanUpElementAfterDragging(el);
858
+ return null;
859
+ }
860
+ // Get the stub's parent (this could be different from the original parent)
861
+ const stubParent = stub.parentElement;
862
+ if (!stubParent) {
863
+ console.warn("Stub parent not found");
864
+ cleanUpElementAfterDragging(el);
865
+ removeStub();
866
+ return null;
867
+ }
868
+ // Get the stub index in its current parent
869
+ const stubIndex = getCurrentStubIndex(stubParent, el);
870
+ console.log("End drag with stub at index:", stubIndex);
871
+ // Clean up elements after recording the position
872
+ cleanUpElementAfterDragging(el);
873
+ if (stubIndex === -1) {
874
+ console.warn("Stub not found in parent element");
875
+ removeStub();
876
+ return null;
877
+ }
878
+ // Determine if this is a cross-container move
879
+ const isCrossContainerMove = originalParent !== stubParent;
880
+ // Get source file information from data-source attribute
881
+ let sourceFile;
882
+ let fromLine;
883
+ const sourceAttr = el.getAttribute("data-source");
884
+ if (sourceAttr) {
885
+ const [file, lineStr] = sourceAttr.split(":");
886
+ sourceFile = file;
887
+ fromLine = parseInt(lineStr, 10);
888
+ }
889
+ // Create result with appropriate parent information
890
+ const result = {
891
+ newIndex: stubIndex,
892
+ child: getDomElement(el, false),
893
+ parent: getDomElement(stubParent, false),
894
+ sourceFile,
895
+ fromLine
896
+ };
897
+ // Add original parent info for cross-container moves
898
+ if (isCrossContainerMove && originalParent) {
899
+ result.originalParent = getDomElement(originalParent, false);
900
+ }
901
+ // Clean up the stub
902
+ removeStub();
903
+ return result;
904
+ }
905
+ function prepareElementForDragging(el) {
906
+ const saved = el.getAttribute(EditorAttributes.DATA_PICASSO_DRAG_SAVED_STYLE);
907
+ if (saved) {
908
+ return;
909
+ }
910
+ // Store more style properties to ensure complete restoration
911
+ const style = {
912
+ position: el.style.position,
913
+ transform: el.style.transform,
914
+ width: el.style.width,
915
+ height: el.style.height,
916
+ left: el.style.left,
917
+ top: el.style.top,
918
+ zIndex: el.style.zIndex,
919
+ opacity: el.style.opacity,
920
+ pointerEvents: el.style.pointerEvents,
921
+ boxShadow: el.style.boxShadow,
922
+ transition: el.style.transition,
923
+ outline: el.style.outline,
924
+ };
925
+ // Store if the element was selected
926
+ const wasSelected = el.dataset["selected"] === "true";
927
+ el.setAttribute(EditorAttributes.DATA_PICASSO_DRAG_SAVED_STYLE, JSON.stringify(style));
928
+ el.setAttribute(EditorAttributes.DATA_PICASSO_DRAGGING, "true");
929
+ // Preserve the selected state if it was selected
930
+ if (wasSelected) {
931
+ el.dataset["selected"] = "true";
932
+ }
933
+ if (el.getAttribute(EditorAttributes.DATA_PICASSO_DRAG_DIRECTION) !== null) {
934
+ const parent = el.parentElement;
935
+ if (parent) {
936
+ const displayDirection = getDisplayDirection(parent);
937
+ el.setAttribute(EditorAttributes.DATA_PICASSO_DRAG_DIRECTION, displayDirection);
938
+ }
939
+ }
940
+ }
941
+ function cleanUpElementAfterDragging(el) {
942
+ console.log("Cleaning up element after dragging:", el);
943
+ // Make sure to restore the original position type
944
+ const computedStyle = window.getComputedStyle(el);
945
+ // First restore saved style
946
+ restoreElementStyle(el);
947
+ // Remove drag attributes
948
+ removeDragAttributes(el);
949
+ // Remove panel ID if element is from panel
950
+ /*if (isFromPanel(el)) {
951
+ console.log("Element is from panel, removing ID");
952
+ // Store the ID value for the result object
953
+ const panelId = el.id;
954
+ // Remove the ID to generate a new one in the page
955
+ el.removeAttribute('id');
956
+ console.log("Removed panel ID:", panelId);
957
+ }*/
958
+ // Ensure pointerEvents is enabled again
959
+ el.style.pointerEvents = "";
960
+ // Make sure the element is properly positioned
961
+ // If it was static and we made it relative, leave it as relative to maintain highlighting
962
+ if (el.style.position === "fixed") {
963
+ // If we moved to fixed, restore to original or relative
964
+ const originalPos = computedStyle.position === "static" ? "relative" : computedStyle.position;
965
+ el.style.position = originalPos;
966
+ }
967
+ // Reset the element-label position if it exists
968
+ const elementLabel = document.querySelector('.element-label');
969
+ if (elementLabel && el.dataset["selected"] === "true") {
970
+ // Get the new position of the element after it's been positioned
971
+ setTimeout(() => {
972
+ const rect = el.getBoundingClientRect();
973
+ elementLabel.style.position = "absolute";
974
+ elementLabel.style.left = `${window.scrollX + rect.left}px`;
975
+ elementLabel.style.top = `${window.scrollY + rect.top - 20}px`;
976
+ elementLabel.style.zIndex = "";
977
+ }, 0);
978
+ }
979
+ // Ensure ID is still assigned
980
+ getOrAssignDomId(el);
981
+ }
982
+ function removeDragAttributes(el) {
983
+ el.removeAttribute(EditorAttributes.DATA_PICASSO_DRAG_SAVED_STYLE);
984
+ el.removeAttribute(EditorAttributes.DATA_PICASSO_DRAGGING);
985
+ el.removeAttribute(EditorAttributes.DATA_PICASSO_DRAG_DIRECTION);
986
+ el.removeAttribute(EditorAttributes.DATA_PICASSO_DRAG_START_POSITION);
987
+ el.removeAttribute(EditorAttributes.DATA_PICASSO_ORIGINAL_PARENT);
988
+ // Clean up any additional drag-related data attributes
989
+ delete el.dataset["picassoDragMouseOffset"];
990
+ delete el.dataset["picassoCurrentDirection"];
991
+ }
992
+ export function endAllDrag() {
993
+ // Clear visual indicators
994
+ clearDropTargetVisuals();
995
+ // Reset all smoothing and position tracking
996
+ lastDragX = 0;
997
+ lastDragY = 0;
998
+ lastInsertionTarget = null;
999
+ lastUpdateTime = 0;
1000
+ lastStableIndex = -1;
1001
+ stablePositionCount = 0;
1002
+ const draggingElements = document.querySelectorAll(`[${EditorAttributes.DATA_PICASSO_DRAGGING}]`);
1003
+ // Collect elements that need their position updated
1004
+ const elementsToUpdate = [];
1005
+ for (const el of draggingElements) {
1006
+ // Remove transitions before cleanup
1007
+ el.style.transition = "";
1008
+ cleanUpElementAfterDragging(el);
1009
+ // Extra safety - make sure critical styles are reset
1010
+ el.style.position =
1011
+ el.style.position === "fixed"
1012
+ ? "relative"
1013
+ : el.style.position;
1014
+ el.style.pointerEvents = "";
1015
+ el.style.zIndex = "";
1016
+ el.style.top = "";
1017
+ el.style.left = "";
1018
+ // Add to list for updating element label position
1019
+ if (el.dataset['selected'] === "true") {
1020
+ elementsToUpdate.push(el);
1021
+ }
1022
+ }
1023
+ // Reset element label positions
1024
+ setTimeout(() => {
1025
+ // Reset any element-label that might be in fixed position
1026
+ const elementLabel = document.querySelector('.element-label');
1027
+ if (elementLabel && elementsToUpdate.length > 0) {
1028
+ const el = elementsToUpdate[0]; // Use the first selected element
1029
+ const rect = el.getBoundingClientRect();
1030
+ elementLabel.style.position = "absolute";
1031
+ elementLabel.style.left = `${window.scrollX + rect.left}px`;
1032
+ elementLabel.style.top = `${window.scrollY + rect.top - 20}px`;
1033
+ elementLabel.style.zIndex = "";
1034
+ }
1035
+ }, 0);
1036
+ removeStub();
1037
+ }
1038
+ // Find valid drop targets (containers that can accept dragged elements)
1039
+ function findValidDropTargets() {
1040
+ // Get the stub element
1041
+ const stub = document.getElementById("drag-stub");
1042
+ // Only consider elements with a data-source attribute as valid drop targets
1043
+ const potentialTargets = Array.from(document.querySelectorAll("[data-source]"));
1044
+ // Filter out elements that are too small or invalid
1045
+ return potentialTargets.filter((el) => {
1046
+ const element = el;
1047
+ // Explicitly exclude the stub from valid drop targets
1048
+ if (stub && element === stub) {
1049
+ return false;
1050
+ }
1051
+ // Exclude any element inside or related to button bar or element controls
1052
+ if (element.classList.contains("drag-button") ||
1053
+ element.classList.contains("duplicate-button") ||
1054
+ element.classList.contains("delete-button") ||
1055
+ element.closest(".element-controls") !== null ||
1056
+ element.classList.contains("ButtonBar") ||
1057
+ element.tagName.toLowerCase() === "buttonbar" ||
1058
+ // Check if the element is a direct parent of control buttons
1059
+ Array.from(element.children).some(child => child.classList?.contains("drag-button") ||
1060
+ child.classList?.contains("duplicate-button") ||
1061
+ child.classList?.contains("delete-button"))) {
1062
+ return false;
1063
+ }
1064
+ // Check if the element is a button and print its children types
1065
+ if (element.tagName.toLowerCase() === "button") {
1066
+ console.log("Button children types:");
1067
+ Array.from(element.childNodes).forEach((child, index) => {
1068
+ let nodeType = "Unknown";
1069
+ if (child.nodeType === Node.TEXT_NODE) {
1070
+ nodeType = "Text";
1071
+ }
1072
+ else if (child.nodeType === Node.ELEMENT_NODE) {
1073
+ nodeType = `Element (${child.tagName})`;
1074
+ }
1075
+ else if (child.nodeType === Node.COMMENT_NODE) {
1076
+ nodeType = "Comment";
1077
+ }
1078
+ console.log(`Child ${index}: ${nodeType}`);
1079
+ });
1080
+ }
1081
+ // Check if the element is already a parent with at least one non-text child
1082
+ const hasNonTextChild = Array.from(element.children).some((child) => isValidHtmlElement(child) && child.nodeType === Node.ELEMENT_NODE);
1083
+ const rect = element.getBoundingClientRect();
1084
+ // Ensure it's a reasonable size (not too small) and has at least one non-text child
1085
+ return (rect.width > 10 &&
1086
+ rect.height > 10 &&
1087
+ isValidHtmlElement(element) &&
1088
+ hasNonTextChild);
1089
+ });
1090
+ }
1091
+ // Check if an element is a child of another element
1092
+ function isChildOf(child, parent) {
1093
+ let node = child.parentElement;
1094
+ while (node) {
1095
+ if (node === parent)
1096
+ return true;
1097
+ node = node.parentElement;
1098
+ }
1099
+ return false;
1100
+ }
1101
+ // Helper function to check binding compatibility
1102
+ function isBindingCompatible(draggingElement, dropTarget) {
1103
+ // Check if element is bound to its rendering component
1104
+ const isBound = draggingElement.getAttribute('data-binding-same-as-rendering-component') === 'true';
1105
+ if (!isBound) {
1106
+ return true; // If not bound, can be dropped anywhere
1107
+ }
1108
+ // Get rendering component values
1109
+ const draggingRendering = draggingElement.getAttribute('data-picasso-rendering-comp');
1110
+ const targetRendering = dropTarget.getAttribute('data-picasso-rendering-comp');
1111
+ // If bound, only allow dropping into targets with matching rendering component
1112
+ return draggingRendering === targetRendering;
1113
+ }
1114
+ // Get element at point, checking for valid drop targets
1115
+ function getDropTargetAt(x, y, draggingElement) {
1116
+ // Get all elements at the given point
1117
+ const elements = document.elementsFromPoint(x, y);
1118
+ // Get valid drop targets
1119
+ const validDropTargets = findValidDropTargets();
1120
+ // Find the first valid drop target at this point
1121
+ for (const el of elements) {
1122
+ if (isValidHtmlElement(el) && el !== draggingElement && !isChildOf(el, draggingElement)) {
1123
+ const htmlEl = el;
1124
+ // Check if this element is in our valid drop targets list
1125
+ if (validDropTargets.includes(htmlEl)) {
1126
+ // Don't allow dropping into panel elements
1127
+ if (htmlEl.id?.startsWith('panel') || isInPanel(htmlEl)) {
1128
+ console.warn("Can't drop elements into the panel");
1129
+ continue;
1130
+ }
1131
+ // Check binding compatibility
1132
+ if (!isBindingCompatible(draggingElement, htmlEl)) {
1133
+ console.warn("Drop target rejected due to binding constraints");
1134
+ continue;
1135
+ }
1136
+ // Also check if the drop target is a descendant of the dragging element
1137
+ // This prevents the "Failed to execute 'appendChild' on 'Node': The new child element contains the parent" error
1138
+ if (!isChildOf(draggingElement, htmlEl)) {
1139
+ return htmlEl;
1140
+ }
1141
+ else {
1142
+ console.warn("Prevented dropping into descendant element to avoid circular reference");
1143
+ }
1144
+ }
1145
+ }
1146
+ }
1147
+ return null;
1148
+ }
1149
+ // Add a helper function to check if an element is inside the panel
1150
+ function isInPanel(el) {
1151
+ // Check if the element itself or any parent has an ID starting with 'panel'
1152
+ let current = el;
1153
+ while (current && current !== document.body) {
1154
+ if (current.id?.startsWith('panel')) {
1155
+ return true;
1156
+ }
1157
+ current = current.parentElement;
1158
+ }
1159
+ return false;
1160
+ }
1161
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG5kLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2Rldi10b29sYmFyL0VkaXRvci9kbmQudHN4Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUNsRSxPQUFPLEtBQUssTUFBTSxPQUFPLENBQUM7QUFFMUIsK0NBQStDO0FBQy9DLElBQUksY0FBYyxHQUF1QyxJQUFJLENBQUM7QUFDOUQsSUFBSSxjQUFjLEdBQXdCLElBQUksQ0FBQztBQUUvQywwQ0FBMEM7QUFDMUMsTUFBTSxVQUFVLGlCQUFpQjtJQUMvQixNQUFNLEVBQUUsY0FBYyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUUsSUFBSSxFQUFFLEdBQUcsYUFBYSxFQUFFLENBQUM7SUFFdkUsK0JBQStCO0lBQy9CLGNBQWMsR0FBRyxJQUFJLENBQUM7SUFDdEIsY0FBYyxHQUFHLElBQUksQ0FBQztBQUN4QixDQUFDO0FBT0QsWUFBWTtBQUNaLElBQUssZ0JBTUo7QUFORCxXQUFLLGdCQUFnQjtJQUNuQixtRUFBK0MsQ0FBQTtJQUMvQyxtRkFBK0QsQ0FBQTtJQUMvRCwrRUFBMkQsQ0FBQTtJQUMzRCx5RkFBcUUsQ0FBQTtJQUNyRSxpRkFBNkQsQ0FBQTtBQUMvRCxDQUFDLEVBTkksZ0JBQWdCLEtBQWhCLGdCQUFnQixRQU1wQjtBQUVELDZDQUE2QztBQUM3QyxNQUFNLHVCQUF1QixHQUFHLDJCQUEyQixDQUFDO0FBQzVELE1BQU0seUJBQXlCLEdBQUcsNkJBQTZCLENBQUM7QUFhaEUsK0NBQStDO0FBQy9DLElBQUkseUJBQXlCLEdBSXZCLEVBQUUsQ0FBQztBQUVULGtEQUFrRDtBQUNsRCxTQUFTLHlCQUF5QixDQUNoQyxTQUFpQixFQUNqQixVQUFrQixFQUNsQixRQUFnQixFQUNoQixNQUFjLEVBQ2QsVUFBa0IsRUFDbEIsUUFBdUIsRUFDdkIsTUFBZSxFQUNmLGtCQUEyQixFQUMzQixnQkFBZ0M7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