@amplifyup/sdk 0.1.26 → 0.1.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/react.js CHANGED
@@ -2,8 +2,8 @@
2
2
  'use strict';
3
3
 
4
4
  var react = require('react');
5
- var jsxRuntime = require('react/jsx-runtime');
6
5
  var marked = require('marked');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
7
 
8
8
  /* @amplifyup/sdk - https://amplifyup.ai */
9
9
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
@@ -1783,6 +1783,12 @@ Available Console Commands:
1783
1783
  return;
1784
1784
  }
1785
1785
  try {
1786
+ if (event.data?.type === "AMPLIFYUP_FIELD_PATCH") {
1787
+ window.dispatchEvent(
1788
+ new CustomEvent("amplifyup:field-patch", { detail: event.data })
1789
+ );
1790
+ return;
1791
+ }
1786
1792
  if (event.data?.type === "COMPONENT_DELETABLE_STATUS") {
1787
1793
  const { componentId, deletable, nodeId } = event.data;
1788
1794
  const element = document.querySelector(`[data-component-id="${componentId}"]`);
@@ -1969,6 +1975,10 @@ Available Console Commands:
1969
1975
  setEventSelectionMode(enabled) {
1970
1976
  if (typeof document === "undefined") return;
1971
1977
  this.eventSelectionMode = enabled;
1978
+ if (typeof window !== "undefined") {
1979
+ window.__AMPLIFYUP_EVENT_SELECTION__ = enabled;
1980
+ window.dispatchEvent(new CustomEvent("amplifyup:composer-edit"));
1981
+ }
1972
1982
  if (this.eventSelectionClickHandler) {
1973
1983
  document.removeEventListener("click", this.eventSelectionClickHandler, true);
1974
1984
  this.eventSelectionClickHandler = null;
@@ -2206,6 +2216,14 @@ Available Console Commands:
2206
2216
  el.classList.add("amplifyup-selected");
2207
2217
  }
2208
2218
  });
2219
+ if (typeof window !== "undefined") {
2220
+ window.__AMPLIFYUP_COMPOSER_EDIT__ = highlightComponents;
2221
+ window.dispatchEvent(
2222
+ new CustomEvent("amplifyup:composer-edit", {
2223
+ detail: { enabled: highlightComponents }
2224
+ })
2225
+ );
2226
+ }
2209
2227
  }
2210
2228
  /** Document-level drag/drop for cross-iframe drags from Composer sidebar. */
