@amplifyup/sdk 0.1.12 → 0.1.14
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.
- package/dist/AmplifyRenderer.d.mts +3 -1
- package/dist/AmplifyRenderer.d.ts +3 -1
- package/dist/AmplifyRenderer.js +302 -137
- package/dist/AmplifyRenderer.js.map +1 -1
- package/dist/AmplifyRenderer.mjs +302 -137
- package/dist/AmplifyRenderer.mjs.map +1 -1
- package/dist/index.d.mts +19 -2
- package/dist/index.d.ts +19 -2
- package/dist/index.js +247 -123
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +247 -123
- package/dist/index.mjs.map +1 -1
- package/dist/react.d.mts +8 -2
- package/dist/react.d.ts +8 -2
- package/dist/react.js +324 -161
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +324 -161
- package/dist/react.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -7,7 +7,9 @@ interface AmplifyRendererProps {
|
|
|
7
7
|
* Component renderer function that maps componentId to React component
|
|
8
8
|
* This is site-specific and must be provided by the developer
|
|
9
9
|
*/
|
|
10
|
-
renderComponent: (componentId: string, props: Record<string, any>, slots?: Record<string, ReactNode
|
|
10
|
+
renderComponent: (componentId: string, props: Record<string, any>, slots?: Record<string, ReactNode>, context?: {
|
|
11
|
+
layoutNodeId: string;
|
|
12
|
+
}) => ReactNode;
|
|
11
13
|
/**
|
|
12
14
|
* Optional page config for server-side rendering (SSR/SSG)
|
|
13
15
|
* If provided, the component will use this instead of fetching client-side
|
|
@@ -7,7 +7,9 @@ interface AmplifyRendererProps {
|
|
|
7
7
|
* Component renderer function that maps componentId to React component
|
|
8
8
|
* This is site-specific and must be provided by the developer
|
|
9
9
|
*/
|
|
10
|
-
renderComponent: (componentId: string, props: Record<string, any>, slots?: Record<string, ReactNode
|
|
10
|
+
renderComponent: (componentId: string, props: Record<string, any>, slots?: Record<string, ReactNode>, context?: {
|
|
11
|
+
layoutNodeId: string;
|
|
12
|
+
}) => ReactNode;
|
|
11
13
|
/**
|
|
12
14
|
* Optional page config for server-side rendering (SSR/SSG)
|
|
13
15
|
* If provided, the component will use this instead of fetching client-side
|
package/dist/AmplifyRenderer.js
CHANGED
|
@@ -285,6 +285,32 @@ function resolveAmplifyUpUrls(target) {
|
|
|
285
285
|
};
|
|
286
286
|
}
|
|
287
287
|
|
|
288
|
+
// src/preview.ts
|
|
289
|
+
function isPreviewRequest(searchParams) {
|
|
290
|
+
if (searchParams instanceof URLSearchParams) {
|
|
291
|
+
return searchParams.get("preview") === "true" || searchParams.get("visualEditor") === "true";
|
|
292
|
+
}
|
|
293
|
+
const preview = searchParams.preview;
|
|
294
|
+
const visualEditor = searchParams.visualEditor;
|
|
295
|
+
return preview === "true" || visualEditor === "true";
|
|
296
|
+
}
|
|
297
|
+
function isComposerPreview() {
|
|
298
|
+
if (typeof window === "undefined") return false;
|
|
299
|
+
if (window.__AMPLIFYUP_PREVIEW_MODE__ === true) return true;
|
|
300
|
+
const params = new URLSearchParams(window.location.search);
|
|
301
|
+
if (isPreviewRequest(params)) return true;
|
|
302
|
+
if (window.self !== window.top && document.referrer) {
|
|
303
|
+
try {
|
|
304
|
+
const refUrl = new URL(document.referrer);
|
|
305
|
+
if (refUrl.hostname === "amplifyup.ai" || refUrl.hostname.endsWith(".amplifyup.ai") || refUrl.hostname === "localhost" && refUrl.port === "5001" || refUrl.pathname.includes("/dashboard/composer") || refUrl.pathname.includes("/dashboard/routes/")) {
|
|
306
|
+
return true;
|
|
307
|
+
}
|
|
308
|
+
} catch {
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
313
|
+
|
|
288
314
|
// src/index.ts
|
|
289
315
|
function readPreviewQueryOverrides() {
|
|
290
316
|
if (typeof window === "undefined") return {};
|
|
@@ -326,6 +352,15 @@ var AmplifyUpSDK = class {
|
|
|
326
352
|
this.messageListener = null;
|
|
327
353
|
this.mutationObserver = null;
|
|
328
354
|
this.composerDragHandlers = null;
|
|
355
|
+
/** Last slot highlighted during Composer drag — avoid clear/re-add flicker. */
|
|
356
|
+
this.lastComposerDragSlot = null;
|
|
357
|
+
/** Consecutive miss frames before clearing highlight (anti-jitter). */
|
|
358
|
+
this.composerDragMissFrames = 0;
|
|
359
|
+
/**
|
|
360
|
+
* Parent overlay is driving drag via postMessage. Native iframe dragleave must
|
|
361
|
+
* not clear highlight — overlay takeover fires a spurious document dragleave.
|
|
362
|
+
*/
|
|
363
|
+
this.composerOverlayDragActive = false;
|
|
329
364
|
this.isVisualEditorMode = false;
|
|
330
365
|
this.eventSelectionMode = false;
|
|
331
366
|
this.eventSelectionClickHandler = null;
|
|
@@ -856,6 +891,12 @@ Available Console Commands:
|
|
|
856
891
|
}
|
|
857
892
|
throw new Error(`Failed to fetch page: ${response.statusText}`);
|
|
858
893
|
}
|
|
894
|
+
const contentType = response.headers.get("content-type") || "";
|
|
895
|
+
if (!contentType.includes("application/json")) {
|
|
896
|
+
throw new Error(
|
|
897
|
+
`Layout provider returned non-JSON (${contentType || "unknown"}). Check Composer preview routing.`
|
|
898
|
+
);
|
|
899
|
+
}
|
|
859
900
|
const data = await response.json();
|
|
860
901
|
const pageConfig = data.page;
|
|
861
902
|
if (pageConfig?.eventTracking) {
|
|
@@ -1140,6 +1181,13 @@ Available Console Commands:
|
|
|
1140
1181
|
}
|
|
1141
1182
|
return;
|
|
1142
1183
|
}
|
|
1184
|
+
if (event.data?.type === "COMPOSER_DRAG_START") {
|
|
1185
|
+
this.composerOverlayDragActive = true;
|
|
1186
|
+
if (typeof document !== "undefined") {
|
|
1187
|
+
document.body.classList.add("amplifyup-composer-dragging");
|
|
1188
|
+
}
|
|
1189
|
+
return;
|
|
1190
|
+
}
|
|
1143
1191
|
if (event.data?.type === "COMPOSER_DRAG_AT_POINT") {
|
|
1144
1192
|
const { x, y } = event.data;
|
|
1145
1193
|
if (typeof x === "number" && typeof y === "number") {
|
|
@@ -1155,36 +1203,72 @@ Available Console Commands:
|
|
|
1155
1203
|
return;
|
|
1156
1204
|
}
|
|
1157
1205
|
if (event.data?.type === "COMPOSER_DRAG_END") {
|
|
1206
|
+
this.composerOverlayDragActive = false;
|
|
1158
1207
|
this.clearComposerDragHighlight();
|
|
1159
1208
|
return;
|
|
1160
1209
|
}
|
|
1161
1210
|
if (event.data?.type === "GET_ELEMENT_POSITION") {
|
|
1162
|
-
const { componentId, slotName } = event.data;
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1211
|
+
const { componentId, slotName, nodeId, isPageSlot } = event.data;
|
|
1212
|
+
let element = null;
|
|
1213
|
+
if (isPageSlot || slotName === "main" && !nodeId && !componentId) {
|
|
1214
|
+
element = document.querySelector(
|
|
1215
|
+
'[data-slot-source="page"]'
|
|
1216
|
+
);
|
|
1217
|
+
}
|
|
1218
|
+
if (!element && nodeId && slotName) {
|
|
1219
|
+
element = document.querySelector(
|
|
1220
|
+
`[data-parent-node-id="${nodeId}"][data-slot-id="${slotName}"], [data-parent-node-id="${nodeId}"][data-amplifyup-slot="${slotName}"]`
|
|
1221
|
+
);
|
|
1222
|
+
}
|
|
1223
|
+
if (!element && nodeId && !slotName) {
|
|
1224
|
+
element = document.querySelector(
|
|
1225
|
+
`[data-node-id="${nodeId}"]`
|
|
1226
|
+
);
|
|
1227
|
+
}
|
|
1228
|
+
if (!element && slotName) {
|
|
1229
|
+
element = document.querySelector(
|
|
1230
|
+
`[data-amplifyup-slot="${slotName}"], [data-slot-id="${slotName}"]`
|
|
1231
|
+
);
|
|
1232
|
+
}
|
|
1233
|
+
if (!element && componentId) {
|
|
1234
|
+
element = document.querySelector(
|
|
1235
|
+
`[data-amplifyup-component="${componentId}"], [data-component-id="${componentId}"]`
|
|
1236
|
+
);
|
|
1237
|
+
}
|
|
1238
|
+
console.log("[AmplifyUp SDK] Finding element position:", {
|
|
1239
|
+
componentId,
|
|
1240
|
+
slotName,
|
|
1241
|
+
nodeId,
|
|
1242
|
+
isPageSlot,
|
|
1243
|
+
found: !!element
|
|
1244
|
+
});
|
|
1166
1245
|
if (element) {
|
|
1167
1246
|
const rect = element.getBoundingClientRect();
|
|
1168
1247
|
const position = {
|
|
1169
1248
|
x: rect.left + rect.width / 2,
|
|
1170
|
-
// Center of element
|
|
1171
1249
|
y: rect.top - 50,
|
|
1172
|
-
// Position above element
|
|
1173
1250
|
width: rect.width,
|
|
1174
1251
|
height: rect.height
|
|
1175
1252
|
};
|
|
1176
|
-
|
|
1253
|
+
const bounds = {
|
|
1254
|
+
top: rect.top,
|
|
1255
|
+
left: rect.left,
|
|
1256
|
+
width: rect.width,
|
|
1257
|
+
height: rect.height
|
|
1258
|
+
};
|
|
1177
1259
|
if (window.parent && window.parent !== window) {
|
|
1178
1260
|
window.parent.postMessage({
|
|
1179
1261
|
type: "ELEMENT_POSITION",
|
|
1180
|
-
componentId,
|
|
1181
|
-
slotName,
|
|
1182
|
-
|
|
1262
|
+
componentId: componentId || null,
|
|
1263
|
+
slotName: slotName || null,
|
|
1264
|
+
nodeId: nodeId || null,
|
|
1265
|
+
isPageSlot: !!isPageSlot,
|
|
1266
|
+
position,
|
|
1267
|
+
bounds
|
|
1183
1268
|
}, "*");
|
|
1184
|
-
console.log("[AmplifyUp SDK] Sent ELEMENT_POSITION message");
|
|
1185
1269
|
}
|
|
1186
1270
|
} else {
|
|
1187
|
-
console.warn("[AmplifyUp SDK] Element not found for
|
|
1271
|
+
console.warn("[AmplifyUp SDK] Element not found for position request");
|
|
1188
1272
|
}
|
|
1189
1273
|
return;
|
|
1190
1274
|
}
|
|
@@ -1299,37 +1383,148 @@ Available Console Commands:
|
|
|
1299
1383
|
el.classList.remove("amplifyup-drag-over-slot");
|
|
1300
1384
|
});
|
|
1301
1385
|
document.body.classList.remove("amplifyup-drag-no-drop");
|
|
1386
|
+
document.body.classList.remove("amplifyup-composer-dragging");
|
|
1387
|
+
this.lastComposerDragSlot = null;
|
|
1388
|
+
this.composerDragMissFrames = 0;
|
|
1389
|
+
}
|
|
1390
|
+
/** Re-apply drag-over class only if missing (avoids classList churn / flicker). */
|
|
1391
|
+
ensureDragOverClass(slot) {
|
|
1392
|
+
if (!slot.classList.contains("amplifyup-drag-over-slot")) {
|
|
1393
|
+
slot.classList.add("amplifyup-drag-over-slot");
|
|
1394
|
+
}
|
|
1395
|
+
if (document.body.classList.contains("amplifyup-drag-no-drop")) {
|
|
1396
|
+
document.body.classList.remove("amplifyup-drag-no-drop");
|
|
1397
|
+
}
|
|
1302
1398
|
}
|
|
1303
1399
|
/**
|
|
1304
|
-
*
|
|
1305
|
-
*
|
|
1400
|
+
* Composer drag targets the innermost (most specific) slot under the cursor.
|
|
1401
|
+
* e.g. FullWidthGrid's main wins over a page-level main that wraps it.
|
|
1306
1402
|
*/
|
|
1307
|
-
|
|
1308
|
-
if (typeof document === "undefined") return;
|
|
1403
|
+
resolveSlotAtPoint(x, y) {
|
|
1404
|
+
if (typeof document === "undefined") return null;
|
|
1309
1405
|
const slotSelector = "[data-slot-id], [data-amplifyup-slot]";
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
el.
|
|
1314
|
-
|
|
1406
|
+
const containing = [];
|
|
1407
|
+
document.querySelectorAll(slotSelector).forEach((node) => {
|
|
1408
|
+
const el = node;
|
|
1409
|
+
const r = el.getBoundingClientRect();
|
|
1410
|
+
if (x >= r.left && x <= r.right && y >= r.top && y <= r.bottom) {
|
|
1411
|
+
containing.push(el);
|
|
1412
|
+
}
|
|
1413
|
+
});
|
|
1414
|
+
if (containing.length === 0) return null;
|
|
1415
|
+
const innermost = containing.filter(
|
|
1416
|
+
(el) => !containing.some((other) => other !== el && el.contains(other))
|
|
1417
|
+
);
|
|
1418
|
+
if (innermost.length === 1) return innermost[0];
|
|
1419
|
+
let best = innermost[0];
|
|
1420
|
+
let bestArea = Infinity;
|
|
1421
|
+
for (const el of innermost) {
|
|
1422
|
+
const r = el.getBoundingClientRect();
|
|
1423
|
+
const area = Math.max(1, r.width) * Math.max(1, r.height);
|
|
1424
|
+
if (area < bestArea) {
|
|
1425
|
+
bestArea = area;
|
|
1426
|
+
best = el;
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
return best;
|
|
1430
|
+
}
|
|
1431
|
+
/** Parent layout node that owns this slot (null for page-level code main). */
|
|
1432
|
+
parentComponentForSlot(slotEl) {
|
|
1433
|
+
let componentId = slotEl.getAttribute("data-parent-component-id");
|
|
1434
|
+
let nodeId = slotEl.getAttribute("data-parent-node-id");
|
|
1435
|
+
let el = slotEl.parentElement;
|
|
1436
|
+
while (el && (!nodeId || !componentId)) {
|
|
1437
|
+
if (!nodeId && el.hasAttribute("data-node-id")) {
|
|
1438
|
+
nodeId = el.getAttribute("data-node-id");
|
|
1439
|
+
}
|
|
1440
|
+
if (!componentId) {
|
|
1441
|
+
componentId = el.getAttribute("data-amplifyup-component") || el.getAttribute("data-component-id");
|
|
1442
|
+
}
|
|
1443
|
+
if (nodeId) break;
|
|
1444
|
+
el = el.parentElement;
|
|
1445
|
+
}
|
|
1446
|
+
return { componentId, nodeId };
|
|
1447
|
+
}
|
|
1448
|
+
pointInRect(x, y, el, pad = 8) {
|
|
1449
|
+
const r = el.getBoundingClientRect();
|
|
1450
|
+
return x >= r.left - pad && x <= r.right + pad && y >= r.top - pad && y <= r.bottom + pad;
|
|
1451
|
+
}
|
|
1452
|
+
setComposerDragHighlight(slot, x, y) {
|
|
1453
|
+
if (slot && slot === this.lastComposerDragSlot) {
|
|
1454
|
+
this.composerDragMissFrames = 0;
|
|
1455
|
+
this.ensureDragOverClass(slot);
|
|
1456
|
+
return;
|
|
1457
|
+
}
|
|
1458
|
+
if (slot && this.lastComposerDragSlot && this.lastComposerDragSlot.contains(slot) && slot !== this.lastComposerDragSlot) {
|
|
1459
|
+
this.composerDragMissFrames = 0;
|
|
1460
|
+
this.lastComposerDragSlot.classList.remove("amplifyup-drag-over-slot");
|
|
1461
|
+
this.lastComposerDragSlot = slot;
|
|
1462
|
+
this.ensureDragOverClass(slot);
|
|
1463
|
+
return;
|
|
1464
|
+
}
|
|
1465
|
+
if (this.lastComposerDragSlot && typeof x === "number" && typeof y === "number" && this.pointInRect(x, y, this.lastComposerDragSlot)) {
|
|
1466
|
+
if (!slot || slot.contains(this.lastComposerDragSlot) || slot === this.lastComposerDragSlot) {
|
|
1467
|
+
this.composerDragMissFrames = 0;
|
|
1468
|
+
this.ensureDragOverClass(this.lastComposerDragSlot);
|
|
1469
|
+
return;
|
|
1470
|
+
}
|
|
1471
|
+
}
|
|
1472
|
+
if (slot) {
|
|
1473
|
+
this.composerDragMissFrames = 0;
|
|
1474
|
+
if (this.lastComposerDragSlot && this.lastComposerDragSlot !== slot) {
|
|
1475
|
+
this.lastComposerDragSlot.classList.remove("amplifyup-drag-over-slot");
|
|
1476
|
+
}
|
|
1477
|
+
this.lastComposerDragSlot = slot;
|
|
1478
|
+
this.ensureDragOverClass(slot);
|
|
1479
|
+
return;
|
|
1480
|
+
}
|
|
1481
|
+
this.composerDragMissFrames += 1;
|
|
1482
|
+
if (this.lastComposerDragSlot && this.composerDragMissFrames < 8) {
|
|
1483
|
+
this.ensureDragOverClass(this.lastComposerDragSlot);
|
|
1484
|
+
return;
|
|
1485
|
+
}
|
|
1486
|
+
if (this.lastComposerDragSlot) {
|
|
1487
|
+
this.lastComposerDragSlot.classList.remove("amplifyup-drag-over-slot");
|
|
1488
|
+
this.lastComposerDragSlot = null;
|
|
1489
|
+
}
|
|
1490
|
+
if (!document.body.classList.contains("amplifyup-drag-no-drop")) {
|
|
1315
1491
|
document.body.classList.add("amplifyup-drag-no-drop");
|
|
1316
1492
|
}
|
|
1317
1493
|
}
|
|
1494
|
+
handleComposerDragAtPoint(x, y) {
|
|
1495
|
+
this.composerOverlayDragActive = true;
|
|
1496
|
+
if (!document.body.classList.contains("amplifyup-composer-dragging")) {
|
|
1497
|
+
document.body.classList.add("amplifyup-composer-dragging");
|
|
1498
|
+
}
|
|
1499
|
+
this.setComposerDragHighlight(this.resolveSlotAtPoint(x, y), x, y);
|
|
1500
|
+
}
|
|
1501
|
+
postDropOnSlot(slotEl) {
|
|
1502
|
+
const win = window;
|
|
1503
|
+
if (!win.parent || win.parent === win) return;
|
|
1504
|
+
const slotName = slotEl.getAttribute("data-amplifyup-slot") || slotEl.getAttribute("data-slot-id");
|
|
1505
|
+
if (!slotName) return;
|
|
1506
|
+
const { componentId, nodeId } = this.parentComponentForSlot(slotEl);
|
|
1507
|
+
const isEmpty = slotEl.getAttribute("data-slot-empty") === "true";
|
|
1508
|
+
win.parent.postMessage(
|
|
1509
|
+
{
|
|
1510
|
+
type: "DROP_ON_SLOT",
|
|
1511
|
+
slotName,
|
|
1512
|
+
slotElement: {
|
|
1513
|
+
path: slotEl.getAttribute("data-slot-path"),
|
|
1514
|
+
isEmpty,
|
|
1515
|
+
parentComponentId: componentId,
|
|
1516
|
+
parentNodeId: nodeId
|
|
1517
|
+
}
|
|
1518
|
+
},
|
|
1519
|
+
"*"
|
|
1520
|
+
);
|
|
1521
|
+
}
|
|
1318
1522
|
handleComposerDropAtPoint(x, y) {
|
|
1319
1523
|
if (typeof document === "undefined") return;
|
|
1320
|
-
const
|
|
1321
|
-
const slotSelector = "[data-slot-id], [data-amplifyup-slot]";
|
|
1524
|
+
const htmlEl = this.resolveSlotAtPoint(x, y);
|
|
1322
1525
|
this.clearComposerDragHighlight();
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
const slotName = htmlEl.getAttribute("data-amplifyup-slot") || htmlEl.getAttribute("data-slot-id");
|
|
1326
|
-
if (!slotName) return;
|
|
1327
|
-
const isEmpty = htmlEl.getAttribute("data-slot-empty") === "true";
|
|
1328
|
-
win.parent.postMessage({
|
|
1329
|
-
type: "DROP_ON_SLOT",
|
|
1330
|
-
slotName,
|
|
1331
|
-
slotElement: { path: htmlEl.getAttribute("data-slot-path"), isEmpty }
|
|
1332
|
-
}, "*");
|
|
1526
|
+
if (!htmlEl) return;
|
|
1527
|
+
this.postDropOnSlot(htmlEl);
|
|
1333
1528
|
}
|
|
1334
1529
|
/**
|
|
1335
1530
|
* Enable component highlighting
|
|
@@ -1357,35 +1552,25 @@ Available Console Commands:
|
|
|
1357
1552
|
this.teardownComposerDragDrop();
|
|
1358
1553
|
const slotSelector = "[data-slot-id], [data-amplifyup-slot]";
|
|
1359
1554
|
const clearDragOverState = () => {
|
|
1360
|
-
|
|
1361
|
-
el.classList.remove("amplifyup-drag-over-slot");
|
|
1362
|
-
});
|
|
1363
|
-
document.body.classList.remove("amplifyup-drag-no-drop");
|
|
1555
|
+
this.clearComposerDragHighlight();
|
|
1364
1556
|
};
|
|
1365
1557
|
const dragenter = (e) => {
|
|
1366
1558
|
e.preventDefault();
|
|
1367
|
-
if (e.dataTransfer?.types?.length) {
|
|
1368
|
-
document.body.classList.add("amplifyup-drag-no-drop");
|
|
1369
|
-
}
|
|
1370
1559
|
};
|
|
1371
1560
|
const dragover = (e) => {
|
|
1372
1561
|
e.preventDefault();
|
|
1373
|
-
|
|
1374
|
-
|
|
1562
|
+
if (this.composerOverlayDragActive) {
|
|
1563
|
+
if (e.dataTransfer) e.dataTransfer.dropEffect = "copy";
|
|
1564
|
+
return;
|
|
1565
|
+
}
|
|
1566
|
+
const slot = this.resolveSlotAtPoint(e.clientX, e.clientY);
|
|
1375
1567
|
if (e.dataTransfer) {
|
|
1376
1568
|
e.dataTransfer.dropEffect = slot ? "copy" : "none";
|
|
1377
1569
|
}
|
|
1378
|
-
|
|
1379
|
-
el.classList.remove("amplifyup-drag-over-slot");
|
|
1380
|
-
});
|
|
1381
|
-
if (slot) {
|
|
1382
|
-
slot.classList.add("amplifyup-drag-over-slot");
|
|
1383
|
-
document.body.classList.remove("amplifyup-drag-no-drop");
|
|
1384
|
-
} else {
|
|
1385
|
-
document.body.classList.add("amplifyup-drag-no-drop");
|
|
1386
|
-
}
|
|
1570
|
+
this.setComposerDragHighlight(slot, e.clientX, e.clientY);
|
|
1387
1571
|
};
|
|
1388
1572
|
const dragleave = (e) => {
|
|
1573
|
+
if (this.composerOverlayDragActive) return;
|
|
1389
1574
|
const related = e.relatedTarget;
|
|
1390
1575
|
if (!related || !document.body.contains(related)) {
|
|
1391
1576
|
clearDragOverState();
|
|
@@ -1393,20 +1578,10 @@ Available Console Commands:
|
|
|
1393
1578
|
};
|
|
1394
1579
|
const drop = (e) => {
|
|
1395
1580
|
e.preventDefault();
|
|
1396
|
-
const
|
|
1397
|
-
const slot = target?.closest?.(slotSelector);
|
|
1581
|
+
const slot = this.resolveSlotAtPoint(e.clientX, e.clientY);
|
|
1398
1582
|
clearDragOverState();
|
|
1399
1583
|
if (!slot || !this.isVisualEditorMode) return;
|
|
1400
|
-
|
|
1401
|
-
const isEmpty = slot.getAttribute("data-slot-empty") === "true";
|
|
1402
|
-
const win = window;
|
|
1403
|
-
if (slotName && win.parent && win.parent !== win) {
|
|
1404
|
-
win.parent.postMessage({
|
|
1405
|
-
type: "DROP_ON_SLOT",
|
|
1406
|
-
slotName,
|
|
1407
|
-
slotElement: { path: slot.getAttribute("data-slot-path"), isEmpty }
|
|
1408
|
-
}, "*");
|
|
1409
|
-
}
|
|
1584
|
+
this.postDropOnSlot(slot);
|
|
1410
1585
|
};
|
|
1411
1586
|
const mouseover = (e) => {
|
|
1412
1587
|
if (!this.showZonesEnabled) return;
|
|
@@ -1445,7 +1620,11 @@ Available Console Commands:
|
|
|
1445
1620
|
document.removeEventListener("mouseover", h.mouseover, true);
|
|
1446
1621
|
document.removeEventListener("mouseout", h.mouseout, true);
|
|
1447
1622
|
this.composerDragHandlers = null;
|
|
1623
|
+
this.composerOverlayDragActive = false;
|
|
1624
|
+
this.lastComposerDragSlot = null;
|
|
1625
|
+
this.composerDragMissFrames = 0;
|
|
1448
1626
|
document.body.classList.remove("amplifyup-drag-no-drop");
|
|
1627
|
+
document.body.classList.remove("amplifyup-composer-dragging");
|
|
1449
1628
|
document.querySelectorAll("[data-slot-id].amplifyup-drag-over-slot, [data-amplifyup-slot].amplifyup-drag-over-slot").forEach((el) => {
|
|
1450
1629
|
el.classList.remove("amplifyup-drag-over-slot");
|
|
1451
1630
|
});
|
|
@@ -1486,21 +1665,32 @@ Available Console Commands:
|
|
|
1486
1665
|
'[data-slot-id="main"], [data-amplifyup-slot="main"] {',
|
|
1487
1666
|
" min-height: 50vh !important;",
|
|
1488
1667
|
"}",
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
"
|
|
1493
|
-
"
|
|
1494
|
-
"
|
|
1495
|
-
"
|
|
1496
|
-
"
|
|
1668
|
+
/* Single empty-state hint — Slot React label uses .amplifyup-slot-placeholder */
|
|
1669
|
+
".amplifyup-slot-placeholder {",
|
|
1670
|
+
" display: flex !important;",
|
|
1671
|
+
" align-items: center !important;",
|
|
1672
|
+
" justify-content: center !important;",
|
|
1673
|
+
" min-height: inherit !important;",
|
|
1674
|
+
" color: rgba(34, 197, 94, 0.75) !important;",
|
|
1675
|
+
" font-size: 14px !important;",
|
|
1676
|
+
" font-weight: 500 !important;",
|
|
1497
1677
|
" pointer-events: none !important;",
|
|
1498
|
-
"
|
|
1678
|
+
" text-align: center !important;",
|
|
1499
1679
|
"}",
|
|
1500
1680
|
"[data-slot-id].amplifyup-slot-hover, [data-amplifyup-slot].amplifyup-slot-hover {",
|
|
1501
1681
|
" outline-color: rgba(34, 197, 94, 1) !important;",
|
|
1502
1682
|
" background: rgba(34, 197, 94, 0.06) !important;",
|
|
1503
1683
|
"}",
|
|
1684
|
+
/* During any Composer drag, hide idle slot labels so they don't flash
|
|
1685
|
+
when the active drag-over class briefly changes */
|
|
1686
|
+
"body.amplifyup-composer-dragging .amplifyup-slot-placeholder {",
|
|
1687
|
+
" visibility: hidden !important;",
|
|
1688
|
+
" opacity: 0 !important;",
|
|
1689
|
+
"}",
|
|
1690
|
+
"body.amplifyup-composer-dragging [data-slot-id]::before,",
|
|
1691
|
+
"body.amplifyup-composer-dragging [data-amplifyup-slot]::before {",
|
|
1692
|
+
" content: none !important;",
|
|
1693
|
+
"}",
|
|
1504
1694
|
"[data-slot-id].amplifyup-drag-over-slot, [data-amplifyup-slot].amplifyup-drag-over-slot {",
|
|
1505
1695
|
" outline: 2px solid rgba(34, 197, 94, 1) !important;",
|
|
1506
1696
|
" background: rgba(34, 197, 94, 0.18) !important;",
|
|
@@ -1516,7 +1706,7 @@ Available Console Commands:
|
|
|
1516
1706
|
" color: rgb(22, 163, 74) !important;",
|
|
1517
1707
|
" pointer-events: none !important;",
|
|
1518
1708
|
" white-space: nowrap !important;",
|
|
1519
|
-
" z-index:
|
|
1709
|
+
" z-index: 2 !important;",
|
|
1520
1710
|
"}",
|
|
1521
1711
|
"body.amplifyup-drag-no-drop { cursor: no-drop !important; }",
|
|
1522
1712
|
"body.amplifyup-drag-no-drop::before {",
|
|
@@ -1643,18 +1833,23 @@ Available Console Commands:
|
|
|
1643
1833
|
sendSelectionMessage(element, hierarchy, isEmpty) {
|
|
1644
1834
|
if (!this.isVisualEditorMode) return;
|
|
1645
1835
|
const componentId = element.getAttribute("data-amplifyup-component") || element.getAttribute("data-component-id");
|
|
1646
|
-
const slotName = element.getAttribute("data-amplifyup-slot") || element.getAttribute("data-slot-id");
|
|
1836
|
+
const slotName = componentId ? null : element.getAttribute("data-amplifyup-slot") || element.getAttribute("data-slot-id");
|
|
1647
1837
|
const componentName = element.getAttribute("data-component-name");
|
|
1648
1838
|
const hierarchyInfo = hierarchy.map((el, index) => {
|
|
1649
1839
|
const elComponentId = el.getAttribute("data-amplifyup-component") || el.getAttribute("data-component-id");
|
|
1650
1840
|
const elSlotName = el.getAttribute("data-amplifyup-slot") || el.getAttribute("data-slot-id");
|
|
1651
1841
|
const elComponentName = el.getAttribute("data-component-name");
|
|
1842
|
+
const isSlot = !elComponentId && !!elSlotName;
|
|
1843
|
+
const isPageSlot = isSlot && el.getAttribute("data-slot-source") === "page";
|
|
1844
|
+
const nodeId = el.getAttribute("data-node-id") || (isSlot ? el.getAttribute("data-parent-node-id") : null);
|
|
1652
1845
|
return {
|
|
1653
1846
|
index,
|
|
1654
1847
|
componentId: elComponentId,
|
|
1655
|
-
componentName: elComponentName,
|
|
1656
|
-
slotName: elSlotName,
|
|
1657
|
-
isSlot
|
|
1848
|
+
componentName: isPageSlot ? "Page" : elComponentName,
|
|
1849
|
+
slotName: isSlot ? elSlotName : null,
|
|
1850
|
+
isSlot,
|
|
1851
|
+
isPageSlot,
|
|
1852
|
+
nodeId
|
|
1658
1853
|
};
|
|
1659
1854
|
});
|
|
1660
1855
|
const rect = element.getBoundingClientRect ? element.getBoundingClientRect() : null;
|
|
@@ -1691,7 +1886,6 @@ Available Console Commands:
|
|
|
1691
1886
|
return;
|
|
1692
1887
|
}
|
|
1693
1888
|
const doc = document;
|
|
1694
|
-
const win = window;
|
|
1695
1889
|
if (highlightComponents) {
|
|
1696
1890
|
const componentElements = doc.querySelectorAll("[data-amplifyup-component], [data-component-id]");
|
|
1697
1891
|
console.log("[AmplifyUp SDK] Found", componentElements.length, "components to highlight");
|
|
@@ -1752,52 +1946,8 @@ Available Console Commands:
|
|
|
1752
1946
|
e.stopPropagation();
|
|
1753
1947
|
this.sendSelectionMessage(htmlEl, hierarchy, isEmpty);
|
|
1754
1948
|
};
|
|
1755
|
-
const handleDrop = (e) => {
|
|
1756
|
-
e.preventDefault();
|
|
1757
|
-
e.stopPropagation();
|
|
1758
|
-
htmlEl.classList.remove("amplifyup-drag-over-slot");
|
|
1759
|
-
if (!win.parent || win.parent === win) return;
|
|
1760
|
-
win.parent.postMessage({
|
|
1761
|
-
type: "DROP_ON_SLOT",
|
|
1762
|
-
slotName,
|
|
1763
|
-
slotElement: { path: htmlEl.getAttribute("data-slot-path"), isEmpty }
|
|
1764
|
-
}, "*");
|
|
1765
|
-
try {
|
|
1766
|
-
const data = JSON.parse(e.dataTransfer.getData("application/json"));
|
|
1767
|
-
if (data.type === "component") {
|
|
1768
|
-
win.parent.postMessage({
|
|
1769
|
-
type: "COMPONENT_DROPPED",
|
|
1770
|
-
componentId: data.componentId,
|
|
1771
|
-
componentName: data.componentName,
|
|
1772
|
-
slotName,
|
|
1773
|
-
slotElement: { path: htmlEl.getAttribute("data-slot-path"), isEmpty }
|
|
1774
|
-
}, "*");
|
|
1775
|
-
}
|
|
1776
|
-
} catch (_err) {
|
|
1777
|
-
}
|
|
1778
|
-
};
|
|
1779
|
-
const handleDragOver = (e) => {
|
|
1780
|
-
e.preventDefault();
|
|
1781
|
-
e.stopPropagation();
|
|
1782
|
-
e.dataTransfer.dropEffect = "copy";
|
|
1783
|
-
htmlEl.classList.add("amplifyup-drag-over-slot");
|
|
1784
|
-
};
|
|
1785
|
-
const handleDragLeave = (e) => {
|
|
1786
|
-
const related = e.relatedTarget;
|
|
1787
|
-
if (!related || !htmlEl.contains(related)) {
|
|
1788
|
-
htmlEl.classList.remove("amplifyup-drag-over-slot");
|
|
1789
|
-
}
|
|
1790
|
-
};
|
|
1791
1949
|
htmlEl.addEventListener("click", handleClick);
|
|
1792
|
-
htmlEl.
|
|
1793
|
-
htmlEl.addEventListener("dragleave", handleDragLeave);
|
|
1794
|
-
htmlEl.addEventListener("drop", handleDrop);
|
|
1795
|
-
htmlEl._amplifyupSlotHandlers = {
|
|
1796
|
-
handleClick,
|
|
1797
|
-
handleDragOver,
|
|
1798
|
-
handleDragLeave,
|
|
1799
|
-
handleDrop
|
|
1800
|
-
};
|
|
1950
|
+
htmlEl._amplifyupSlotHandlers = { handleClick };
|
|
1801
1951
|
});
|
|
1802
1952
|
}
|
|
1803
1953
|
}
|
|
@@ -1911,7 +2061,9 @@ function AmplifyRenderer({
|
|
|
1911
2061
|
if (!pageConfig) {
|
|
1912
2062
|
return;
|
|
1913
2063
|
}
|
|
1914
|
-
|
|
2064
|
+
const rawTree2 = pageConfig.layoutTree;
|
|
2065
|
+
const normalizedTree = Array.isArray(rawTree2) ? rawTree2 : rawTree2 && typeof rawTree2 === "object" && rawTree2.componentId ? [rawTree2] : [];
|
|
2066
|
+
if (normalizedTree.length === 0) {
|
|
1915
2067
|
if (typeof window !== "undefined" && window.parent && window.parent !== window) {
|
|
1916
2068
|
window.parent.postMessage({
|
|
1917
2069
|
type: "COMPONENT_TREE",
|
|
@@ -1923,6 +2075,7 @@ function AmplifyRenderer({
|
|
|
1923
2075
|
const convertLayoutTreeToComponentTree = (nodes, parentId = null) => {
|
|
1924
2076
|
const result = [];
|
|
1925
2077
|
nodes.forEach((node) => {
|
|
2078
|
+
if (!node) return;
|
|
1926
2079
|
const treeNode = {
|
|
1927
2080
|
id: node.id,
|
|
1928
2081
|
componentId: node.componentId,
|
|
@@ -1933,8 +2086,9 @@ function AmplifyRenderer({
|
|
|
1933
2086
|
};
|
|
1934
2087
|
if (node.slots && node.slots.length > 0) {
|
|
1935
2088
|
node.slots.forEach((slot) => {
|
|
1936
|
-
|
|
1937
|
-
|
|
2089
|
+
const kids = Array.isArray(slot?.children) ? slot.children : [];
|
|
2090
|
+
if (kids.length > 0) {
|
|
2091
|
+
const slotChildren = convertLayoutTreeToComponentTree(kids, node.id);
|
|
1938
2092
|
treeNode.children.push(...slotChildren);
|
|
1939
2093
|
}
|
|
1940
2094
|
});
|
|
@@ -1943,7 +2097,7 @@ function AmplifyRenderer({
|
|
|
1943
2097
|
});
|
|
1944
2098
|
return result;
|
|
1945
2099
|
};
|
|
1946
|
-
const layoutTree2 =
|
|
2100
|
+
const layoutTree2 = normalizedTree;
|
|
1947
2101
|
const componentTree = convertLayoutTreeToComponentTree(layoutTree2);
|
|
1948
2102
|
const describeLayoutTree = (nodes, depth = 0) => {
|
|
1949
2103
|
if (!nodes?.length) return "";
|
|
@@ -2116,18 +2270,21 @@ function AmplifyRenderer({
|
|
|
2116
2270
|
childrenCount: childrenToRender.length
|
|
2117
2271
|
});
|
|
2118
2272
|
} else {
|
|
2119
|
-
childrenToRender = slot.children;
|
|
2273
|
+
childrenToRender = Array.isArray(slot.children) ? slot.children : [];
|
|
2120
2274
|
console.log(`[AmplifyRenderer] Using direct children for slot ${slot.slotId}`, {
|
|
2121
2275
|
childrenCount: childrenToRender.length
|
|
2122
2276
|
});
|
|
2123
2277
|
}
|
|
2278
|
+
const safeChildren = Array.isArray(childrenToRender) ? childrenToRender : [];
|
|
2124
2279
|
slotChildren[slot.slotId] = /* @__PURE__ */ jsxRuntime.jsx(
|
|
2125
2280
|
"div",
|
|
2126
2281
|
{
|
|
2127
2282
|
"data-slot-id": slot.slotId,
|
|
2128
2283
|
"data-amplifyup-slot": slot.slotId,
|
|
2129
2284
|
"data-zone-id": slot.zoneId || void 0,
|
|
2130
|
-
|
|
2285
|
+
"data-parent-node-id": node.id,
|
|
2286
|
+
"data-parent-component-id": node.componentId,
|
|
2287
|
+
children: safeChildren.filter(Boolean).map((child) => renderNode(child))
|
|
2131
2288
|
},
|
|
2132
2289
|
slot.slotId
|
|
2133
2290
|
);
|
|
@@ -2142,17 +2299,25 @@ function AmplifyRenderer({
|
|
|
2142
2299
|
hasSlots: !!slotsToPass,
|
|
2143
2300
|
slotKeys: slotsToPass ? Object.keys(slotsToPass) : []
|
|
2144
2301
|
});
|
|
2145
|
-
return renderComponent(
|
|
2146
|
-
node.
|
|
2147
|
-
|
|
2148
|
-
slotsToPass
|
|
2149
|
-
);
|
|
2302
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-node-id": node.id, "data-amplifyup-node": "", children: renderComponent(node.componentId, node.props || {}, slotsToPass, {
|
|
2303
|
+
layoutNodeId: node.id
|
|
2304
|
+
}) });
|
|
2150
2305
|
};
|
|
2151
|
-
const
|
|
2152
|
-
|
|
2306
|
+
const rawTree = pageConfig.layoutTree;
|
|
2307
|
+
const layoutTree = Array.isArray(rawTree) ? rawTree : rawTree && typeof rawTree === "object" && rawTree.componentId ? [rawTree] : [];
|
|
2308
|
+
if (layoutTree.length === 0) {
|
|
2153
2309
|
return /* @__PURE__ */ jsxRuntime.jsx("main", { children: emptyComponent || /* @__PURE__ */ jsxRuntime.jsx("div", { className: "container mx-auto px-4 py-16", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: "No content configured for this page." }) }) });
|
|
2154
2310
|
}
|
|
2155
|
-
return /* @__PURE__ */ jsxRuntime.jsx("main", { children:
|
|
2311
|
+
return /* @__PURE__ */ jsxRuntime.jsx("main", { children: isComposerPreview() ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2312
|
+
"div",
|
|
2313
|
+
{
|
|
2314
|
+
"data-slot-id": "main",
|
|
2315
|
+
"data-amplifyup-slot": "main",
|
|
2316
|
+
"data-slot-source": "page",
|
|
2317
|
+
"data-slot-empty": layoutTree.length === 0 ? "true" : void 0,
|
|
2318
|
+
children: layoutTree.map((node) => /* @__PURE__ */ jsxRuntime.jsx("div", { children: renderNode(node) }, node.id))
|
|
2319
|
+
}
|
|
2320
|
+
) : layoutTree.map((node) => /* @__PURE__ */ jsxRuntime.jsx("div", { children: renderNode(node) }, node.id)) });
|
|
2156
2321
|
}
|
|
2157
2322
|
|
|
2158
2323
|
exports.AmplifyRenderer = AmplifyRenderer;
|