@base44-preview/vite-plugin 1.0.4-pr.60.4be3ea6 → 1.0.4-pr.61.ce93e3f

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.
@@ -15,6 +15,7 @@ export function setupVisualEditAgent() {
15
15
  let currentHighlightedElements: Element[] = [];
16
16
  let selectedElementId: string | null = null;
17
17
  let selectedElement: Element | null = null;
18
+ let newInlineEditEnabled = false;
18
19
 
19
20
  // Create overlay element
20
21
  const createOverlay = (isSelected = false): HTMLDivElement => {
@@ -126,7 +127,7 @@ export function setupVisualEditAgent() {
126
127
 
127
128
  const TEXT_TAGS = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'span', 'a', 'label'];
128
129
 
129
- const notifyElementSelected = (element: Element, clickX?: number, clickY?: number) => {
130
+ const notifyElementSelected = (element: Element) => {
130
131
  const htmlElement = element as HTMLElement;
131
132
  const rect = element.getBoundingClientRect();
132
133
  const svgElement = element as SVGElement;
@@ -142,38 +143,19 @@ export function setupVisualEditAgent() {
142
143
  const itemFieldEl = htmlElement.closest("[data-collection-item-field]") as HTMLElement | null;
143
144
  const itemIdEl = htmlElement.closest("[data-collection-item-id]") as HTMLElement | null;
144
145
 
145
- // Detect if the user clicked on a wrapper that contains an <img>.
146
- // When an <img> is found underneath, report tagName 'IMG' and pass the
147
- // img's own data-source-location so update-attribute targets it directly.
148
- let reportedTagName = element.tagName;
149
- let imgSourceLocation: string | undefined;
150
- let attributes = collectAllowedAttributes(element, ALLOWED_ATTRIBUTES);
151
-
152
- if (element.tagName === 'IMG') {
153
- // Direct <img> click — attributes already has src from collectAllowedAttributes
154
- } else if (clickX != null && clickY != null) {
155
- // Wrapper click — check if an <img> is at the click point
156
- const pointerStyle = document.getElementById('freeze-pointer-events') as HTMLStyleElement | null;
157
- if (pointerStyle) (pointerStyle as any).disabled = true;
158
- const elementsAtPoint = document.elementsFromPoint(clickX, clickY);
159
- if (pointerStyle) (pointerStyle as any).disabled = false;
160
-
161
- const imgEl = elementsAtPoint.find(el => el.tagName === 'IMG') as HTMLImageElement | undefined;
162
- if (imgEl) {
163
- reportedTagName = 'IMG';
164
- imgSourceLocation = (imgEl as HTMLElement).dataset?.sourceLocation || undefined;
165
- attributes = { src: imgEl.src || '' };
166
- }
167
- }
146
+ const visualSelectorId = getElementSelectorId(element);
147
+ const siblings = findElementsById(visualSelectorId || null);
148
+ const instanceIndex = newInlineEditEnabled ? siblings.indexOf(element) : 0;
149
+ const siblingCount = newInlineEditEnabled ? siblings.length : 1;
168
150
 
169
151
  window.parent.postMessage({
170
152
  type: "element-selected",
171
- tagName: reportedTagName,
153
+ tagName: element.tagName,
172
154
  classes:
173
155
  (svgElement.className as unknown as SVGAnimatedString)?.baseVal ||
174
156
  element.className ||
175
157
  "",
176
- visualSelectorId: getElementSelectorId(element),
158
+ visualSelectorId,
177
159
  content: isTextElement ? htmlElement.innerText : undefined,
178
160
  dataSourceLocation: htmlElement.dataset.sourceLocation,
179
161
  isDynamicContent: htmlElement.dataset.dynamicContent === "true",
@@ -189,8 +171,7 @@ export function setupVisualEditAgent() {
189
171
  centerX: rect.left + rect.width / 2,
190
172
  centerY: rect.top + rect.height / 2,
191
173
  },
192
- attributes,
193
- imgSourceLocation,
174
+ attributes: collectAllowedAttributes(element, ALLOWED_ATTRIBUTES),
194
175
  isTextElement,
195
176
  staticArrayName,
196
177
  staticArrayIndex,
@@ -198,17 +179,20 @@ export function setupVisualEditAgent() {
198
179
  collectionId: collectionEl?.dataset?.collectionId || null,
199
180
  collectionItemField: itemFieldEl?.dataset?.collectionItemField || null,
200
181
  collectionItemId: itemIdEl?.dataset?.collectionItemId || null,
182
+ instanceIndex,
183
+ siblingCount,
201
184
  }, "*");
202
185
  };
203
186
 
204
187
  // Select an element: create overlays, update state, notify parent
205
- const selectElement = (element: Element, clickX?: number, clickY?: number): HTMLDivElement | undefined => {
188
+ const selectElement = (element: Element): HTMLDivElement | undefined => {
206
189
  const visualSelectorId = getElementSelectorId(element);
207
190
 
208
191
  clearSelectedOverlays();
209
192
 
210
193
  const elements = findElementsById(visualSelectorId || null);
211
- elements.forEach((el) => {
194
+ const overlayTargets = newInlineEditEnabled ? [element] : elements;
195
+ overlayTargets.forEach((el) => {
212
196
  const overlay = createOverlay(true);
213
197
  document.body.appendChild(overlay);
214
198
  selectedOverlays.push(overlay);
@@ -218,7 +202,7 @@ export function setupVisualEditAgent() {
218
202
  selectedElementId = visualSelectorId || null;
219
203
  selectedElement = element;
220
204
  clearHoverOverlays();
221
- notifyElementSelected(element, clickX, clickY);
205
+ notifyElementSelected(element);
222
206
 
223
207
  return selectedOverlays[0];
224
208
  };
@@ -340,7 +324,7 @@ export function setupVisualEditAgent() {
340
324
  inlineEdit.markElementsSelected(findElementsById(visualSelectorId));
341
325
  }
342
326
 
343
- const selectedOverlay = selectElement(element, e.clientX, e.clientY);
327
+ const selectedOverlay = selectElement(element);
344
328
  layerController.attachToOverlay(selectedOverlay, element);
345
329
  };
346
330
 
@@ -349,10 +333,12 @@ export function setupVisualEditAgent() {
349
333
  clearSelection();
350
334
  };
351
335
 
352
- const updateElementClassesAndReposition = (visualSelectorId: string, classes: string) => {
353
- const elements = findElementsById(visualSelectorId);
354
- if (elements.length === 0) return;
336
+ const updateElementClassesAndReposition = (visualSelectorId: string, classes: string, instanceIndex?: number | null) => {
337
+ const allElements = findElementsById(visualSelectorId);
338
+ if (allElements.length === 0) return;
339
+ if (instanceIndex != null && instanceIndex >= allElements.length) return;
355
340
 
341
+ const elements = instanceIndex != null ? [allElements[instanceIndex]!] : allElements;
356
342
  updateElementClasses(elements, classes);
357
343
 
358
344
  // Use a small delay to allow the browser to recalculate layout before repositioning
@@ -385,11 +371,14 @@ export function setupVisualEditAgent() {
385
371
  const updateElementAttributeAndReposition = (
386
372
  visualSelectorId: string,
387
373
  attribute: string,
388
- value: string
374
+ value: string,
375
+ instanceIndex?: number | null
389
376
  ) => {
390
- const elements = findElementsById(visualSelectorId);
391
- if (elements.length === 0) return;
377
+ const allElements = findElementsById(visualSelectorId);
378
+ if (allElements.length === 0) return;
379
+ if (instanceIndex != null && instanceIndex >= allElements.length) return;
392
380
 
381
+ const elements = instanceIndex != null ? [allElements[instanceIndex]!] : allElements;
393
382
  updateElementAttribute(elements, attribute, value);
394
383
 
395
384
  // Reposition overlays after attribute change (e.g. image src swap can affect layout)
@@ -404,17 +393,24 @@ export function setupVisualEditAgent() {
404
393
  }, REPOSITION_DELAY_MS);
405
394
  };
406
395
 
407
- const updateElementContent = (visualSelectorId: string, content: string, arrIndex?: number) => {
408
- let elements = findElementsById(visualSelectorId);
396
+ const updateElementContent = (visualSelectorId: string, content: string, arrIndex?: number, instanceIndex?: number | null) => {
397
+ const allElements = findElementsById(visualSelectorId);
409
398
 
410
- if (elements.length === 0) {
399
+ if (allElements.length === 0) {
411
400
  return;
412
401
  }
413
402
 
414
- if (arrIndex != null) {
415
- elements = elements.filter(
403
+ if (instanceIndex != null && instanceIndex >= allElements.length) return;
404
+
405
+ let elements: Element[];
406
+ if (instanceIndex != null) {
407
+ elements = [allElements[instanceIndex]!];
408
+ } else if (arrIndex != null) {
409
+ elements = allElements.filter(
416
410
  (el) => (el as HTMLElement).dataset.arrIndex === String(arrIndex)
417
411
  );
412
+ } else {
413
+ elements = allElements;
418
414
  }
419
415
 
420
416
  elements.forEach((element) => {
@@ -518,6 +514,7 @@ export function setupVisualEditAgent() {
518
514
  toggleVisualEditMode(message.data.enabled);
519
515
  if (message.data.specs?.newInlineEditEnabled !== undefined) {
520
516
  inlineEdit.enabled = message.data.specs.newInlineEditEnabled;
517
+ newInlineEditEnabled = message.data.specs.newInlineEditEnabled;
521
518
  }
522
519
  break;
523
520
 
@@ -525,7 +522,8 @@ export function setupVisualEditAgent() {
525
522
  if (message.data && message.data.classes !== undefined) {
526
523
  updateElementClassesAndReposition(
527
524
  message.data.visualSelectorId,
528
- message.data.classes
525
+ message.data.classes,
526
+ message.data.instanceIndex
529
527
  );
530
528
  } else {
531
529
  console.warn(
@@ -545,7 +543,8 @@ export function setupVisualEditAgent() {
545
543
  updateElementAttributeAndReposition(
546
544
  message.data.visualSelectorId,
547
545
  message.data.attribute,
548
- message.data.value
546
+ message.data.value,
547
+ message.data.instanceIndex
549
548
  );
550
549
  } else {
551
550
  console.warn(
@@ -568,7 +567,8 @@ export function setupVisualEditAgent() {
568
567
  updateElementContent(
569
568
  message.data.visualSelectorId,
570
569
  message.data.content,
571
- message.data.arrIndex
570
+ message.data.arrIndex,
571
+ message.data.instanceIndex
572
572
  );
573
573
  } else {
574
574
  console.warn(