@amplifyup/sdk 0.1.55 → 0.1.57

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
@@ -90,8 +90,8 @@ declare function Field(props: {
90
90
  /** Field value from your component props. Do not also pass `name`. */
91
91
  value?: unknown;
92
92
  /**
93
- * @deprecated Will be removed. Use `value={…}` instead and omit `name`.
94
- * Do not pass `name` together with `value`.
93
+ * @deprecated Prefer `value={…}`. Still used as the Composer save key when
94
+ * the same value appears on more than one prop.
95
95
  */
96
96
  name?: string;
97
97
  fallback?: ReactNode;
@@ -120,8 +120,8 @@ declare function RichText(props: {
120
120
  /** Markdown (or HTML) string from your component props. Do not also pass `name`. */
121
121
  value?: string | null;
122
122
  /**
123
- * @deprecated Will be removed. Use `value={…}` (or string children) and omit `name`.
124
- * Do not pass `name` together with `value`.
123
+ * @deprecated Prefer `value={…}`. Still used as the Composer save key when
124
+ * the same value appears on more than one prop.
125
125
  */
126
126
  name?: string;
127
127
  fallback?: ReactNode;
package/dist/react.d.ts CHANGED
@@ -90,8 +90,8 @@ declare function Field(props: {
90
90
  /** Field value from your component props. Do not also pass `name`. */
91
91
  value?: unknown;
92
92
  /**
93
- * @deprecated Will be removed. Use `value={…}` instead and omit `name`.
94
- * Do not pass `name` together with `value`.
93
+ * @deprecated Prefer `value={…}`. Still used as the Composer save key when
94
+ * the same value appears on more than one prop.
95
95
  */
96
96
  name?: string;
97
97
  fallback?: ReactNode;
@@ -120,8 +120,8 @@ declare function RichText(props: {
120
120
  /** Markdown (or HTML) string from your component props. Do not also pass `name`. */
121
121
  value?: string | null;
122
122
  /**
123
- * @deprecated Will be removed. Use `value={…}` (or string children) and omit `name`.
124
- * Do not pass `name` together with `value`.
123
+ * @deprecated Prefer `value={…}`. Still used as the Composer save key when
124
+ * the same value appears on more than one prop.
125
125
  */
126
126
  name?: string;
127
127
  fallback?: ReactNode;
package/dist/react.js CHANGED
@@ -2815,7 +2815,7 @@ Available Console Commands:
2815
2815
  if (typeof document === "undefined") return;
2816
2816
  this.teardownComposerDragDrop();
2817
2817
  const slotSelector = "[data-slot-id], [data-amplifyup-slot]";
2818
- const componentSelector = "[data-amplifyup-component], [data-component-id]";
2818
+ const componentSelector = "[data-amplifyup-component], [data-component-id], [data-amplifyup-node], [data-node-id]";
2819
2819
  const clearDragOverState = () => {
2820
2820
  this.clearComposerDragHighlight();
2821
2821
  };
@@ -2864,6 +2864,7 @@ Available Console Commands:
2864
2864
  if (!target?.closest) return;
2865
2865
  const component = target.closest(componentSelector);
2866
2866
  const slot = target.closest(slotSelector);
2867
+ const pageSlot = slot && slot.getAttribute("data-slot-source") === "page" ? slot : null;
2867
2868
  if (this.highlightComponentsEnabled && component) {
2868
2869
  if (!component.classList.contains("amplifyup-component-hover")) {
2869
2870
  clearComponentHover();
@@ -2875,7 +2876,7 @@ Available Console Commands:
2875
2876
  return;
2876
2877
  }
2877
2878
  clearComponentHover();
2878
- if (this.showZonesEnabled && slot) {
2879
+ if (this.showZonesEnabled && slot && !pageSlot) {
2879
2880
  if (!slot.classList.contains("amplifyup-slot-hover")) {
2880
2881
  clearSlotHover();
2881
2882
  slot.classList.add("amplifyup-slot-hover");
@@ -3005,16 +3006,18 @@ Available Console Commands:
3005
3006
  const lines = [];
3006
3007
  if (highlightComponents) {
3007
3008
  lines.push(
3008
- "[data-amplifyup-component], [data-component-id] {",
3009
+ "[data-amplifyup-component], [data-component-id], [data-amplifyup-node], [data-node-id] {",
3009
3010
  " cursor: pointer !important;",
3010
3011
  "}",
3011
- "[data-amplifyup-component].amplifyup-selected, [data-component-id].amplifyup-selected {",
3012
+ "[data-amplifyup-component].amplifyup-selected, [data-component-id].amplifyup-selected, [data-amplifyup-node].amplifyup-selected, [data-node-id].amplifyup-selected {",
3012
3013
  ` outline: 2px solid ${primary} !important;`,
3013
3014
  " outline-offset: -2px !important;",
3014
3015
  " box-shadow: inset 0 0 0 1px hsl(82 100% 52% / 0.25) !important;",
3015
3016
  "}",
3016
3017
  "[data-amplifyup-component].amplifyup-component-hover:not(.amplifyup-selected),",
3017
- "[data-component-id].amplifyup-component-hover:not(.amplifyup-selected) {",
3018
+ "[data-component-id].amplifyup-component-hover:not(.amplifyup-selected),",
3019
+ "[data-amplifyup-node].amplifyup-component-hover:not(.amplifyup-selected),",
3020
+ "[data-node-id].amplifyup-component-hover:not(.amplifyup-selected) {",
3018
3021
  ` outline: 2px solid ${primary} !important;`,
3019
3022
  " outline-offset: -2px !important;",
3020
3023
  "}"
@@ -3217,7 +3220,7 @@ Available Console Commands:
3217
3220
  let current = element;
3218
3221
  let sawPageSlot = false;
3219
3222
  while (current) {
3220
- if (current.hasAttribute("data-amplifyup-component") || current.hasAttribute("data-component-id") || current.hasAttribute("data-amplifyup-slot") || current.hasAttribute("data-slot-id")) {
3223
+ if (current.hasAttribute("data-amplifyup-component") || current.hasAttribute("data-component-id") || current.hasAttribute("data-amplifyup-slot") || current.hasAttribute("data-slot-id") || current.hasAttribute("data-node-id") || current.hasAttribute("data-amplifyup-node")) {
3221
3224
  hierarchy.push(current);
3222
3225
  if (current.getAttribute("data-slot-source") === "page") {
3223
3226
  sawPageSlot = true;
@@ -3242,13 +3245,14 @@ Available Console Commands:
3242
3245
  const componentId = element.getAttribute("data-amplifyup-component") || element.getAttribute("data-component-id");
3243
3246
  const slotName = componentId ? null : element.getAttribute("data-amplifyup-slot") || element.getAttribute("data-slot-id");
3244
3247
  const componentName = element.getAttribute("data-component-name");
3248
+ const nodeId = element.getAttribute("data-node-id") || element.closest("[data-node-id]")?.getAttribute("data-node-id") || null;
3245
3249
  const hierarchyInfo = hierarchy.map((el, index) => {
3246
3250
  const elComponentId = el.getAttribute("data-amplifyup-component") || el.getAttribute("data-component-id");
3247
3251
  const elSlotName = el.getAttribute("data-amplifyup-slot") || el.getAttribute("data-slot-id");
3248
3252
  const elComponentName = el.getAttribute("data-component-name");
3249
3253
  const isSlot = !elComponentId && !!elSlotName;
3250
3254
  const isPageSlot = isSlot && el.getAttribute("data-slot-source") === "page";
3251
- const nodeId = el.getAttribute("data-node-id") || (isSlot ? el.getAttribute("data-parent-node-id") : null);
3255
+ const nodeId2 = el.getAttribute("data-node-id") || (isSlot ? el.getAttribute("data-parent-node-id") : null);
3252
3256
  return {
3253
3257
  index,
3254
3258
  componentId: elComponentId,
@@ -3256,7 +3260,7 @@ Available Console Commands:
3256
3260
  slotName: isSlot ? elSlotName : null,
3257
3261
  isSlot,
3258
3262
  isPageSlot,
3259
- nodeId
3263
+ nodeId: nodeId2
3260
3264
  };
3261
3265
  });
3262
3266
  const rect = element.getBoundingClientRect ? element.getBoundingClientRect() : null;
@@ -3266,6 +3270,7 @@ Available Console Commands:
3266
3270
  componentId,
3267
3271
  componentName,
3268
3272
  slotName,
3273
+ nodeId,
3269
3274
  hierarchy: hierarchyInfo,
3270
3275
  selectedIndex: hierarchy.length - 1,
3271
3276
  ...bounds && { bounds },
@@ -3295,22 +3300,27 @@ Available Console Commands:
3295
3300
  }
3296
3301
  const doc = document;
3297
3302
  if (highlightComponents) {
3298
- const componentElements = doc.querySelectorAll("[data-amplifyup-component], [data-component-id]");
3303
+ const componentElements = doc.querySelectorAll(
3304
+ "[data-amplifyup-component], [data-component-id], [data-amplifyup-node], [data-node-id]"
3305
+ );
3299
3306
  console.log("[AmplifyUp SDK] Found", componentElements.length, "components to highlight");
3300
3307
  componentElements.forEach((el) => {
3301
3308
  const htmlEl = el;
3302
3309
  const componentId = htmlEl.getAttribute("data-amplifyup-component") || htmlEl.getAttribute("data-component-id");
3303
- if (!componentId) return;
3310
+ const isLayoutNode = htmlEl.hasAttribute("data-node-id") || htmlEl.hasAttribute("data-amplifyup-node");
3311
+ if (!componentId && !isLayoutNode) return;
3304
3312
  if (htmlEl.classList.contains("amplifyup-component-highlight")) return;
3305
- const component = this.componentRegistry.find((c) => c.component_id === componentId);
3313
+ const component = componentId ? this.componentRegistry.find((c) => c.component_id === componentId) : void 0;
3306
3314
  htmlEl.classList.add("amplifyup-component-highlight");
3307
- htmlEl.setAttribute("data-component-id", componentId);
3308
- htmlEl.setAttribute("data-component-name", component?.component_name || componentId);
3315
+ if (componentId) {
3316
+ htmlEl.setAttribute("data-component-id", componentId);
3317
+ htmlEl.setAttribute("data-component-name", component?.component_name || componentId);
3318
+ }
3309
3319
  const hierarchy = this.buildComponentHierarchy(htmlEl);
3310
3320
  const handleClick = (e) => {
3311
3321
  e.stopPropagation();
3312
3322
  this.sendSelectionMessage(htmlEl, hierarchy);
3313
- if (window.parent && window.parent !== window) {
3323
+ if (componentId && window.parent && window.parent !== window) {
3314
3324
  window.parent.postMessage({ type: "CHECK_COMPONENT_DELETABLE", componentId }, "*");
3315
3325
  }
3316
3326
  };
@@ -3351,6 +3361,15 @@ Available Console Commands:
3351
3361
  htmlEl.classList.add("amplifyup-slot-highlight");
3352
3362
  const hierarchy = this.buildComponentHierarchy(htmlEl);
3353
3363
  const handleClick = (e) => {
3364
+ const clickTarget = e.target;
3365
+ if (htmlEl.getAttribute("data-slot-source") === "page" && clickTarget?.closest) {
3366
+ const nested = clickTarget.closest(
3367
+ "[data-node-id], [data-amplifyup-node], [data-amplifyup-component], [data-component-id]"
3368
+ );
3369
+ if (nested && nested !== htmlEl && htmlEl.contains(nested)) {
3370
+ return;
3371
+ }
3372
+ }
3354
3373
  e.stopPropagation();
3355
3374
  this.sendSelectionMessage(htmlEl, hierarchy, isEmpty);
3356
3375
  };
@@ -3685,13 +3704,31 @@ function htmlHasVisualChrome(html) {
3685
3704
  );
3686
3705
  }
3687
3706
  function canInlineEdit(name, value) {
3688
- if (isLikelyNonTextFieldName(name)) return false;
3707
+ if (!name || isLikelyNonTextFieldName(name)) return false;
3689
3708
  if (value !== void 0 && value !== null && typeof value === "object") {
3690
3709
  return false;
3691
3710
  }
3692
3711
  if (typeof value === "boolean") return false;
3693
3712
  return true;
3694
3713
  }
3714
+ function canInlineEditRichText(name, value) {
3715
+ if (!name || isLikelyNonTextFieldName(name)) return false;
3716
+ if (typeof value === "boolean") return false;
3717
+ if (value !== void 0 && value !== null && typeof value === "object" && !Array.isArray(value)) {
3718
+ return false;
3719
+ }
3720
+ return true;
3721
+ }
3722
+ function inferEditName(explicitName, contextProps, sourceValue) {
3723
+ if (explicitName) return explicitName;
3724
+ if (!contextProps) return "";
3725
+ const keys = Object.keys(contextProps).filter(
3726
+ (key) => Object.is(contextProps[key], sourceValue)
3727
+ );
3728
+ if (keys.length === 1) return keys[0];
3729
+ if (keys.length === 0 || isComposerEmptyText(sourceValue)) return "";
3730
+ return keys[0];
3731
+ }
3695
3732
  function subscribeComposerEdit(onStoreChange) {
3696
3733
  if (typeof window === "undefined") return () => {
3697
3734
  };
@@ -3886,9 +3923,11 @@ function ComposerInlineHtml({
3886
3923
  const finishEdit = () => {
3887
3924
  const el = elRef.current;
3888
3925
  if (!el) return;
3889
- const next = (el.innerText ?? "").replace(/\u00a0/g, " ").replace(/\n+$/g, "");
3890
- if (next.trim() === sourceTextRef.current) return;
3891
- commitComposerField(layoutNodeId, componentId, name, next.trim());
3926
+ const nextHtml = el.innerHTML;
3927
+ const nextText = (el.innerText ?? "").replace(/\u00a0/g, " ").replace(/\n+$/g, "").trim();
3928
+ if (nextText === sourceTextRef.current && nextHtml === html) return;
3929
+ const commitValue = htmlHasVisualChrome(html) || /<[a-z][\s\S]*>/i.test(html) ? nextHtml : nextText;
3930
+ commitComposerField(layoutNodeId, componentId, name, commitValue);
3892
3931
  };
3893
3932
  return React__default.default.createElement(Tag, {
3894
3933
  ref: elRef,
@@ -3930,15 +3969,10 @@ function formatFieldValue(value) {
3930
3969
  }
3931
3970
  function warnProjectionProps(component, name, hasExplicitValue) {
3932
3971
  if (process.env.NODE_ENV === "production") return;
3933
- if (hasExplicitValue && name) {
3934
- console.warn(
3935
- `[AmplifyUp SDK] ${component}: pass either value={\u2026} or deprecated name="\u2026", not both. Prefer value={\u2026} and omit name.`
3936
- );
3937
- return;
3938
- }
3972
+ if (hasExplicitValue) return;
3939
3973
  if (name) {
3940
3974
  console.warn(
3941
- `[AmplifyUp SDK] ${component} \`name\` is deprecated and will be removed. Prefer value={${name}} from your component props and omit name.`
3975
+ `[AmplifyUp SDK] ${component} \`name\` is deprecated and will be removed. Prefer value={${name}} from your component props.`
3942
3976
  );
3943
3977
  }
3944
3978
  }
@@ -3978,7 +4012,7 @@ function Field(props) {
3978
4012
  const composerEdit = useComposerEditMode();
3979
4013
  const hasExplicitValue = hasOwnProp(props, "value");
3980
4014
  const sourceValue = hasExplicitValue ? value : name ? context?.props?.[name] : void 0;
3981
- const editName = hasExplicitValue ? "" : name || "";
4015
+ const editName = inferEditName(name, context?.props, sourceValue);
3982
4016
  const fieldValue = useFieldOverlay(
3983
4017
  context?.layoutNodeId,
3984
4018
  editName,
@@ -3992,6 +4026,20 @@ function Field(props) {
3992
4026
  return fallback ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: fallback }) : null;
3993
4027
  }
3994
4028
  if (render) {
4029
+ if (composerEdit && editName && context && canInlineEdit(editName, fieldValue)) {
4030
+ return /* @__PURE__ */ jsxRuntime.jsx(
4031
+ ComposerInlineField,
4032
+ {
4033
+ name: editName,
4034
+ value: fieldValue,
4035
+ fallback,
4036
+ className,
4037
+ render,
4038
+ layoutNodeId: context.layoutNodeId,
4039
+ componentId: context.componentId
4040
+ }
4041
+ );
4042
+ }
3995
4043
  return /* @__PURE__ */ jsxRuntime.jsx("span", { className, style: { display: "contents" }, children: render(fieldValue) });
3996
4044
  }
3997
4045
  if (Array.isArray(fieldValue)) {
@@ -4045,7 +4093,7 @@ function RichText(props) {
4045
4093
  const hasValueProp = hasOwnProp(props, "value");
4046
4094
  const hasExplicitValue = hasValueProp || childrenValue !== void 0;
4047
4095
  const sourceValue = hasValueProp ? value : childrenValue !== void 0 ? childrenValue : name ? context?.props?.[name] : void 0;
4048
- const editName = hasExplicitValue ? "" : name || "";
4096
+ const editName = inferEditName(name, context?.props, sourceValue);
4049
4097
  const fieldValue = useFieldOverlay(
4050
4098
  context?.layoutNodeId,
4051
4099
  editName,
@@ -4058,7 +4106,7 @@ function RichText(props) {
4058
4106
  return fallback ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: fallback }) : null;
4059
4107
  }
4060
4108
  warnProjectionProps("RichText", name, hasExplicitValue);
4061
- const canEdit = !!editName && !!context && canInlineEdit(editName, fieldValue);
4109
+ const canEdit = !!context && canInlineEditRichText(editName, fieldValue);
4062
4110
  if (isComposerEmptyText(fieldValue)) {
4063
4111
  if (composerEdit && canEdit && !isReactNodeFallback(fallback) && !classNameIsBlock(className)) {
4064
4112
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -4090,17 +4138,6 @@ function RichText(props) {
4090
4138
  if (!html) {
4091
4139
  return fallback ? /* @__PURE__ */ jsxRuntime.jsx(Tag, { className, children: fallback }) : null;
4092
4140
  }
4093
- if (composerEdit && htmlHasVisualChrome(html)) {
4094
- return /* @__PURE__ */ jsxRuntime.jsx(
4095
- Tag,
4096
- {
4097
- className,
4098
- "data-amplifyup-field": editName || void 0,
4099
- "data-amplifyup-node-id": context?.layoutNodeId || void 0,
4100
- dangerouslySetInnerHTML: { __html: html }
4101
- }
4102
- );
4103
- }
4104
4141
  if (composerEdit && canEdit) {
4105
4142
  return /* @__PURE__ */ jsxRuntime.jsx(
4106
4143
  ComposerInlineHtml,
@@ -4141,7 +4178,7 @@ function Image(props) {
4141
4178
  const sourceValue = hasExplicitValue ? value : name ? context?.props?.[name] : void 0;
4142
4179
  const fieldValue = useFieldOverlay(
4143
4180
  context?.layoutNodeId,
4144
- hasExplicitValue ? "" : name || "",
4181
+ inferEditName(name, context?.props, sourceValue),
4145
4182
  sourceValue
4146
4183
  );
4147
4184
  warnProjectionProps("Image", name, hasExplicitValue);
@@ -4575,23 +4612,32 @@ function AmplifyRendererInner({
4575
4612
  }
4576
4613
  }
4577
4614
  const slotsToPass = Object.keys(slotChildren).length > 0 ? slotChildren : void 0;
4578
- return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-node-id": node.id, "data-amplifyup-node": "", children: /* @__PURE__ */ jsxRuntime.jsx(
4579
- ComponentRenderBoundary,
4615
+ return /* @__PURE__ */ jsxRuntime.jsx(
4616
+ "div",
4580
4617
  {
4581
- componentId: node.componentId,
4582
- nodeId: node.id,
4618
+ "data-node-id": node.id,
4619
+ "data-amplifyup-node": "",
4620
+ "data-component-id": node.componentId,
4621
+ "data-amplifyup-component": node.componentId,
4583
4622
  children: /* @__PURE__ */ jsxRuntime.jsx(
4584
- LiveNodeRender,
4623
+ ComponentRenderBoundary,
4585
4624
  {
4586
- nodeId: node.id,
4587
4625
  componentId: node.componentId,
4588
- props: nodeRenderProps(node),
4589
- slots: slotsToPass,
4590
- renderComponent
4626
+ nodeId: node.id,
4627
+ children: /* @__PURE__ */ jsxRuntime.jsx(
4628
+ LiveNodeRender,
4629
+ {
4630
+ nodeId: node.id,
4631
+ componentId: node.componentId,
4632
+ props: nodeRenderProps(node),
4633
+ slots: slotsToPass,
4634
+ renderComponent
4635
+ }
4636
+ )
4591
4637
  }
4592
4638
  )
4593
4639
  }
4594
- ) });
4640
+ );
4595
4641
  };
4596
4642
  const rawTree = pageConfig.layoutTree;
4597
4643
  const layoutTree = Array.isArray(rawTree) ? rawTree : rawTree && typeof rawTree === "object" && rawTree.componentId ? [rawTree] : [];
@@ -4605,9 +4651,9 @@ function AmplifyRendererInner({
4605
4651
  "data-amplifyup-slot": "main",
4606
4652
  "data-slot-source": "page",
4607
4653
  "data-slot-empty": layoutTree.length === 0 ? "true" : void 0,
4608
- children: layoutTree.map((node) => /* @__PURE__ */ jsxRuntime.jsx("div", { children: renderNode(node) }, node.id))
4654
+ children: layoutTree.map((node) => /* @__PURE__ */ jsxRuntime.jsx(React.Fragment, { children: renderNode(node) }, node.id))
4609
4655
  }
4610
- ) : layoutTree.map((node) => /* @__PURE__ */ jsxRuntime.jsx("div", { children: renderNode(node) }, node.id)) });
4656
+ ) : layoutTree.map((node) => /* @__PURE__ */ jsxRuntime.jsx(React.Fragment, { children: renderNode(node) }, node.id)) });
4611
4657
  }
4612
4658
  var AmplifyRenderer = React.memo(AmplifyRendererInner);
4613
4659
  function defaultPreviewCanvas() {