2211
2229
  setupComposerDragDrop() {
@@ -2514,6 +2532,12 @@ Available Console Commands:
2514
2532
  const clearSelection = opts?.clearSelection !== false;
2515
2533
  this.highlightingEnabled = false;
2516
2534
  this.teardownComposerDragDrop();
2535
+ if (opts?.clearSelection !== false && typeof window !== "undefined") {
2536
+ window.__AMPLIFYUP_COMPOSER_EDIT__ = false;
2537
+ window.dispatchEvent(
2538
+ new CustomEvent("amplifyup:composer-edit", { detail: { enabled: false } })
2539
+ );
2540
+ }
2517
2541
  if (this.mutationObserver) {
2518
2542
  this.mutationObserver.disconnect();
2519
2543
  this.mutationObserver = null;
@@ -2719,6 +2743,417 @@ function getSDK(adapter) {
2719
2743
  var trackContentView = (contentId, contentType, properties) => getSDK().trackContentView(contentId, contentType, properties);
2720
2744
  var refreshEventTracking = () => getSDK().refreshEventTracking();
2721
2745
  getSDK();
2746
+ var ComponentContext = react.createContext(null);
2747
+ function useLiveComposerProps(layoutNodeId, props) {
2748
+ const [live, setLive] = react.useState(props);
2749
+ react.useEffect(() => {
2750
+ setLive(props);
2751
+ }, [props]);
2752
+ react.useEffect(() => {
2753
+ const apply = (fieldName, value, nodeId) => {
2754
+ if (!fieldName || typeof fieldName !== "string") return;
2755
+ if (nodeId && layoutNodeId && String(nodeId) !== String(layoutNodeId)) {
2756
+ return;
2757
+ }
2758
+ setLive((prev) => ({ ...prev, [fieldName]: value }));
2759
+ };
2760
+ const onPatch = (event) => {
2761
+ const detail = event.detail || {};
2762
+ apply(detail.fieldName, detail.value, detail.layoutNodeId);
2763
+ };
2764
+ const onMessage = (event) => {
2765
+ if (event.data?.type !== "AMPLIFYUP_FIELD_PATCH") return;
2766
+ apply(event.data.fieldName, event.data.value, event.data.layoutNodeId);
2767
+ };
2768
+ window.addEventListener("amplifyup:field-patch", onPatch);
2769
+ window.addEventListener("message", onMessage);
2770
+ return () => {
2771
+ window.removeEventListener("amplifyup:field-patch", onPatch);
2772
+ window.removeEventListener("message", onMessage);
2773
+ };
2774
+ }, [layoutNodeId]);
2775
+ return live;
2776
+ }
2777
+ function ComponentContextProvider({
2778
+ children,
2779
+ slots,
2780
+ props,
2781
+ layoutNodeId,
2782
+ componentId
2783
+ }) {
2784
+ const liveProps = useLiveComposerProps(layoutNodeId, props || {});
2785
+ return /* @__PURE__ */ jsxRuntime.jsx(
2786
+ ComponentContext.Provider,
2787
+ {
2788
+ value: { slots, props: liveProps, layoutNodeId, componentId },
2789
+ children
2790
+ }
2791
+ );
2792
+ }
2793
+ function Slot({
2794
+ name,
2795
+ className
2796
+ }) {
2797
+ const context = react.useContext(ComponentContext);
2798
+ console.log(`[Slot:${name}] Rendering slot`, {
2799
+ hasContext: !!context,
2800
+ availableSlotKeys: context?.slots ? Object.keys(context.slots) : [],
2801
+ slotContent: context?.slots?.[name] ? "EXISTS" : "MISSING",
2802
+ contextSlots: context?.slots
2803
+ });
2804
+ if (!context) {
2805
+ console.warn(`[AmplifyUp SDK] Slot "${name}" used outside ComponentContextProvider`);
2806
+ return null;
2807
+ }
2808
+ const slotContent = context.slots?.[name];
2809
+ const isEmpty = !slotContent;
2810
+ console.log(`[Slot:${name}] Slot state`, {
2811
+ isEmpty,
2812
+ hasSlotContent: !!slotContent,
2813
+ slotContentType: slotContent ? typeof slotContent : "null"
2814
+ });
2815
+ const isEditorMode = typeof window !== "undefined" && // Check for preview mode flag set by proxy
2816
+ (window.__AMPLIFYUP_PREVIEW_MODE__ === true || // Check URL query params
2817
+ 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)
2818
+ window.self !== window.top && document.referrer && (() => {
2819
+ try {
2820
+ const referrerUrl = new URL(document.referrer);
2821
+ return referrerUrl.hostname === "localhost" && referrerUrl.port === "5001" || referrerUrl.pathname.includes("/dashboard/composer") || referrerUrl.pathname.includes("/dashboard/routes/");
2822
+ } catch {
2823
+ return false;
2824
+ }
2825
+ })());
2826
+ console.log(`[Slot:${name}] Editor mode detection`, {
2827
+ isEditorMode,
2828
+ isWindowDefined: typeof window !== "undefined",
2829
+ previewModeFlag: typeof window !== "undefined" ? window.__AMPLIFYUP_PREVIEW_MODE__ : void 0,
2830
+ urlParams: typeof window !== "undefined" ? {
2831
+ preview: new URLSearchParams(window.location.search).get("preview"),
2832
+ visualEditor: new URLSearchParams(window.location.search).get("visualEditor")
2833
+ } : void 0,
2834
+ inIframe: typeof window !== "undefined" ? window.self !== window.top : false,
2835
+ referrer: typeof window !== "undefined" && document.referrer ? document.referrer : void 0
2836
+ });
2837
+ return /* @__PURE__ */ jsxRuntime.jsx(
2838
+ "div",
2839
+ {
2840
+ className,
2841
+ "data-slot-name": name,
2842
+ "data-slot-id": name,
2843
+ "data-amplifyup-slot": name,
2844
+ "data-slot-empty": isEmpty ? "true" : void 0,
2845
+ "data-parent-node-id": context.layoutNodeId || void 0,
2846
+ "data-parent-component-id": context.componentId || void 0,
2847
+ style: {
2848
+ // Only add minimum height when empty (for drop target visibility)
2849
+ minHeight: isEmpty ? "60px" : void 0,
2850
+ // Only add position relative for overlay positioning in editor mode
2851
+ position: isEditorMode ? "relative" : void 0
2852
+ },
2853
+ children: isEmpty ? /* @__PURE__ */ jsxRuntime.jsx(
2854
+ "div",
2855
+ {
2856
+ className: "amplifyup-slot-placeholder",
2857
+ style: {
2858
+ minHeight: "60px",
2859
+ color: "#9ca3af",
2860
+ fontSize: "14px",
2861
+ pointerEvents: "none"
2862
+ },
2863
+ children: isEditorMode ? `Drop components here` : `Empty slot: ${name}`
2864
+ }
2865
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2866
+ isEditorMode && /* @__PURE__ */ jsxRuntime.jsxs(
2867
+ "div",
2868
+ {
2869
+ className: "amplifyup-slot-placeholder",
2870
+ style: {
2871
+ position: "absolute",
2872
+ top: "4px",
2873
+ left: "4px",
2874
+ fontSize: "10px",
2875
+ color: "#9ca3af",
2876
+ pointerEvents: "none",
2877
+ zIndex: 1,
2878
+ minHeight: "auto"
2879
+ },
2880
+ children: [
2881
+ "Slot: ",
2882
+ name
2883
+ ]
2884
+ }
2885
+ ),
2886
+ slotContent
2887
+ ] })
2888
+ }
2889
+ );
2890
+ }
2891
+ function isComposerEditMode() {
2892
+ if (typeof window === "undefined") return false;
2893
+ return isComposerPreview() && window.__AMPLIFYUP_EVENT_SELECTION__ !== true;
2894
+ }
2895
+ function isLikelyNonTextFieldName(name) {
2896
+ const n = name.toLowerCase();
2897
+ return n.includes("href") || n.includes("url") || n.includes("src") || n.includes("image") || n.includes("icon") || n.includes("overlay") || n.includes("color");
2898
+ }
2899
+ function canInlineEdit(name, value) {
2900
+ if (isLikelyNonTextFieldName(name)) return false;
2901
+ if (value !== void 0 && value !== null && typeof value === "object") {
2902
+ return false;
2903
+ }
2904
+ if (typeof value === "boolean") return false;
2905
+ return true;
2906
+ }
2907
+ function useComposerEditMode() {
2908
+ const [enabled, setEnabled] = react.useState(false);
2909
+ react.useEffect(() => {
2910
+ const sync = () => setEnabled(isComposerEditMode());
2911
+ sync();
2912
+ window.addEventListener("amplifyup:composer-edit", sync);
2913
+ return () => window.removeEventListener("amplifyup:composer-edit", sync);
2914
+ }, []);
2915
+ return enabled;
2916
+ }
2917
+ function useFieldOverlay(layoutNodeId, name, source) {
2918
+ const [overlay, setOverlay] = react.useState(void 0);
2919
+ react.useEffect(() => {
2920
+ const onPatch = (event) => {
2921
+ const detail = event.detail || {};
2922
+ if (detail.fieldName !== name) return;
2923
+ if (detail.layoutNodeId && layoutNodeId && String(detail.layoutNodeId) !== String(layoutNodeId)) {
2924
+ return;
2925
+ }
2926
+ setOverlay(detail.value);
2927
+ };
2928
+ window.addEventListener("amplifyup:field-patch", onPatch);
2929
+ return () => window.removeEventListener("amplifyup:field-patch", onPatch);
2930
+ }, [layoutNodeId, name]);
2931
+ return overlay !== void 0 ? overlay : source;
2932
+ }
2933
+ function commitComposerField(layoutNodeId, componentId, name, value) {
2934
+ if (typeof window === "undefined" || window.parent === window) return;
2935
+ window.parent.postMessage(
2936
+ {
2937
+ type: "AMPLIFYUP_FIELD_COMMIT",
2938
+ layoutNodeId,
2939
+ componentId,
2940
+ fieldName: name,
2941
+ value
2942
+ },
2943
+ "*"
2944
+ );
2945
+ }
2946
+ function ComposerInlineField({
2947
+ name,
2948
+ value,
2949
+ fallback,
2950
+ className,
2951
+ render,
2952
+ layoutNodeId,
2953
+ componentId
2954
+ }) {
2955
+ const [editing, setEditing] = react.useState(false);
2956
+ const elRef = react.useRef(null);
2957
+ const text = formatFieldValue(value);
2958
+ const fallbackText = typeof fallback === "string" || typeof fallback === "number" ? String(fallback) : "";
2959
+ const display = text || fallbackText;
2960
+ const showRendered = !!render && !editing;
2961
+ react.useEffect(() => {
2962
+ const el = elRef.current;
2963
+ if (!el || showRendered) return;
2964
+ if (document.activeElement === el) return;
2965
+ const next = display || "";
2966
+ if (el.textContent !== next) el.textContent = next;
2967
+ }, [display, showRendered]);
2968
+ react.useEffect(() => {
2969
+ if (!editing || !elRef.current) return;
2970
+ const el = elRef.current;
2971
+ el.textContent = display || "";
2972
+ el.focus();
2973
+ const range = document.createRange();
2974
+ range.selectNodeContents(el);
2975
+ const sel = window.getSelection();
2976
+ sel?.removeAllRanges();
2977
+ sel?.addRange(range);
2978
+ }, [editing]);
2979
+ const finishEdit = () => {
2980
+ const raw = (elRef.current?.innerText ?? "").replace(/\u00a0/g, " ").replace(/\n+$/g, "");
2981
+ const next = raw.trim() === "" ? "" : raw;
2982
+ setEditing(false);
2983
+ if (next === text) return;
2984
+ if (!text && next === fallbackText) return;
2985
+ commitComposerField(layoutNodeId, componentId, name, next);
2986
+ };
2987
+ return /* @__PURE__ */ jsxRuntime.jsx(
2988
+ "span",
2989
+ {
2990
+ ref: elRef,
2991
+ className,
2992
+ "data-amplifyup-field": name,
2993
+ "data-amplifyup-node-id": layoutNodeId || void 0,
2994
+ contentEditable: !showRendered,
2995
+ suppressContentEditableWarning: true,
2996
+ role: "textbox",
2997
+ tabIndex: 0,
2998
+ onMouseDown: (event) => {
2999
+ event.stopPropagation();
3000
+ },
3001
+ onClick: (event) => {
3002
+ const link = event.target?.closest?.("a");
3003
+ if (link) event.preventDefault();
3004
+ if (render && isComposerEditMode()) {
3005
+ setEditing(true);
3006
+ }
3007
+ },
3008
+ onFocus: () => {
3009
+ if (!isComposerEditMode()) return;
3010
+ if (render) setEditing(true);
3011
+ },
3012
+ onBlur: finishEdit,
3013
+ onKeyDown: (event) => {
3014
+ event.stopPropagation();
3015
+ if (event.key === "Enter" && !event.shiftKey) {
3016
+ event.preventDefault();
3017
+ event.currentTarget.blur();
3018
+ }
3019
+ if (event.key === "Escape") {
3020
+ event.preventDefault();
3021
+ if (elRef.current) elRef.current.textContent = display || "";
3022
+ setEditing(false);
3023
+ event.currentTarget.blur();
3024
+ }
3025
+ },
3026
+ style: {
3027
+ cursor: "text",
3028
+ outline: "1px dashed color-mix(in srgb, currentColor 40%, transparent)",
3029
+ outlineOffset: "2px",
3030
+ minWidth: "1ch",
3031
+ display: render ? void 0 : "inline"
3032
+ },
3033
+ children: showRendered ? value != null && value !== "" ? render(value) : fallback ?? display : null
3034
+ }
3035
+ );
3036
+ }
3037
+ function formatFieldValue(value) {
3038
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
3039
+ return String(value);
3040
+ }
3041
+ if (Array.isArray(value)) {
3042
+ const parts = value.map((item) => {
3043
+ if (typeof item === "string") return item;
3044
+ if (item && typeof item === "object" && "children" in item && Array.isArray(item.children)) {
3045
+ return item.children.map((c) => typeof c?.text === "string" ? c.text : "").join("");
3046
+ }
3047
+ return "";
3048
+ }).filter(Boolean);
3049
+ if (parts.length > 0) return parts.join(" ");
3050
+ }
3051
+ if (value && typeof value === "object") {
3052
+ return "";
3053
+ }
3054
+ return "";
3055
+ }
3056
+ function Field({
3057
+ name,
3058
+ fallback,
3059
+ className,
3060
+ render
3061
+ }) {
3062
+ const context = react.useContext(ComponentContext);
3063
+ const composerEdit = useComposerEditMode();
3064
+ const fieldValue = useFieldOverlay(
3065
+ context?.layoutNodeId,
3066
+ name,
3067
+ context?.props?.[name]
3068
+ );
3069
+ if (!context) {
3070
+ console.warn(`[AmplifyUp SDK] Field "${name}" used outside ComponentContextProvider`);
3071
+ return fallback ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: fallback }) : null;
3072
+ }
3073
+ if (composerEdit && canInlineEdit(name, fieldValue)) {
3074
+ return /* @__PURE__ */ jsxRuntime.jsx(
3075
+ ComposerInlineField,
3076
+ {
3077
+ name,
3078
+ value: fieldValue,
3079
+ fallback,
3080
+ className,
3081
+ render,
3082
+ layoutNodeId: context.layoutNodeId,
3083
+ componentId: context.componentId
3084
+ }
3085
+ );
3086
+ }
3087
+ if (fieldValue === void 0 || fieldValue === null) {
3088
+ return fallback ? /* @__PURE__ */ jsxRuntime.jsx("span", { className, children: fallback }) : null;
3089
+ }
3090
+ if (render) {
3091
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className, children: render(fieldValue) });
3092
+ }
3093
+ const text = formatFieldValue(fieldValue);
3094
+ if (!text) {
3095
+ return fallback ? /* @__PURE__ */ jsxRuntime.jsx("span", { className, children: fallback }) : null;
3096
+ }
3097
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className, children: text });
3098
+ }
3099
+ function markdownToHtml(markdown) {
3100
+ try {
3101
+ const result = marked.marked.parse(markdown, { async: false });
3102
+ return typeof result === "string" ? result : "";
3103
+ } catch {
3104
+ return markdown;
3105
+ }
3106
+ }
3107
+ function RichText({
3108
+ name,
3109
+ fallback,
3110
+ className,
3111
+ as: Tag = "div"
3112
+ }) {
3113
+ const context = react.useContext(ComponentContext);
3114
+ const composerEdit = useComposerEditMode();
3115
+ const fieldValue = useFieldOverlay(
3116
+ context?.layoutNodeId,
3117
+ name,
3118
+ context?.props?.[name]
3119
+ );
3120
+ if (!context) {
3121
+ console.warn(`[AmplifyUp SDK] RichText "${name}" used outside ComponentContextProvider`);
3122
+ return fallback ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: fallback }) : null;
3123
+ }
3124
+ if (composerEdit && canInlineEdit(name, fieldValue)) {
3125
+ return /* @__PURE__ */ jsxRuntime.jsx(
3126
+ ComposerInlineField,
3127
+ {
3128
+ name,
3129
+ value: fieldValue,
3130
+ fallback,
3131
+ className,
3132
+ layoutNodeId: context.layoutNodeId,
3133
+ componentId: context.componentId
3134
+ }
3135
+ );
3136
+ }
3137
+ if (fieldValue === void 0 || fieldValue === null || fieldValue === "") {
3138
+ return fallback ? /* @__PURE__ */ jsxRuntime.jsx(Tag, { className, children: fallback }) : null;
3139
+ }
3140
+ let html = "";
3141
+ if (typeof fieldValue === "string") {
3142
+ const trimmed = fieldValue.trim();
3143
+ if (trimmed.startsWith("<") && trimmed.includes(">")) {
3144
+ html = fieldValue;
3145
+ } else {
3146
+ html = markdownToHtml(fieldValue);
3147
+ }
3148
+ } else {
3149
+ const text = formatFieldValue(fieldValue);
3150
+ html = text ? markdownToHtml(text) : "";
3151
+ }
3152
+ if (!html) {
3153
+ return fallback ? /* @__PURE__ */ jsxRuntime.jsx(Tag, { className, children: fallback }) : null;
3154
+ }
3155
+ return /* @__PURE__ */ jsxRuntime.jsx(Tag, { className, dangerouslySetInnerHTML: { __html: html } });
3156
+ }
2722
3157
  var ComponentRenderBoundary = class extends react.Component {
2723
3158
  constructor() {
2724
3159
  super(...arguments);
@@ -2766,6 +3201,18 @@ var ComponentRenderBoundary = class extends react.Component {
2766
3201
  return this.props.children;
2767
3202
  }
2768
3203
  };
3204
+ function LiveNodeRender({
3205
+ nodeId,
3206
+ componentId,
3207
+ props,
3208
+ slots,
3209
+ renderComponent
3210
+ }) {
3211
+ const liveProps = useLiveComposerProps(nodeId, props);
3212
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: renderComponent(componentId, liveProps, slots, {
3213
+ layoutNodeId: nodeId
3214
+ }) });
3215
+ }
2769
3216
  function AmplifyRenderer({
2770
3217
  renderComponent,
2771
3218
  pageConfig: serverPageConfig,
@@ -3120,20 +3567,21 @@ function AmplifyRenderer({
3120
3567
  }
3121
3568
  }
3122
3569
  const slotsToPass = Object.keys(slotChildren).length > 0 ? slotChildren : void 0;
3123
- console.log(`[AmplifyRenderer] Calling renderComponent for ${node.componentId}`, {
3124
- hasSlots: !!slotsToPass,
3125
- slotKeys: slotsToPass ? Object.keys(slotsToPass) : [],
3126
- propKeys: Object.keys(node.props || {}),
3127
- props: node.props || {}
3128
- });
3129
3570
  return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-node-id": node.id, "data-amplifyup-node": "", children: /* @__PURE__ */ jsxRuntime.jsx(
3130
3571
  ComponentRenderBoundary,
3131
3572
  {
3132
3573
  componentId: node.componentId,
3133
3574
  nodeId: node.id,
3134
- children: renderComponent(node.componentId, node.props || {}, slotsToPass, {
3135
- layoutNodeId: node.id
3136
- })
3575
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3576
+ LiveNodeRender,
3577
+ {
3578
+ nodeId: node.id,
3579
+ componentId: node.componentId,
3580
+ props: node.props || {},
3581
+ slots: slotsToPass,
3582
+ renderComponent
3583
+ }
3584
+ )
3137
3585
  }
3138
3586
  ) });
