@amplifyup/sdk 0.1.61 → 0.1.63
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/README.md +404 -10
- package/dist/AmplifyRenderer-Bwob7ICJ.d.ts +93 -0
- package/dist/AmplifyRenderer-TawbUIKZ.d.mts +93 -0
- package/dist/AmplifyRenderer.d.mts +4 -40
- package/dist/AmplifyRenderer.d.ts +4 -40
- package/dist/AmplifyRenderer.js +327 -30
- package/dist/AmplifyRenderer.js.map +1 -1
- package/dist/AmplifyRenderer.mjs +328 -31
- package/dist/AmplifyRenderer.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +135 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +135 -3
- package/dist/index.mjs.map +1 -1
- package/dist/{query-BqApXxQi.d.ts → query-3AXnQgzO.d.ts} +1 -0
- package/dist/{query-DaJlqU-Z.d.mts → query-DIZjc7st.d.mts} +1 -0
- package/dist/react.d.mts +74 -42
- package/dist/react.d.ts +74 -42
- package/dist/react.js +1613 -1253
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +1690 -1334
- package/dist/react.mjs.map +1 -1
- package/dist/server.d.mts +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +134 -2
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +134 -2
- package/dist/server.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import
|
|
3
|
-
import { marked } from 'marked';
|
|
2
|
+
import React2, { createContext, memo, useState, useEffect, Fragment as Fragment$1, useContext, Component, useMemo, useRef, useSyncExternalStore, useCallback } from 'react';
|
|
4
3
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
4
|
+
import { marked } from 'marked';
|
|
5
5
|
|
|
6
6
|
/* @amplifyup/sdk - https://amplifyup.ai */
|
|
7
7
|
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
@@ -405,6 +405,200 @@ function isComposerPreview() {
|
|
|
405
405
|
return false;
|
|
406
406
|
}
|
|
407
407
|
|
|
408
|
+
// src/field-envelope.ts
|
|
409
|
+
var FIELDS_BRAND = Symbol("amplifyup.fields");
|
|
410
|
+
function isBrandedFields(value) {
|
|
411
|
+
return !!value && typeof value === "object" && FIELDS_BRAND in value;
|
|
412
|
+
}
|
|
413
|
+
function brandFields(bag) {
|
|
414
|
+
if (isBrandedFields(bag)) return bag;
|
|
415
|
+
Object.defineProperty(bag, FIELDS_BRAND, {
|
|
416
|
+
value: true,
|
|
417
|
+
enumerable: false,
|
|
418
|
+
configurable: false
|
|
419
|
+
});
|
|
420
|
+
return bag;
|
|
421
|
+
}
|
|
422
|
+
function isFieldEnvelope(value) {
|
|
423
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
424
|
+
const rec = value;
|
|
425
|
+
return typeof rec.name === "string" && "value" in rec && !("url" in rec);
|
|
426
|
+
}
|
|
427
|
+
function isPortableImageShape(value) {
|
|
428
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
429
|
+
return "url" in value;
|
|
430
|
+
}
|
|
431
|
+
function isEntryRefItem(value) {
|
|
432
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
433
|
+
const rec = value;
|
|
434
|
+
return typeof rec.id === "string" && rec.id.trim().length > 0 || typeof rec._id === "string" && rec._id.trim().length > 0 || typeof rec.docId === "string" && rec.docId.trim().length > 0;
|
|
435
|
+
}
|
|
436
|
+
function isRepeaterArray(value) {
|
|
437
|
+
if (!Array.isArray(value) || value.length === 0) return false;
|
|
438
|
+
const sample = value.find((item) => item != null);
|
|
439
|
+
if (sample === void 0) return false;
|
|
440
|
+
if (typeof sample !== "object" || Array.isArray(sample)) return false;
|
|
441
|
+
if (isPortableImageShape(sample)) return false;
|
|
442
|
+
if (isEntryRefItem(sample)) return false;
|
|
443
|
+
if (sample.$$typeof) return false;
|
|
444
|
+
return true;
|
|
445
|
+
}
|
|
446
|
+
function joinPath(prefix, key) {
|
|
447
|
+
return prefix ? `${prefix}.${key}` : key;
|
|
448
|
+
}
|
|
449
|
+
function emptyValue(raw) {
|
|
450
|
+
if (raw === void 0) return null;
|
|
451
|
+
return raw;
|
|
452
|
+
}
|
|
453
|
+
function toFieldEnvelopes(source, prefix = "") {
|
|
454
|
+
const input = source && typeof source === "object" && !Array.isArray(source) ? source : {};
|
|
455
|
+
if (isBrandedFields(input)) {
|
|
456
|
+
return input;
|
|
457
|
+
}
|
|
458
|
+
const out = {};
|
|
459
|
+
for (const [key, raw] of Object.entries(input)) {
|
|
460
|
+
const path = joinPath(prefix, key);
|
|
461
|
+
if (isFieldEnvelope(raw)) {
|
|
462
|
+
const inner = raw.value;
|
|
463
|
+
if (isRepeaterArray(inner)) {
|
|
464
|
+
out[key] = {
|
|
465
|
+
value: envelopeRepeaterItems(inner, raw.name || path),
|
|
466
|
+
name: raw.name || path
|
|
467
|
+
};
|
|
468
|
+
continue;
|
|
469
|
+
}
|
|
470
|
+
out[key] = { value: raw.value ?? null, name: raw.name || path };
|
|
471
|
+
continue;
|
|
472
|
+
}
|
|
473
|
+
if (isRepeaterArray(raw)) {
|
|
474
|
+
out[key] = { value: envelopeRepeaterItems(raw, path), name: path };
|
|
475
|
+
continue;
|
|
476
|
+
}
|
|
477
|
+
if (raw && typeof raw === "object" && !Array.isArray(raw) && !isPortableImageShape(raw) && !raw.$$typeof) {
|
|
478
|
+
out[key] = toFieldEnvelopes(raw, path);
|
|
479
|
+
continue;
|
|
480
|
+
}
|
|
481
|
+
out[key] = { value: emptyValue(raw), name: path };
|
|
482
|
+
}
|
|
483
|
+
return brandFields(out);
|
|
484
|
+
}
|
|
485
|
+
function envelopeRepeaterItems(items, prefix) {
|
|
486
|
+
return items.map((item, i) => {
|
|
487
|
+
const path = joinPath(prefix, String(i));
|
|
488
|
+
if (isBrandedFields(item)) return item;
|
|
489
|
+
if (item && typeof item === "object" && !Array.isArray(item)) {
|
|
490
|
+
return toFieldEnvelopes(item, path);
|
|
491
|
+
}
|
|
492
|
+
return toFieldEnvelopes({}, path);
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
function attachFieldEnvelopes(props) {
|
|
496
|
+
const raw = props && typeof props === "object" ? { ...props } : {};
|
|
497
|
+
if (isBrandedFields(raw.fields)) return raw;
|
|
498
|
+
const { fields: existing, ...content } = raw;
|
|
499
|
+
const source = existing && typeof existing === "object" && !isFieldEnvelope(existing) ? existing : content;
|
|
500
|
+
return { ...raw, fields: toFieldEnvelopes(source) };
|
|
501
|
+
}
|
|
502
|
+
function walkLayoutNodes(nodes) {
|
|
503
|
+
if (!Array.isArray(nodes)) return;
|
|
504
|
+
for (const node of nodes) {
|
|
505
|
+
if (!node || typeof node !== "object") continue;
|
|
506
|
+
const rec = node;
|
|
507
|
+
rec.props = attachFieldEnvelopes(rec.props);
|
|
508
|
+
for (const slot of rec.slots || []) {
|
|
509
|
+
walkLayoutNodes(slot.children);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
function envelopePageConfig(page) {
|
|
514
|
+
if (!page || typeof page !== "object") return page ?? null;
|
|
515
|
+
const tree = page.layoutTree;
|
|
516
|
+
if (Array.isArray(tree)) walkLayoutNodes(tree);
|
|
517
|
+
return page;
|
|
518
|
+
}
|
|
519
|
+
function collectFieldPatches(props) {
|
|
520
|
+
const out = [];
|
|
521
|
+
const walkRepeater = (items, prefix) => {
|
|
522
|
+
items.forEach((item, i) => {
|
|
523
|
+
const itemPath = joinPath(prefix, String(i));
|
|
524
|
+
if (isBrandedFields(item) || item && typeof item === "object" && !Array.isArray(item) && !isFieldEnvelope(item)) {
|
|
525
|
+
walk(item, itemPath);
|
|
526
|
+
}
|
|
527
|
+
});
|
|
528
|
+
};
|
|
529
|
+
const walk = (obj, prefix) => {
|
|
530
|
+
for (const [key, raw] of Object.entries(obj)) {
|
|
531
|
+
if (key === "fields" && raw && typeof raw === "object" && !Array.isArray(raw) && !isFieldEnvelope(raw)) {
|
|
532
|
+
walk(raw, prefix);
|
|
533
|
+
continue;
|
|
534
|
+
}
|
|
535
|
+
const path = joinPath(prefix, key);
|
|
536
|
+
if (isFieldEnvelope(raw)) {
|
|
537
|
+
if (isRepeaterArray(raw.value)) {
|
|
538
|
+
walkRepeater(raw.value, raw.name || path);
|
|
539
|
+
continue;
|
|
540
|
+
}
|
|
541
|
+
out.push({ name: raw.name || path, value: raw.value });
|
|
542
|
+
continue;
|
|
543
|
+
}
|
|
544
|
+
if (isRepeaterArray(raw)) {
|
|
545
|
+
walkRepeater(raw, path);
|
|
546
|
+
continue;
|
|
547
|
+
}
|
|
548
|
+
if (raw && typeof raw === "object" && !Array.isArray(raw) && !isPortableImageShape(raw) && !raw.$$typeof) {
|
|
549
|
+
walk(raw, path);
|
|
550
|
+
continue;
|
|
551
|
+
}
|
|
552
|
+
out.push({ name: path, value: emptyValue(raw) });
|
|
553
|
+
}
|
|
554
|
+
};
|
|
555
|
+
if (props && typeof props === "object" && !Array.isArray(props)) {
|
|
556
|
+
walk(props, "");
|
|
557
|
+
}
|
|
558
|
+
return out;
|
|
559
|
+
}
|
|
560
|
+
function unwrapFieldsBag(item) {
|
|
561
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) return {};
|
|
562
|
+
const out = {};
|
|
563
|
+
for (const [key, raw] of Object.entries(item)) {
|
|
564
|
+
if (isFieldEnvelope(raw)) {
|
|
565
|
+
out[key] = raw.value;
|
|
566
|
+
continue;
|
|
567
|
+
}
|
|
568
|
+
if (raw && typeof raw === "object" && !Array.isArray(raw) && !isPortableImageShape(raw) && !isEntryRefItem(raw) && !raw.$$typeof) {
|
|
569
|
+
out[key] = unwrapFieldsBag(raw);
|
|
570
|
+
continue;
|
|
571
|
+
}
|
|
572
|
+
out[key] = raw;
|
|
573
|
+
}
|
|
574
|
+
return out;
|
|
575
|
+
}
|
|
576
|
+
function resolveCollectionItems(field, overlay) {
|
|
577
|
+
const name = typeof field?.name === "string" ? field.name : "";
|
|
578
|
+
const raw = overlay !== void 0 ? overlay : field?.value;
|
|
579
|
+
const list = Array.isArray(raw) ? raw : isFieldEnvelope(raw) && Array.isArray(raw.value) ? raw.value : [];
|
|
580
|
+
if (list.length === 0) return [];
|
|
581
|
+
if (isRepeaterArray(list) || list.every((item) => isBrandedFields(item))) {
|
|
582
|
+
return envelopeRepeaterItems(list, name);
|
|
583
|
+
}
|
|
584
|
+
return envelopeRepeaterItems(
|
|
585
|
+
list.map(
|
|
586
|
+
(item) => item && typeof item === "object" && !Array.isArray(item) ? item : {}
|
|
587
|
+
),
|
|
588
|
+
name
|
|
589
|
+
);
|
|
590
|
+
}
|
|
591
|
+
function resolveEditableBinding(field, value, name) {
|
|
592
|
+
if (isFieldEnvelope(field)) {
|
|
593
|
+
return { name: field.name, value: field.value, requiresName: false };
|
|
594
|
+
}
|
|
595
|
+
return {
|
|
596
|
+
name: name || "",
|
|
597
|
+
value,
|
|
598
|
+
requiresName: value !== void 0 && !name
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
|
|
408
602
|
// src/page-context.ts
|
|
409
603
|
function extractRouteParams(pattern, url) {
|
|
410
604
|
const patternParts = String(pattern || "").split("/").filter(Boolean);
|
|
@@ -588,10 +782,34 @@ function hydratePageResourceValue(value, fields) {
|
|
|
588
782
|
if (value.path) return getByDotPath(fields, value.path) ?? null;
|
|
589
783
|
return fields;
|
|
590
784
|
}
|
|
785
|
+
function hydrateFieldsBag(bag, fields) {
|
|
786
|
+
const out = {};
|
|
787
|
+
for (const [key, val] of Object.entries(bag)) {
|
|
788
|
+
if (val && typeof val === "object" && !Array.isArray(val) && typeof val.name === "string" && "value" in val && !("url" in val)) {
|
|
789
|
+
const env = val;
|
|
790
|
+
out[key] = {
|
|
791
|
+
name: env.name,
|
|
792
|
+
value: isPageResourceSentinel(env.value) ? hydratePageResourceValue(env.value, fields) : env.value
|
|
793
|
+
};
|
|
794
|
+
continue;
|
|
795
|
+
}
|
|
796
|
+
if (val && typeof val === "object" && !Array.isArray(val) && !("url" in val)) {
|
|
797
|
+
out[key] = hydrateFieldsBag(val, fields);
|
|
798
|
+
continue;
|
|
799
|
+
}
|
|
800
|
+
out[key] = isPageResourceSentinel(val) ? hydratePageResourceValue(val, fields) : val;
|
|
801
|
+
}
|
|
802
|
+
return out;
|
|
803
|
+
}
|
|
591
804
|
function hydratePageResourceProps(props, fields) {
|
|
592
805
|
const source = props && typeof props === "object" ? props : {};
|
|
593
806
|
const out = { ...source };
|
|
807
|
+
if (out.fields && typeof out.fields === "object" && !Array.isArray(out.fields)) {
|
|
808
|
+
const next = hydrateFieldsBag(out.fields, fields);
|
|
809
|
+
out.fields = isBrandedFields(out.fields) ? brandFields(next) : next;
|
|
810
|
+
}
|
|
594
811
|
for (const [key, val] of Object.entries(out)) {
|
|
812
|
+
if (key === "fields") continue;
|
|
595
813
|
if (isPageResourceSentinel(val)) {
|
|
596
814
|
out[key] = hydratePageResourceValue(val, fields);
|
|
597
815
|
}
|
|
@@ -728,7 +946,25 @@ async function fetchEdgeResolve(options) {
|
|
|
728
946
|
body
|
|
729
947
|
);
|
|
730
948
|
}
|
|
731
|
-
return body;
|
|
949
|
+
return envelopeResolvedPayload(body);
|
|
950
|
+
}
|
|
951
|
+
function envelopeResolvedComponent(node) {
|
|
952
|
+
node.props = attachFieldEnvelopes(node.props);
|
|
953
|
+
if (!node.children) return;
|
|
954
|
+
for (const kids of Object.values(node.children)) {
|
|
955
|
+
for (const child of kids || []) envelopeResolvedComponent(child);
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
function envelopeResolvedPayload(payload) {
|
|
959
|
+
if (payload.tree) {
|
|
960
|
+
for (const node of payload.tree) envelopeResolvedComponent(node);
|
|
961
|
+
}
|
|
962
|
+
if (payload.zones) {
|
|
963
|
+
for (const roots of Object.values(payload.zones)) {
|
|
964
|
+
for (const node of roots || []) envelopeResolvedComponent(node);
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
return payload;
|
|
732
968
|
}
|
|
733
969
|
|
|
734
970
|
// src/edge/mapResolvedToPageConfig.ts
|
|
@@ -788,7 +1024,9 @@ async function fetchContent(options) {
|
|
|
788
1024
|
const preview = options.preview ?? (typeof window !== "undefined" ? isComposerPreview() : false);
|
|
789
1025
|
if (preview) {
|
|
790
1026
|
try {
|
|
791
|
-
const page =
|
|
1027
|
+
const page = envelopePageConfig(
|
|
1028
|
+
await options.fetchOrchestratorPage(options.route, true)
|
|
1029
|
+
);
|
|
792
1030
|
return {
|
|
793
1031
|
pageConfig: page,
|
|
794
1032
|
source: "orchestrator",
|
|
@@ -2059,7 +2297,7 @@ Available Console Commands:
|
|
|
2059
2297
|
this.refreshEventTracking();
|
|
2060
2298
|
}, 800);
|
|
2061
2299
|
}
|
|
2062
|
-
return pageConfig;
|
|
2300
|
+
return envelopePageConfig(pageConfig);
|
|
2063
2301
|
}
|
|
2064
2302
|
/**
|
|
2065
2303
|
* Set up view-level event tracking based on configuration
|
|
@@ -3432,125 +3670,83 @@ function getSDK(adapter) {
|
|
|
3432
3670
|
var trackContentView = (contentId, contentType, properties) => getSDK().trackContentView(contentId, contentType, properties);
|
|
3433
3671
|
var refreshEventTracking = () => getSDK().refreshEventTracking();
|
|
3434
3672
|
getSDK();
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
/* @__PURE__ */ jsx(
|
|
3460
|
-
"path",
|
|
3461
|
-
{
|
|
3462
|
-
d: "M12 8v8M8 12h8",
|
|
3463
|
-
stroke: "currentColor",
|
|
3464
|
-
strokeWidth: "1.75",
|
|
3465
|
-
strokeLinecap: "round"
|
|
3466
|
-
}
|
|
3467
|
-
)
|
|
3468
|
-
]
|
|
3673
|
+
|
|
3674
|
+
// src/composer-store.ts
|
|
3675
|
+
var ComposerFieldStore = class {
|
|
3676
|
+
constructor() {
|
|
3677
|
+
this.values = /* @__PURE__ */ new Map();
|
|
3678
|
+
this.listeners = /* @__PURE__ */ new Map();
|
|
3679
|
+
}
|
|
3680
|
+
get(name) {
|
|
3681
|
+
return this.values.has(name) ? this.values.get(name) : void 0;
|
|
3682
|
+
}
|
|
3683
|
+
set(name, value) {
|
|
3684
|
+
if (!name) return;
|
|
3685
|
+
this.values.set(name, value);
|
|
3686
|
+
const set = this.listeners.get(name);
|
|
3687
|
+
if (!set) return;
|
|
3688
|
+
for (const fn of set) fn();
|
|
3689
|
+
}
|
|
3690
|
+
subscribe(name, fn) {
|
|
3691
|
+
if (!name) return () => {
|
|
3692
|
+
};
|
|
3693
|
+
let set = this.listeners.get(name);
|
|
3694
|
+
if (!set) {
|
|
3695
|
+
set = /* @__PURE__ */ new Set();
|
|
3696
|
+
this.listeners.set(name, set);
|
|
3469
3697
|
}
|
|
3470
|
-
|
|
3698
|
+
set.add(fn);
|
|
3699
|
+
return () => {
|
|
3700
|
+
set.delete(fn);
|
|
3701
|
+
if (set.size === 0) this.listeners.delete(name);
|
|
3702
|
+
};
|
|
3703
|
+
}
|
|
3704
|
+
keys() {
|
|
3705
|
+
return [...this.values.keys()];
|
|
3706
|
+
}
|
|
3707
|
+
delete(name) {
|
|
3708
|
+
if (!name || !this.values.has(name)) return;
|
|
3709
|
+
this.values.delete(name);
|
|
3710
|
+
const set = this.listeners.get(name);
|
|
3711
|
+
if (!set) return;
|
|
3712
|
+
for (const fn of set) fn();
|
|
3713
|
+
}
|
|
3714
|
+
};
|
|
3715
|
+
var ComposerStoreContext = createContext(null);
|
|
3716
|
+
function matchesNode(eventNodeId, layoutNodeId) {
|
|
3717
|
+
if (eventNodeId && layoutNodeId && String(eventNodeId) !== String(layoutNodeId)) {
|
|
3718
|
+
return false;
|
|
3719
|
+
}
|
|
3720
|
+
return true;
|
|
3471
3721
|
}
|
|
3472
|
-
function
|
|
3473
|
-
|
|
3474
|
-
|
|
3722
|
+
function ComposerProvider({
|
|
3723
|
+
layoutNodeId,
|
|
3724
|
+
children
|
|
3475
3725
|
}) {
|
|
3476
|
-
const
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
{
|
|
3480
|
-
className: "amplifyup-slot-placeholder",
|
|
3481
|
-
style: {
|
|
3482
|
-
display: "flex",
|
|
3483
|
-
flexDirection: "column",
|
|
3484
|
-
alignItems: "center",
|
|
3485
|
-
justifyContent: "center",
|
|
3486
|
-
gap: compact ? 8 : 12,
|
|
3487
|
-
minHeight: compact ? 60 : void 0,
|
|
3488
|
-
width: "100%",
|
|
3489
|
-
pointerEvents: "none",
|
|
3490
|
-
textAlign: "center",
|
|
3491
|
-
boxSizing: "border-box",
|
|
3492
|
-
padding: compact ? "12px 8px" : "24px 16px"
|
|
3493
|
-
},
|
|
3494
|
-
children: [
|
|
3495
|
-
/* @__PURE__ */ jsx(
|
|
3496
|
-
"span",
|
|
3497
|
-
{
|
|
3498
|
-
className: "amplifyup-slot-placeholder-icon",
|
|
3499
|
-
style: {
|
|
3500
|
-
display: "inline-flex",
|
|
3501
|
-
alignItems: "center",
|
|
3502
|
-
justifyContent: "center",
|
|
3503
|
-
width: compact ? 36 : 48,
|
|
3504
|
-
height: compact ? 36 : 48,
|
|
3505
|
-
borderRadius: 12,
|
|
3506
|
-
border: "1.5px dashed currentColor",
|
|
3507
|
-
opacity: 0.9
|
|
3508
|
-
},
|
|
3509
|
-
children: /* @__PURE__ */ jsx(AddComponentIcon, { size: iconSize })
|
|
3510
|
-
}
|
|
3511
|
-
),
|
|
3512
|
-
/* @__PURE__ */ jsx(
|
|
3513
|
-
"span",
|
|
3514
|
-
{
|
|
3515
|
-
className: "amplifyup-slot-placeholder-label",
|
|
3516
|
-
style: {
|
|
3517
|
-
fontSize: compact ? 13 : 15,
|
|
3518
|
-
fontWeight: 600,
|
|
3519
|
-
lineHeight: 1.3,
|
|
3520
|
-
letterSpacing: "0.01em"
|
|
3521
|
-
},
|
|
3522
|
-
children: label
|
|
3523
|
-
}
|
|
3524
|
-
)
|
|
3525
|
-
]
|
|
3526
|
-
}
|
|
3527
|
-
);
|
|
3528
|
-
}
|
|
3529
|
-
var ComponentContext = createContext(null);
|
|
3530
|
-
function useLiveComposerProps(layoutNodeId, props) {
|
|
3531
|
-
const [patch, setPatch] = useState(null);
|
|
3726
|
+
const storeRef = useRef(null);
|
|
3727
|
+
if (!storeRef.current) storeRef.current = new ComposerFieldStore();
|
|
3728
|
+
const store = storeRef.current;
|
|
3532
3729
|
useEffect(() => {
|
|
3533
|
-
setPatch(null);
|
|
3534
|
-
const matchesNode = (nodeId) => {
|
|
3535
|
-
if (nodeId && layoutNodeId && String(nodeId) !== String(layoutNodeId)) {
|
|
3536
|
-
return false;
|
|
3537
|
-
}
|
|
3538
|
-
return true;
|
|
3539
|
-
};
|
|
3540
3730
|
const applyField = (fieldName, value, nodeId) => {
|
|
3541
3731
|
if (!fieldName || typeof fieldName !== "string") return;
|
|
3542
|
-
if (!matchesNode(nodeId)) return;
|
|
3543
|
-
|
|
3732
|
+
if (!matchesNode(nodeId, layoutNodeId)) return;
|
|
3733
|
+
store.set(fieldName, value);
|
|
3734
|
+
if (value && typeof value === "object") {
|
|
3735
|
+
for (const patch of collectFieldPatches(
|
|
3736
|
+
toFieldEnvelopes({ [fieldName]: value })
|
|
3737
|
+
)) {
|
|
3738
|
+
store.set(patch.name, patch.value);
|
|
3739
|
+
}
|
|
3740
|
+
}
|
|
3544
3741
|
};
|
|
3545
3742
|
const applyProps = (nextProps, nodeId) => {
|
|
3546
3743
|
if (!nextProps || typeof nextProps !== "object" || Array.isArray(nextProps)) {
|
|
3547
3744
|
return;
|
|
3548
3745
|
}
|
|
3549
|
-
if (!matchesNode(nodeId)) return;
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
}));
|
|
3746
|
+
if (!matchesNode(nodeId, layoutNodeId)) return;
|
|
3747
|
+
for (const patch of collectFieldPatches(nextProps)) {
|
|
3748
|
+
store.set(patch.name, patch.value);
|
|
3749
|
+
}
|
|
3554
3750
|
};
|
|
3555
3751
|
const onPatch = (event) => {
|
|
3556
3752
|
const detail = event.detail || {};
|
|
@@ -3576,1321 +3772,1481 @@ function useLiveComposerProps(layoutNodeId, props) {
|
|
|
3576
3772
|
window.removeEventListener("amplifyup:props-patch", onPropsPatch);
|
|
3577
3773
|
window.removeEventListener("message", onMessage);
|
|
3578
3774
|
};
|
|
3579
|
-
}, [layoutNodeId]);
|
|
3580
|
-
return
|
|
3775
|
+
}, [layoutNodeId, store]);
|
|
3776
|
+
return /* @__PURE__ */ jsx(ComposerStoreContext.Provider, { value: store, children });
|
|
3581
3777
|
}
|
|
3582
|
-
function
|
|
3583
|
-
const
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3778
|
+
function useComposerFieldValue(name, fallback) {
|
|
3779
|
+
const store = useContext(ComposerStoreContext);
|
|
3780
|
+
const subscribe = useCallback(
|
|
3781
|
+
(onStoreChange) => {
|
|
3782
|
+
if (!store || !name) return () => {
|
|
3783
|
+
};
|
|
3784
|
+
return store.subscribe(name, onStoreChange);
|
|
3785
|
+
},
|
|
3786
|
+
[store, name]
|
|
3787
|
+
);
|
|
3788
|
+
const getSnapshot = useCallback(() => {
|
|
3789
|
+
if (!store || !name) return void 0;
|
|
3790
|
+
return store.get(name);
|
|
3791
|
+
}, [store, name]);
|
|
3792
|
+
const overlay = useSyncExternalStore(subscribe, getSnapshot, () => void 0);
|
|
3793
|
+
return overlay !== void 0 ? overlay : fallback;
|
|
3591
3794
|
}
|
|
3592
|
-
function
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3795
|
+
function useComposerStore() {
|
|
3796
|
+
return useContext(ComposerStoreContext);
|
|
3797
|
+
}
|
|
3798
|
+
function MaybeComposerProvider({
|
|
3799
|
+
enabled,
|
|
3596
3800
|
layoutNodeId,
|
|
3597
|
-
|
|
3801
|
+
children
|
|
3598
3802
|
}) {
|
|
3599
|
-
const
|
|
3600
|
-
|
|
3601
|
-
|
|
3803
|
+
const content = useMemo(() => children, [children]);
|
|
3804
|
+
if (!enabled) return /* @__PURE__ */ jsx(Fragment, { children: content });
|
|
3805
|
+
return /* @__PURE__ */ jsx(ComposerProvider, { layoutNodeId, children });
|
|
3806
|
+
}
|
|
3807
|
+
function nodeRenderProps(node) {
|
|
3808
|
+
const settings = node.settings || {};
|
|
3809
|
+
const hydrated = hydratePageResourceProps(
|
|
3810
|
+
node.props || {},
|
|
3811
|
+
getPageResourceFields()
|
|
3602
3812
|
);
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
{
|
|
3606
|
-
value: { slots, props: liveProps, layoutNodeId, componentId },
|
|
3607
|
-
children
|
|
3608
|
-
}
|
|
3813
|
+
const fields = hydrated.fields;
|
|
3814
|
+
const branded = isBrandedFields(fields) ? fields : brandFields(
|
|
3815
|
+
fields && typeof fields === "object" ? fields : {}
|
|
3609
3816
|
);
|
|
3817
|
+
return {
|
|
3818
|
+
...settings,
|
|
3819
|
+
...hydrated,
|
|
3820
|
+
fields: branded
|
|
3821
|
+
};
|
|
3610
3822
|
}
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
const context = useContext(ComponentContext);
|
|
3616
|
-
if (!context) {
|
|
3617
|
-
console.warn(`[AmplifyUp SDK] Slot "${name}" used outside ComponentContextProvider`);
|
|
3618
|
-
return null;
|
|
3823
|
+
var ComponentRenderBoundary = class extends Component {
|
|
3824
|
+
constructor() {
|
|
3825
|
+
super(...arguments);
|
|
3826
|
+
this.state = { error: null };
|
|
3619
3827
|
}
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
(
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
sdkDebugOnce(
|
|
3634
|
-
`slot:${context.layoutNodeId || ""}:${name}`,
|
|
3635
|
-
`[Slot:${name}]`,
|
|
3636
|
-
{
|
|
3637
|
-
isEmpty,
|
|
3638
|
-
isEditorMode,
|
|
3639
|
-
availableSlotKeys: context.slots ? Object.keys(context.slots) : []
|
|
3640
|
-
}
|
|
3641
|
-
);
|
|
3642
|
-
return /* @__PURE__ */ jsx(
|
|
3643
|
-
"div",
|
|
3644
|
-
{
|
|
3645
|
-
className,
|
|
3646
|
-
"data-slot-name": name,
|
|
3647
|
-
"data-slot-id": name,
|
|
3648
|
-
"data-amplifyup-slot": name,
|
|
3649
|
-
"data-slot-empty": isEmpty ? "true" : void 0,
|
|
3650
|
-
"data-parent-node-id": context.layoutNodeId || void 0,
|
|
3651
|
-
"data-parent-component-id": context.componentId || void 0,
|
|
3652
|
-
style: {
|
|
3653
|
-
// Only add minimum height when empty (for drop target visibility)
|
|
3654
|
-
minHeight: isEmpty ? "60px" : void 0,
|
|
3655
|
-
// Only add position relative for overlay positioning in editor mode
|
|
3656
|
-
position: isEditorMode ? "relative" : void 0
|
|
3657
|
-
},
|
|
3658
|
-
children: isEmpty ? isEditorMode ? /* @__PURE__ */ jsx(EmptySlotHint, { compact: true }) : /* @__PURE__ */ jsx(
|
|
3659
|
-
"div",
|
|
3660
|
-
{
|
|
3661
|
-
className: "amplifyup-slot-placeholder",
|
|
3662
|
-
style: {
|
|
3663
|
-
minHeight: "60px",
|
|
3664
|
-
color: "#9ca3af",
|
|
3665
|
-
fontSize: "14px",
|
|
3666
|
-
pointerEvents: "none"
|
|
3667
|
-
},
|
|
3668
|
-
children: `Empty slot: ${name}`
|
|
3669
|
-
}
|
|
3670
|
-
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3671
|
-
isEditorMode && /* @__PURE__ */ jsxs(
|
|
3828
|
+
static getDerivedStateFromError(error) {
|
|
3829
|
+
return { error };
|
|
3830
|
+
}
|
|
3831
|
+
componentDidCatch(error) {
|
|
3832
|
+
console.error(
|
|
3833
|
+
`[AmplifyRenderer] "${this.props.componentId}" (${this.props.nodeId}) threw while rendering:`,
|
|
3834
|
+
error
|
|
3835
|
+
);
|
|
3836
|
+
}
|
|
3837
|
+
render() {
|
|
3838
|
+
if (this.state.error) {
|
|
3839
|
+
if (process.env.NODE_ENV !== "production") {
|
|
3840
|
+
return /* @__PURE__ */ jsxs(
|
|
3672
3841
|
"div",
|
|
3673
3842
|
{
|
|
3674
|
-
|
|
3843
|
+
"data-amplifyup-render-error": "",
|
|
3844
|
+
"data-component-id": this.props.componentId,
|
|
3845
|
+
"data-node-id": this.props.nodeId,
|
|
3675
3846
|
style: {
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3847
|
+
margin: "1rem 0",
|
|
3848
|
+
padding: "0.75rem 1rem",
|
|
3849
|
+
border: "1px solid #fca5a5",
|
|
3850
|
+
borderRadius: "0.5rem",
|
|
3851
|
+
background: "#fef2f2",
|
|
3852
|
+
color: "#991b1b",
|
|
3853
|
+
fontSize: "0.875rem"
|
|
3683
3854
|
},
|
|
3684
3855
|
children: [
|
|
3685
|
-
|
|
3686
|
-
|
|
3856
|
+
'Component "',
|
|
3857
|
+
this.props.componentId,
|
|
3858
|
+
'" failed to render:',
|
|
3859
|
+
" ",
|
|
3860
|
+
this.state.error.message
|
|
3687
3861
|
]
|
|
3688
3862
|
}
|
|
3689
|
-
)
|
|
3690
|
-
|
|
3691
|
-
|
|
3863
|
+
);
|
|
3864
|
+
}
|
|
3865
|
+
return null;
|
|
3692
3866
|
}
|
|
3693
|
-
|
|
3694
|
-
}
|
|
3695
|
-
function isComposerEditMode() {
|
|
3696
|
-
if (typeof window === "undefined") return false;
|
|
3697
|
-
return isComposerPreview() && window.__AMPLIFYUP_EVENT_SELECTION__ !== true;
|
|
3698
|
-
}
|
|
3699
|
-
function isLikelyNonTextFieldName(name) {
|
|
3700
|
-
const n = name.toLowerCase();
|
|
3701
|
-
return n.includes("href") || n.includes("url") || n.includes("src") || n.includes("image") || n.includes("icon") || n.includes("overlay") || n.includes("color");
|
|
3702
|
-
}
|
|
3703
|
-
function isPlainTextValue(value) {
|
|
3704
|
-
return typeof value === "string" || typeof value === "number";
|
|
3705
|
-
}
|
|
3706
|
-
var COMPOSER_EMPTY_FIELD_HINT = "Click here to edit this field";
|
|
3707
|
-
var EMPTY_FIELD_PLACEHOLDERS = /* @__PURE__ */ new Set([
|
|
3708
|
-
COMPOSER_EMPTY_FIELD_HINT,
|
|
3709
|
-
"Click here to enter text",
|
|
3710
|
-
"Sample Title",
|
|
3711
|
-
"Sample Heading",
|
|
3712
|
-
"Sample Subheading"
|
|
3713
|
-
]);
|
|
3714
|
-
function isComposerEmptyText(value) {
|
|
3715
|
-
if (value === void 0 || value === null) return true;
|
|
3716
|
-
if (typeof value !== "string") return false;
|
|
3717
|
-
const trimmed = value.trim();
|
|
3718
|
-
return trimmed === "" || EMPTY_FIELD_PLACEHOLDERS.has(trimmed);
|
|
3719
|
-
}
|
|
3720
|
-
function isReactNodeFallback(fallback) {
|
|
3721
|
-
if (fallback == null || fallback === false) return false;
|
|
3722
|
-
return !isPlainTextValue(fallback);
|
|
3723
|
-
}
|
|
3724
|
-
function classNameIsBlock(className) {
|
|
3725
|
-
return /(?:^|\s)block(?:\s|$)/.test(className || "");
|
|
3726
|
-
}
|
|
3727
|
-
function canInlineEdit(name, value) {
|
|
3728
|
-
if (!name || isLikelyNonTextFieldName(name)) return false;
|
|
3729
|
-
if (value !== void 0 && value !== null && typeof value === "object") {
|
|
3730
|
-
return false;
|
|
3731
|
-
}
|
|
3732
|
-
if (typeof value === "boolean") return false;
|
|
3733
|
-
return true;
|
|
3734
|
-
}
|
|
3735
|
-
function canInlineEditRichText(name, value) {
|
|
3736
|
-
if (!name || isLikelyNonTextFieldName(name)) return false;
|
|
3737
|
-
if (typeof value === "boolean") return false;
|
|
3738
|
-
if (value !== void 0 && value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
3739
|
-
return false;
|
|
3740
|
-
}
|
|
3741
|
-
return true;
|
|
3742
|
-
}
|
|
3743
|
-
function isLikelyImagePropName(name) {
|
|
3744
|
-
const n = name.toLowerCase();
|
|
3745
|
-
return n.includes("image") || n.includes("thumbnail") || n.includes("photo") || n.includes("avatar") || n.includes("poster") || n.includes("logo") || n.endsWith("img") || n.endsWith("_src") || n.endsWith("Src");
|
|
3746
|
-
}
|
|
3747
|
-
function portableImageUrl(value) {
|
|
3748
|
-
if (typeof value === "string") return value.trim();
|
|
3749
|
-
if (value && typeof value === "object" && !Array.isArray(value) && "url" in value) {
|
|
3750
|
-
const url = value.url;
|
|
3751
|
-
if (url == null) return "";
|
|
3752
|
-
if (typeof url === "string") return url.trim();
|
|
3753
|
-
return null;
|
|
3867
|
+
return this.props.children;
|
|
3754
3868
|
}
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
const emptyImageKeys = Object.keys(contextProps).filter((key) => {
|
|
3773
|
-
if (!isLikelyImagePropName(key)) return false;
|
|
3774
|
-
const other = portableImageUrl(contextProps[key]);
|
|
3775
|
-
return other === "" || contextProps[key] == null;
|
|
3776
|
-
});
|
|
3777
|
-
if (emptyImageKeys.length === 1) return emptyImageKeys[0];
|
|
3869
|
+
};
|
|
3870
|
+
function NodeWithFields({
|
|
3871
|
+
nodeId,
|
|
3872
|
+
componentId,
|
|
3873
|
+
props,
|
|
3874
|
+
slots,
|
|
3875
|
+
renderComponent,
|
|
3876
|
+
composerPreview
|
|
3877
|
+
}) {
|
|
3878
|
+
return /* @__PURE__ */ jsx(
|
|
3879
|
+
MaybeComposerProvider,
|
|
3880
|
+
{
|
|
3881
|
+
enabled: !!(composerPreview || isComposerPreview()),
|
|
3882
|
+
layoutNodeId: nodeId,
|
|
3883
|
+
children: renderComponent(componentId, props, slots, {
|
|
3884
|
+
layoutNodeId: nodeId
|
|
3885
|
+
})
|
|
3778
3886
|
}
|
|
3779
|
-
}
|
|
3780
|
-
if (keys.length === 0 || isComposerEmptyText(sourceValue)) return "";
|
|
3781
|
-
return keys[0];
|
|
3782
|
-
}
|
|
3783
|
-
function subscribeComposerEdit(onStoreChange) {
|
|
3784
|
-
if (typeof window === "undefined") return () => {
|
|
3785
|
-
};
|
|
3786
|
-
window.addEventListener("amplifyup:composer-edit", onStoreChange);
|
|
3787
|
-
return () => window.removeEventListener("amplifyup:composer-edit", onStoreChange);
|
|
3788
|
-
}
|
|
3789
|
-
function useComposerEditMode() {
|
|
3790
|
-
return useSyncExternalStore(
|
|
3791
|
-
subscribeComposerEdit,
|
|
3792
|
-
isComposerEditMode,
|
|
3793
|
-
() => false
|
|
3794
3887
|
);
|
|
3795
3888
|
}
|
|
3796
|
-
function
|
|
3797
|
-
|
|
3889
|
+
function AmplifyRendererInner({
|
|
3890
|
+
renderComponent,
|
|
3891
|
+
pageConfig: serverPageConfig,
|
|
3892
|
+
loadingComponent,
|
|
3893
|
+
errorComponent,
|
|
3894
|
+
emptyComponent,
|
|
3895
|
+
composerPreview
|
|
3896
|
+
}) {
|
|
3897
|
+
const clientHook = useAmplifyUp();
|
|
3898
|
+
const pageConfig = serverPageConfig || clientHook.pageConfig || null;
|
|
3899
|
+
const loading = serverPageConfig ? false : clientHook.loading;
|
|
3900
|
+
const error = serverPageConfig ? null : clientHook.error;
|
|
3901
|
+
const contentSource = clientHook.source;
|
|
3902
|
+
const [variantCache, setVariantCache] = useState({});
|
|
3798
3903
|
useEffect(() => {
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
if (detail.fieldName !== name) return;
|
|
3802
|
-
if (detail.layoutNodeId && layoutNodeId && String(detail.layoutNodeId) !== String(layoutNodeId)) {
|
|
3904
|
+
if (typeof window !== "undefined") {
|
|
3905
|
+
if (window.__AMPLIFYUP_PREVIEW_MODE__ === true) {
|
|
3803
3906
|
return;
|
|
3804
3907
|
}
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
layoutNodeId,
|
|
3818
|
-
componentId,
|
|
3819
|
-
fieldName: name,
|
|
3820
|
-
value
|
|
3821
|
-
},
|
|
3822
|
-
"*"
|
|
3823
|
-
);
|
|
3824
|
-
}
|
|
3825
|
-
function looksLikeRichCanvasField(name) {
|
|
3826
|
-
const tokens = String(name || "").replace(/([a-z])([A-Z])/g, "$1 $2").split(/[._\-\s/]+/).map((s) => s.toLowerCase()).filter(Boolean);
|
|
3827
|
-
const last = tokens[tokens.length - 1] || "";
|
|
3828
|
-
return last === "body" || last === "content" || last === "copy" || last === "excerpt" || last === "markdown" || last === "richtext";
|
|
3829
|
-
}
|
|
3830
|
-
var lastRichTextRequestAt = 0;
|
|
3831
|
-
function requestCanvasRichTextEdit(opts) {
|
|
3832
|
-
if (typeof window === "undefined" || window.parent === window) return;
|
|
3833
|
-
if (!opts.name) return;
|
|
3834
|
-
const now = Date.now();
|
|
3835
|
-
if (now - lastRichTextRequestAt < 400) return;
|
|
3836
|
-
lastRichTextRequestAt = now;
|
|
3837
|
-
const rect = opts.el.getBoundingClientRect();
|
|
3838
|
-
window.parent.postMessage(
|
|
3839
|
-
{
|
|
3840
|
-
type: "AMPLIFYUP_RICHTEXT_EDIT",
|
|
3841
|
-
layoutNodeId: opts.layoutNodeId,
|
|
3842
|
-
componentId: opts.componentId,
|
|
3843
|
-
fieldName: opts.name,
|
|
3844
|
-
value: opts.value,
|
|
3845
|
-
bounds: {
|
|
3846
|
-
top: rect.top,
|
|
3847
|
-
left: rect.left,
|
|
3848
|
-
width: Math.max(rect.width, 240),
|
|
3849
|
-
height: Math.max(rect.height, 64)
|
|
3908
|
+
if (window.location.pathname.includes("/api/pages/proxy")) {
|
|
3909
|
+
return;
|
|
3910
|
+
}
|
|
3911
|
+
if (window.self !== window.top) {
|
|
3912
|
+
return;
|
|
3913
|
+
}
|
|
3914
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
3915
|
+
if (urlParams.get("preview") === "true" || urlParams.get("visualEditor") === "true") {
|
|
3916
|
+
return;
|
|
3917
|
+
}
|
|
3918
|
+
if (window.location.href.includes("preview=true") || window.location.href.includes("visualEditor=true")) {
|
|
3919
|
+
return;
|
|
3850
3920
|
}
|
|
3851
|
-
},
|
|
3852
|
-
"*"
|
|
3853
|
-
);
|
|
3854
|
-
}
|
|
3855
|
-
function placeCaret(el, atStart = false) {
|
|
3856
|
-
const range = document.createRange();
|
|
3857
|
-
range.selectNodeContents(el);
|
|
3858
|
-
range.collapse(atStart);
|
|
3859
|
-
const sel = window.getSelection();
|
|
3860
|
-
sel?.removeAllRanges();
|
|
3861
|
-
sel?.addRange(range);
|
|
3862
|
-
}
|
|
3863
|
-
function ComposerInlineField({
|
|
3864
|
-
name,
|
|
3865
|
-
value,
|
|
3866
|
-
fallback,
|
|
3867
|
-
className,
|
|
3868
|
-
render,
|
|
3869
|
-
layoutNodeId,
|
|
3870
|
-
componentId,
|
|
3871
|
-
rich = false
|
|
3872
|
-
}) {
|
|
3873
|
-
const [editing, setEditing] = useState(false);
|
|
3874
|
-
const [focused, setFocused] = useState(false);
|
|
3875
|
-
const elRef = useRef(null);
|
|
3876
|
-
const storedEmpty = isComposerEmptyText(value);
|
|
3877
|
-
const text = storedEmpty ? "" : formatFieldValue(value);
|
|
3878
|
-
const fallbackText = typeof fallback === "string" || typeof fallback === "number" ? String(fallback) : "";
|
|
3879
|
-
const hint = COMPOSER_EMPTY_FIELD_HINT;
|
|
3880
|
-
const idleDisplay = storedEmpty ? hint : text || fallbackText;
|
|
3881
|
-
const showRendered = !!render && !editing;
|
|
3882
|
-
const showHint = storedEmpty && !focused && !showRendered;
|
|
3883
|
-
useEffect(() => {
|
|
3884
|
-
const el = elRef.current;
|
|
3885
|
-
if (!el || showRendered) return;
|
|
3886
|
-
if (document.activeElement === el) return;
|
|
3887
|
-
if (el.querySelector(
|
|
3888
|
-
"input, button, select, textarea, form, svg, iframe, img"
|
|
3889
|
-
)) {
|
|
3890
|
-
return;
|
|
3891
|
-
}
|
|
3892
|
-
const next = idleDisplay || "";
|
|
3893
|
-
if (el.textContent !== next) el.textContent = next;
|
|
3894
|
-
}, [idleDisplay, showRendered]);
|
|
3895
|
-
useEffect(() => {
|
|
3896
|
-
if (!editing || !elRef.current) return;
|
|
3897
|
-
const el = elRef.current;
|
|
3898
|
-
if (storedEmpty) {
|
|
3899
|
-
el.textContent = "";
|
|
3900
|
-
el.focus();
|
|
3901
|
-
placeCaret(el, true);
|
|
3902
|
-
return;
|
|
3903
3921
|
}
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
const raw = (elRef.current?.innerText ?? "").replace(/\u00a0/g, " ").replace(/\n+$/g, "");
|
|
3910
|
-
const next = raw.trim() === "" ? "" : raw;
|
|
3911
|
-
setEditing(false);
|
|
3912
|
-
setFocused(false);
|
|
3913
|
-
if (storedEmpty && next === "") {
|
|
3914
|
-
if (elRef.current) elRef.current.textContent = hint;
|
|
3915
|
-
if (typeof value === "string" && EMPTY_FIELD_PLACEHOLDERS.has(value.trim())) {
|
|
3916
|
-
commitComposerField(layoutNodeId, componentId, name, "");
|
|
3917
|
-
}
|
|
3918
|
-
return;
|
|
3922
|
+
if (pageConfig && pageConfig.id !== "default") {
|
|
3923
|
+
trackContentView(pageConfig.id, "page", {
|
|
3924
|
+
route: pageConfig.route,
|
|
3925
|
+
title: pageConfig.title
|
|
3926
|
+
});
|
|
3919
3927
|
}
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
if (
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
setEditing(true);
|
|
3963
|
-
}
|
|
3964
|
-
},
|
|
3965
|
-
onFocus: () => {
|
|
3966
|
-
if (!isComposerEditMode()) return;
|
|
3967
|
-
if (rich) {
|
|
3968
|
-
openRichEditor();
|
|
3969
|
-
return;
|
|
3970
|
-
}
|
|
3971
|
-
setFocused(true);
|
|
3972
|
-
const el = elRef.current;
|
|
3973
|
-
if (el && storedEmpty) {
|
|
3974
|
-
el.textContent = "";
|
|
3975
|
-
placeCaret(el, true);
|
|
3976
|
-
}
|
|
3977
|
-
if (render) setEditing(true);
|
|
3978
|
-
},
|
|
3979
|
-
onBlur: rich ? void 0 : finishEdit,
|
|
3980
|
-
onKeyDown: (event) => {
|
|
3981
|
-
event.stopPropagation();
|
|
3982
|
-
if (event.key === "Enter" && !event.shiftKey) {
|
|
3983
|
-
event.preventDefault();
|
|
3984
|
-
event.currentTarget.blur();
|
|
3985
|
-
}
|
|
3986
|
-
if (event.key === "Escape") {
|
|
3987
|
-
event.preventDefault();
|
|
3988
|
-
if (elRef.current) elRef.current.textContent = idleDisplay || "";
|
|
3989
|
-
setEditing(false);
|
|
3990
|
-
setFocused(false);
|
|
3991
|
-
event.currentTarget.blur();
|
|
3928
|
+
}, [pageConfig]);
|
|
3929
|
+
useEffect(() => {
|
|
3930
|
+
if (!pageConfig?.eventTracking?.length) return;
|
|
3931
|
+
const sdk = getSDK();
|
|
3932
|
+
if (!sdk.isInitialized()) return;
|
|
3933
|
+
sdk.setupEventTracking(pageConfig.eventTracking);
|
|
3934
|
+
const t1 = window.setTimeout(() => {
|
|
3935
|
+
sdk.setupComponentViewTracking();
|
|
3936
|
+
refreshEventTracking();
|
|
3937
|
+
}, 200);
|
|
3938
|
+
const t2 = window.setTimeout(() => {
|
|
3939
|
+
sdk.setupComponentViewTracking();
|
|
3940
|
+
refreshEventTracking();
|
|
3941
|
+
}, 1e3);
|
|
3942
|
+
return () => {
|
|
3943
|
+
window.clearTimeout(t1);
|
|
3944
|
+
window.clearTimeout(t2);
|
|
3945
|
+
};
|
|
3946
|
+
}, [pageConfig?.id, pageConfig?.eventTracking]);
|
|
3947
|
+
useEffect(() => {
|
|
3948
|
+
if (!pageConfig) return;
|
|
3949
|
+
const t = window.setTimeout(() => {
|
|
3950
|
+
getSDK().setupComponentViewTracking();
|
|
3951
|
+
refreshEventTracking();
|
|
3952
|
+
}, 100);
|
|
3953
|
+
return () => window.clearTimeout(t);
|
|
3954
|
+
}, [variantCache, pageConfig?.id]);
|
|
3955
|
+
useEffect(() => {
|
|
3956
|
+
const isVisualEditorMode = () => {
|
|
3957
|
+
if (typeof window === "undefined") return false;
|
|
3958
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
3959
|
+
if (urlParams.get("visualEditor") === "true" || urlParams.get("preview") === "true") {
|
|
3960
|
+
return true;
|
|
3961
|
+
}
|
|
3962
|
+
const inIframe = window.self !== window.top;
|
|
3963
|
+
if (!inIframe) return false;
|
|
3964
|
+
try {
|
|
3965
|
+
if (document.referrer) {
|
|
3966
|
+
const referrerUrl = new URL(document.referrer);
|
|
3967
|
+
if (referrerUrl.hostname === "localhost" && referrerUrl.port === "5001") {
|
|
3968
|
+
return true;
|
|
3969
|
+
}
|
|
3992
3970
|
}
|
|
3993
|
-
}
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
minHeight: "1em",
|
|
4000
|
-
// Do not force `inline` — that overrides Tailwind `block` and parks
|
|
4001
|
-
// an empty-field hint on the same line as a sibling that has a value.
|
|
4002
|
-
opacity: showHint ? 0.5 : void 0
|
|
4003
|
-
},
|
|
4004
|
-
children: showRendered ? value != null && value !== "" && !storedEmpty ? render(value) : fallback ?? idleDisplay : isReactNodeFallback(fallback) && !idleDisplay ? fallback : null
|
|
3971
|
+
} catch (e) {
|
|
3972
|
+
}
|
|
3973
|
+
return false;
|
|
3974
|
+
};
|
|
3975
|
+
if (!isVisualEditorMode()) {
|
|
3976
|
+
return;
|
|
4005
3977
|
}
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
function ComposerInlineHtml({
|
|
4009
|
-
name,
|
|
4010
|
-
html,
|
|
4011
|
-
sourceValue,
|
|
4012
|
-
className,
|
|
4013
|
-
Tag = "div",
|
|
4014
|
-
layoutNodeId,
|
|
4015
|
-
componentId
|
|
4016
|
-
}) {
|
|
4017
|
-
const elRef = useRef(null);
|
|
4018
|
-
useEffect(() => {
|
|
4019
|
-
const el = elRef.current;
|
|
4020
|
-
if (!el) return;
|
|
4021
|
-
if (el.innerHTML !== html) el.innerHTML = html;
|
|
4022
|
-
}, [html]);
|
|
4023
|
-
const openRichEditor = (event) => {
|
|
4024
|
-
if (!elRef.current) return;
|
|
4025
|
-
event.preventDefault();
|
|
4026
|
-
event.stopPropagation();
|
|
4027
|
-
requestCanvasRichTextEdit({
|
|
4028
|
-
el: elRef.current,
|
|
4029
|
-
layoutNodeId,
|
|
4030
|
-
componentId,
|
|
4031
|
-
name,
|
|
4032
|
-
value: sourceValue
|
|
4033
|
-
});
|
|
4034
|
-
};
|
|
4035
|
-
return React.createElement(Tag, {
|
|
4036
|
-
ref: elRef,
|
|
4037
|
-
className,
|
|
4038
|
-
"data-amplifyup-field": name,
|
|
4039
|
-
"data-amplifyup-field-type": "richtext",
|
|
4040
|
-
"data-amplifyup-node-id": layoutNodeId || void 0,
|
|
4041
|
-
dangerouslySetInnerHTML: { __html: html },
|
|
4042
|
-
onMouseDown: (event) => {
|
|
4043
|
-
event.stopPropagation();
|
|
4044
|
-
},
|
|
4045
|
-
onClick: openRichEditor,
|
|
4046
|
-
style: {
|
|
4047
|
-
cursor: "text",
|
|
4048
|
-
outline: "1px dashed color-mix(in srgb, currentColor 40%, transparent)",
|
|
4049
|
-
outlineOffset: "2px"
|
|
3978
|
+
if (!pageConfig) {
|
|
3979
|
+
return;
|
|
4050
3980
|
}
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
if (typeof item === "string") return item;
|
|
4060
|
-
if (item && typeof item === "object" && "children" in item && Array.isArray(item.children)) {
|
|
4061
|
-
return item.children.map((c) => typeof c?.text === "string" ? c.text : "").join("");
|
|
3981
|
+
const rawTree2 = pageConfig.layoutTree;
|
|
3982
|
+
const normalizedTree = Array.isArray(rawTree2) ? rawTree2 : rawTree2 && typeof rawTree2 === "object" && rawTree2.componentId ? [rawTree2] : [];
|
|
3983
|
+
if (normalizedTree.length === 0) {
|
|
3984
|
+
if (typeof window !== "undefined" && window.parent && window.parent !== window) {
|
|
3985
|
+
window.parent.postMessage({
|
|
3986
|
+
type: "COMPONENT_TREE",
|
|
3987
|
+
tree: []
|
|
3988
|
+
}, "*");
|
|
4062
3989
|
}
|
|
4063
|
-
return
|
|
4064
|
-
}
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
}
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
const
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
);
|
|
4109
|
-
}) });
|
|
4110
|
-
}
|
|
4111
|
-
function Field(props) {
|
|
4112
|
-
const { value, name, fallback, className, render } = props;
|
|
4113
|
-
const context = useContext(ComponentContext);
|
|
4114
|
-
const composerEdit = useComposerEditMode();
|
|
4115
|
-
const hasExplicitValue = hasOwnProp(props, "value");
|
|
4116
|
-
const sourceValue = hasExplicitValue ? value : name ? context?.props?.[name] : void 0;
|
|
4117
|
-
const editName = inferEditName(name, context?.props, sourceValue);
|
|
4118
|
-
const fieldValue = useFieldOverlay(
|
|
4119
|
-
context?.layoutNodeId,
|
|
4120
|
-
editName,
|
|
4121
|
-
sourceValue
|
|
4122
|
-
);
|
|
4123
|
-
warnProjectionProps("Field", name, hasExplicitValue);
|
|
4124
|
-
if (!context && !hasExplicitValue) {
|
|
4125
|
-
console.warn(
|
|
4126
|
-
"[AmplifyUp SDK] Field needs a `value` prop (or deprecated `name` alone)"
|
|
3990
|
+
return;
|
|
3991
|
+
}
|
|
3992
|
+
const convertLayoutTreeToComponentTree = (nodes, parentId = null) => {
|
|
3993
|
+
const result = [];
|
|
3994
|
+
nodes.forEach((node) => {
|
|
3995
|
+
if (!node) return;
|
|
3996
|
+
const treeNode = {
|
|
3997
|
+
id: node.id,
|
|
3998
|
+
componentId: node.componentId,
|
|
3999
|
+
componentName: node.componentId,
|
|
4000
|
+
// Will be enhanced with actual name if available
|
|
4001
|
+
parentId,
|
|
4002
|
+
children: []
|
|
4003
|
+
};
|
|
4004
|
+
if (node.slots && node.slots.length > 0) {
|
|
4005
|
+
node.slots.forEach((slot) => {
|
|
4006
|
+
const kids = Array.isArray(slot?.children) ? slot.children : [];
|
|
4007
|
+
if (kids.length > 0) {
|
|
4008
|
+
const slotChildren = convertLayoutTreeToComponentTree(kids, node.id);
|
|
4009
|
+
treeNode.children.push(...slotChildren);
|
|
4010
|
+
}
|
|
4011
|
+
});
|
|
4012
|
+
}
|
|
4013
|
+
result.push(treeNode);
|
|
4014
|
+
});
|
|
4015
|
+
return result;
|
|
4016
|
+
};
|
|
4017
|
+
const layoutTree2 = normalizedTree;
|
|
4018
|
+
const componentTree = convertLayoutTreeToComponentTree(layoutTree2);
|
|
4019
|
+
const describeLayoutTree = (nodes, depth = 0) => {
|
|
4020
|
+
if (!nodes?.length) return "";
|
|
4021
|
+
const indent = " ".repeat(depth);
|
|
4022
|
+
return nodes.map((n) => {
|
|
4023
|
+
const slotsDesc = (n.slots || []).map((s) => {
|
|
4024
|
+
const childCount = Array.isArray(s.children) ? s.children.length : 0;
|
|
4025
|
+
const childrenDesc = childCount > 0 ? describeLayoutTree(s.children || [], depth + 1) : "";
|
|
4026
|
+
return `${indent} slot "${s.slotId || s.slotName || "?"}" (${childCount} children)${childrenDesc ? "\n" + childrenDesc : ""}`;
|
|
4027
|
+
}).join("\n");
|
|
4028
|
+
return `${indent}- ${n.id} (${n.componentId || "?"})${slotsDesc ? "\n" + slotsDesc : ""}`;
|
|
4029
|
+
}).join("\n");
|
|
4030
|
+
};
|
|
4031
|
+
sdkDebugOnce(
|
|
4032
|
+
`layoutTree:${pageConfig?.id || ""}:${pageConfig?.route || ""}`,
|
|
4033
|
+
"[AmplifyRenderer] layoutTree received:\n%s",
|
|
4034
|
+
describeLayoutTree(layoutTree2)
|
|
4127
4035
|
);
|
|
4128
|
-
|
|
4129
|
-
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
|
|
4138
|
-
|
|
4139
|
-
|
|
4140
|
-
|
|
4141
|
-
|
|
4142
|
-
|
|
4036
|
+
if (typeof window !== "undefined" && window.parent && window.parent !== window) {
|
|
4037
|
+
const message = {
|
|
4038
|
+
type: "COMPONENT_TREE",
|
|
4039
|
+
tree: componentTree
|
|
4040
|
+
};
|
|
4041
|
+
window.parent.postMessage(message, "*");
|
|
4042
|
+
sdkDebug(
|
|
4043
|
+
"[AmplifyRenderer] Sent component tree from layoutTree:",
|
|
4044
|
+
componentTree.length,
|
|
4045
|
+
"root components"
|
|
4046
|
+
);
|
|
4047
|
+
}
|
|
4048
|
+
}, [pageConfig]);
|
|
4049
|
+
useEffect(() => {
|
|
4050
|
+
if (!pageConfig?.layoutTree || !pageConfig.layoutId) return;
|
|
4051
|
+
const roots = pageConfig.layoutTree;
|
|
4052
|
+
const fromEdge = contentSource === "edge" || roots.some((n) => n._contentSource === "edge");
|
|
4053
|
+
if (fromEdge) return;
|
|
4054
|
+
const sdk = getSDK();
|
|
4055
|
+
const instanceId = sdk.getInstanceId();
|
|
4056
|
+
const decisionApiUrl = sdk.getDecisionApiUrl();
|
|
4057
|
+
const orchestratorUrl = sdk.getOrchestratorUrl();
|
|
4058
|
+
if (!decisionApiUrl && !orchestratorUrl || !instanceId) return;
|
|
4059
|
+
const fetchVariants = async () => {
|
|
4060
|
+
const nodes = pageConfig.layoutTree;
|
|
4061
|
+
const newCache = {};
|
|
4062
|
+
const findZonedSlots = (nodeList) => {
|
|
4063
|
+
const results = [];
|
|
4064
|
+
for (const node of nodeList) {
|
|
4065
|
+
if (node.slots) {
|
|
4066
|
+
for (const slot of node.slots) {
|
|
4067
|
+
if (slot.zoneId && slot.variants) {
|
|
4068
|
+
const key = `${node.id}-${slot.slotId}`;
|
|
4069
|
+
results.push({ node, slot, key });
|
|
4070
|
+
}
|
|
4071
|
+
}
|
|
4072
|
+
}
|
|
4143
4073
|
}
|
|
4074
|
+
return results;
|
|
4075
|
+
};
|
|
4076
|
+
const zonedSlots = findZonedSlots(nodes);
|
|
4077
|
+
await Promise.all(
|
|
4078
|
+
zonedSlots.map(async ({ node, slot, key }) => {
|
|
4079
|
+
try {
|
|
4080
|
+
let personalizationUrl;
|
|
4081
|
+
if (decisionApiUrl) {
|
|
4082
|
+
const url = new URL(decisionApiUrl);
|
|
4083
|
+
url.searchParams.set("instanceId", instanceId);
|
|
4084
|
+
const zoneId = slot.zoneId;
|
|
4085
|
+
if (zoneId) {
|
|
4086
|
+
url.searchParams.set("zoneId", zoneId);
|
|
4087
|
+
}
|
|
4088
|
+
const campaignId = slot.campaignId;
|
|
4089
|
+
if (campaignId) {
|
|
4090
|
+
url.searchParams.set("campaignId", campaignId);
|
|
4091
|
+
}
|
|
4092
|
+
personalizationUrl = url.toString();
|
|
4093
|
+
} else if (orchestratorUrl) {
|
|
4094
|
+
personalizationUrl = `${orchestratorUrl}/api/personalization/variant?instanceId=${encodeURIComponent(instanceId)}&layoutId=${encodeURIComponent(pageConfig.layoutId)}&slotId=${encodeURIComponent(slot.slotId)}&nodeId=${encodeURIComponent(node.id)}`;
|
|
4095
|
+
} else {
|
|
4096
|
+
return;
|
|
4097
|
+
}
|
|
4098
|
+
const response = await fetch(personalizationUrl);
|
|
4099
|
+
if (response.ok) {
|
|
4100
|
+
const data = await response.json();
|
|
4101
|
+
if (data.variantId && data.componentTree) {
|
|
4102
|
+
newCache[key] = {
|
|
4103
|
+
variantId: data.variantId,
|
|
4104
|
+
children: data.componentTree
|
|
4105
|
+
};
|
|
4106
|
+
if (typeof window !== "undefined") {
|
|
4107
|
+
if (window.__AMPLIFYUP_PREVIEW_MODE__ === true) {
|
|
4108
|
+
return;
|
|
4109
|
+
}
|
|
4110
|
+
if (window.location.pathname.includes("/api/pages/proxy")) {
|
|
4111
|
+
return;
|
|
4112
|
+
}
|
|
4113
|
+
if (window.self !== window.top) {
|
|
4114
|
+
return;
|
|
4115
|
+
}
|
|
4116
|
+
}
|
|
4117
|
+
sdk.track("Zone Impression", {
|
|
4118
|
+
zoneId: slot.zoneId,
|
|
4119
|
+
variantId: data.variantId,
|
|
4120
|
+
layoutId: pageConfig.layoutId,
|
|
4121
|
+
route: pageConfig.route
|
|
4122
|
+
});
|
|
4123
|
+
} else {
|
|
4124
|
+
const defaultVariant = slot.variants?.find((v) => v.isDefault);
|
|
4125
|
+
if (defaultVariant) {
|
|
4126
|
+
newCache[key] = {
|
|
4127
|
+
variantId: defaultVariant.variantId,
|
|
4128
|
+
children: defaultVariant.children
|
|
4129
|
+
};
|
|
4130
|
+
}
|
|
4131
|
+
}
|
|
4132
|
+
}
|
|
4133
|
+
} catch (err) {
|
|
4134
|
+
console.error(`Error fetching variant for slot ${key}:`, err);
|
|
4135
|
+
const defaultVariant = slot.variants?.find((v) => v.isDefault);
|
|
4136
|
+
if (defaultVariant) {
|
|
4137
|
+
newCache[key] = {
|
|
4138
|
+
variantId: defaultVariant.variantId,
|
|
4139
|
+
children: defaultVariant.children
|
|
4140
|
+
};
|
|
4141
|
+
}
|
|
4142
|
+
}
|
|
4143
|
+
})
|
|
4144
4144
|
);
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
4151
|
-
|
|
4152
|
-
|
|
4153
|
-
|
|
4154
|
-
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
{
|
|
4159
|
-
name: editName,
|
|
4160
|
-
value: fieldValue,
|
|
4161
|
-
fallback,
|
|
4162
|
-
className,
|
|
4163
|
-
layoutNodeId: context.layoutNodeId,
|
|
4164
|
-
componentId: context.componentId,
|
|
4165
|
-
rich: looksLikeRichCanvasField(editName)
|
|
4166
|
-
}
|
|
4167
|
-
);
|
|
4168
|
-
}
|
|
4169
|
-
if (fieldValue === void 0 || fieldValue === null || isComposerEmptyText(fieldValue)) {
|
|
4170
|
-
return fallback ? /* @__PURE__ */ jsx("span", { className, children: fallback }) : null;
|
|
4171
|
-
}
|
|
4172
|
-
if (!text) {
|
|
4173
|
-
return fallback ? /* @__PURE__ */ jsx("span", { className, children: fallback }) : null;
|
|
4145
|
+
setVariantCache(newCache);
|
|
4146
|
+
};
|
|
4147
|
+
fetchVariants();
|
|
4148
|
+
}, [pageConfig?.layoutTree, pageConfig?.layoutId, pageConfig?.route, contentSource]);
|
|
4149
|
+
if (loading) {
|
|
4150
|
+
return /* @__PURE__ */ jsx(Fragment, { children: loadingComponent || /* @__PURE__ */ jsx("div", { className: "min-h-screen bg-gray-50", children: /* @__PURE__ */ jsx("div", { className: "container mx-auto px-4 py-16", children: /* @__PURE__ */ jsxs("div", { className: "animate-pulse", children: [
|
|
4151
|
+
/* @__PURE__ */ jsx("div", { className: "h-8 bg-gray-200 rounded w-1/4 mb-4" }),
|
|
4152
|
+
/* @__PURE__ */ jsx("div", { className: "h-4 bg-gray-200 rounded w-1/2 mb-8" }),
|
|
4153
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
4154
|
+
/* @__PURE__ */ jsx("div", { className: "h-64 bg-gray-200 rounded" }),
|
|
4155
|
+
/* @__PURE__ */ jsx("div", { className: "h-32 bg-gray-200 rounded" })
|
|
4156
|
+
] })
|
|
4157
|
+
] }) }) }) });
|
|
4174
4158
|
}
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
return typeof result === "string" ? result : "";
|
|
4181
|
-
} catch {
|
|
4182
|
-
return markdown;
|
|
4159
|
+
if (error) {
|
|
4160
|
+
return /* @__PURE__ */ jsx(Fragment, { children: errorComponent ? errorComponent(error) : /* @__PURE__ */ jsx("div", { className: "min-h-screen bg-gray-50", children: /* @__PURE__ */ jsx("div", { className: "container mx-auto px-4 py-16", children: /* @__PURE__ */ jsxs("div", { className: "bg-red-50 border border-red-200 rounded-lg p-6", children: [
|
|
4161
|
+
/* @__PURE__ */ jsx("h1", { className: "text-2xl font-bold text-red-900 mb-2", children: "Error Loading Page" }),
|
|
4162
|
+
/* @__PURE__ */ jsx("p", { className: "text-red-700", children: error })
|
|
4163
|
+
] }) }) }) });
|
|
4183
4164
|
}
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
const {
|
|
4187
|
-
value,
|
|
4188
|
-
name,
|
|
4189
|
-
fallback,
|
|
4190
|
-
className,
|
|
4191
|
-
as: Tag = "div",
|
|
4192
|
-
children
|
|
4193
|
-
} = props;
|
|
4194
|
-
const context = useContext(ComponentContext);
|
|
4195
|
-
const composerEdit = useComposerEditMode();
|
|
4196
|
-
const childrenValue = typeof children === "string" || typeof children === "number" ? String(children) : void 0;
|
|
4197
|
-
const hasValueProp = hasOwnProp(props, "value");
|
|
4198
|
-
const hasExplicitValue = hasValueProp || childrenValue !== void 0;
|
|
4199
|
-
const sourceValue = hasValueProp ? value : childrenValue !== void 0 ? childrenValue : name ? context?.props?.[name] : void 0;
|
|
4200
|
-
const editName = inferEditName(name, context?.props, sourceValue);
|
|
4201
|
-
const fieldValue = useFieldOverlay(
|
|
4202
|
-
context?.layoutNodeId,
|
|
4203
|
-
editName,
|
|
4204
|
-
sourceValue
|
|
4205
|
-
);
|
|
4206
|
-
if (!context && !hasExplicitValue) {
|
|
4207
|
-
console.warn(
|
|
4208
|
-
"[AmplifyUp SDK] RichText needs a `value` prop (or string children), or deprecated `name` alone"
|
|
4209
|
-
);
|
|
4210
|
-
return fallback ? /* @__PURE__ */ jsx(Fragment, { children: fallback }) : null;
|
|
4165
|
+
if (!pageConfig) {
|
|
4166
|
+
return null;
|
|
4211
4167
|
}
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4168
|
+
pageConfig.layout?.header !== false;
|
|
4169
|
+
pageConfig.layout?.footer !== false;
|
|
4170
|
+
const renderNode = (node) => {
|
|
4171
|
+
const zoneIdFromProps = node.componentId === "AmplifyZone" ? String(node.props?.zoneId || "") : "";
|
|
4172
|
+
if (node.componentId === "AmplifyZone") {
|
|
4173
|
+
const contentSlot = node.slots?.find((s) => s.slotId === "content") || node.slots?.[0];
|
|
4174
|
+
const children = Array.isArray(contentSlot?.children) ? contentSlot.children : [];
|
|
4216
4175
|
return /* @__PURE__ */ jsx(
|
|
4217
|
-
|
|
4176
|
+
"div",
|
|
4218
4177
|
{
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4178
|
+
"data-node-id": node.id,
|
|
4179
|
+
"data-amplifyup-node": "",
|
|
4180
|
+
"data-amplifyup-component": "AmplifyZone",
|
|
4181
|
+
"data-amplifyup-zone": zoneIdFromProps || void 0,
|
|
4182
|
+
"data-zone-id": zoneIdFromProps || void 0,
|
|
4183
|
+
children: /* @__PURE__ */ jsx(
|
|
4184
|
+
"div",
|
|
4185
|
+
{
|
|
4186
|
+
"data-slot-id": "content",
|
|
4187
|
+
"data-amplifyup-slot": "content",
|
|
4188
|
+
"data-parent-node-id": node.id,
|
|
4189
|
+
"data-parent-component-id": "AmplifyZone",
|
|
4190
|
+
children: children.filter(Boolean).map((child) => /* @__PURE__ */ jsx(Fragment$1, { children: renderNode(child) }, child.id))
|
|
4191
|
+
}
|
|
4192
|
+
)
|
|
4226
4193
|
}
|
|
4227
4194
|
);
|
|
4228
4195
|
}
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4196
|
+
let slotChildren = {};
|
|
4197
|
+
sdkDebugOnce(`node:${node.id}`, `[AmplifyRenderer] Rendering node ${node.id} (${node.componentId})`, {
|
|
4198
|
+
hasSlots: !!(node.slots && node.slots.length > 0),
|
|
4199
|
+
slotCount: node.slots?.length || 0,
|
|
4200
|
+
slots: node.slots?.map((s) => ({ slotId: s.slotId, zoneId: s.zoneId, childrenCount: s.children?.length || 0 }))
|
|
4201
|
+
});
|
|
4202
|
+
if (node.slots && node.slots.length > 0) {
|
|
4203
|
+
for (const slot of node.slots) {
|
|
4204
|
+
const slotKey = `${node.id}-${slot.slotId}`;
|
|
4205
|
+
let childrenToRender = [];
|
|
4206
|
+
if (slot.zoneId && slot.variants && variantCache[slotKey]) {
|
|
4207
|
+
childrenToRender = variantCache[slotKey].children;
|
|
4208
|
+
} else if (slot.zoneId && slot.variants) {
|
|
4209
|
+
const defaultVariant = slot.variants.find((v) => v.isDefault);
|
|
4210
|
+
childrenToRender = defaultVariant?.children || [];
|
|
4211
|
+
} else {
|
|
4212
|
+
childrenToRender = Array.isArray(slot.children) ? slot.children : [];
|
|
4213
|
+
}
|
|
4214
|
+
const safeChildren = Array.isArray(childrenToRender) ? childrenToRender : [];
|
|
4215
|
+
slotChildren[slot.slotId] = /* @__PURE__ */ jsx(
|
|
4216
|
+
"div",
|
|
4217
|
+
{
|
|
4218
|
+
"data-slot-id": slot.slotId,
|
|
4219
|
+
"data-amplifyup-slot": slot.slotId,
|
|
4220
|
+
"data-zone-id": slot.zoneId || void 0,
|
|
4221
|
+
"data-parent-node-id": node.id,
|
|
4222
|
+
"data-parent-component-id": node.componentId,
|
|
4223
|
+
children: safeChildren.filter(Boolean).map((child) => /* @__PURE__ */ jsx(Fragment$1, { children: renderNode(child) }, child.id))
|
|
4224
|
+
},
|
|
4225
|
+
slot.slotId
|
|
4226
|
+
);
|
|
4257
4227
|
}
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
return /* @__PURE__ */ jsx(Tag, { className, dangerouslySetInnerHTML: { __html: html } });
|
|
4261
|
-
}
|
|
4262
|
-
function isPortableImageValue(value) {
|
|
4263
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
4264
|
-
const url = value.url;
|
|
4265
|
-
return typeof url === "string" && url.trim().length > 0;
|
|
4266
|
-
}
|
|
4267
|
-
function imageSrc(value) {
|
|
4268
|
-
if (typeof value === "string") return value.trim();
|
|
4269
|
-
if (isPortableImageValue(value)) return value.url.trim();
|
|
4270
|
-
return "";
|
|
4271
|
-
}
|
|
4272
|
-
function Image(props) {
|
|
4273
|
-
const {
|
|
4274
|
-
value,
|
|
4275
|
-
name,
|
|
4276
|
-
alt: altProp,
|
|
4277
|
-
className,
|
|
4278
|
-
width: widthProp,
|
|
4279
|
-
height: heightProp,
|
|
4280
|
-
...imgProps
|
|
4281
|
-
} = props;
|
|
4282
|
-
const context = useContext(ComponentContext);
|
|
4283
|
-
const hasExplicitValue = hasOwnProp(props, "value");
|
|
4284
|
-
const sourceValue = hasExplicitValue ? value : name ? context?.props?.[name] : void 0;
|
|
4285
|
-
const fieldValue = useFieldOverlay(
|
|
4286
|
-
context?.layoutNodeId,
|
|
4287
|
-
inferEditName(name, context?.props, sourceValue),
|
|
4288
|
-
sourceValue
|
|
4289
|
-
);
|
|
4290
|
-
const composerEdit = useComposerEditMode();
|
|
4291
|
-
const editName = inferEditName(name, context?.props, sourceValue);
|
|
4292
|
-
warnProjectionProps("Image", name, hasExplicitValue);
|
|
4293
|
-
if (!context && !hasExplicitValue) {
|
|
4294
|
-
console.warn(
|
|
4295
|
-
"[AmplifyUp SDK] Image needs a `value` prop (or deprecated `name` alone)"
|
|
4296
|
-
);
|
|
4297
|
-
return null;
|
|
4298
|
-
}
|
|
4299
|
-
const src = imageSrc(fieldValue);
|
|
4300
|
-
const portable = isPortableImageValue(fieldValue) ? fieldValue : null;
|
|
4301
|
-
const alt = altProp ?? portable?.alt ?? "";
|
|
4302
|
-
const width = widthProp ?? portable?.width;
|
|
4303
|
-
const height = heightProp ?? portable?.height;
|
|
4304
|
-
const fieldAttrs = composerEdit && editName ? {
|
|
4305
|
-
"data-amplifyup-field": editName,
|
|
4306
|
-
"data-amplifyup-field-type": "image",
|
|
4307
|
-
"data-amplifyup-node-id": context?.layoutNodeId || void 0
|
|
4308
|
-
} : null;
|
|
4309
|
-
if (composerEdit && !editName && (hasExplicitValue || name)) {
|
|
4310
|
-
console.warn(
|
|
4311
|
-
'[AmplifyUp SDK] Image could not infer a Composer field name from value={\u2026}. Pass name="yourProp" (same as the component prop) so the image can be selected.'
|
|
4312
|
-
);
|
|
4313
|
-
}
|
|
4314
|
-
if (!src) {
|
|
4315
|
-
if (!composerEdit || !fieldAttrs) return null;
|
|
4228
|
+
}
|
|
4229
|
+
const slotsToPass = Object.keys(slotChildren).length > 0 ? slotChildren : void 0;
|
|
4316
4230
|
return /* @__PURE__ */ jsx(
|
|
4317
|
-
"
|
|
4231
|
+
"div",
|
|
4318
4232
|
{
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
"
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
|
|
4333
|
-
|
|
4334
|
-
|
|
4233
|
+
"data-node-id": node.id,
|
|
4234
|
+
"data-amplifyup-node": "",
|
|
4235
|
+
"data-component-id": node.componentId,
|
|
4236
|
+
"data-amplifyup-component": node.componentId,
|
|
4237
|
+
children: /* @__PURE__ */ jsx(
|
|
4238
|
+
ComponentRenderBoundary,
|
|
4239
|
+
{
|
|
4240
|
+
componentId: node.componentId,
|
|
4241
|
+
nodeId: node.id,
|
|
4242
|
+
children: /* @__PURE__ */ jsx(
|
|
4243
|
+
NodeWithFields,
|
|
4244
|
+
{
|
|
4245
|
+
nodeId: node.id,
|
|
4246
|
+
componentId: node.componentId,
|
|
4247
|
+
props: nodeRenderProps(node),
|
|
4248
|
+
slots: slotsToPass,
|
|
4249
|
+
renderComponent,
|
|
4250
|
+
composerPreview
|
|
4251
|
+
}
|
|
4252
|
+
)
|
|
4253
|
+
}
|
|
4254
|
+
)
|
|
4335
4255
|
}
|
|
4336
4256
|
);
|
|
4257
|
+
};
|
|
4258
|
+
const rawTree = pageConfig.layoutTree;
|
|
4259
|
+
const layoutTree = Array.isArray(rawTree) ? rawTree : rawTree && typeof rawTree === "object" && rawTree.componentId ? [rawTree] : [];
|
|
4260
|
+
if (layoutTree.length === 0) {
|
|
4261
|
+
return /* @__PURE__ */ jsx("main", { children: emptyComponent || /* @__PURE__ */ jsx("div", { className: "container mx-auto px-4 py-16", children: /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: "No content configured for this page." }) }) });
|
|
4337
4262
|
}
|
|
4338
|
-
return /* @__PURE__ */ jsx(
|
|
4339
|
-
"
|
|
4263
|
+
return /* @__PURE__ */ jsx("main", { children: composerPreview || isComposerPreview() ? /* @__PURE__ */ jsx(
|
|
4264
|
+
"div",
|
|
4340
4265
|
{
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
width,
|
|
4347
|
-
height,
|
|
4348
|
-
style: {
|
|
4349
|
-
...typeof imgProps.style === "object" && imgProps.style ? imgProps.style : {},
|
|
4350
|
-
...composerEdit && fieldAttrs ? { cursor: "pointer" } : null
|
|
4351
|
-
}
|
|
4266
|
+
"data-slot-id": "main",
|
|
4267
|
+
"data-amplifyup-slot": "main",
|
|
4268
|
+
"data-slot-source": "page",
|
|
4269
|
+
"data-slot-empty": layoutTree.length === 0 ? "true" : void 0,
|
|
4270
|
+
children: layoutTree.map((node) => /* @__PURE__ */ jsx(Fragment$1, { children: renderNode(node) }, node.id))
|
|
4352
4271
|
}
|
|
4353
|
-
);
|
|
4354
|
-
}
|
|
4355
|
-
function nodeRenderProps(node) {
|
|
4356
|
-
return {
|
|
4357
|
-
...node.settings || {},
|
|
4358
|
-
...node.props || {}
|
|
4359
|
-
};
|
|
4272
|
+
) : layoutTree.map((node) => /* @__PURE__ */ jsx(Fragment$1, { children: renderNode(node) }, node.id)) });
|
|
4360
4273
|
}
|
|
4361
|
-
var
|
|
4362
|
-
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4367
|
-
|
|
4368
|
-
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
|
|
4372
|
-
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
if (this.state.error) {
|
|
4377
|
-
if (process.env.NODE_ENV !== "production") {
|
|
4378
|
-
return /* @__PURE__ */ jsxs(
|
|
4379
|
-
"div",
|
|
4274
|
+
var AmplifyRenderer = memo(AmplifyRendererInner);
|
|
4275
|
+
function AddComponentIcon({ size = 28 }) {
|
|
4276
|
+
return /* @__PURE__ */ jsxs(
|
|
4277
|
+
"svg",
|
|
4278
|
+
{
|
|
4279
|
+
width: size,
|
|
4280
|
+
height: size,
|
|
4281
|
+
viewBox: "0 0 24 24",
|
|
4282
|
+
fill: "none",
|
|
4283
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
4284
|
+
"aria-hidden": "true",
|
|
4285
|
+
focusable: "false",
|
|
4286
|
+
children: [
|
|
4287
|
+
/* @__PURE__ */ jsx(
|
|
4288
|
+
"rect",
|
|
4380
4289
|
{
|
|
4381
|
-
|
|
4382
|
-
"
|
|
4383
|
-
"
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
borderRadius: "0.5rem",
|
|
4389
|
-
background: "#fef2f2",
|
|
4390
|
-
color: "#991b1b",
|
|
4391
|
-
fontSize: "0.875rem"
|
|
4392
|
-
},
|
|
4393
|
-
children: [
|
|
4394
|
-
'Component "',
|
|
4395
|
-
this.props.componentId,
|
|
4396
|
-
'" failed to render:',
|
|
4397
|
-
" ",
|
|
4398
|
-
this.state.error.message
|
|
4399
|
-
]
|
|
4290
|
+
x: "3",
|
|
4291
|
+
y: "3",
|
|
4292
|
+
width: "18",
|
|
4293
|
+
height: "18",
|
|
4294
|
+
rx: "4",
|
|
4295
|
+
stroke: "currentColor",
|
|
4296
|
+
strokeWidth: "1.75"
|
|
4400
4297
|
}
|
|
4401
|
-
)
|
|
4402
|
-
|
|
4403
|
-
|
|
4298
|
+
),
|
|
4299
|
+
/* @__PURE__ */ jsx(
|
|
4300
|
+
"path",
|
|
4301
|
+
{
|
|
4302
|
+
d: "M12 8v8M8 12h8",
|
|
4303
|
+
stroke: "currentColor",
|
|
4304
|
+
strokeWidth: "1.75",
|
|
4305
|
+
strokeLinecap: "round"
|
|
4306
|
+
}
|
|
4307
|
+
)
|
|
4308
|
+
]
|
|
4404
4309
|
}
|
|
4405
|
-
|
|
4406
|
-
}
|
|
4407
|
-
};
|
|
4408
|
-
function LiveNodeRender({
|
|
4409
|
-
nodeId,
|
|
4410
|
-
componentId,
|
|
4411
|
-
props,
|
|
4412
|
-
slots,
|
|
4413
|
-
renderComponent
|
|
4414
|
-
}) {
|
|
4415
|
-
const liveProps = useLiveComposerProps(nodeId, props);
|
|
4416
|
-
return /* @__PURE__ */ jsx(Fragment, { children: renderComponent(componentId, liveProps, slots, {
|
|
4417
|
-
layoutNodeId: nodeId
|
|
4418
|
-
}) });
|
|
4310
|
+
);
|
|
4419
4311
|
}
|
|
4420
|
-
function
|
|
4421
|
-
|
|
4422
|
-
|
|
4423
|
-
loadingComponent,
|
|
4424
|
-
errorComponent,
|
|
4425
|
-
emptyComponent,
|
|
4426
|
-
composerPreview
|
|
4312
|
+
function EmptySlotHint({
|
|
4313
|
+
label = "Click here to Add Component",
|
|
4314
|
+
compact = false
|
|
4427
4315
|
}) {
|
|
4428
|
-
const
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
|
|
4436
|
-
|
|
4437
|
-
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
|
|
4441
|
-
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
|
|
4450
|
-
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
|
|
4455
|
-
|
|
4456
|
-
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
|
|
4461
|
-
|
|
4462
|
-
const sdk = getSDK();
|
|
4463
|
-
if (!sdk.isInitialized()) return;
|
|
4464
|
-
sdk.setupEventTracking(pageConfig.eventTracking);
|
|
4465
|
-
const t1 = window.setTimeout(() => {
|
|
4466
|
-
sdk.setupComponentViewTracking();
|
|
4467
|
-
refreshEventTracking();
|
|
4468
|
-
}, 200);
|
|
4469
|
-
const t2 = window.setTimeout(() => {
|
|
4470
|
-
sdk.setupComponentViewTracking();
|
|
4471
|
-
refreshEventTracking();
|
|
4472
|
-
}, 1e3);
|
|
4473
|
-
return () => {
|
|
4474
|
-
window.clearTimeout(t1);
|
|
4475
|
-
window.clearTimeout(t2);
|
|
4476
|
-
};
|
|
4477
|
-
}, [pageConfig?.id, pageConfig?.eventTracking]);
|
|
4478
|
-
useEffect(() => {
|
|
4479
|
-
if (!pageConfig) return;
|
|
4480
|
-
const t = window.setTimeout(() => {
|
|
4481
|
-
getSDK().setupComponentViewTracking();
|
|
4482
|
-
refreshEventTracking();
|
|
4483
|
-
}, 100);
|
|
4484
|
-
return () => window.clearTimeout(t);
|
|
4485
|
-
}, [variantCache, pageConfig?.id]);
|
|
4486
|
-
useEffect(() => {
|
|
4487
|
-
const isVisualEditorMode = () => {
|
|
4488
|
-
if (typeof window === "undefined") return false;
|
|
4489
|
-
const urlParams = new URLSearchParams(window.location.search);
|
|
4490
|
-
if (urlParams.get("visualEditor") === "true" || urlParams.get("preview") === "true") {
|
|
4491
|
-
return true;
|
|
4492
|
-
}
|
|
4493
|
-
const inIframe = window.self !== window.top;
|
|
4494
|
-
if (!inIframe) return false;
|
|
4495
|
-
try {
|
|
4496
|
-
if (document.referrer) {
|
|
4497
|
-
const referrerUrl = new URL(document.referrer);
|
|
4498
|
-
if (referrerUrl.hostname === "localhost" && referrerUrl.port === "5001") {
|
|
4499
|
-
return true;
|
|
4316
|
+
const iconSize = compact ? 20 : 28;
|
|
4317
|
+
return /* @__PURE__ */ jsxs(
|
|
4318
|
+
"div",
|
|
4319
|
+
{
|
|
4320
|
+
className: "amplifyup-slot-placeholder",
|
|
4321
|
+
style: {
|
|
4322
|
+
display: "flex",
|
|
4323
|
+
flexDirection: "column",
|
|
4324
|
+
alignItems: "center",
|
|
4325
|
+
justifyContent: "center",
|
|
4326
|
+
gap: compact ? 8 : 12,
|
|
4327
|
+
minHeight: compact ? 60 : void 0,
|
|
4328
|
+
width: "100%",
|
|
4329
|
+
pointerEvents: "none",
|
|
4330
|
+
textAlign: "center",
|
|
4331
|
+
boxSizing: "border-box",
|
|
4332
|
+
padding: compact ? "12px 8px" : "24px 16px"
|
|
4333
|
+
},
|
|
4334
|
+
children: [
|
|
4335
|
+
/* @__PURE__ */ jsx(
|
|
4336
|
+
"span",
|
|
4337
|
+
{
|
|
4338
|
+
className: "amplifyup-slot-placeholder-icon",
|
|
4339
|
+
style: {
|
|
4340
|
+
display: "inline-flex",
|
|
4341
|
+
alignItems: "center",
|
|
4342
|
+
justifyContent: "center",
|
|
4343
|
+
width: compact ? 36 : 48,
|
|
4344
|
+
height: compact ? 36 : 48,
|
|
4345
|
+
borderRadius: 12,
|
|
4346
|
+
border: "1.5px dashed currentColor",
|
|
4347
|
+
opacity: 0.9
|
|
4348
|
+
},
|
|
4349
|
+
children: /* @__PURE__ */ jsx(AddComponentIcon, { size: iconSize })
|
|
4500
4350
|
}
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4351
|
+
),
|
|
4352
|
+
/* @__PURE__ */ jsx(
|
|
4353
|
+
"span",
|
|
4354
|
+
{
|
|
4355
|
+
className: "amplifyup-slot-placeholder-label",
|
|
4356
|
+
style: {
|
|
4357
|
+
fontSize: compact ? 13 : 15,
|
|
4358
|
+
fontWeight: 600,
|
|
4359
|
+
lineHeight: 1.3,
|
|
4360
|
+
letterSpacing: "0.01em"
|
|
4361
|
+
},
|
|
4362
|
+
children: label
|
|
4363
|
+
}
|
|
4364
|
+
)
|
|
4365
|
+
]
|
|
4508
4366
|
}
|
|
4509
|
-
|
|
4510
|
-
|
|
4367
|
+
);
|
|
4368
|
+
}
|
|
4369
|
+
function defaultPreviewCanvas() {
|
|
4370
|
+
return /* @__PURE__ */ jsx(
|
|
4371
|
+
"div",
|
|
4372
|
+
{
|
|
4373
|
+
"data-slot-id": "main",
|
|
4374
|
+
"data-amplifyup-slot": "main",
|
|
4375
|
+
"data-slot-source": "page",
|
|
4376
|
+
"data-slot-empty": "true",
|
|
4377
|
+
style: { minHeight: "50vh", width: "100%", display: "block", position: "relative" },
|
|
4378
|
+
children: /* @__PURE__ */ jsx(EmptySlotHint, {})
|
|
4511
4379
|
}
|
|
4512
|
-
|
|
4513
|
-
|
|
4514
|
-
|
|
4515
|
-
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
|
|
4380
|
+
);
|
|
4381
|
+
}
|
|
4382
|
+
function hasAmplifyLayout(pageConfig) {
|
|
4383
|
+
return !!(pageConfig && pageConfig.id !== "default" && Array.isArray(pageConfig.layoutTree) && pageConfig.layoutTree.length > 0);
|
|
4384
|
+
}
|
|
4385
|
+
function normalizeRoutePath(route) {
|
|
4386
|
+
if (!route) return "";
|
|
4387
|
+
const path = route.split("?")[0] || "/";
|
|
4388
|
+
if (path.length > 1 && path.endsWith("/")) return path.replace(/\/+$/, "");
|
|
4389
|
+
return path || "/";
|
|
4390
|
+
}
|
|
4391
|
+
function samePageRoute(a, b) {
|
|
4392
|
+
const ar = normalizeRoutePath(a?.route);
|
|
4393
|
+
const br = normalizeRoutePath(b?.route);
|
|
4394
|
+
return !!ar && !!br && ar === br;
|
|
4395
|
+
}
|
|
4396
|
+
function layoutTreesEqual(a, b) {
|
|
4397
|
+
if (!a || !b) return a === b;
|
|
4398
|
+
return JSON.stringify(a.layoutTree) === JSON.stringify(b.layoutTree);
|
|
4399
|
+
}
|
|
4400
|
+
function AmplifyPageContent({
|
|
4401
|
+
fallback,
|
|
4402
|
+
renderComponent,
|
|
4403
|
+
pageConfig: pageConfigProp,
|
|
4404
|
+
forceComposerPreview = false,
|
|
4405
|
+
previewLoadingComponent,
|
|
4406
|
+
previewEmptyComponent,
|
|
4407
|
+
loadingComponent,
|
|
4408
|
+
emptyComponent,
|
|
4409
|
+
errorComponent
|
|
4410
|
+
}) {
|
|
4411
|
+
const client = useAmplifyUp();
|
|
4412
|
+
const preview = forceComposerPreview || isComposerPreview();
|
|
4413
|
+
const clientLayout = hasAmplifyLayout(client.pageConfig) ? client.pageConfig : null;
|
|
4414
|
+
const serverLayout = hasAmplifyLayout(pageConfigProp) ? pageConfigProp : null;
|
|
4415
|
+
let pageConfig = serverLayout ?? clientLayout;
|
|
4416
|
+
if (preview && clientLayout) {
|
|
4417
|
+
pageConfig = clientLayout;
|
|
4418
|
+
} else if (clientLayout && serverLayout && samePageRoute(clientLayout, serverLayout) && !layoutTreesEqual(clientLayout, serverLayout)) {
|
|
4419
|
+
pageConfig = clientLayout;
|
|
4420
|
+
} else if (clientLayout && !serverLayout) {
|
|
4421
|
+
pageConfig = clientLayout;
|
|
4422
|
+
}
|
|
4423
|
+
const loading = !hasAmplifyLayout(pageConfig) && client.loading;
|
|
4424
|
+
const error = hasAmplifyLayout(pageConfig) ? null : pageConfigProp ? null : client.error;
|
|
4425
|
+
const previewCanvas = previewEmptyComponent ?? defaultPreviewCanvas();
|
|
4426
|
+
const previewLoading = previewLoadingComponent ?? previewCanvas;
|
|
4427
|
+
if (preview) {
|
|
4428
|
+
return /* @__PURE__ */ jsx(
|
|
4429
|
+
AmplifyRenderer,
|
|
4430
|
+
{
|
|
4431
|
+
pageConfig: pageConfig ?? void 0,
|
|
4432
|
+
renderComponent,
|
|
4433
|
+
composerPreview: true,
|
|
4434
|
+
loadingComponent: loadingComponent ?? previewLoading,
|
|
4435
|
+
emptyComponent: emptyComponent ?? previewCanvas,
|
|
4436
|
+
errorComponent: errorComponent ?? (() => previewCanvas)
|
|
4520
4437
|
}
|
|
4521
|
-
return;
|
|
4522
|
-
}
|
|
4523
|
-
const convertLayoutTreeToComponentTree = (nodes, parentId = null) => {
|
|
4524
|
-
const result = [];
|
|
4525
|
-
nodes.forEach((node) => {
|
|
4526
|
-
if (!node) return;
|
|
4527
|
-
const treeNode = {
|
|
4528
|
-
id: node.id,
|
|
4529
|
-
componentId: node.componentId,
|
|
4530
|
-
componentName: node.componentId,
|
|
4531
|
-
// Will be enhanced with actual name if available
|
|
4532
|
-
parentId,
|
|
4533
|
-
children: []
|
|
4534
|
-
};
|
|
4535
|
-
if (node.slots && node.slots.length > 0) {
|
|
4536
|
-
node.slots.forEach((slot) => {
|
|
4537
|
-
const kids = Array.isArray(slot?.children) ? slot.children : [];
|
|
4538
|
-
if (kids.length > 0) {
|
|
4539
|
-
const slotChildren = convertLayoutTreeToComponentTree(kids, node.id);
|
|
4540
|
-
treeNode.children.push(...slotChildren);
|
|
4541
|
-
}
|
|
4542
|
-
});
|
|
4543
|
-
}
|
|
4544
|
-
result.push(treeNode);
|
|
4545
|
-
});
|
|
4546
|
-
return result;
|
|
4547
|
-
};
|
|
4548
|
-
const layoutTree2 = normalizedTree;
|
|
4549
|
-
const componentTree = convertLayoutTreeToComponentTree(layoutTree2);
|
|
4550
|
-
const describeLayoutTree = (nodes, depth = 0) => {
|
|
4551
|
-
if (!nodes?.length) return "";
|
|
4552
|
-
const indent = " ".repeat(depth);
|
|
4553
|
-
return nodes.map((n) => {
|
|
4554
|
-
const slotsDesc = (n.slots || []).map((s) => {
|
|
4555
|
-
const childCount = Array.isArray(s.children) ? s.children.length : 0;
|
|
4556
|
-
const childrenDesc = childCount > 0 ? describeLayoutTree(s.children || [], depth + 1) : "";
|
|
4557
|
-
return `${indent} slot "${s.slotId || s.slotName || "?"}" (${childCount} children)${childrenDesc ? "\n" + childrenDesc : ""}`;
|
|
4558
|
-
}).join("\n");
|
|
4559
|
-
return `${indent}- ${n.id} (${n.componentId || "?"})${slotsDesc ? "\n" + slotsDesc : ""}`;
|
|
4560
|
-
}).join("\n");
|
|
4561
|
-
};
|
|
4562
|
-
sdkDebugOnce(
|
|
4563
|
-
`layoutTree:${pageConfig?.id || ""}:${pageConfig?.route || ""}`,
|
|
4564
|
-
"[AmplifyRenderer] layoutTree received:\n%s",
|
|
4565
|
-
describeLayoutTree(layoutTree2)
|
|
4566
4438
|
);
|
|
4567
|
-
|
|
4568
|
-
const message = {
|
|
4569
|
-
type: "COMPONENT_TREE",
|
|
4570
|
-
tree: componentTree
|
|
4571
|
-
};
|
|
4572
|
-
window.parent.postMessage(message, "*");
|
|
4573
|
-
sdkDebug(
|
|
4574
|
-
"[AmplifyRenderer] Sent component tree from layoutTree:",
|
|
4575
|
-
componentTree.length,
|
|
4576
|
-
"root components"
|
|
4577
|
-
);
|
|
4578
|
-
}
|
|
4579
|
-
}, [pageConfig]);
|
|
4580
|
-
useEffect(() => {
|
|
4581
|
-
if (!pageConfig?.layoutTree || !pageConfig.layoutId) return;
|
|
4582
|
-
const roots = pageConfig.layoutTree;
|
|
4583
|
-
const fromEdge = contentSource === "edge" || roots.some((n) => n._contentSource === "edge");
|
|
4584
|
-
if (fromEdge) return;
|
|
4585
|
-
const sdk = getSDK();
|
|
4586
|
-
const instanceId = sdk.getInstanceId();
|
|
4587
|
-
const decisionApiUrl = sdk.getDecisionApiUrl();
|
|
4588
|
-
const orchestratorUrl = sdk.getOrchestratorUrl();
|
|
4589
|
-
if (!decisionApiUrl && !orchestratorUrl || !instanceId) return;
|
|
4590
|
-
const fetchVariants = async () => {
|
|
4591
|
-
const nodes = pageConfig.layoutTree;
|
|
4592
|
-
const newCache = {};
|
|
4593
|
-
const findZonedSlots = (nodeList) => {
|
|
4594
|
-
const results = [];
|
|
4595
|
-
for (const node of nodeList) {
|
|
4596
|
-
if (node.slots) {
|
|
4597
|
-
for (const slot of node.slots) {
|
|
4598
|
-
if (slot.zoneId && slot.variants) {
|
|
4599
|
-
const key = `${node.id}-${slot.slotId}`;
|
|
4600
|
-
results.push({ node, slot, key });
|
|
4601
|
-
}
|
|
4602
|
-
}
|
|
4603
|
-
}
|
|
4604
|
-
}
|
|
4605
|
-
return results;
|
|
4606
|
-
};
|
|
4607
|
-
const zonedSlots = findZonedSlots(nodes);
|
|
4608
|
-
await Promise.all(
|
|
4609
|
-
zonedSlots.map(async ({ node, slot, key }) => {
|
|
4610
|
-
try {
|
|
4611
|
-
let personalizationUrl;
|
|
4612
|
-
if (decisionApiUrl) {
|
|
4613
|
-
const url = new URL(decisionApiUrl);
|
|
4614
|
-
url.searchParams.set("instanceId", instanceId);
|
|
4615
|
-
const zoneId = slot.zoneId;
|
|
4616
|
-
if (zoneId) {
|
|
4617
|
-
url.searchParams.set("zoneId", zoneId);
|
|
4618
|
-
}
|
|
4619
|
-
const campaignId = slot.campaignId;
|
|
4620
|
-
if (campaignId) {
|
|
4621
|
-
url.searchParams.set("campaignId", campaignId);
|
|
4622
|
-
}
|
|
4623
|
-
personalizationUrl = url.toString();
|
|
4624
|
-
} else if (orchestratorUrl) {
|
|
4625
|
-
personalizationUrl = `${orchestratorUrl}/api/personalization/variant?instanceId=${encodeURIComponent(instanceId)}&layoutId=${encodeURIComponent(pageConfig.layoutId)}&slotId=${encodeURIComponent(slot.slotId)}&nodeId=${encodeURIComponent(node.id)}`;
|
|
4626
|
-
} else {
|
|
4627
|
-
return;
|
|
4628
|
-
}
|
|
4629
|
-
const response = await fetch(personalizationUrl);
|
|
4630
|
-
if (response.ok) {
|
|
4631
|
-
const data = await response.json();
|
|
4632
|
-
if (data.variantId && data.componentTree) {
|
|
4633
|
-
newCache[key] = {
|
|
4634
|
-
variantId: data.variantId,
|
|
4635
|
-
children: data.componentTree
|
|
4636
|
-
};
|
|
4637
|
-
if (typeof window !== "undefined") {
|
|
4638
|
-
if (window.__AMPLIFYUP_PREVIEW_MODE__ === true) {
|
|
4639
|
-
return;
|
|
4640
|
-
}
|
|
4641
|
-
if (window.location.pathname.includes("/api/pages/proxy")) {
|
|
4642
|
-
return;
|
|
4643
|
-
}
|
|
4644
|
-
if (window.self !== window.top) {
|
|
4645
|
-
return;
|
|
4646
|
-
}
|
|
4647
|
-
}
|
|
4648
|
-
sdk.track("Zone Impression", {
|
|
4649
|
-
zoneId: slot.zoneId,
|
|
4650
|
-
variantId: data.variantId,
|
|
4651
|
-
layoutId: pageConfig.layoutId,
|
|
4652
|
-
route: pageConfig.route
|
|
4653
|
-
});
|
|
4654
|
-
} else {
|
|
4655
|
-
const defaultVariant = slot.variants?.find((v) => v.isDefault);
|
|
4656
|
-
if (defaultVariant) {
|
|
4657
|
-
newCache[key] = {
|
|
4658
|
-
variantId: defaultVariant.variantId,
|
|
4659
|
-
children: defaultVariant.children
|
|
4660
|
-
};
|
|
4661
|
-
}
|
|
4662
|
-
}
|
|
4663
|
-
}
|
|
4664
|
-
} catch (err) {
|
|
4665
|
-
console.error(`Error fetching variant for slot ${key}:`, err);
|
|
4666
|
-
const defaultVariant = slot.variants?.find((v) => v.isDefault);
|
|
4667
|
-
if (defaultVariant) {
|
|
4668
|
-
newCache[key] = {
|
|
4669
|
-
variantId: defaultVariant.variantId,
|
|
4670
|
-
children: defaultVariant.children
|
|
4671
|
-
};
|
|
4672
|
-
}
|
|
4673
|
-
}
|
|
4674
|
-
})
|
|
4675
|
-
);
|
|
4676
|
-
setVariantCache(newCache);
|
|
4677
|
-
};
|
|
4678
|
-
fetchVariants();
|
|
4679
|
-
}, [pageConfig?.layoutTree, pageConfig?.layoutId, pageConfig?.route, contentSource]);
|
|
4439
|
+
}
|
|
4680
4440
|
if (loading) {
|
|
4681
|
-
return
|
|
4682
|
-
/* @__PURE__ */ jsx("div", { className: "h-8 bg-gray-200 rounded w-1/4 mb-4" }),
|
|
4683
|
-
/* @__PURE__ */ jsx("div", { className: "h-4 bg-gray-200 rounded w-1/2 mb-8" }),
|
|
4684
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
4685
|
-
/* @__PURE__ */ jsx("div", { className: "h-64 bg-gray-200 rounded" }),
|
|
4686
|
-
/* @__PURE__ */ jsx("div", { className: "h-32 bg-gray-200 rounded" })
|
|
4687
|
-
] })
|
|
4688
|
-
] }) }) }) });
|
|
4441
|
+
return loadingComponent ? /* @__PURE__ */ jsx(Fragment, { children: loadingComponent }) : null;
|
|
4689
4442
|
}
|
|
4690
|
-
if (error) {
|
|
4691
|
-
return /* @__PURE__ */ jsx(Fragment, { children: errorComponent
|
|
4692
|
-
|
|
4693
|
-
/* @__PURE__ */ jsx("p", { className: "text-red-700", children: error })
|
|
4694
|
-
] }) }) }) });
|
|
4443
|
+
if (error) {
|
|
4444
|
+
if (errorComponent) return /* @__PURE__ */ jsx(Fragment, { children: errorComponent(error) });
|
|
4445
|
+
return fallback ? /* @__PURE__ */ jsx(Fragment, { children: fallback }) : null;
|
|
4695
4446
|
}
|
|
4696
|
-
if (!pageConfig) {
|
|
4447
|
+
if (!hasAmplifyLayout(pageConfig)) {
|
|
4448
|
+
return fallback ? /* @__PURE__ */ jsx(Fragment, { children: fallback }) : null;
|
|
4449
|
+
}
|
|
4450
|
+
return /* @__PURE__ */ jsx(
|
|
4451
|
+
AmplifyRenderer,
|
|
4452
|
+
{
|
|
4453
|
+
pageConfig: pageConfig ?? void 0,
|
|
4454
|
+
renderComponent,
|
|
4455
|
+
loadingComponent,
|
|
4456
|
+
emptyComponent,
|
|
4457
|
+
errorComponent
|
|
4458
|
+
}
|
|
4459
|
+
);
|
|
4460
|
+
}
|
|
4461
|
+
|
|
4462
|
+
// src/composer-edit-mode.ts
|
|
4463
|
+
function isComposerEditMode() {
|
|
4464
|
+
if (typeof window === "undefined") return false;
|
|
4465
|
+
return isComposerPreview() && window.__AMPLIFYUP_EVENT_SELECTION__ !== true;
|
|
4466
|
+
}
|
|
4467
|
+
function subscribeComposerEdit(onStoreChange) {
|
|
4468
|
+
if (typeof window === "undefined") return () => {
|
|
4469
|
+
};
|
|
4470
|
+
window.addEventListener("amplifyup:composer-edit", onStoreChange);
|
|
4471
|
+
return () => window.removeEventListener("amplifyup:composer-edit", onStoreChange);
|
|
4472
|
+
}
|
|
4473
|
+
function getComposerEditModeServer() {
|
|
4474
|
+
return false;
|
|
4475
|
+
}
|
|
4476
|
+
var ComponentContext = createContext(null);
|
|
4477
|
+
function ComponentContextProvider({
|
|
4478
|
+
children,
|
|
4479
|
+
slots,
|
|
4480
|
+
props,
|
|
4481
|
+
layoutNodeId,
|
|
4482
|
+
componentId
|
|
4483
|
+
}) {
|
|
4484
|
+
const next = hydratePageResourceProps(props || {}, getPageResourceFields());
|
|
4485
|
+
return /* @__PURE__ */ jsx(
|
|
4486
|
+
ComponentContext.Provider,
|
|
4487
|
+
{
|
|
4488
|
+
value: { slots, props: next, layoutNodeId, componentId },
|
|
4489
|
+
children
|
|
4490
|
+
}
|
|
4491
|
+
);
|
|
4492
|
+
}
|
|
4493
|
+
function Slot({
|
|
4494
|
+
name,
|
|
4495
|
+
className
|
|
4496
|
+
}) {
|
|
4497
|
+
const context = useContext(ComponentContext);
|
|
4498
|
+
if (!context) {
|
|
4499
|
+
console.warn(`[AmplifyUp SDK] Slot "${name}" used outside ComponentContextProvider`);
|
|
4697
4500
|
return null;
|
|
4698
4501
|
}
|
|
4699
|
-
|
|
4700
|
-
|
|
4701
|
-
const
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4502
|
+
const slotContent = context.slots?.[name];
|
|
4503
|
+
const isEmpty = !slotContent;
|
|
4504
|
+
const isEditorMode = typeof window !== "undefined" && // Check for preview mode flag set by proxy
|
|
4505
|
+
(window.__AMPLIFYUP_PREVIEW_MODE__ === true || // Check URL query params
|
|
4506
|
+
new URLSearchParams(window.location.search).get("preview") === "true" || new URLSearchParams(window.location.search).get("visualEditor") === "true" || // Check if in iframe from orchestrator (check referrer hostname/port)
|
|
4507
|
+
window.self !== window.top && document.referrer && (() => {
|
|
4508
|
+
try {
|
|
4509
|
+
const referrerUrl = new URL(document.referrer);
|
|
4510
|
+
return referrerUrl.hostname === "localhost" && referrerUrl.port === "5001" || referrerUrl.pathname.includes("/dashboard/composer") || referrerUrl.pathname.includes("/dashboard/routes/");
|
|
4511
|
+
} catch {
|
|
4512
|
+
return false;
|
|
4513
|
+
}
|
|
4514
|
+
})());
|
|
4515
|
+
sdkDebugOnce(
|
|
4516
|
+
`slot:${context.layoutNodeId || ""}:${name}`,
|
|
4517
|
+
`[Slot:${name}]`,
|
|
4518
|
+
{
|
|
4519
|
+
isEmpty,
|
|
4520
|
+
isEditorMode,
|
|
4521
|
+
availableSlotKeys: context.slots ? Object.keys(context.slots) : []
|
|
4522
|
+
}
|
|
4523
|
+
);
|
|
4524
|
+
return /* @__PURE__ */ jsx(
|
|
4525
|
+
"div",
|
|
4526
|
+
{
|
|
4527
|
+
className,
|
|
4528
|
+
"data-slot-name": name,
|
|
4529
|
+
"data-slot-id": name,
|
|
4530
|
+
"data-amplifyup-slot": name,
|
|
4531
|
+
"data-slot-empty": isEmpty ? "true" : void 0,
|
|
4532
|
+
"data-parent-node-id": context.layoutNodeId || void 0,
|
|
4533
|
+
"data-parent-component-id": context.componentId || void 0,
|
|
4534
|
+
style: {
|
|
4535
|
+
// Only add minimum height when empty (for drop target visibility)
|
|
4536
|
+
minHeight: isEmpty ? "60px" : void 0,
|
|
4537
|
+
// Only add position relative for overlay positioning in editor mode
|
|
4538
|
+
position: isEditorMode ? "relative" : void 0
|
|
4539
|
+
},
|
|
4540
|
+
children: isEmpty ? isEditorMode ? /* @__PURE__ */ jsx(EmptySlotHint, { compact: true }) : /* @__PURE__ */ jsx(
|
|
4707
4541
|
"div",
|
|
4708
4542
|
{
|
|
4709
|
-
"
|
|
4710
|
-
|
|
4711
|
-
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
"data-slot-id": "content",
|
|
4718
|
-
"data-amplifyup-slot": "content",
|
|
4719
|
-
"data-parent-node-id": node.id,
|
|
4720
|
-
"data-parent-component-id": "AmplifyZone",
|
|
4721
|
-
children: children.filter(Boolean).map((child) => /* @__PURE__ */ jsx(Fragment$1, { children: renderNode(child) }, child.id))
|
|
4722
|
-
}
|
|
4723
|
-
)
|
|
4543
|
+
className: "amplifyup-slot-placeholder",
|
|
4544
|
+
style: {
|
|
4545
|
+
minHeight: "60px",
|
|
4546
|
+
color: "#9ca3af",
|
|
4547
|
+
fontSize: "14px",
|
|
4548
|
+
pointerEvents: "none"
|
|
4549
|
+
},
|
|
4550
|
+
children: `Empty slot: ${name}`
|
|
4724
4551
|
}
|
|
4725
|
-
)
|
|
4552
|
+
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4553
|
+
isEditorMode && /* @__PURE__ */ jsxs(
|
|
4554
|
+
"div",
|
|
4555
|
+
{
|
|
4556
|
+
className: "amplifyup-slot-label",
|
|
4557
|
+
style: {
|
|
4558
|
+
position: "absolute",
|
|
4559
|
+
top: "4px",
|
|
4560
|
+
left: "4px",
|
|
4561
|
+
fontSize: "10px",
|
|
4562
|
+
color: "#9ca3af",
|
|
4563
|
+
pointerEvents: "none",
|
|
4564
|
+
zIndex: 1
|
|
4565
|
+
},
|
|
4566
|
+
children: [
|
|
4567
|
+
"Slot: ",
|
|
4568
|
+
name
|
|
4569
|
+
]
|
|
4570
|
+
}
|
|
4571
|
+
),
|
|
4572
|
+
slotContent
|
|
4573
|
+
] })
|
|
4574
|
+
}
|
|
4575
|
+
);
|
|
4576
|
+
}
|
|
4577
|
+
function isLikelyNonTextFieldName(name) {
|
|
4578
|
+
const n = name.toLowerCase();
|
|
4579
|
+
return n.includes("href") || n.includes("url") || n.includes("src") || n.includes("image") || n.includes("icon") || n.includes("overlay") || n.includes("color");
|
|
4580
|
+
}
|
|
4581
|
+
var COMPOSER_EMPTY_FIELD_HINT = "Click here to edit this field";
|
|
4582
|
+
var EMPTY_FIELD_PLACEHOLDERS = /* @__PURE__ */ new Set([
|
|
4583
|
+
COMPOSER_EMPTY_FIELD_HINT,
|
|
4584
|
+
"Click here to enter text",
|
|
4585
|
+
"Sample Title",
|
|
4586
|
+
"Sample Heading",
|
|
4587
|
+
"Sample Subheading"
|
|
4588
|
+
]);
|
|
4589
|
+
function isComposerEmptyText(value) {
|
|
4590
|
+
if (value === void 0 || value === null) return true;
|
|
4591
|
+
if (typeof value !== "string") return false;
|
|
4592
|
+
const trimmed = value.trim();
|
|
4593
|
+
return trimmed === "" || EMPTY_FIELD_PLACEHOLDERS.has(trimmed);
|
|
4594
|
+
}
|
|
4595
|
+
function canInlineEdit(name, value) {
|
|
4596
|
+
if (!name || isLikelyNonTextFieldName(name)) return false;
|
|
4597
|
+
if (value !== void 0 && value !== null && typeof value === "object") {
|
|
4598
|
+
return false;
|
|
4599
|
+
}
|
|
4600
|
+
if (typeof value === "boolean") return false;
|
|
4601
|
+
return true;
|
|
4602
|
+
}
|
|
4603
|
+
function canInlineEditRichText(name, value) {
|
|
4604
|
+
if (!name || isLikelyNonTextFieldName(name)) return false;
|
|
4605
|
+
if (typeof value === "boolean") return false;
|
|
4606
|
+
if (value !== void 0 && value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
4607
|
+
return false;
|
|
4608
|
+
}
|
|
4609
|
+
return true;
|
|
4610
|
+
}
|
|
4611
|
+
function useComposerEditMode() {
|
|
4612
|
+
return useSyncExternalStore(
|
|
4613
|
+
subscribeComposerEdit,
|
|
4614
|
+
isComposerEditMode,
|
|
4615
|
+
getComposerEditModeServer
|
|
4616
|
+
);
|
|
4617
|
+
}
|
|
4618
|
+
function useBoundField(field, value, name, component) {
|
|
4619
|
+
const bound = resolveEditableBinding(field, value, name);
|
|
4620
|
+
if (bound.requiresName) {
|
|
4621
|
+
console.warn(
|
|
4622
|
+
`[AmplifyUp SDK] ${component} value={\u2026} requires name="\u2026" for computed values`
|
|
4623
|
+
);
|
|
4624
|
+
}
|
|
4625
|
+
const fieldValue = useComposerFieldValue(bound.name, bound.value);
|
|
4626
|
+
return { editName: bound.name, fieldValue };
|
|
4627
|
+
}
|
|
4628
|
+
function commitComposerField(layoutNodeId, componentId, name, value) {
|
|
4629
|
+
if (typeof window === "undefined" || window.parent === window) return;
|
|
4630
|
+
window.parent.postMessage(
|
|
4631
|
+
{
|
|
4632
|
+
type: "AMPLIFYUP_FIELD_COMMIT",
|
|
4633
|
+
layoutNodeId,
|
|
4634
|
+
componentId,
|
|
4635
|
+
fieldName: name,
|
|
4636
|
+
value
|
|
4637
|
+
},
|
|
4638
|
+
"*"
|
|
4639
|
+
);
|
|
4640
|
+
}
|
|
4641
|
+
function looksLikeRichCanvasField(name) {
|
|
4642
|
+
const tokens = String(name || "").replace(/([a-z])([A-Z])/g, "$1 $2").split(/[._\-\s/]+/).map((s) => s.toLowerCase()).filter(Boolean);
|
|
4643
|
+
const last = tokens[tokens.length - 1] || "";
|
|
4644
|
+
return last === "body" || last === "content" || last === "copy" || last === "excerpt" || last === "markdown" || last === "richtext";
|
|
4645
|
+
}
|
|
4646
|
+
var lastRichTextRequestAt = 0;
|
|
4647
|
+
function requestCanvasRichTextEdit(opts) {
|
|
4648
|
+
if (typeof window === "undefined" || window.parent === window) return;
|
|
4649
|
+
if (!opts.name) return;
|
|
4650
|
+
const now = Date.now();
|
|
4651
|
+
if (now - lastRichTextRequestAt < 400) return;
|
|
4652
|
+
lastRichTextRequestAt = now;
|
|
4653
|
+
const rect = opts.el.getBoundingClientRect();
|
|
4654
|
+
window.parent.postMessage(
|
|
4655
|
+
{
|
|
4656
|
+
type: "AMPLIFYUP_RICHTEXT_EDIT",
|
|
4657
|
+
layoutNodeId: opts.layoutNodeId,
|
|
4658
|
+
componentId: opts.componentId,
|
|
4659
|
+
fieldName: opts.name,
|
|
4660
|
+
value: opts.value,
|
|
4661
|
+
bounds: {
|
|
4662
|
+
top: rect.top,
|
|
4663
|
+
left: rect.left,
|
|
4664
|
+
width: Math.max(rect.width, 240),
|
|
4665
|
+
height: Math.max(rect.height, 64)
|
|
4666
|
+
}
|
|
4667
|
+
},
|
|
4668
|
+
"*"
|
|
4669
|
+
);
|
|
4670
|
+
}
|
|
4671
|
+
function placeCaret(el, atStart = false) {
|
|
4672
|
+
const range = document.createRange();
|
|
4673
|
+
range.selectNodeContents(el);
|
|
4674
|
+
range.collapse(atStart);
|
|
4675
|
+
const sel = window.getSelection();
|
|
4676
|
+
sel?.removeAllRanges();
|
|
4677
|
+
sel?.addRange(range);
|
|
4678
|
+
}
|
|
4679
|
+
function ComposerInlineField({
|
|
4680
|
+
name,
|
|
4681
|
+
value,
|
|
4682
|
+
className,
|
|
4683
|
+
layoutNodeId,
|
|
4684
|
+
componentId,
|
|
4685
|
+
rich = false
|
|
4686
|
+
}) {
|
|
4687
|
+
const [focused, setFocused] = useState(false);
|
|
4688
|
+
const elRef = useRef(null);
|
|
4689
|
+
const storedEmpty = isComposerEmptyText(value);
|
|
4690
|
+
const text = storedEmpty ? "" : formatFieldValue(value);
|
|
4691
|
+
const hint = COMPOSER_EMPTY_FIELD_HINT;
|
|
4692
|
+
const idleDisplay = storedEmpty ? hint : text;
|
|
4693
|
+
const showHint = storedEmpty && !focused;
|
|
4694
|
+
useEffect(() => {
|
|
4695
|
+
const el = elRef.current;
|
|
4696
|
+
if (!el) return;
|
|
4697
|
+
if (document.activeElement === el) return;
|
|
4698
|
+
if (el.querySelector(
|
|
4699
|
+
"input, button, select, textarea, form, svg, iframe, img"
|
|
4700
|
+
)) {
|
|
4701
|
+
return;
|
|
4726
4702
|
}
|
|
4727
|
-
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
|
|
4703
|
+
const next = idleDisplay || "";
|
|
4704
|
+
if (el.textContent !== next) el.textContent = next;
|
|
4705
|
+
}, [idleDisplay]);
|
|
4706
|
+
const finishEdit = () => {
|
|
4707
|
+
const raw = (elRef.current?.innerText ?? "").replace(/\u00a0/g, " ").replace(/\n+$/g, "");
|
|
4708
|
+
const next = raw.trim() === "" ? "" : raw;
|
|
4709
|
+
setFocused(false);
|
|
4710
|
+
if (storedEmpty && next === "") {
|
|
4711
|
+
if (elRef.current) elRef.current.textContent = hint;
|
|
4712
|
+
if (typeof value === "string" && EMPTY_FIELD_PLACEHOLDERS.has(value.trim())) {
|
|
4713
|
+
commitComposerField(layoutNodeId, componentId, name, "");
|
|
4714
|
+
}
|
|
4715
|
+
return;
|
|
4716
|
+
}
|
|
4717
|
+
if (next === text) return;
|
|
4718
|
+
commitComposerField(layoutNodeId, componentId, name, next);
|
|
4719
|
+
};
|
|
4720
|
+
const openRichEditor = (event) => {
|
|
4721
|
+
if (!isComposerEditMode() || !elRef.current) return;
|
|
4722
|
+
event?.preventDefault();
|
|
4723
|
+
event?.stopPropagation();
|
|
4724
|
+
const source = typeof value === "string" && !storedEmpty ? value : text || "";
|
|
4725
|
+
requestCanvasRichTextEdit({
|
|
4726
|
+
el: elRef.current,
|
|
4727
|
+
layoutNodeId,
|
|
4728
|
+
componentId,
|
|
4729
|
+
name,
|
|
4730
|
+
value: source
|
|
4732
4731
|
});
|
|
4733
|
-
|
|
4734
|
-
|
|
4735
|
-
|
|
4736
|
-
|
|
4737
|
-
|
|
4738
|
-
|
|
4739
|
-
|
|
4740
|
-
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
|
|
4732
|
+
};
|
|
4733
|
+
return /* @__PURE__ */ jsx(
|
|
4734
|
+
"span",
|
|
4735
|
+
{
|
|
4736
|
+
ref: elRef,
|
|
4737
|
+
className,
|
|
4738
|
+
"data-amplifyup-field": name,
|
|
4739
|
+
"data-amplifyup-field-type": rich ? "richtext" : "text",
|
|
4740
|
+
"data-amplifyup-node-id": layoutNodeId || void 0,
|
|
4741
|
+
"data-amplifyup-empty-hint": showHint ? "true" : void 0,
|
|
4742
|
+
contentEditable: !rich,
|
|
4743
|
+
suppressContentEditableWarning: true,
|
|
4744
|
+
role: "textbox",
|
|
4745
|
+
tabIndex: 0,
|
|
4746
|
+
onMouseDown: (event) => {
|
|
4747
|
+
event.stopPropagation();
|
|
4748
|
+
},
|
|
4749
|
+
onClick: (event) => {
|
|
4750
|
+
if (!isComposerEditMode()) return;
|
|
4751
|
+
const link = event.target?.closest?.("a");
|
|
4752
|
+
if (link) event.preventDefault();
|
|
4753
|
+
if (rich) {
|
|
4754
|
+
openRichEditor(event);
|
|
4755
|
+
return;
|
|
4744
4756
|
}
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
4751
|
-
|
|
4752
|
-
|
|
4753
|
-
|
|
4754
|
-
|
|
4755
|
-
|
|
4756
|
-
|
|
4757
|
-
|
|
4757
|
+
},
|
|
4758
|
+
onFocus: () => {
|
|
4759
|
+
if (!isComposerEditMode()) return;
|
|
4760
|
+
if (rich) {
|
|
4761
|
+
openRichEditor();
|
|
4762
|
+
return;
|
|
4763
|
+
}
|
|
4764
|
+
setFocused(true);
|
|
4765
|
+
const el = elRef.current;
|
|
4766
|
+
if (el && storedEmpty) {
|
|
4767
|
+
el.textContent = "";
|
|
4768
|
+
placeCaret(el, true);
|
|
4769
|
+
}
|
|
4770
|
+
},
|
|
4771
|
+
onBlur: rich ? void 0 : finishEdit,
|
|
4772
|
+
onKeyDown: (event) => {
|
|
4773
|
+
event.stopPropagation();
|
|
4774
|
+
if (event.key === "Enter" && !event.shiftKey) {
|
|
4775
|
+
event.preventDefault();
|
|
4776
|
+
event.currentTarget.blur();
|
|
4777
|
+
}
|
|
4778
|
+
if (event.key === "Escape") {
|
|
4779
|
+
event.preventDefault();
|
|
4780
|
+
if (elRef.current) elRef.current.textContent = idleDisplay || "";
|
|
4781
|
+
setFocused(false);
|
|
4782
|
+
event.currentTarget.blur();
|
|
4783
|
+
}
|
|
4784
|
+
},
|
|
4785
|
+
style: {
|
|
4786
|
+
cursor: "text",
|
|
4787
|
+
outline: "1px dashed color-mix(in srgb, currentColor 40%, transparent)",
|
|
4788
|
+
outlineOffset: "2px",
|
|
4789
|
+
minWidth: "1ch",
|
|
4790
|
+
minHeight: "1em",
|
|
4791
|
+
// Do not force `inline` — that overrides Tailwind `block` and parks
|
|
4792
|
+
// an empty-field hint on the same line as a sibling that has a value.
|
|
4793
|
+
opacity: showHint ? 0.5 : void 0
|
|
4758
4794
|
}
|
|
4759
4795
|
}
|
|
4760
|
-
|
|
4796
|
+
);
|
|
4797
|
+
}
|
|
4798
|
+
function ComposerInlineHtml({
|
|
4799
|
+
name,
|
|
4800
|
+
html,
|
|
4801
|
+
sourceValue,
|
|
4802
|
+
className,
|
|
4803
|
+
Tag = "div",
|
|
4804
|
+
layoutNodeId,
|
|
4805
|
+
componentId
|
|
4806
|
+
}) {
|
|
4807
|
+
const elRef = useRef(null);
|
|
4808
|
+
useEffect(() => {
|
|
4809
|
+
const el = elRef.current;
|
|
4810
|
+
if (!el) return;
|
|
4811
|
+
if (el.innerHTML !== html) el.innerHTML = html;
|
|
4812
|
+
}, [html]);
|
|
4813
|
+
const openRichEditor = (event) => {
|
|
4814
|
+
if (!elRef.current) return;
|
|
4815
|
+
event.preventDefault();
|
|
4816
|
+
event.stopPropagation();
|
|
4817
|
+
requestCanvasRichTextEdit({
|
|
4818
|
+
el: elRef.current,
|
|
4819
|
+
layoutNodeId,
|
|
4820
|
+
componentId,
|
|
4821
|
+
name,
|
|
4822
|
+
value: sourceValue
|
|
4823
|
+
});
|
|
4824
|
+
};
|
|
4825
|
+
return React2.createElement(Tag, {
|
|
4826
|
+
ref: elRef,
|
|
4827
|
+
className,
|
|
4828
|
+
"data-amplifyup-field": name,
|
|
4829
|
+
"data-amplifyup-field-type": "richtext",
|
|
4830
|
+
"data-amplifyup-node-id": layoutNodeId || void 0,
|
|
4831
|
+
dangerouslySetInnerHTML: { __html: html },
|
|
4832
|
+
onMouseDown: (event) => {
|
|
4833
|
+
event.stopPropagation();
|
|
4834
|
+
},
|
|
4835
|
+
onClick: openRichEditor,
|
|
4836
|
+
style: {
|
|
4837
|
+
cursor: "text",
|
|
4838
|
+
outline: "1px dashed color-mix(in srgb, currentColor 40%, transparent)",
|
|
4839
|
+
outlineOffset: "2px"
|
|
4840
|
+
}
|
|
4841
|
+
});
|
|
4842
|
+
}
|
|
4843
|
+
function formatFieldValue(value) {
|
|
4844
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
4845
|
+
return String(value);
|
|
4846
|
+
}
|
|
4847
|
+
if (Array.isArray(value)) {
|
|
4848
|
+
const parts = value.map((item) => {
|
|
4849
|
+
if (typeof item === "string") return item;
|
|
4850
|
+
if (item && typeof item === "object" && "children" in item && Array.isArray(item.children)) {
|
|
4851
|
+
return item.children.map((c) => typeof c?.text === "string" ? c.text : "").join("");
|
|
4852
|
+
}
|
|
4853
|
+
return "";
|
|
4854
|
+
}).filter(Boolean);
|
|
4855
|
+
if (parts.length > 0) return parts.join(" ");
|
|
4856
|
+
}
|
|
4857
|
+
if (value && typeof value === "object") {
|
|
4858
|
+
return "";
|
|
4859
|
+
}
|
|
4860
|
+
return "";
|
|
4861
|
+
}
|
|
4862
|
+
function warnProjectionProps(component, hasField, hasValue, name) {
|
|
4863
|
+
if (process.env.NODE_ENV === "production") return;
|
|
4864
|
+
if (!hasField && !hasValue && !name) {
|
|
4865
|
+
console.warn(
|
|
4866
|
+
`[AmplifyUp SDK] ${component} needs field={fields.yourProp} (or value + name for computed values)`
|
|
4867
|
+
);
|
|
4868
|
+
}
|
|
4869
|
+
}
|
|
4870
|
+
function hasOwnProp(props, key) {
|
|
4871
|
+
return Object.prototype.hasOwnProperty.call(props, key);
|
|
4872
|
+
}
|
|
4873
|
+
function Field(props) {
|
|
4874
|
+
const { field, value, name, className } = props;
|
|
4875
|
+
const context = useContext(ComponentContext);
|
|
4876
|
+
const composerEdit = useComposerEditMode();
|
|
4877
|
+
const hasField = isFieldEnvelope(field);
|
|
4878
|
+
const hasValue = hasOwnProp(props, "value");
|
|
4879
|
+
const { editName, fieldValue } = useBoundField(field, value, name, "Field");
|
|
4880
|
+
warnProjectionProps("Field", hasField, hasValue, name);
|
|
4881
|
+
if (!hasField && !hasValue && !name) {
|
|
4882
|
+
return null;
|
|
4883
|
+
}
|
|
4884
|
+
if (Array.isArray(fieldValue)) {
|
|
4885
|
+
return null;
|
|
4886
|
+
}
|
|
4887
|
+
const empty = isComposerEmptyText(fieldValue);
|
|
4888
|
+
if (composerEdit && editName && context && canInlineEdit(editName, fieldValue)) {
|
|
4761
4889
|
return /* @__PURE__ */ jsx(
|
|
4762
|
-
|
|
4890
|
+
ComposerInlineField,
|
|
4763
4891
|
{
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
4892
|
+
name: editName,
|
|
4893
|
+
value: fieldValue,
|
|
4894
|
+
className,
|
|
4895
|
+
layoutNodeId: context.layoutNodeId,
|
|
4896
|
+
componentId: context.componentId,
|
|
4897
|
+
rich: looksLikeRichCanvasField(editName)
|
|
4898
|
+
}
|
|
4899
|
+
);
|
|
4900
|
+
}
|
|
4901
|
+
if (empty) return null;
|
|
4902
|
+
const text = formatFieldValue(fieldValue);
|
|
4903
|
+
if (!text) return null;
|
|
4904
|
+
return /* @__PURE__ */ jsx("span", { className, children: text });
|
|
4905
|
+
}
|
|
4906
|
+
var COMPOSER_EMPTY_COLLECTION_HINT = "Click here to add an item";
|
|
4907
|
+
function CollectionChromeButton({
|
|
4908
|
+
label,
|
|
4909
|
+
onClick
|
|
4910
|
+
}) {
|
|
4911
|
+
return /* @__PURE__ */ jsx(
|
|
4912
|
+
"button",
|
|
4913
|
+
{
|
|
4914
|
+
type: "button",
|
|
4915
|
+
onMouseDown: (event) => event.stopPropagation(),
|
|
4916
|
+
onClick: (event) => {
|
|
4917
|
+
event.preventDefault();
|
|
4918
|
+
event.stopPropagation();
|
|
4919
|
+
onClick();
|
|
4920
|
+
},
|
|
4921
|
+
style: {
|
|
4922
|
+
fontSize: 11,
|
|
4923
|
+
lineHeight: 1.2,
|
|
4924
|
+
padding: "4px 8px",
|
|
4925
|
+
border: "1px solid color-mix(in srgb, currentColor 28%, transparent)",
|
|
4926
|
+
borderRadius: 6,
|
|
4927
|
+
background: "transparent",
|
|
4928
|
+
cursor: "pointer",
|
|
4929
|
+
color: "inherit"
|
|
4930
|
+
},
|
|
4931
|
+
children: label
|
|
4932
|
+
}
|
|
4933
|
+
);
|
|
4934
|
+
}
|
|
4935
|
+
function Collection({
|
|
4936
|
+
field,
|
|
4937
|
+
children,
|
|
4938
|
+
className
|
|
4939
|
+
}) {
|
|
4940
|
+
const context = useContext(ComponentContext);
|
|
4941
|
+
const store = useComposerStore();
|
|
4942
|
+
const composerEdit = useComposerEditMode();
|
|
4943
|
+
const name = isFieldEnvelope(field) ? field.name : "";
|
|
4944
|
+
const overlay = useComposerFieldValue(name, void 0);
|
|
4945
|
+
const items = resolveCollectionItems(field, overlay);
|
|
4946
|
+
const writeItems = (nextPlain) => {
|
|
4947
|
+
if (name && store) {
|
|
4948
|
+
const prefixed = name ? store.keys().filter((key) => key === name || key.startsWith(`${name}.`)) : [];
|
|
4949
|
+
for (const key of prefixed) store.delete(key);
|
|
4950
|
+
store.set(name, nextPlain);
|
|
4951
|
+
for (const patch of collectFieldPatches(
|
|
4952
|
+
toFieldEnvelopes({ [name]: nextPlain })
|
|
4953
|
+
)) {
|
|
4954
|
+
store.set(patch.name, patch.value);
|
|
4785
4955
|
}
|
|
4956
|
+
}
|
|
4957
|
+
commitComposerField(
|
|
4958
|
+
context?.layoutNodeId,
|
|
4959
|
+
context?.componentId,
|
|
4960
|
+
name,
|
|
4961
|
+
nextPlain
|
|
4786
4962
|
);
|
|
4787
4963
|
};
|
|
4788
|
-
const
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
{
|
|
4796
|
-
"data-slot-id": "main",
|
|
4797
|
-
"data-amplifyup-slot": "main",
|
|
4798
|
-
"data-slot-source": "page",
|
|
4799
|
-
"data-slot-empty": layoutTree.length === 0 ? "true" : void 0,
|
|
4800
|
-
children: layoutTree.map((node) => /* @__PURE__ */ jsx(Fragment$1, { children: renderNode(node) }, node.id))
|
|
4964
|
+
const plainItems = () => items.map((item, index) => {
|
|
4965
|
+
const base = unwrapFieldsBag(item);
|
|
4966
|
+
if (!store || !name) return base;
|
|
4967
|
+
const out = { ...base };
|
|
4968
|
+
for (const key of Object.keys(out)) {
|
|
4969
|
+
const overlayValue = store.get(`${name}.${index}.${key}`);
|
|
4970
|
+
if (overlayValue !== void 0) out[key] = overlayValue;
|
|
4801
4971
|
}
|
|
4802
|
-
|
|
4803
|
-
}
|
|
4804
|
-
|
|
4805
|
-
|
|
4806
|
-
|
|
4807
|
-
|
|
4972
|
+
return out;
|
|
4973
|
+
});
|
|
4974
|
+
const addItem = () => writeItems([...plainItems(), {}]);
|
|
4975
|
+
const removeItem = (index) => writeItems(plainItems().filter((_, i) => i !== index));
|
|
4976
|
+
const moveItem = (index, delta) => {
|
|
4977
|
+
const next = plainItems();
|
|
4978
|
+
const target = index + delta;
|
|
4979
|
+
if (target < 0 || target >= next.length) return;
|
|
4980
|
+
const swap = next[index];
|
|
4981
|
+
next[index] = next[target];
|
|
4982
|
+
next[target] = swap;
|
|
4983
|
+
writeItems(next);
|
|
4984
|
+
};
|
|
4985
|
+
if (!composerEdit) {
|
|
4986
|
+
if (items.length === 0) return null;
|
|
4987
|
+
return /* @__PURE__ */ jsx("span", { className, style: { display: "contents" }, children: items.map((item, index) => /* @__PURE__ */ jsx(React2.Fragment, { children: children(item, index) }, item && typeof item === "object" ? `${name}.${index}` : index)) });
|
|
4988
|
+
}
|
|
4989
|
+
if (items.length === 0) {
|
|
4990
|
+
return /* @__PURE__ */ jsx(
|
|
4991
|
+
"span",
|
|
4992
|
+
{
|
|
4993
|
+
className,
|
|
4994
|
+
"data-amplifyup-collection": name || void 0,
|
|
4995
|
+
"data-amplifyup-collection-empty": "true",
|
|
4996
|
+
"data-amplifyup-node-id": context?.layoutNodeId || void 0,
|
|
4997
|
+
role: "button",
|
|
4998
|
+
tabIndex: 0,
|
|
4999
|
+
onMouseDown: (event) => event.stopPropagation(),
|
|
5000
|
+
onClick: (event) => {
|
|
5001
|
+
event.preventDefault();
|
|
5002
|
+
event.stopPropagation();
|
|
5003
|
+
addItem();
|
|
5004
|
+
},
|
|
5005
|
+
onKeyDown: (event) => {
|
|
5006
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
5007
|
+
event.preventDefault();
|
|
5008
|
+
addItem();
|
|
5009
|
+
}
|
|
5010
|
+
},
|
|
5011
|
+
style: {
|
|
5012
|
+
display: "block",
|
|
5013
|
+
cursor: "pointer",
|
|
5014
|
+
outline: "1px dashed color-mix(in srgb, currentColor 40%, transparent)",
|
|
5015
|
+
outlineOffset: 2,
|
|
5016
|
+
minHeight: "3em",
|
|
5017
|
+
opacity: 0.5
|
|
5018
|
+
},
|
|
5019
|
+
children: /* @__PURE__ */ jsx(EmptySlotHint, { label: COMPOSER_EMPTY_COLLECTION_HINT, compact: true })
|
|
5020
|
+
}
|
|
5021
|
+
);
|
|
5022
|
+
}
|
|
5023
|
+
return /* @__PURE__ */ jsxs(
|
|
5024
|
+
"span",
|
|
4808
5025
|
{
|
|
4809
|
-
|
|
4810
|
-
"data-amplifyup-
|
|
4811
|
-
"data-
|
|
4812
|
-
"
|
|
4813
|
-
|
|
4814
|
-
|
|
5026
|
+
className,
|
|
5027
|
+
"data-amplifyup-collection": name || void 0,
|
|
5028
|
+
"data-amplifyup-node-id": context?.layoutNodeId || void 0,
|
|
5029
|
+
style: { display: "flex", flexDirection: "column", gap: 8 },
|
|
5030
|
+
children: [
|
|
5031
|
+
items.map((item, index) => /* @__PURE__ */ jsxs(
|
|
5032
|
+
"span",
|
|
5033
|
+
{
|
|
5034
|
+
"data-amplifyup-collection-item": `${name}.${index}`,
|
|
5035
|
+
style: {
|
|
5036
|
+
display: "block",
|
|
5037
|
+
outline: "1px dashed color-mix(in srgb, currentColor 28%, transparent)",
|
|
5038
|
+
outlineOffset: 2,
|
|
5039
|
+
padding: 8
|
|
5040
|
+
},
|
|
5041
|
+
children: [
|
|
5042
|
+
/* @__PURE__ */ jsxs(
|
|
5043
|
+
"span",
|
|
5044
|
+
{
|
|
5045
|
+
style: {
|
|
5046
|
+
display: "flex",
|
|
5047
|
+
gap: 6,
|
|
5048
|
+
justifyContent: "flex-end",
|
|
5049
|
+
marginBottom: 8
|
|
5050
|
+
},
|
|
5051
|
+
children: [
|
|
5052
|
+
/* @__PURE__ */ jsx(
|
|
5053
|
+
CollectionChromeButton,
|
|
5054
|
+
{
|
|
5055
|
+
label: "Move up",
|
|
5056
|
+
onClick: () => moveItem(index, -1)
|
|
5057
|
+
}
|
|
5058
|
+
),
|
|
5059
|
+
/* @__PURE__ */ jsx(
|
|
5060
|
+
CollectionChromeButton,
|
|
5061
|
+
{
|
|
5062
|
+
label: "Move down",
|
|
5063
|
+
onClick: () => moveItem(index, 1)
|
|
5064
|
+
}
|
|
5065
|
+
),
|
|
5066
|
+
/* @__PURE__ */ jsx(
|
|
5067
|
+
CollectionChromeButton,
|
|
5068
|
+
{
|
|
5069
|
+
label: "Remove",
|
|
5070
|
+
onClick: () => removeItem(index)
|
|
5071
|
+
}
|
|
5072
|
+
)
|
|
5073
|
+
]
|
|
5074
|
+
}
|
|
5075
|
+
),
|
|
5076
|
+
children(item, index)
|
|
5077
|
+
]
|
|
5078
|
+
},
|
|
5079
|
+
`${name}.${index}`
|
|
5080
|
+
)),
|
|
5081
|
+
/* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(CollectionChromeButton, { label: "Add item", onClick: addItem }) })
|
|
5082
|
+
]
|
|
4815
5083
|
}
|
|
4816
5084
|
);
|
|
4817
5085
|
}
|
|
4818
|
-
function
|
|
4819
|
-
|
|
4820
|
-
}
|
|
4821
|
-
|
|
4822
|
-
|
|
4823
|
-
|
|
4824
|
-
|
|
4825
|
-
return path || "/";
|
|
4826
|
-
}
|
|
4827
|
-
function samePageRoute(a, b) {
|
|
4828
|
-
const ar = normalizeRoutePath(a?.route);
|
|
4829
|
-
const br = normalizeRoutePath(b?.route);
|
|
4830
|
-
return !!ar && !!br && ar === br;
|
|
4831
|
-
}
|
|
4832
|
-
function layoutTreesEqual(a, b) {
|
|
4833
|
-
if (!a || !b) return a === b;
|
|
4834
|
-
return JSON.stringify(a.layoutTree) === JSON.stringify(b.layoutTree);
|
|
5086
|
+
function markdownToHtml(markdown) {
|
|
5087
|
+
try {
|
|
5088
|
+
const result = marked.parse(markdown, { async: false });
|
|
5089
|
+
return typeof result === "string" ? result : "";
|
|
5090
|
+
} catch {
|
|
5091
|
+
return markdown;
|
|
5092
|
+
}
|
|
4835
5093
|
}
|
|
4836
|
-
function
|
|
4837
|
-
|
|
4838
|
-
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
|
|
4842
|
-
|
|
4843
|
-
|
|
4844
|
-
|
|
4845
|
-
|
|
4846
|
-
|
|
4847
|
-
const
|
|
4848
|
-
const
|
|
4849
|
-
const
|
|
4850
|
-
const
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
|
|
4854
|
-
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
|
|
5094
|
+
function RichText(props) {
|
|
5095
|
+
const {
|
|
5096
|
+
field,
|
|
5097
|
+
value,
|
|
5098
|
+
name,
|
|
5099
|
+
className,
|
|
5100
|
+
as: Tag = "div",
|
|
5101
|
+
children
|
|
5102
|
+
} = props;
|
|
5103
|
+
const context = useContext(ComponentContext);
|
|
5104
|
+
const composerEdit = useComposerEditMode();
|
|
5105
|
+
const childrenValue = typeof children === "string" || typeof children === "number" ? String(children) : void 0;
|
|
5106
|
+
const hasField = isFieldEnvelope(field);
|
|
5107
|
+
const hasValueProp = hasOwnProp(props, "value") || childrenValue !== void 0;
|
|
5108
|
+
const boundValue = hasOwnProp(props, "value") ? value : childrenValue !== void 0 ? childrenValue : value;
|
|
5109
|
+
const { editName, fieldValue } = useBoundField(
|
|
5110
|
+
field,
|
|
5111
|
+
boundValue,
|
|
5112
|
+
name,
|
|
5113
|
+
"RichText"
|
|
5114
|
+
);
|
|
5115
|
+
if (!hasField && !hasValueProp && !name) {
|
|
5116
|
+
return null;
|
|
4858
5117
|
}
|
|
4859
|
-
|
|
4860
|
-
const
|
|
4861
|
-
|
|
4862
|
-
|
|
4863
|
-
|
|
5118
|
+
warnProjectionProps("RichText", hasField, hasValueProp, name);
|
|
5119
|
+
const canEdit = !!context && canInlineEditRichText(editName, fieldValue);
|
|
5120
|
+
if (isComposerEmptyText(fieldValue)) {
|
|
5121
|
+
if (composerEdit && canEdit) {
|
|
5122
|
+
return /* @__PURE__ */ jsx(
|
|
5123
|
+
ComposerInlineField,
|
|
5124
|
+
{
|
|
5125
|
+
name: editName,
|
|
5126
|
+
value: fieldValue,
|
|
5127
|
+
className,
|
|
5128
|
+
layoutNodeId: context?.layoutNodeId,
|
|
5129
|
+
componentId: context?.componentId,
|
|
5130
|
+
rich: true
|
|
5131
|
+
}
|
|
5132
|
+
);
|
|
5133
|
+
}
|
|
5134
|
+
return null;
|
|
5135
|
+
}
|
|
5136
|
+
let html = "";
|
|
5137
|
+
if (typeof fieldValue === "string") {
|
|
5138
|
+
const trimmed = fieldValue.trim();
|
|
5139
|
+
if (trimmed.startsWith("<") && trimmed.includes(">")) {
|
|
5140
|
+
html = fieldValue;
|
|
5141
|
+
} else {
|
|
5142
|
+
html = markdownToHtml(fieldValue);
|
|
5143
|
+
}
|
|
5144
|
+
} else {
|
|
5145
|
+
const text = formatFieldValue(fieldValue);
|
|
5146
|
+
html = text ? markdownToHtml(text) : "";
|
|
5147
|
+
}
|
|
5148
|
+
if (!html) {
|
|
5149
|
+
return null;
|
|
5150
|
+
}
|
|
5151
|
+
if (composerEdit && canEdit) {
|
|
4864
5152
|
return /* @__PURE__ */ jsx(
|
|
4865
|
-
|
|
5153
|
+
ComposerInlineHtml,
|
|
4866
5154
|
{
|
|
4867
|
-
|
|
4868
|
-
|
|
4869
|
-
|
|
4870
|
-
|
|
4871
|
-
|
|
4872
|
-
|
|
5155
|
+
name: editName,
|
|
5156
|
+
html,
|
|
5157
|
+
sourceValue: typeof fieldValue === "string" ? fieldValue : html,
|
|
5158
|
+
className,
|
|
5159
|
+
Tag,
|
|
5160
|
+
layoutNodeId: context?.layoutNodeId,
|
|
5161
|
+
componentId: context?.componentId
|
|
4873
5162
|
}
|
|
4874
5163
|
);
|
|
4875
5164
|
}
|
|
4876
|
-
|
|
4877
|
-
|
|
5165
|
+
return /* @__PURE__ */ jsx(Tag, { className, dangerouslySetInnerHTML: { __html: html } });
|
|
5166
|
+
}
|
|
5167
|
+
function isPortableImageValue(value) {
|
|
5168
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
5169
|
+
const url = value.url;
|
|
5170
|
+
return typeof url === "string" && url.trim().length > 0;
|
|
5171
|
+
}
|
|
5172
|
+
function imageSrc(value) {
|
|
5173
|
+
if (typeof value === "string") return value.trim();
|
|
5174
|
+
if (isPortableImageValue(value)) return value.url.trim();
|
|
5175
|
+
return "";
|
|
5176
|
+
}
|
|
5177
|
+
function Image(props) {
|
|
5178
|
+
const {
|
|
5179
|
+
field,
|
|
5180
|
+
value,
|
|
5181
|
+
name,
|
|
5182
|
+
alt: altProp,
|
|
5183
|
+
className,
|
|
5184
|
+
width: widthProp,
|
|
5185
|
+
height: heightProp,
|
|
5186
|
+
...imgProps
|
|
5187
|
+
} = props;
|
|
5188
|
+
const context = useContext(ComponentContext);
|
|
5189
|
+
const hasField = isFieldEnvelope(field);
|
|
5190
|
+
const hasValue = hasOwnProp(props, "value");
|
|
5191
|
+
const { editName, fieldValue } = useBoundField(field, value, name, "Image");
|
|
5192
|
+
const composerEdit = useComposerEditMode();
|
|
5193
|
+
warnProjectionProps("Image", hasField, hasValue, name);
|
|
5194
|
+
if (!hasField && !hasValue && !name) {
|
|
5195
|
+
return null;
|
|
4878
5196
|
}
|
|
4879
|
-
|
|
4880
|
-
|
|
4881
|
-
|
|
5197
|
+
const src = imageSrc(fieldValue);
|
|
5198
|
+
const portable = isPortableImageValue(fieldValue) ? fieldValue : null;
|
|
5199
|
+
const alt = altProp ?? portable?.alt ?? "";
|
|
5200
|
+
const width = widthProp ?? portable?.width;
|
|
5201
|
+
const height = heightProp ?? portable?.height;
|
|
5202
|
+
const fieldAttrs = composerEdit && editName ? {
|
|
5203
|
+
"data-amplifyup-field": editName,
|
|
5204
|
+
"data-amplifyup-field-type": "image",
|
|
5205
|
+
"data-amplifyup-node-id": context?.layoutNodeId || void 0
|
|
5206
|
+
} : null;
|
|
5207
|
+
if (composerEdit && !editName && (hasField || hasValue)) {
|
|
5208
|
+
console.warn(
|
|
5209
|
+
'[AmplifyUp SDK] Image value={\u2026} requires name="\u2026" for computed values'
|
|
5210
|
+
);
|
|
4882
5211
|
}
|
|
4883
|
-
if (!
|
|
4884
|
-
|
|
5212
|
+
if (!src) {
|
|
5213
|
+
if (!composerEdit || !fieldAttrs) return null;
|
|
5214
|
+
return /* @__PURE__ */ jsx(
|
|
5215
|
+
"span",
|
|
5216
|
+
{
|
|
5217
|
+
...fieldAttrs,
|
|
5218
|
+
className,
|
|
5219
|
+
role: "img",
|
|
5220
|
+
"aria-label": alt || editName || "Image",
|
|
5221
|
+
style: {
|
|
5222
|
+
display: "block",
|
|
5223
|
+
boxSizing: "border-box",
|
|
5224
|
+
minWidth: width ? void 0 : 120,
|
|
5225
|
+
minHeight: height ? void 0 : 80,
|
|
5226
|
+
width: width || "100%",
|
|
5227
|
+
height: height || void 0,
|
|
5228
|
+
background: "color-mix(in srgb, currentColor 8%, transparent)",
|
|
5229
|
+
outline: "2px dashed hsl(82 100% 45%)",
|
|
5230
|
+
outlineOffset: 2,
|
|
5231
|
+
cursor: "pointer"
|
|
5232
|
+
}
|
|
5233
|
+
}
|
|
5234
|
+
);
|
|
4885
5235
|
}
|
|
4886
5236
|
return /* @__PURE__ */ jsx(
|
|
4887
|
-
|
|
5237
|
+
"img",
|
|
4888
5238
|
{
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
5239
|
+
...imgProps,
|
|
5240
|
+
...fieldAttrs,
|
|
5241
|
+
src,
|
|
5242
|
+
alt,
|
|
5243
|
+
className,
|
|
5244
|
+
width,
|
|
5245
|
+
height,
|
|
5246
|
+
style: {
|
|
5247
|
+
...typeof imgProps.style === "object" && imgProps.style ? imgProps.style : {},
|
|
5248
|
+
...composerEdit && fieldAttrs ? { cursor: "pointer" } : null
|
|
5249
|
+
}
|
|
4894
5250
|
}
|
|
4895
5251
|
);
|
|
4896
5252
|
}
|
|
@@ -5115,6 +5471,6 @@ function useAmplifyUp() {
|
|
|
5115
5471
|
return context;
|
|
5116
5472
|
}
|
|
5117
5473
|
|
|
5118
|
-
export { AmplifyPageContent, AmplifyRenderer, AmplifyUpProvider, ComponentContextProvider, Field, Image, QueryContentError, RichText, SelectVariantsError, Slot, isComposerPreview, isPreviewRequest, isWorkingContentRequest, nextPageSpec, queryContent, searchSpec, selectVariants,
|
|
5474
|
+
export { AmplifyPageContent, AmplifyRenderer, AmplifyUpProvider, Collection, ComponentContextProvider, ComposerProvider, Field, Image, MaybeComposerProvider, QueryContentError, RichText, SelectVariantsError, Slot, isBrandedFields, isComposerPreview, isFieldEnvelope, isPreviewRequest, isWorkingContentRequest, nextPageSpec, queryContent, searchSpec, selectVariants, toFieldEnvelopes, useAmplifyUp };
|
|
5119
5475
|
//# sourceMappingURL=react.mjs.map
|
|
5120
5476
|
//# sourceMappingURL=react.mjs.map
|