@amplifyup/sdk 0.1.13 → 0.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/react.d.mts CHANGED
@@ -21,6 +21,11 @@ interface AmplifyPageContentProps {
21
21
  renderComponent: RenderComponentFn;
22
22
  /** Optional pre-fetched layout (e.g. from server in preview mode). */
23
23
  pageConfig?: PageConfig | null;
24
+ /**
25
+ * Force Composer mode (e.g. from SSR `?preview=true`). Ensures the page slot
26
+ * wrapper exists even before client-side preview detection runs.
27
+ */
28
+ forceComposerPreview?: boolean;
24
29
  /** Shown while layout loads in Composer (default: empty main canvas). */
25
30
  previewLoadingComponent?: ReactNode;
26
31
  /** Shown when no layout components exist yet in Composer (default: empty main canvas). */
@@ -33,7 +38,7 @@ interface AmplifyPageContentProps {
33
38
  * Hybrid page wrapper: Composer shows only the AmplifyUp layout canvas;
34
39
  * normal visits show the configured layout or your native `fallback`.
35
40
  */
36
- declare function AmplifyPageContent({ fallback, renderComponent, pageConfig: pageConfigProp, previewLoadingComponent, previewEmptyComponent, loadingComponent, emptyComponent, errorComponent, }: AmplifyPageContentProps): react_jsx_runtime.JSX.Element | null;
41
+ declare function AmplifyPageContent({ fallback, renderComponent, pageConfig: pageConfigProp, forceComposerPreview, previewLoadingComponent, previewEmptyComponent, loadingComponent, emptyComponent, errorComponent, }: AmplifyPageContentProps): react_jsx_runtime.JSX.Element | null;
37
42
 
38
43
  /**
39
44
  * ComponentContextProvider - Provides slots and props to child components
package/dist/react.d.ts CHANGED
@@ -21,6 +21,11 @@ interface AmplifyPageContentProps {
21
21
  renderComponent: RenderComponentFn;
22
22
  /** Optional pre-fetched layout (e.g. from server in preview mode). */
23
23
  pageConfig?: PageConfig | null;
24
+ /**
25
+ * Force Composer mode (e.g. from SSR `?preview=true`). Ensures the page slot
26
+ * wrapper exists even before client-side preview detection runs.
27
+ */
28
+ forceComposerPreview?: boolean;
24
29
  /** Shown while layout loads in Composer (default: empty main canvas). */
25
30
  previewLoadingComponent?: ReactNode;
26
31
  /** Shown when no layout components exist yet in Composer (default: empty main canvas). */
@@ -33,7 +38,7 @@ interface AmplifyPageContentProps {
33
38
  * Hybrid page wrapper: Composer shows only the AmplifyUp layout canvas;
34
39
  * normal visits show the configured layout or your native `fallback`.
35
40
  */
36
- declare function AmplifyPageContent({ fallback, renderComponent, pageConfig: pageConfigProp, previewLoadingComponent, previewEmptyComponent, loadingComponent, emptyComponent, errorComponent, }: AmplifyPageContentProps): react_jsx_runtime.JSX.Element | null;
41
+ declare function AmplifyPageContent({ fallback, renderComponent, pageConfig: pageConfigProp, forceComposerPreview, previewLoadingComponent, previewEmptyComponent, loadingComponent, emptyComponent, errorComponent, }: AmplifyPageContentProps): react_jsx_runtime.JSX.Element | null;
37
42
 
38
43
  /**
39
44
  * ComponentContextProvider - Provides slots and props to child components
package/dist/react.js CHANGED
@@ -1225,6 +1225,11 @@ Available Console Commands:
1225
1225
  `[data-node-id="${nodeId}"]`
1226
1226
  );
1227
1227
  }
1228
+ if (!element && slotName) {
1229
+ element = document.querySelector(
1230
+ `[data-slot-source="page"][data-slot-id="${slotName}"], [data-slot-source="page"][data-amplifyup-slot="${slotName}"]`
1231
+ );
1232
+ }
1228
1233
  if (!element && slotName) {
1229
1234
  element = document.querySelector(
1230
1235
  `[data-amplifyup-slot="${slotName}"], [data-slot-id="${slotName}"]`
@@ -1257,12 +1262,28 @@ Available Console Commands:
1257
1262
  height: rect.height
1258
1263
  };
1259
1264
  if (window.parent && window.parent !== window) {
1265
+ const hierarchyEls = this.buildComponentHierarchy(element);
1260
1266
  window.parent.postMessage({
1261
1267
  type: "ELEMENT_POSITION",
1262
1268
  componentId: componentId || null,
1263
1269
  slotName: slotName || null,
1264
1270
  nodeId: nodeId || null,
1265
- isPageSlot: !!isPageSlot,
1271
+ isPageSlot: !!isPageSlot || element.getAttribute("data-slot-source") === "page",
1272
+ hierarchy: hierarchyEls.map((el, index) => {
1273
+ const elComponentId = el.getAttribute("data-amplifyup-component") || el.getAttribute("data-component-id");
1274
+ const elSlotName = el.getAttribute("data-amplifyup-slot") || el.getAttribute("data-slot-id");
1275
+ const isSlot = !elComponentId && !!elSlotName;
1276
+ const pageSlot = isSlot && el.getAttribute("data-slot-source") === "page";
1277
+ return {
1278
+ index,
1279
+ componentId: elComponentId,
1280
+ componentName: pageSlot ? "Page" : el.getAttribute("data-component-name"),
1281
+ slotName: isSlot ? elSlotName : null,
1282
+ isSlot,
1283
+ isPageSlot: pageSlot,
1284
+ nodeId: el.getAttribute("data-node-id") || (isSlot ? el.getAttribute("data-parent-node-id") : null)
1285
+ };
1286
+ }),
1266
1287
  position,
1267
1288
  bounds
1268
1289
  }, "*");
@@ -1819,13 +1840,24 @@ Available Console Commands:
1819
1840
  buildComponentHierarchy(element) {
1820
1841
  const hierarchy = [];
1821
1842
  let current = element;
1843
+ let sawPageSlot = false;
1822
1844
  while (current) {
1823
1845
  if (current.hasAttribute("data-amplifyup-component") || current.hasAttribute("data-component-id") || current.hasAttribute("data-amplifyup-slot") || current.hasAttribute("data-slot-id")) {
1824
1846
  hierarchy.push(current);
1847
+ if (current.getAttribute("data-slot-source") === "page") {
1848
+ sawPageSlot = true;
1849
+ }
1825
1850
  }
1826
1851
  current = current.parentElement;
1827
1852
  }
1828
- return hierarchy.reverse();
1853
+ const ordered = hierarchy.reverse();
1854
+ if (!sawPageSlot) {
1855
+ const pageSlot = element.closest('[data-slot-source="page"]');
1856
+ if (pageSlot && !ordered.includes(pageSlot)) {
1857
+ ordered.unshift(pageSlot);
1858
+ }
1859
+ }
1860
+ return ordered;
1829
1861
  }
1830
1862
  /**
1831
1863
  * Send selection message to orchestrator (includes element bounds for overlay positioning).
@@ -1983,7 +2015,8 @@ function AmplifyRenderer({
1983
2015
  pageConfig: serverPageConfig,
1984
2016
  loadingComponent,
1985
2017
  errorComponent,
1986
- emptyComponent
2018
+ emptyComponent,
2019
+ composerPreview
1987
2020
  }) {
1988
2021
  const clientHook = useAmplifyUp();
1989
2022
  const pageConfig = serverPageConfig || clientHook.pageConfig || null;
@@ -2042,7 +2075,9 @@ function AmplifyRenderer({
2042
2075
  if (!pageConfig) {
2043
2076
  return;
2044
2077
  }
2045
- if (!pageConfig.layoutTree || Array.isArray(pageConfig.layoutTree) && pageConfig.layoutTree.length === 0) {
2078
+ const rawTree2 = pageConfig.layoutTree;
2079
+ const normalizedTree = Array.isArray(rawTree2) ? rawTree2 : rawTree2 && typeof rawTree2 === "object" && rawTree2.componentId ? [rawTree2] : [];
2080
+ if (normalizedTree.length === 0) {
2046
2081
  if (typeof window !== "undefined" && window.parent && window.parent !== window) {
2047
2082
  window.parent.postMessage({
2048
2083
  type: "COMPONENT_TREE",
@@ -2054,6 +2089,7 @@ function AmplifyRenderer({
2054
2089
  const convertLayoutTreeToComponentTree = (nodes, parentId = null) => {
2055
2090
  const result = [];
2056
2091
  nodes.forEach((node) => {
2092
+ if (!node) return;
2057
2093
  const treeNode = {
2058
2094
  id: node.id,
2059
2095
  componentId: node.componentId,
@@ -2064,8 +2100,9 @@ function AmplifyRenderer({
2064
2100
  };
2065
2101
  if (node.slots && node.slots.length > 0) {
2066
2102
  node.slots.forEach((slot) => {
2067
- if (slot.children && slot.children.length > 0) {
2068
- const slotChildren = convertLayoutTreeToComponentTree(slot.children, node.id);
2103
+ const kids = Array.isArray(slot?.children) ? slot.children : [];
2104
+ if (kids.length > 0) {
2105
+ const slotChildren = convertLayoutTreeToComponentTree(kids, node.id);
2069
2106
  treeNode.children.push(...slotChildren);
2070
2107
  }
2071
2108
  });
@@ -2074,7 +2111,7 @@ function AmplifyRenderer({
2074
2111
  });
2075
2112
  return result;
2076
2113
  };
2077
- const layoutTree2 = pageConfig.layoutTree;
2114
+ const layoutTree2 = normalizedTree;
2078
2115
  const componentTree = convertLayoutTreeToComponentTree(layoutTree2);
2079
2116
  const describeLayoutTree = (nodes, depth = 0) => {
2080
2117
  if (!nodes?.length) return "";
@@ -2247,11 +2284,12 @@ function AmplifyRenderer({
2247
2284
  childrenCount: childrenToRender.length
2248
2285
  });
2249
2286
  } else {
2250
- childrenToRender = slot.children;
2287
+ childrenToRender = Array.isArray(slot.children) ? slot.children : [];
2251
2288
  console.log(`[AmplifyRenderer] Using direct children for slot ${slot.slotId}`, {
2252
2289
  childrenCount: childrenToRender.length
2253
2290
  });
2254
2291
  }
2292
+ const safeChildren = Array.isArray(childrenToRender) ? childrenToRender : [];
2255
2293
  slotChildren[slot.slotId] = /* @__PURE__ */ jsxRuntime.jsx(
2256
2294
  "div",
2257
2295
  {
@@ -2260,7 +2298,7 @@ function AmplifyRenderer({
2260
2298
  "data-zone-id": slot.zoneId || void 0,
2261
2299
  "data-parent-node-id": node.id,
2262
2300
  "data-parent-component-id": node.componentId,
2263
- children: childrenToRender.map((child) => renderNode(child))
2301
+ children: safeChildren.filter(Boolean).map((child) => renderNode(child))
2264
2302
  },
2265
2303
  slot.slotId
2266
2304
  );
@@ -2284,7 +2322,7 @@ function AmplifyRenderer({
2284
2322
  if (layoutTree.length === 0) {
2285
2323
  return /* @__PURE__ */ jsxRuntime.jsx("main", { children: emptyComponent || /* @__PURE__ */ jsxRuntime.jsx("div", { className: "container mx-auto px-4 py-16", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: "No content configured for this page." }) }) });
2286
2324
  }
2287
- return /* @__PURE__ */ jsxRuntime.jsx("main", { children: isComposerPreview() ? /* @__PURE__ */ jsxRuntime.jsx(
2325
+ return /* @__PURE__ */ jsxRuntime.jsx("main", { children: composerPreview || isComposerPreview() ? /* @__PURE__ */ jsxRuntime.jsx(
2288
2326
  "div",
2289
2327
  {
2290
2328
  "data-slot-id": "main",
@@ -2315,6 +2353,7 @@ function AmplifyPageContent({
2315
2353
  fallback,
2316
2354
  renderComponent,
2317
2355
  pageConfig: pageConfigProp,
2356
+ forceComposerPreview = false,
2318
2357
  previewLoadingComponent,
2319
2358
  previewEmptyComponent,
2320
2359
  loadingComponent,
@@ -2322,7 +2361,7 @@ function AmplifyPageContent({
2322
2361
  errorComponent
2323
2362
  }) {
2324
2363
  const client = useAmplifyUp();
2325
- const preview = isComposerPreview();
2364
+ const preview = forceComposerPreview || isComposerPreview();
2326
2365
  const pageConfig = pageConfigProp ?? client.pageConfig;
2327
2366
  const loading = pageConfigProp ? false : client.loading;
2328
2367
  const error = pageConfigProp ? null : client.error;
@@ -2334,6 +2373,7 @@ function AmplifyPageContent({
2334
2373
  {
2335
2374
  pageConfig: pageConfig ?? void 0,
2336
2375
  renderComponent,
2376
+ composerPreview: true,
2337
2377
  loadingComponent: loadingComponent ?? previewLoading,
2338
2378
  emptyComponent: emptyComponent ?? previewCanvas,
2339
2379
  errorComponent: errorComponent ?? (() => previewCanvas)