3139
3587
  };
@@ -3260,210 +3708,6 @@ async function fetchPageConfigServer(route, trackingId, preview = false, options
3260
3708
  });
3261
3709
  return result.pageConfig;
3262
3710
  }
3263
- var ComponentContext = react.createContext(null);
3264
- function ComponentContextProvider({
3265
- children,
3266
- slots,
3267
- props,
3268
- layoutNodeId,
3269
- componentId
3270
- }) {
3271
- console.log("[ComponentContextProvider] Providing context", {
3272
- hasSlots: !!slots,
3273
- slotKeys: slots ? Object.keys(slots) : [],
3274
- slotDetails: slots ? Object.keys(slots).map((key) => ({
3275
- key,
3276
- hasContent: !!slots[key],
3277
- contentType: slots[key] ? typeof slots[key] : "null"
3278
- })) : [],
3279
- hasProps: !!props,
3280
- propKeys: props ? Object.keys(props) : [],
3281
- layoutNodeId,
3282
- componentId
3283
- });
3284
- return /* @__PURE__ */ jsxRuntime.jsx(ComponentContext.Provider, { value: { slots, props, layoutNodeId, componentId }, children });
3285
- }
3286
- function Slot({
3287
- name,
3288
- className
3289
- }) {
3290
- const context = react.useContext(ComponentContext);
3291
- console.log(`[Slot:${name}] Rendering slot`, {
3292
- hasContext: !!context,
3293
- availableSlotKeys: context?.slots ? Object.keys(context.slots) : [],
3294
- slotContent: context?.slots?.[name] ? "EXISTS" : "MISSING",
3295
- contextSlots: context?.slots
3296
- });
3297
- if (!context) {
3298
- console.warn(`[AmplifyUp SDK] Slot "${name}" used outside ComponentContextProvider`);
3299
- return null;
3300
- }
3301
- const slotContent = context.slots?.[name];
3302
- const isEmpty = !slotContent;
3303
- console.log(`[Slot:${name}] Slot state`, {
3304
- isEmpty,
3305
- hasSlotContent: !!slotContent,
3306
- slotContentType: slotContent ? typeof slotContent : "null"
3307
- });
3308
- const isEditorMode = typeof window !== "undefined" && // Check for preview mode flag set by proxy
3309
- (window.__AMPLIFYUP_PREVIEW_MODE__ === true || // Check URL query params
3310
- 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)
3311
- window.self !== window.top && document.referrer && (() => {
3312
- try {
3313
- const referrerUrl = new URL(document.referrer);
3314
- return referrerUrl.hostname === "localhost" && referrerUrl.port === "5001" || referrerUrl.pathname.includes("/dashboard/composer") || referrerUrl.pathname.includes("/dashboard/routes/");
3315
- } catch {
3316
- return false;
3317
- }
3318
- })());
3319
- console.log(`[Slot:${name}] Editor mode detection`, {
3320
- isEditorMode,
3321
- isWindowDefined: typeof window !== "undefined",
3322
- previewModeFlag: typeof window !== "undefined" ? window.__AMPLIFYUP_PREVIEW_MODE__ : void 0,
3323
- urlParams: typeof window !== "undefined" ? {
3324
- preview: new URLSearchParams(window.location.search).get("preview"),
3325
- visualEditor: new URLSearchParams(window.location.search).get("visualEditor")
3326
- } : void 0,
3327
- inIframe: typeof window !== "undefined" ? window.self !== window.top : false,
3328
- referrer: typeof window !== "undefined" && document.referrer ? document.referrer : void 0
3329
- });
3330
- return /* @__PURE__ */ jsxRuntime.jsx(
3331
- "div",
3332
- {
3333
- className,
3334
- "data-slot-name": name,
3335
- "data-slot-id": name,
3336
- "data-amplifyup-slot": name,
3337
- "data-slot-empty": isEmpty ? "true" : void 0,
3338
- "data-parent-node-id": context.layoutNodeId || void 0,
3339
- "data-parent-component-id": context.componentId || void 0,
3340
- style: {
3341
- // Only add minimum height when empty (for drop target visibility)
3342
- minHeight: isEmpty ? "60px" : void 0,
3343
- // Only add position relative for overlay positioning in editor mode
3344
- position: isEditorMode ? "relative" : void 0
3345
- },
3346
- children: isEmpty ? /* @__PURE__ */ jsxRuntime.jsx(
3347
- "div",
3348
- {
3349
- className: "amplifyup-slot-placeholder",
3350
- style: {
3351
- minHeight: "60px",
3352
- color: "#9ca3af",
3353
- fontSize: "14px",
3354
- pointerEvents: "none"
3355
- },
3356
- children: isEditorMode ? `Drop components here` : `Empty slot: ${name}`
3357
- }
3358
- ) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3359
- isEditorMode && /* @__PURE__ */ jsxRuntime.jsxs(
3360
- "div",
3361
- {
3362
- className: "amplifyup-slot-placeholder",
3363
- style: {
3364
- position: "absolute",
3365
- top: "4px",
3366
- left: "4px",
3367
- fontSize: "10px",
3368
- color: "#9ca3af",
3369
- pointerEvents: "none",
3370
- zIndex: 1,
3371
- minHeight: "auto"
3372
- },
3373
- children: [
3374
- "Slot: ",
3375
- name
3376
- ]
3377
- }
3378
- ),
3379
- slotContent
3380
- ] })
3381
- }
3382
- );
3383
- }
3384
- function formatFieldValue(value) {
3385
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
3386
- return String(value);
3387
- }
3388
- if (Array.isArray(value)) {
3389
- const parts = value.map((item) => {
3390
- if (typeof item === "string") return item;
3391
- if (item && typeof item === "object" && "children" in item && Array.isArray(item.children)) {
3392
- return item.children.map((c) => typeof c?.text === "string" ? c.text : "").join("");
3393
- }
3394
- return "";
3395
- }).filter(Boolean);
3396
- if (parts.length > 0) return parts.join(" ");
3397
- }
3398
- if (value && typeof value === "object") {
3399
- return "";
3400
- }
3401
- return "";
3402
- }
3403
- function Field({
3404
- name,
3405
- fallback,
3406
- className,
3407
- render
3408
- }) {
3409
- const context = react.useContext(ComponentContext);
3410
- if (!context) {
3411
- console.warn(`[AmplifyUp SDK] Field "${name}" used outside ComponentContextProvider`);
3412
- return fallback ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: fallback }) : null;
3413
- }
3414
- const fieldValue = context.props?.[name];
3415
- if (fieldValue === void 0 || fieldValue === null) {
3416
- return fallback ? /* @__PURE__ */ jsxRuntime.jsx("span", { className, children: fallback }) : null;
3417
- }
3418
- if (render) {
3419
- return /* @__PURE__ */ jsxRuntime.jsx("span", { className, children: render(fieldValue) });
3420
- }
3421
- const text = formatFieldValue(fieldValue);
3422
- if (!text) {
3423
- return fallback ? /* @__PURE__ */ jsxRuntime.jsx("span", { className, children: fallback }) : null;
3424
- }
3425
- return /* @__PURE__ */ jsxRuntime.jsx("span", { className, children: text });
3426
- }
3427
- function markdownToHtml(markdown) {
3428
- try {
3429
- const result = marked.marked.parse(markdown, { async: false });
3430
- return typeof result === "string" ? result : "";
3431
- } catch {
3432
- return markdown;
3433
- }
3434
- }
3435
- function RichText({
3436
- name,
3437
- fallback,
3438
- className,
3439
- as: Tag = "div"
3440
- }) {
3441
- const context = react.useContext(ComponentContext);
3442
- if (!context) {
3443
- console.warn(`[AmplifyUp SDK] RichText "${name}" used outside ComponentContextProvider`);
3444
- return fallback ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: fallback }) : null;
3445
- }
3446
- const fieldValue = context.props?.[name];
3447
- if (fieldValue === void 0 || fieldValue === null || fieldValue === "") {
3448
- return fallback ? /* @__PURE__ */ jsxRuntime.jsx(Tag, { className, children: fallback }) : null;
3449
- }
3450
- let html = "";
3451
- if (typeof fieldValue === "string") {
3452
- const trimmed = fieldValue.trim();
3453
- if (trimmed.startsWith("<") && trimmed.includes(">")) {
3454
- html = fieldValue;
3455
- } else {
3456
- html = markdownToHtml(fieldValue);
3457
- }
3458
- } else {
3459
- const text = formatFieldValue(fieldValue);
3460
- html = text ? markdownToHtml(text) : "";
3461
- }
3462
- if (!html) {
3463
- return fallback ? /* @__PURE__ */ jsxRuntime.jsx(Tag, { className, children: fallback }) : null;
3464
- }
3465
- return /* @__PURE__ */ jsxRuntime.jsx(Tag, { className, dangerouslySetInnerHTML: { __html: html } });
3466
- }
3467
3711
  var usePathname = null;
3468
3712
  if (typeof window !== "undefined") {
3469
3713
  try {
@@ -3632,5 +3876,6 @@ exports.fetchPageConfigServer = fetchPageConfigServer;
3632
3876
  exports.isComposerPreview = isComposerPreview;
3633
3877
  exports.isPreviewRequest = isPreviewRequest;
3634
3878
  exports.useAmplifyUp = useAmplifyUp;
3879
+ exports.useLiveComposerProps = useLiveComposerProps;
3635
3880
  //# sourceMappingURL=react.js.map
3636
3881
  //# sourceMappingURL=react.js.map