@amplifyup/sdk 0.1.38 → 0.1.40
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/AmplifyRenderer.js +14 -5
- package/dist/AmplifyRenderer.js.map +1 -1
- package/dist/AmplifyRenderer.mjs +14 -5
- package/dist/AmplifyRenderer.mjs.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3 -3
- package/dist/index.mjs.map +1 -1
- package/dist/react.js +234 -85
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +194 -49
- package/dist/react.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { createContext, useState, useEffect, useContext, Fragment as Fragment$1, useRef, Component } from 'react';
|
|
2
|
+
import React, { createContext, useState, useEffect, useContext, Fragment as Fragment$1, useSyncExternalStore, useRef, Component } from 'react';
|
|
3
3
|
import { marked } from 'marked';
|
|
4
4
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
5
5
|
|
|
@@ -2634,7 +2634,7 @@ Available Console Commands:
|
|
|
2634
2634
|
if (!highlightComponents && !showZones) return;
|
|
2635
2635
|
const existing = document.getElementById("amplifyup-preview-highlights");
|
|
2636
2636
|
if (existing) existing.remove();
|
|
2637
|
-
const primary = "hsl(82
|
|
2637
|
+
const primary = "hsl(82 100% 52%)";
|
|
2638
2638
|
const lines = [];
|
|
2639
2639
|
if (highlightComponents) {
|
|
2640
2640
|
lines.push(
|
|
@@ -2644,7 +2644,7 @@ Available Console Commands:
|
|
|
2644
2644
|
"[data-amplifyup-component].amplifyup-selected, [data-component-id].amplifyup-selected {",
|
|
2645
2645
|
` outline: 2px solid ${primary} !important;`,
|
|
2646
2646
|
" outline-offset: -2px !important;",
|
|
2647
|
-
" box-shadow: inset 0 0 0 1px hsl(82
|
|
2647
|
+
" box-shadow: inset 0 0 0 1px hsl(82 100% 52% / 0.25) !important;",
|
|
2648
2648
|
"}",
|
|
2649
2649
|
"[data-amplifyup-component].amplifyup-component-hover:not(.amplifyup-selected),",
|
|
2650
2650
|
"[data-component-id].amplifyup-component-hover:not(.amplifyup-selected) {",
|
|
@@ -2656,7 +2656,7 @@ Available Console Commands:
|
|
|
2656
2656
|
if (highlightComponents || showZones) {
|
|
2657
2657
|
lines.push(
|
|
2658
2658
|
"[data-slot-id].amplifyup-selected, [data-amplifyup-slot].amplifyup-selected {",
|
|
2659
|
-
" background-color:
|
|
2659
|
+
" background-color: hsl(82 100% 52% / 0.12) !important;",
|
|
2660
2660
|
"}"
|
|
2661
2661
|
);
|
|
2662
2662
|
}
|
|
@@ -3031,7 +3031,10 @@ function useLiveComposerProps(layoutNodeId, props) {
|
|
|
3031
3031
|
return;
|
|
3032
3032
|
}
|
|
3033
3033
|
if (!matchesNode(nodeId)) return;
|
|
3034
|
-
setLive(
|
|
3034
|
+
setLive((prev) => ({
|
|
3035
|
+
...prev,
|
|
3036
|
+
...nextProps
|
|
3037
|
+
}));
|
|
3035
3038
|
};
|
|
3036
3039
|
const onPatch = (event) => {
|
|
3037
3040
|
const detail = event.detail || {};
|
|
@@ -3192,6 +3195,32 @@ function isLikelyNonTextFieldName(name) {
|
|
|
3192
3195
|
const n = name.toLowerCase();
|
|
3193
3196
|
return n.includes("href") || n.includes("url") || n.includes("src") || n.includes("image") || n.includes("icon") || n.includes("overlay") || n.includes("color");
|
|
3194
3197
|
}
|
|
3198
|
+
function isPlainTextValue(value) {
|
|
3199
|
+
return typeof value === "string" || typeof value === "number";
|
|
3200
|
+
}
|
|
3201
|
+
var COMPOSER_EMPTY_FIELD_HINT = "Click here to edit this field";
|
|
3202
|
+
var EMPTY_FIELD_PLACEHOLDERS = /* @__PURE__ */ new Set([
|
|
3203
|
+
COMPOSER_EMPTY_FIELD_HINT,
|
|
3204
|
+
"Click here to enter text",
|
|
3205
|
+
"Sample Title",
|
|
3206
|
+
"Sample Heading",
|
|
3207
|
+
"Sample Subheading"
|
|
3208
|
+
]);
|
|
3209
|
+
function isComposerEmptyText(value) {
|
|
3210
|
+
if (value === void 0 || value === null) return true;
|
|
3211
|
+
if (typeof value !== "string") return false;
|
|
3212
|
+
const trimmed = value.trim();
|
|
3213
|
+
return trimmed === "" || EMPTY_FIELD_PLACEHOLDERS.has(trimmed);
|
|
3214
|
+
}
|
|
3215
|
+
function isReactNodeFallback(fallback) {
|
|
3216
|
+
if (fallback == null || fallback === false) return false;
|
|
3217
|
+
return !isPlainTextValue(fallback);
|
|
3218
|
+
}
|
|
3219
|
+
function htmlHasVisualChrome(html) {
|
|
3220
|
+
return /<(input|button|select|textarea|form|svg|iframe|video|audio|img)\b/i.test(
|
|
3221
|
+
html
|
|
3222
|
+
);
|
|
3223
|
+
}
|
|
3195
3224
|
function canInlineEdit(name, value) {
|
|
3196
3225
|
if (isLikelyNonTextFieldName(name)) return false;
|
|
3197
3226
|
if (value !== void 0 && value !== null && typeof value === "object") {
|
|
@@ -3200,15 +3229,18 @@ function canInlineEdit(name, value) {
|
|
|
3200
3229
|
if (typeof value === "boolean") return false;
|
|
3201
3230
|
return true;
|
|
3202
3231
|
}
|
|
3232
|
+
function subscribeComposerEdit(onStoreChange) {
|
|
3233
|
+
if (typeof window === "undefined") return () => {
|
|
3234
|
+
};
|
|
3235
|
+
window.addEventListener("amplifyup:composer-edit", onStoreChange);
|
|
3236
|
+
return () => window.removeEventListener("amplifyup:composer-edit", onStoreChange);
|
|
3237
|
+
}
|
|
3203
3238
|
function useComposerEditMode() {
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
return () => window.removeEventListener("amplifyup:composer-edit", sync);
|
|
3210
|
-
}, []);
|
|
3211
|
-
return enabled;
|
|
3239
|
+
return useSyncExternalStore(
|
|
3240
|
+
subscribeComposerEdit,
|
|
3241
|
+
isComposerEditMode,
|
|
3242
|
+
() => false
|
|
3243
|
+
);
|
|
3212
3244
|
}
|
|
3213
3245
|
function useFieldOverlay(layoutNodeId, name, source) {
|
|
3214
3246
|
const [overlay, setOverlay] = useState(void 0);
|
|
@@ -3239,6 +3271,14 @@ function commitComposerField(layoutNodeId, componentId, name, value) {
|
|
|
3239
3271
|
"*"
|
|
3240
3272
|
);
|
|
3241
3273
|
}
|
|
3274
|
+
function placeCaret(el, atStart = false) {
|
|
3275
|
+
const range = document.createRange();
|
|
3276
|
+
range.selectNodeContents(el);
|
|
3277
|
+
range.collapse(atStart);
|
|
3278
|
+
const sel = window.getSelection();
|
|
3279
|
+
sel?.removeAllRanges();
|
|
3280
|
+
sel?.addRange(range);
|
|
3281
|
+
}
|
|
3242
3282
|
function ComposerInlineField({
|
|
3243
3283
|
name,
|
|
3244
3284
|
value,
|
|
@@ -3249,35 +3289,54 @@ function ComposerInlineField({
|
|
|
3249
3289
|
componentId
|
|
3250
3290
|
}) {
|
|
3251
3291
|
const [editing, setEditing] = useState(false);
|
|
3292
|
+
const [focused, setFocused] = useState(false);
|
|
3252
3293
|
const elRef = useRef(null);
|
|
3253
|
-
const
|
|
3294
|
+
const storedEmpty = isComposerEmptyText(value);
|
|
3295
|
+
const text = storedEmpty ? "" : formatFieldValue(value);
|
|
3254
3296
|
const fallbackText = typeof fallback === "string" || typeof fallback === "number" ? String(fallback) : "";
|
|
3255
|
-
const
|
|
3297
|
+
const hint = COMPOSER_EMPTY_FIELD_HINT;
|
|
3298
|
+
const idleDisplay = storedEmpty ? hint : text || fallbackText;
|
|
3256
3299
|
const showRendered = !!render && !editing;
|
|
3300
|
+
const showHint = storedEmpty && !focused && !showRendered;
|
|
3257
3301
|
useEffect(() => {
|
|
3258
3302
|
const el = elRef.current;
|
|
3259
3303
|
if (!el || showRendered) return;
|
|
3260
3304
|
if (document.activeElement === el) return;
|
|
3261
|
-
|
|
3305
|
+
if (el.querySelector(
|
|
3306
|
+
"input, button, select, textarea, form, svg, iframe, img"
|
|
3307
|
+
)) {
|
|
3308
|
+
return;
|
|
3309
|
+
}
|
|
3310
|
+
const next = idleDisplay || "";
|
|
3262
3311
|
if (el.textContent !== next) el.textContent = next;
|
|
3263
|
-
}, [
|
|
3312
|
+
}, [idleDisplay, showRendered]);
|
|
3264
3313
|
useEffect(() => {
|
|
3265
3314
|
if (!editing || !elRef.current) return;
|
|
3266
3315
|
const el = elRef.current;
|
|
3267
|
-
|
|
3316
|
+
if (storedEmpty) {
|
|
3317
|
+
el.textContent = "";
|
|
3318
|
+
el.focus();
|
|
3319
|
+
placeCaret(el, true);
|
|
3320
|
+
return;
|
|
3321
|
+
}
|
|
3322
|
+
el.textContent = idleDisplay || "";
|
|
3268
3323
|
el.focus();
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
const sel = window.getSelection();
|
|
3272
|
-
sel?.removeAllRanges();
|
|
3273
|
-
sel?.addRange(range);
|
|
3274
|
-
}, [editing]);
|
|
3324
|
+
placeCaret(el, false);
|
|
3325
|
+
}, [editing, storedEmpty, idleDisplay]);
|
|
3275
3326
|
const finishEdit = () => {
|
|
3276
3327
|
const raw = (elRef.current?.innerText ?? "").replace(/\u00a0/g, " ").replace(/\n+$/g, "");
|
|
3277
3328
|
const next = raw.trim() === "" ? "" : raw;
|
|
3278
3329
|
setEditing(false);
|
|
3330
|
+
setFocused(false);
|
|
3331
|
+
if (storedEmpty && next === "") {
|
|
3332
|
+
if (elRef.current) elRef.current.textContent = hint;
|
|
3333
|
+
if (typeof value === "string" && EMPTY_FIELD_PLACEHOLDERS.has(value.trim())) {
|
|
3334
|
+
commitComposerField(layoutNodeId, componentId, name, "");
|
|
3335
|
+
}
|
|
3336
|
+
return;
|
|
3337
|
+
}
|
|
3279
3338
|
if (next === text) return;
|
|
3280
|
-
if (!text && next === fallbackText) return;
|
|
3339
|
+
if (!text && !storedEmpty && next === fallbackText) return;
|
|
3281
3340
|
commitComposerField(layoutNodeId, componentId, name, next);
|
|
3282
3341
|
};
|
|
3283
3342
|
return /* @__PURE__ */ jsx(
|
|
@@ -3287,6 +3346,7 @@ function ComposerInlineField({
|
|
|
3287
3346
|
className,
|
|
3288
3347
|
"data-amplifyup-field": name,
|
|
3289
3348
|
"data-amplifyup-node-id": layoutNodeId || void 0,
|
|
3349
|
+
"data-amplifyup-empty-hint": showHint ? "true" : void 0,
|
|
3290
3350
|
contentEditable: !showRendered,
|
|
3291
3351
|
suppressContentEditableWarning: true,
|
|
3292
3352
|
role: "textbox",
|
|
@@ -3303,6 +3363,12 @@ function ComposerInlineField({
|
|
|
3303
3363
|
},
|
|
3304
3364
|
onFocus: () => {
|
|
3305
3365
|
if (!isComposerEditMode()) return;
|
|
3366
|
+
setFocused(true);
|
|
3367
|
+
const el = elRef.current;
|
|
3368
|
+
if (el && storedEmpty) {
|
|
3369
|
+
el.textContent = "";
|
|
3370
|
+
placeCaret(el, true);
|
|
3371
|
+
}
|
|
3306
3372
|
if (render) setEditing(true);
|
|
3307
3373
|
},
|
|
3308
3374
|
onBlur: finishEdit,
|
|
@@ -3314,8 +3380,9 @@ function ComposerInlineField({
|
|
|
3314
3380
|
}
|
|
3315
3381
|
if (event.key === "Escape") {
|
|
3316
3382
|
event.preventDefault();
|
|
3317
|
-
if (elRef.current) elRef.current.textContent =
|
|
3383
|
+
if (elRef.current) elRef.current.textContent = idleDisplay || "";
|
|
3318
3384
|
setEditing(false);
|
|
3385
|
+
setFocused(false);
|
|
3319
3386
|
event.currentTarget.blur();
|
|
3320
3387
|
}
|
|
3321
3388
|
},
|
|
@@ -3324,12 +3391,59 @@ function ComposerInlineField({
|
|
|
3324
3391
|
outline: "1px dashed color-mix(in srgb, currentColor 40%, transparent)",
|
|
3325
3392
|
outlineOffset: "2px",
|
|
3326
3393
|
minWidth: "1ch",
|
|
3327
|
-
|
|
3394
|
+
minHeight: "1em",
|
|
3395
|
+
display: render ? void 0 : "inline",
|
|
3396
|
+
opacity: showHint ? 0.5 : void 0
|
|
3328
3397
|
},
|
|
3329
|
-
children: showRendered ? value != null && value !== "" ? render(value) : fallback ??
|
|
3398
|
+
children: showRendered ? value != null && value !== "" && !storedEmpty ? render(value) : fallback ?? idleDisplay : isReactNodeFallback(fallback) && !idleDisplay ? fallback : null
|
|
3330
3399
|
}
|
|
3331
3400
|
);
|
|
3332
3401
|
}
|
|
3402
|
+
function ComposerInlineHtml({
|
|
3403
|
+
name,
|
|
3404
|
+
html,
|
|
3405
|
+
className,
|
|
3406
|
+
Tag = "div",
|
|
3407
|
+
layoutNodeId,
|
|
3408
|
+
componentId
|
|
3409
|
+
}) {
|
|
3410
|
+
const elRef = useRef(null);
|
|
3411
|
+
const sourceTextRef = useRef("");
|
|
3412
|
+
useEffect(() => {
|
|
3413
|
+
const el = elRef.current;
|
|
3414
|
+
if (!el) return;
|
|
3415
|
+
if (document.activeElement === el || el.contains(document.activeElement)) {
|
|
3416
|
+
return;
|
|
3417
|
+
}
|
|
3418
|
+
if (el.innerHTML !== html) el.innerHTML = html;
|
|
3419
|
+
sourceTextRef.current = (el.innerText ?? "").replace(/\u00a0/g, " ").trim();
|
|
3420
|
+
}, [html]);
|
|
3421
|
+
const finishEdit = () => {
|
|
3422
|
+
const el = elRef.current;
|
|
3423
|
+
if (!el) return;
|
|
3424
|
+
const next = (el.innerText ?? "").replace(/\u00a0/g, " ").replace(/\n+$/g, "");
|
|
3425
|
+
if (next.trim() === sourceTextRef.current) return;
|
|
3426
|
+
commitComposerField(layoutNodeId, componentId, name, next.trim());
|
|
3427
|
+
};
|
|
3428
|
+
return React.createElement(Tag, {
|
|
3429
|
+
ref: elRef,
|
|
3430
|
+
className,
|
|
3431
|
+
"data-amplifyup-field": name,
|
|
3432
|
+
"data-amplifyup-node-id": layoutNodeId || void 0,
|
|
3433
|
+
contentEditable: true,
|
|
3434
|
+
suppressContentEditableWarning: true,
|
|
3435
|
+
dangerouslySetInnerHTML: { __html: html },
|
|
3436
|
+
onMouseDown: (event) => {
|
|
3437
|
+
event.stopPropagation();
|
|
3438
|
+
},
|
|
3439
|
+
onBlur: finishEdit,
|
|
3440
|
+
style: {
|
|
3441
|
+
cursor: "text",
|
|
3442
|
+
outline: "1px dashed color-mix(in srgb, currentColor 40%, transparent)",
|
|
3443
|
+
outlineOffset: "2px"
|
|
3444
|
+
}
|
|
3445
|
+
});
|
|
3446
|
+
}
|
|
3333
3447
|
function formatFieldValue(value) {
|
|
3334
3448
|
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
3335
3449
|
return String(value);
|
|
@@ -3396,7 +3510,13 @@ function Field({
|
|
|
3396
3510
|
if (render) {
|
|
3397
3511
|
return /* @__PURE__ */ jsx("span", { className, style: { display: "contents" }, children: render(fieldValue) });
|
|
3398
3512
|
}
|
|
3399
|
-
if (
|
|
3513
|
+
if (Array.isArray(fieldValue)) {
|
|
3514
|
+
const list = renderLinkList(fieldValue, className);
|
|
3515
|
+
if (list) return list;
|
|
3516
|
+
}
|
|
3517
|
+
const text = formatFieldValue(fieldValue);
|
|
3518
|
+
const showVisualFallback = !text && isReactNodeFallback(fallback);
|
|
3519
|
+
if (composerEdit && canInlineEdit(name, fieldValue) && !showVisualFallback) {
|
|
3400
3520
|
return /* @__PURE__ */ jsx(
|
|
3401
3521
|
ComposerInlineField,
|
|
3402
3522
|
{
|
|
@@ -3412,11 +3532,6 @@ function Field({
|
|
|
3412
3532
|
if (fieldValue === void 0 || fieldValue === null) {
|
|
3413
3533
|
return fallback ? /* @__PURE__ */ jsx("span", { className, children: fallback }) : null;
|
|
3414
3534
|
}
|
|
3415
|
-
if (Array.isArray(fieldValue)) {
|
|
3416
|
-
const list = renderLinkList(fieldValue, className);
|
|
3417
|
-
if (list) return list;
|
|
3418
|
-
}
|
|
3419
|
-
const text = formatFieldValue(fieldValue);
|
|
3420
3535
|
if (!text) {
|
|
3421
3536
|
return fallback ? /* @__PURE__ */ jsx("span", { className, children: fallback }) : null;
|
|
3422
3537
|
}
|
|
@@ -3447,20 +3562,20 @@ function RichText({
|
|
|
3447
3562
|
console.warn(`[AmplifyUp SDK] RichText "${name}" used outside ComponentContextProvider`);
|
|
3448
3563
|
return fallback ? /* @__PURE__ */ jsx(Fragment, { children: fallback }) : null;
|
|
3449
3564
|
}
|
|
3450
|
-
if (
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3565
|
+
if (isComposerEmptyText(fieldValue)) {
|
|
3566
|
+
if (composerEdit && canInlineEdit(name, fieldValue) && !isReactNodeFallback(fallback)) {
|
|
3567
|
+
return /* @__PURE__ */ jsx(
|
|
3568
|
+
ComposerInlineField,
|
|
3569
|
+
{
|
|
3570
|
+
name,
|
|
3571
|
+
value: fieldValue,
|
|
3572
|
+
fallback: typeof fallback === "string" || typeof fallback === "number" ? fallback : void 0,
|
|
3573
|
+
className,
|
|
3574
|
+
layoutNodeId: context.layoutNodeId,
|
|
3575
|
+
componentId: context.componentId
|
|
3576
|
+
}
|
|
3577
|
+
);
|
|
3578
|
+
}
|
|
3464
3579
|
return fallback ? /* @__PURE__ */ jsx(Tag, { className, children: fallback }) : null;
|
|
3465
3580
|
}
|
|
3466
3581
|
let html = "";
|
|
@@ -3478,6 +3593,30 @@ function RichText({
|
|
|
3478
3593
|
if (!html) {
|
|
3479
3594
|
return fallback ? /* @__PURE__ */ jsx(Tag, { className, children: fallback }) : null;
|
|
3480
3595
|
}
|
|
3596
|
+
if (composerEdit && htmlHasVisualChrome(html)) {
|
|
3597
|
+
return /* @__PURE__ */ jsx(
|
|
3598
|
+
Tag,
|
|
3599
|
+
{
|
|
3600
|
+
className,
|
|
3601
|
+
"data-amplifyup-field": name,
|
|
3602
|
+
"data-amplifyup-node-id": context.layoutNodeId || void 0,
|
|
3603
|
+
dangerouslySetInnerHTML: { __html: html }
|
|
3604
|
+
}
|
|
3605
|
+
);
|
|
3606
|
+
}
|
|
3607
|
+
if (composerEdit && canInlineEdit(name, fieldValue)) {
|
|
3608
|
+
return /* @__PURE__ */ jsx(
|
|
3609
|
+
ComposerInlineHtml,
|
|
3610
|
+
{
|
|
3611
|
+
name,
|
|
3612
|
+
html,
|
|
3613
|
+
className,
|
|
3614
|
+
Tag,
|
|
3615
|
+
layoutNodeId: context.layoutNodeId,
|
|
3616
|
+
componentId: context.componentId
|
|
3617
|
+
}
|
|
3618
|
+
);
|
|
3619
|
+
}
|
|
3481
3620
|
return /* @__PURE__ */ jsx(Tag, { className, dangerouslySetInnerHTML: { __html: html } });
|
|
3482
3621
|
}
|
|
3483
3622
|
function isPortableImageValue(value) {
|
|
@@ -3528,6 +3667,12 @@ function Image({
|
|
|
3528
3667
|
}
|
|
3529
3668
|
);
|
|
3530
3669
|
}
|
|
3670
|
+
function nodeRenderProps(node) {
|
|
3671
|
+
return {
|
|
3672
|
+
...node.settings || {},
|
|
3673
|
+
...node.props || {}
|
|
3674
|
+
};
|
|
3675
|
+
}
|
|
3531
3676
|
var ComponentRenderBoundary = class extends Component {
|
|
3532
3677
|
constructor() {
|
|
3533
3678
|
super(...arguments);
|
|
@@ -3951,7 +4096,7 @@ function AmplifyRenderer({
|
|
|
3951
4096
|
{
|
|
3952
4097
|
nodeId: node.id,
|
|
3953
4098
|
componentId: node.componentId,
|
|
3954
|
-
props: node
|
|
4099
|
+
props: nodeRenderProps(node),
|
|
3955
4100
|
slots: slotsToPass,
|
|
3956
4101
|
renderComponent
|
|
3957
4102
|
}
|