@amplifyup/sdk 0.1.57 → 0.1.59

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.mjs CHANGED
@@ -2348,6 +2348,25 @@ Available Console Commands:
2348
2348
  return;
2349
2349
  }
2350
2350
  try {
2351
+ if (event.data?.type === "AMPLIFYUP_RICHTEXT_EDITING") {
2352
+ document.querySelectorAll(".amplifyup-richtext-editing").forEach((el) => el.classList.remove("amplifyup-richtext-editing"));
2353
+ if (event.data.active && event.data.fieldName) {
2354
+ if (!document.getElementById("amplifyup-richtext-editing-style")) {
2355
+ const style = document.createElement("style");
2356
+ style.id = "amplifyup-richtext-editing-style";
2357
+ style.textContent = "[data-amplifyup-field].amplifyup-richtext-editing{outline:none!important;visibility:hidden!important;}";
2358
+ document.head.appendChild(style);
2359
+ }
2360
+ const editRoot = event.data.layoutNodeId ? document.querySelector(
2361
+ `[data-node-id="${event.data.layoutNodeId}"], [data-amplifyup-node-id="${event.data.layoutNodeId}"]`
2362
+ ) || document : document;
2363
+ const editField = editRoot.querySelector(
2364
+ `[data-amplifyup-field="${event.data.fieldName}"]`
2365
+ );
2366
+ if (editField) editField.classList.add("amplifyup-richtext-editing");
2367
+ }
2368
+ return;
2369
+ }
2351
2370
  if (event.data?.type === "AMPLIFYUP_FIELD_PATCH") {
2352
2371
  window.dispatchEvent(
2353
2372
  new CustomEvent("amplifyup:field-patch", { detail: event.data })
@@ -3692,11 +3711,6 @@ function isReactNodeFallback(fallback) {
3692
3711
  function classNameIsBlock(className) {
3693
3712
  return /(?:^|\s)block(?:\s|$)/.test(className || "");
3694
3713
  }
3695
- function htmlHasVisualChrome(html) {
3696
- return /<(input|button|select|textarea|form|svg|iframe|video|audio|img)\b/i.test(
3697
- html
3698
- );
3699
- }
3700
3714
  function canInlineEdit(name, value) {
3701
3715
  if (!name || isLikelyNonTextFieldName(name)) return false;
3702
3716
  if (value !== void 0 && value !== null && typeof value === "object") {
@@ -3765,6 +3779,36 @@ function commitComposerField(layoutNodeId, componentId, name, value) {
3765
3779
  "*"
3766
3780
  );
3767
3781
  }
3782
+ function looksLikeRichCanvasField(name) {
3783
+ const tokens = String(name || "").replace(/([a-z])([A-Z])/g, "$1 $2").split(/[._\-\s/]+/).map((s) => s.toLowerCase()).filter(Boolean);
3784
+ const last = tokens[tokens.length - 1] || "";
3785
+ return last === "body" || last === "content" || last === "copy" || last === "excerpt" || last === "markdown" || last === "richtext";
3786
+ }
3787
+ var lastRichTextRequestAt = 0;
3788
+ function requestCanvasRichTextEdit(opts) {
3789
+ if (typeof window === "undefined" || window.parent === window) return;
3790
+ if (!opts.name) return;
3791
+ const now = Date.now();
3792
+ if (now - lastRichTextRequestAt < 400) return;
3793
+ lastRichTextRequestAt = now;
3794
+ const rect = opts.el.getBoundingClientRect();
3795
+ window.parent.postMessage(
3796
+ {
3797
+ type: "AMPLIFYUP_RICHTEXT_EDIT",
3798
+ layoutNodeId: opts.layoutNodeId,
3799
+ componentId: opts.componentId,
3800
+ fieldName: opts.name,
3801
+ value: opts.value,
3802
+ bounds: {
3803
+ top: rect.top,
3804
+ left: rect.left,
3805
+ width: Math.max(rect.width, 240),
3806
+ height: Math.max(rect.height, 64)
3807
+ }
3808
+ },
3809
+ "*"
3810
+ );
3811
+ }
3768
3812
  function placeCaret(el, atStart = false) {
3769
3813
  const range = document.createRange();
3770
3814
  range.selectNodeContents(el);
@@ -3780,7 +3824,8 @@ function ComposerInlineField({
3780
3824
  className,
3781
3825
  render,
3782
3826
  layoutNodeId,
3783
- componentId
3827
+ componentId,
3828
+ rich = false
3784
3829
  }) {
3785
3830
  const [editing, setEditing] = useState(false);
3786
3831
  const [focused, setFocused] = useState(false);
@@ -3833,6 +3878,19 @@ function ComposerInlineField({
3833
3878
  if (!text && !storedEmpty && next === fallbackText) return;
3834
3879
  commitComposerField(layoutNodeId, componentId, name, next);
3835
3880
  };
3881
+ const openRichEditor = (event) => {
3882
+ if (!isComposerEditMode() || !elRef.current) return;
3883
+ event?.preventDefault();
3884
+ event?.stopPropagation();
3885
+ const source = typeof value === "string" && !storedEmpty ? value : text || "";
3886
+ requestCanvasRichTextEdit({
3887
+ el: elRef.current,
3888
+ layoutNodeId,
3889
+ componentId,
3890
+ name,
3891
+ value: source
3892
+ });
3893
+ };
3836
3894
  return /* @__PURE__ */ jsx(
3837
3895
  "span",
3838
3896
  {
@@ -3841,7 +3899,7 @@ function ComposerInlineField({
3841
3899
  "data-amplifyup-field": name,
3842
3900
  "data-amplifyup-node-id": layoutNodeId || void 0,
3843
3901
  "data-amplifyup-empty-hint": showHint ? "true" : void 0,
3844
- contentEditable: !showRendered,
3902
+ contentEditable: !rich && !showRendered,
3845
3903
  suppressContentEditableWarning: true,
3846
3904
  role: "textbox",
3847
3905
  tabIndex: 0,
@@ -3852,12 +3910,20 @@ function ComposerInlineField({
3852
3910
  if (!isComposerEditMode()) return;
3853
3911
  const link = event.target?.closest?.("a");
3854
3912
  if (link) event.preventDefault();
3913
+ if (rich) {
3914
+ openRichEditor(event);
3915
+ return;
3916
+ }
3855
3917
  if (render) {
3856
3918
  setEditing(true);
3857
3919
  }
3858
3920
  },
3859
3921
  onFocus: () => {
3860
3922
  if (!isComposerEditMode()) return;
3923
+ if (rich) {
3924
+ openRichEditor();
3925
+ return;
3926
+ }
3861
3927
  setFocused(true);
3862
3928
  const el = elRef.current;
3863
3929
  if (el && storedEmpty) {
@@ -3866,7 +3932,7 @@ function ComposerInlineField({
3866
3932
  }
3867
3933
  if (render) setEditing(true);
3868
3934
  },
3869
- onBlur: finishEdit,
3935
+ onBlur: rich ? void 0 : finishEdit,
3870
3936
  onKeyDown: (event) => {
3871
3937
  event.stopPropagation();
3872
3938
  if (event.key === "Enter" && !event.shiftKey) {
@@ -3898,43 +3964,40 @@ function ComposerInlineField({
3898
3964
  function ComposerInlineHtml({
3899
3965
  name,
3900
3966
  html,
3967
+ sourceValue,
3901
3968
  className,
3902
3969
  Tag = "div",
3903
3970
  layoutNodeId,
3904
3971
  componentId
3905
3972
  }) {
3906
3973
  const elRef = useRef(null);
3907
- const sourceTextRef = useRef("");
3908
3974
  useEffect(() => {
3909
3975
  const el = elRef.current;
3910
3976
  if (!el) return;
3911
- if (document.activeElement === el || el.contains(document.activeElement)) {
3912
- return;
3913
- }
3914
3977
  if (el.innerHTML !== html) el.innerHTML = html;
3915
- sourceTextRef.current = (el.innerText ?? "").replace(/\u00a0/g, " ").trim();
3916
3978
  }, [html]);
3917
- const finishEdit = () => {
3918
- const el = elRef.current;
3919
- if (!el) return;
3920
- const nextHtml = el.innerHTML;
3921
- const nextText = (el.innerText ?? "").replace(/\u00a0/g, " ").replace(/\n+$/g, "").trim();
3922
- if (nextText === sourceTextRef.current && nextHtml === html) return;
3923
- const commitValue = htmlHasVisualChrome(html) || /<[a-z][\s\S]*>/i.test(html) ? nextHtml : nextText;
3924
- commitComposerField(layoutNodeId, componentId, name, commitValue);
3979
+ const openRichEditor = (event) => {
3980
+ if (!elRef.current) return;
3981
+ event.preventDefault();
3982
+ event.stopPropagation();
3983
+ requestCanvasRichTextEdit({
3984
+ el: elRef.current,
3985
+ layoutNodeId,
3986
+ componentId,
3987
+ name,
3988
+ value: sourceValue
3989
+ });
3925
3990
  };
3926
3991
  return React.createElement(Tag, {
3927
3992
  ref: elRef,
3928
3993
  className,
3929
3994
  "data-amplifyup-field": name,
3930
3995
  "data-amplifyup-node-id": layoutNodeId || void 0,
3931
- contentEditable: true,
3932
- suppressContentEditableWarning: true,
3933
3996
  dangerouslySetInnerHTML: { __html: html },
3934
3997
  onMouseDown: (event) => {
3935
3998
  event.stopPropagation();
3936
3999
  },
3937
- onBlur: finishEdit,
4000
+ onClick: openRichEditor,
3938
4001
  style: {
3939
4002
  cursor: "text",
3940
4003
  outline: "1px dashed color-mix(in srgb, currentColor 40%, transparent)",
@@ -4030,7 +4093,8 @@ function Field(props) {
4030
4093
  className,
4031
4094
  render,
4032
4095
  layoutNodeId: context.layoutNodeId,
4033
- componentId: context.componentId
4096
+ componentId: context.componentId,
4097
+ rich: looksLikeRichCanvasField(editName)
4034
4098
  }
4035
4099
  );
4036
4100
  }
@@ -4052,7 +4116,8 @@ function Field(props) {
4052
4116
  fallback,
4053
4117
  className,
4054
4118
  layoutNodeId: context.layoutNodeId,
4055
- componentId: context.componentId
4119
+ componentId: context.componentId,
4120
+ rich: looksLikeRichCanvasField(editName)
4056
4121
  }
4057
4122
  );
4058
4123
  }
@@ -4111,7 +4176,8 @@ function RichText(props) {
4111
4176
  fallback: typeof fallback === "string" || typeof fallback === "number" ? fallback : void 0,
4112
4177
  className,
4113
4178
  layoutNodeId: context?.layoutNodeId,
4114
- componentId: context?.componentId
4179
+ componentId: context?.componentId,
4180
+ rich: true
4115
4181
  }
4116
4182
  );
4117
4183
  }
@@ -4138,6 +4204,7 @@ function RichText(props) {
4138
4204
  {
4139
4205
  name: editName,
4140
4206
  html,
4207
+ sourceValue: typeof fieldValue === "string" ? fieldValue : html,
4141
4208
  className,
4142
4209
  Tag,
4143
4210
  layoutNodeId: context?.layoutNodeId,