@puckeditor/plugin-ai 0.9.0-canary.d8bdabee → 0.9.0-canary.fb1abcf5
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/index.js +567 -411
- package/dist/index.mjs +551 -395
- package/package.json +9 -9
package/dist/index.js
CHANGED
|
@@ -995,7 +995,7 @@ function useChat({
|
|
|
995
995
|
// src/components/Chat/index.tsx
|
|
996
996
|
var import_core5 = require("@puckeditor/core");
|
|
997
997
|
var import_ai5 = require("ai");
|
|
998
|
-
var
|
|
998
|
+
var import_react27 = require("react");
|
|
999
999
|
var import_ulid = require("ulid");
|
|
1000
1000
|
|
|
1001
1001
|
// ../utils/lib/get-class-name-factory.ts
|
|
@@ -2490,7 +2490,6 @@ function ExamplePrompt({
|
|
|
2490
2490
|
// src/components/Chat/index.tsx
|
|
2491
2491
|
var import_qler = __toESM(require("qler"));
|
|
2492
2492
|
var import_reducer = __toESM(require_dist());
|
|
2493
|
-
var import_html2canvas_pro = __toESM(require("html2canvas-pro"));
|
|
2494
2493
|
var import_use_debounce = require("use-debounce");
|
|
2495
2494
|
|
|
2496
2495
|
// src/lib/scroll-tracking-events.ts
|
|
@@ -2546,151 +2545,20 @@ var import_core4 = require("@puckeditor/core");
|
|
|
2546
2545
|
// src/lib/design/component.tsx
|
|
2547
2546
|
init_react_import();
|
|
2548
2547
|
var import_core3 = require("@puckeditor/core");
|
|
2549
|
-
var
|
|
2548
|
+
var import_react24 = require("react");
|
|
2550
2549
|
|
|
2551
2550
|
// src/lib/morph-html.ts
|
|
2552
2551
|
init_react_import();
|
|
2553
|
-
var PROTECTED_ATTRS = /* @__PURE__ */ new Set([
|
|
2554
|
-
"contenteditable",
|
|
2555
|
-
"data-puck-overlay-portal"
|
|
2556
|
-
]);
|
|
2557
|
-
var SLOT_OWNED_ATTRS = /* @__PURE__ */ new Set(["style", "class"]);
|
|
2558
|
-
var isEventHandlerAttr = (name) => /^on/i.test(name);
|
|
2559
|
-
var cssEscape = (value) => typeof CSS !== "undefined" && CSS.escape ? CSS.escape(value) : value.replace(/["\\]/g, "\\$&");
|
|
2560
|
-
var FIELD_ATTR_PREFIX = "data-puck-field-";
|
|
2561
|
-
var hasJsonFieldBinding = (el) => {
|
|
2562
|
-
const attrBoundNames = /* @__PURE__ */ new Set();
|
|
2563
|
-
const jsonFieldNames = [];
|
|
2564
|
-
for (const attr of Array.from(el.attributes)) {
|
|
2565
|
-
if (!attr.name.startsWith(FIELD_ATTR_PREFIX)) continue;
|
|
2566
|
-
if (attr.name.startsWith("data-puck-field-value-")) continue;
|
|
2567
|
-
if (attr.value.trimStart().startsWith("{")) {
|
|
2568
|
-
const fieldName = attr.name.slice(FIELD_ATTR_PREFIX.length);
|
|
2569
|
-
if (fieldName && fieldName !== "name") {
|
|
2570
|
-
jsonFieldNames.push(fieldName);
|
|
2571
|
-
}
|
|
2572
|
-
} else {
|
|
2573
|
-
const fieldName = attr.value.trim();
|
|
2574
|
-
if (fieldName) attrBoundNames.add(fieldName);
|
|
2575
|
-
}
|
|
2576
|
-
}
|
|
2577
|
-
return jsonFieldNames.some((name) => !attrBoundNames.has(name));
|
|
2578
|
-
};
|
|
2579
|
-
var ownsItsChildren = (el) => el.hasAttribute("data-puck-slot") || el.hasAttribute("data-puck-field-name") || el.hasAttribute("data-puck-array") || hasJsonFieldBinding(el);
|
|
2580
|
-
var syncAttributes = (target, source) => {
|
|
2581
|
-
const isSlot = target.hasAttribute("data-puck-slot");
|
|
2582
|
-
for (const attr of Array.from(target.attributes)) {
|
|
2583
|
-
if (PROTECTED_ATTRS.has(attr.name)) continue;
|
|
2584
|
-
if (isSlot && SLOT_OWNED_ATTRS.has(attr.name)) continue;
|
|
2585
|
-
if (isEventHandlerAttr(attr.name) || !source.hasAttribute(attr.name)) {
|
|
2586
|
-
target.removeAttribute(attr.name);
|
|
2587
|
-
}
|
|
2588
|
-
}
|
|
2589
|
-
for (const attr of Array.from(source.attributes)) {
|
|
2590
|
-
if (PROTECTED_ATTRS.has(attr.name)) continue;
|
|
2591
|
-
if (isSlot && SLOT_OWNED_ATTRS.has(attr.name)) continue;
|
|
2592
|
-
if (isEventHandlerAttr(attr.name)) continue;
|
|
2593
|
-
if (target.getAttribute(attr.name) !== attr.value) {
|
|
2594
|
-
target.setAttribute(attr.name, attr.value);
|
|
2595
|
-
}
|
|
2596
|
-
}
|
|
2597
|
-
};
|
|
2598
|
-
var isSameKind = (a, b) => a.nodeType === b.nodeType && (a.nodeType !== Node.ELEMENT_NODE || a.tagName === b.tagName);
|
|
2599
|
-
var isIncompleteTagArtifact = (node) => node.nodeType === Node.TEXT_NODE && /^<\/?[a-zA-Z]*$/.test(node.nodeValue ?? "");
|
|
2600
|
-
var stripIncompleteTagArtifacts = (root) => {
|
|
2601
|
-
for (const child of Array.from(root.childNodes)) {
|
|
2602
|
-
if (isIncompleteTagArtifact(child)) {
|
|
2603
|
-
root.removeChild(child);
|
|
2604
|
-
} else if (child.nodeType === Node.ELEMENT_NODE) {
|
|
2605
|
-
stripIncompleteTagArtifacts(child);
|
|
2606
|
-
}
|
|
2607
|
-
}
|
|
2608
|
-
};
|
|
2609
|
-
var stripEventHandlerAttrs = (root) => {
|
|
2610
|
-
root.querySelectorAll("*").forEach((el) => {
|
|
2611
|
-
for (const attr of Array.from(el.attributes)) {
|
|
2612
|
-
if (isEventHandlerAttr(attr.name)) el.removeAttribute(attr.name);
|
|
2613
|
-
}
|
|
2614
|
-
});
|
|
2615
|
-
};
|
|
2616
|
-
var morphChildren = (target, source, skipChildrenOf = ownsItsChildren) => {
|
|
2617
|
-
const sourceChildren = Array.from(source.childNodes);
|
|
2618
|
-
for (let i = 0; i < sourceChildren.length; i++) {
|
|
2619
|
-
const sourceChild = sourceChildren[i];
|
|
2620
|
-
const targetChild = target.childNodes[i];
|
|
2621
|
-
if (!targetChild) {
|
|
2622
|
-
target.appendChild(sourceChild);
|
|
2623
|
-
continue;
|
|
2624
|
-
}
|
|
2625
|
-
if (!isSameKind(targetChild, sourceChild)) {
|
|
2626
|
-
target.replaceChild(sourceChild, targetChild);
|
|
2627
|
-
continue;
|
|
2628
|
-
}
|
|
2629
|
-
if (sourceChild.nodeType !== Node.ELEMENT_NODE) {
|
|
2630
|
-
if (targetChild.nodeValue !== sourceChild.nodeValue) {
|
|
2631
|
-
targetChild.nodeValue = sourceChild.nodeValue;
|
|
2632
|
-
}
|
|
2633
|
-
continue;
|
|
2634
|
-
}
|
|
2635
|
-
const targetEl = targetChild;
|
|
2636
|
-
syncAttributes(targetEl, sourceChild);
|
|
2637
|
-
if (!skipChildrenOf(targetEl)) {
|
|
2638
|
-
morphChildren(targetEl, sourceChild, skipChildrenOf);
|
|
2639
|
-
}
|
|
2640
|
-
}
|
|
2641
|
-
while (target.childNodes.length > sourceChildren.length) {
|
|
2642
|
-
target.removeChild(target.lastChild);
|
|
2643
|
-
}
|
|
2644
|
-
};
|
|
2645
|
-
function morphHtml(container, html, attrOverrides = [], skipChildrenOf = ownsItsChildren) {
|
|
2646
|
-
const template = container.ownerDocument.createElement("template");
|
|
2647
|
-
template.innerHTML = html;
|
|
2648
|
-
stripIncompleteTagArtifacts(template.content);
|
|
2649
|
-
stripEventHandlerAttrs(template.content);
|
|
2650
|
-
for (const { name, attr, value } of attrOverrides) {
|
|
2651
|
-
template.content.querySelectorAll(`[data-puck-field-${attr}="${cssEscape(name)}"]`).forEach((el) => {
|
|
2652
|
-
if (el.closest("[data-puck-array]")) return;
|
|
2653
|
-
el.setAttribute(attr, value);
|
|
2654
|
-
});
|
|
2655
|
-
}
|
|
2656
|
-
morphChildren(container, template.content, skipChildrenOf);
|
|
2657
|
-
}
|
|
2658
2552
|
|
|
2659
|
-
// src/lib/design/
|
|
2553
|
+
// src/lib/design/annotations.ts
|
|
2660
2554
|
init_react_import();
|
|
2661
|
-
var wrapScriptWithObserverGuard = (script) => {
|
|
2662
|
-
if (!script.includes("MutationObserver")) return script;
|
|
2663
|
-
return `(function () {
|
|
2664
|
-
var __NativeMutationObserver = window.MutationObserver;
|
|
2665
|
-
function MutationObserver(callback) {
|
|
2666
|
-
var observed = [];
|
|
2667
|
-
var inner = new __NativeMutationObserver(function (records) {
|
|
2668
|
-
inner.disconnect();
|
|
2669
|
-
try {
|
|
2670
|
-
callback(records, inner);
|
|
2671
|
-
} finally {
|
|
2672
|
-
for (var i = 0; i < observed.length; i++) {
|
|
2673
|
-
__nativeObserve.call(inner, observed[i][0], observed[i][1]);
|
|
2674
|
-
}
|
|
2675
|
-
}
|
|
2676
|
-
});
|
|
2677
|
-
var __nativeObserve = inner.observe;
|
|
2678
|
-
inner.observe = function (target, options) {
|
|
2679
|
-
observed.push([target, options]);
|
|
2680
|
-
return __nativeObserve.call(inner, target, options);
|
|
2681
|
-
};
|
|
2682
|
-
return inner;
|
|
2683
|
-
}
|
|
2684
|
-
${script}
|
|
2685
|
-
})();`;
|
|
2686
|
-
};
|
|
2687
2555
|
|
|
2688
2556
|
// src/lib/html-annotations.ts
|
|
2689
2557
|
init_react_import();
|
|
2690
2558
|
var import_htmlparser2 = require("htmlparser2");
|
|
2691
2559
|
var import_domutils = require("domutils");
|
|
2692
2560
|
var import_domhandler = require("domhandler");
|
|
2693
|
-
var
|
|
2561
|
+
var FIELD_ATTR_PREFIX = "data-puck-field-";
|
|
2694
2562
|
var OPTIONS_ATTR_PREFIX = "data-puck-options-";
|
|
2695
2563
|
var BIND_ATTR_PREFIX = "data-puck-bind-";
|
|
2696
2564
|
var BIND_INPUT_ATTR_PREFIX = "data-puck-bind-input-";
|
|
@@ -2700,26 +2568,21 @@ var MAX_ATTR_PREFIX = "data-puck-max-";
|
|
|
2700
2568
|
var STEP_ATTR_PREFIX = "data-puck-step-";
|
|
2701
2569
|
var SLOT_ATTR = "data-puck-slot";
|
|
2702
2570
|
var ARRAY_ATTR = "data-puck-array";
|
|
2703
|
-
var
|
|
2571
|
+
var RECOGNIZED_FIELD_TYPES = /* @__PURE__ */ new Set([
|
|
2704
2572
|
"text",
|
|
2705
2573
|
"textarea",
|
|
2706
2574
|
"number",
|
|
2707
2575
|
"richtext",
|
|
2708
2576
|
"radio",
|
|
2709
2577
|
"select",
|
|
2710
|
-
"slot"
|
|
2711
|
-
"array",
|
|
2712
|
-
"object",
|
|
2713
|
-
"external",
|
|
2714
|
-
"custom"
|
|
2578
|
+
"slot"
|
|
2715
2579
|
]);
|
|
2716
|
-
var
|
|
2717
|
-
|
|
2718
|
-
const trimmed = attrValue.trimStart();
|
|
2580
|
+
var tryParseFieldShape = (value) => {
|
|
2581
|
+
const trimmed = value.trimStart();
|
|
2719
2582
|
if (!trimmed.startsWith("{")) return null;
|
|
2720
2583
|
try {
|
|
2721
2584
|
const parsed = JSON.parse(trimmed);
|
|
2722
|
-
if (isRecord(parsed) && typeof parsed.type === "string" && parsed.type) {
|
|
2585
|
+
if (isRecord(parsed) && typeof parsed.type === "string" && RECOGNIZED_FIELD_TYPES.has(parsed.type)) {
|
|
2723
2586
|
return parsed;
|
|
2724
2587
|
}
|
|
2725
2588
|
} catch {
|
|
@@ -2743,6 +2606,19 @@ var textContentWithBreaks = (node) => {
|
|
|
2743
2606
|
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2744
2607
|
var FIELD_NAME_RE = /^[A-Za-z0-9_]+(?:[-.][A-Za-z0-9_]+)*$/;
|
|
2745
2608
|
var isValidFieldName = (name) => FIELD_NAME_RE.test(name);
|
|
2609
|
+
var isFieldNameClaimed = (name, claimed, includeExact = true) => {
|
|
2610
|
+
for (const entry of claimed) {
|
|
2611
|
+
if (includeExact && entry === name || entry.startsWith(`${name}.`) || name.startsWith(`${entry}.`)) {
|
|
2612
|
+
return true;
|
|
2613
|
+
}
|
|
2614
|
+
}
|
|
2615
|
+
return false;
|
|
2616
|
+
};
|
|
2617
|
+
var attrBoundFieldNames = (attribs) => new Set(
|
|
2618
|
+
Object.entries(attribs).filter(
|
|
2619
|
+
([name, value]) => name.startsWith(FIELD_ATTR_PREFIX) && name !== `${FIELD_ATTR_PREFIX}name` && !name.startsWith(`${FIELD_ATTR_PREFIX}value-`) && !tryParseFieldShape(value)
|
|
2620
|
+
).map(([, value]) => value.trim()).filter(isValidFieldName)
|
|
2621
|
+
);
|
|
2746
2622
|
var getDeepValue = (source, path) => {
|
|
2747
2623
|
if (!path.includes(".")) return source[path];
|
|
2748
2624
|
let current = source;
|
|
@@ -2843,6 +2719,7 @@ var collectElementFields = (element, acc) => {
|
|
|
2843
2719
|
return true;
|
|
2844
2720
|
}
|
|
2845
2721
|
let skipChildren = false;
|
|
2722
|
+
const attrBound = attrBoundFieldNames(attribs);
|
|
2846
2723
|
for (const [attrName, attrValue] of Object.entries(attribs)) {
|
|
2847
2724
|
if (attrName.startsWith(OPTIONS_ATTR_PREFIX)) {
|
|
2848
2725
|
const fieldName = attrName.slice(OPTIONS_ATTR_PREFIX.length);
|
|
@@ -2871,8 +2748,8 @@ var collectElementFields = (element, acc) => {
|
|
|
2871
2748
|
}
|
|
2872
2749
|
continue;
|
|
2873
2750
|
}
|
|
2874
|
-
if (!attrName.startsWith(
|
|
2875
|
-
const target = attrName.slice(
|
|
2751
|
+
if (!attrName.startsWith(FIELD_ATTR_PREFIX)) continue;
|
|
2752
|
+
const target = attrName.slice(FIELD_ATTR_PREFIX.length);
|
|
2876
2753
|
if (!target) continue;
|
|
2877
2754
|
const shape = tryParseFieldShape(attrValue);
|
|
2878
2755
|
if (shape) {
|
|
@@ -2886,17 +2763,11 @@ var collectElementFields = (element, acc) => {
|
|
|
2886
2763
|
if (existing) existing.shape = shape;
|
|
2887
2764
|
continue;
|
|
2888
2765
|
}
|
|
2766
|
+
if (isFieldNameClaimed(name2, attrBound, false) || isFieldNameClaimed(name2, acc.seenFields)) {
|
|
2767
|
+
continue;
|
|
2768
|
+
}
|
|
2889
2769
|
acc.seenFields.add(name2);
|
|
2890
|
-
if (
|
|
2891
|
-
const { type, ...value } = shape;
|
|
2892
|
-
acc.fields.push({
|
|
2893
|
-
name: name2,
|
|
2894
|
-
binding: "text",
|
|
2895
|
-
shape: { type },
|
|
2896
|
-
format: "json"
|
|
2897
|
-
});
|
|
2898
|
-
setExtractedValue(acc.values, name2, value);
|
|
2899
|
-
} else if (shape.type === "richtext") {
|
|
2770
|
+
if (shape.type === "richtext") {
|
|
2900
2771
|
acc.fields.push({ name: name2, binding: "text", shape, format: "json" });
|
|
2901
2772
|
setExtractedValue(acc.values, name2, (0, import_domutils.getInnerHTML)(element).trim());
|
|
2902
2773
|
skipChildren = true;
|
|
@@ -2949,6 +2820,9 @@ var collectElementFields = (element, acc) => {
|
|
|
2949
2820
|
}
|
|
2950
2821
|
continue;
|
|
2951
2822
|
}
|
|
2823
|
+
if (target === "name" && isFieldNameClaimed(name, attrBound) || isFieldNameClaimed(name, acc.seenFields)) {
|
|
2824
|
+
continue;
|
|
2825
|
+
}
|
|
2952
2826
|
acc.seenFields.add(name);
|
|
2953
2827
|
const fieldType = getTypeModifier(attribs, name);
|
|
2954
2828
|
const constraints = fieldType === "number" ? getNumberConstraints(attribs, name) : {};
|
|
@@ -3042,7 +2916,7 @@ var parseHtmlAnnotations = (html) => {
|
|
|
3042
2916
|
if (slotName && isValidFieldName(slotName) && !seenSlots.has(slotName)) {
|
|
3043
2917
|
seenSlots.add(slotName);
|
|
3044
2918
|
const shape = tryParseFieldShape(
|
|
3045
|
-
attribs[
|
|
2919
|
+
attribs[FIELD_ATTR_PREFIX + slotName.toLowerCase()] ?? ""
|
|
3046
2920
|
);
|
|
3047
2921
|
const allow = shape?.type === "slot" ? sanitizeStringArray(shape.allow) : void 0;
|
|
3048
2922
|
const disallow = shape?.type === "slot" ? sanitizeStringArray(shape.disallow) : void 0;
|
|
@@ -3191,21 +3065,16 @@ var patchElement = (element, props) => {
|
|
|
3191
3065
|
}
|
|
3192
3066
|
return { didPatch, skipChildren: true };
|
|
3193
3067
|
}
|
|
3194
|
-
const attrBoundFields =
|
|
3195
|
-
for (const [an, av] of Object.entries(attribs)) {
|
|
3196
|
-
if (an.startsWith(FIELD_ATTR_PREFIX2) && an !== `${FIELD_ATTR_PREFIX2}name` && !tryParseFieldShape(av)) {
|
|
3197
|
-
attrBoundFields.add(av.trim());
|
|
3198
|
-
}
|
|
3199
|
-
}
|
|
3068
|
+
const attrBoundFields = attrBoundFieldNames(attribs);
|
|
3200
3069
|
for (const [attrName, attrValue] of Object.entries(attribs)) {
|
|
3201
|
-
if (!attrName.startsWith(
|
|
3202
|
-
const target = attrName.slice(
|
|
3070
|
+
if (!attrName.startsWith(FIELD_ATTR_PREFIX)) continue;
|
|
3071
|
+
const target = attrName.slice(FIELD_ATTR_PREFIX.length);
|
|
3203
3072
|
if (!target) continue;
|
|
3204
3073
|
const shape = tryParseFieldShape(attrValue);
|
|
3205
3074
|
if (shape) {
|
|
3206
3075
|
if (shape.type === "slot") continue;
|
|
3207
3076
|
const name2 = target;
|
|
3208
|
-
if (
|
|
3077
|
+
if (isFieldNameClaimed(name2, attrBoundFields)) continue;
|
|
3209
3078
|
const value2 = getDeepValue(props, name2);
|
|
3210
3079
|
if (shape.type === "richtext") {
|
|
3211
3080
|
if (typeof value2 !== "string") continue;
|
|
@@ -3223,6 +3092,9 @@ var patchElement = (element, props) => {
|
|
|
3223
3092
|
}
|
|
3224
3093
|
const name = attrValue.trim();
|
|
3225
3094
|
if (!name) continue;
|
|
3095
|
+
if (target === "name" && isFieldNameClaimed(name, attrBoundFields)) {
|
|
3096
|
+
continue;
|
|
3097
|
+
}
|
|
3226
3098
|
const value = getDeepValue(props, name);
|
|
3227
3099
|
if (target === "name" && getTypeModifier(attribs, name) === "richtext") {
|
|
3228
3100
|
if (typeof value !== "string") continue;
|
|
@@ -3295,7 +3167,6 @@ var renderHtmlArrayItems = (html, arrayName, items) => {
|
|
|
3295
3167
|
};
|
|
3296
3168
|
|
|
3297
3169
|
// src/lib/design/annotations.ts
|
|
3298
|
-
init_react_import();
|
|
3299
3170
|
var cache = /* @__PURE__ */ new Map();
|
|
3300
3171
|
var MAX_CACHE_ENTRIES = 32;
|
|
3301
3172
|
var getAnnotations = (html) => {
|
|
@@ -3311,22 +3182,159 @@ var getAnnotations = (html) => {
|
|
|
3311
3182
|
var getSlotFields = (html) => Object.fromEntries(
|
|
3312
3183
|
getAnnotations(html).slots.map((slot) => [slot.name, toSlotField(slot)])
|
|
3313
3184
|
);
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3185
|
+
|
|
3186
|
+
// src/lib/morph-html.ts
|
|
3187
|
+
var PROTECTED_ATTRS = /* @__PURE__ */ new Set([
|
|
3188
|
+
"contenteditable",
|
|
3189
|
+
"data-puck-overlay-portal"
|
|
3190
|
+
]);
|
|
3191
|
+
var SLOT_OWNED_ATTRS = /* @__PURE__ */ new Set(["style", "class"]);
|
|
3192
|
+
var isEventHandlerAttr = (name) => /^on/i.test(name);
|
|
3193
|
+
var FIELD_ATTR_PREFIX2 = "data-puck-field-";
|
|
3194
|
+
var LEGACY_TEXT_ATTR = `${FIELD_ATTR_PREFIX2}name`;
|
|
3195
|
+
var VALUE_ATTR_PREFIX = `${FIELD_ATTR_PREFIX2}value-`;
|
|
3196
|
+
var hasTextBinding = (el, parsedTextFields) => {
|
|
3197
|
+
for (const attr of Array.from(el.attributes)) {
|
|
3198
|
+
if (!attr.name.startsWith(FIELD_ATTR_PREFIX2)) continue;
|
|
3199
|
+
if (attr.name.startsWith(VALUE_ATTR_PREFIX)) continue;
|
|
3200
|
+
const isShape = attr.value.trimStart().startsWith("{");
|
|
3201
|
+
const fieldName = isShape ? attr.name.slice(FIELD_ATTR_PREFIX2.length) : attr.value.trim();
|
|
3202
|
+
if (isValidFieldName(fieldName) && (attr.name === LEGACY_TEXT_ATTR || isShape) && (!parsedTextFields || parsedTextFields.has(fieldName))) {
|
|
3203
|
+
return true;
|
|
3204
|
+
}
|
|
3205
|
+
}
|
|
3206
|
+
return false;
|
|
3320
3207
|
};
|
|
3321
|
-
var
|
|
3322
|
-
|
|
3323
|
-
const
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3208
|
+
var ownsItsChildren = (el, parsedTextFields) => el.hasAttribute("data-puck-slot") || el.hasAttribute("data-puck-array") || hasTextBinding(el, parsedTextFields);
|
|
3209
|
+
var syncAttributes = (target, source) => {
|
|
3210
|
+
const isSlot = target.hasAttribute("data-puck-slot");
|
|
3211
|
+
for (const attr of Array.from(target.attributes)) {
|
|
3212
|
+
if (PROTECTED_ATTRS.has(attr.name)) continue;
|
|
3213
|
+
if (isSlot && SLOT_OWNED_ATTRS.has(attr.name)) continue;
|
|
3214
|
+
if (isEventHandlerAttr(attr.name) || !source.hasAttribute(attr.name)) {
|
|
3215
|
+
target.removeAttribute(attr.name);
|
|
3216
|
+
}
|
|
3217
|
+
}
|
|
3218
|
+
for (const attr of Array.from(source.attributes)) {
|
|
3219
|
+
if (PROTECTED_ATTRS.has(attr.name)) continue;
|
|
3220
|
+
if (isSlot && SLOT_OWNED_ATTRS.has(attr.name)) continue;
|
|
3221
|
+
if (isEventHandlerAttr(attr.name)) continue;
|
|
3222
|
+
if (target.getAttribute(attr.name) !== attr.value) {
|
|
3223
|
+
target.setAttribute(attr.name, attr.value);
|
|
3224
|
+
}
|
|
3225
|
+
}
|
|
3226
|
+
};
|
|
3227
|
+
var isSameKind = (a, b) => a.nodeType === b.nodeType && (a.nodeType !== Node.ELEMENT_NODE || a.tagName === b.tagName);
|
|
3228
|
+
var isIncompleteTagArtifact = (node) => node.nodeType === Node.TEXT_NODE && /^<\/?[a-zA-Z]*$/.test(node.nodeValue ?? "");
|
|
3229
|
+
var stripIncompleteTagArtifacts = (root) => {
|
|
3230
|
+
for (const child of Array.from(root.childNodes)) {
|
|
3231
|
+
if (isIncompleteTagArtifact(child)) {
|
|
3232
|
+
root.removeChild(child);
|
|
3233
|
+
} else if (child.nodeType === Node.ELEMENT_NODE) {
|
|
3234
|
+
stripIncompleteTagArtifacts(child);
|
|
3235
|
+
}
|
|
3236
|
+
}
|
|
3237
|
+
};
|
|
3238
|
+
var stripEventHandlerAttrs = (root) => {
|
|
3239
|
+
root.querySelectorAll("*").forEach((el) => {
|
|
3240
|
+
for (const attr of Array.from(el.attributes)) {
|
|
3241
|
+
if (isEventHandlerAttr(attr.name)) el.removeAttribute(attr.name);
|
|
3242
|
+
}
|
|
3243
|
+
});
|
|
3244
|
+
};
|
|
3245
|
+
var morphChildren = (target, source, skipChildrenOf = ownsItsChildren) => {
|
|
3246
|
+
const sourceChildren = Array.from(source.childNodes);
|
|
3247
|
+
for (let i = 0; i < sourceChildren.length; i++) {
|
|
3248
|
+
const sourceChild = sourceChildren[i];
|
|
3249
|
+
const targetChild = target.childNodes[i];
|
|
3250
|
+
if (!targetChild) {
|
|
3251
|
+
target.appendChild(sourceChild);
|
|
3252
|
+
continue;
|
|
3253
|
+
}
|
|
3254
|
+
if (!isSameKind(targetChild, sourceChild)) {
|
|
3255
|
+
target.replaceChild(sourceChild, targetChild);
|
|
3256
|
+
continue;
|
|
3257
|
+
}
|
|
3258
|
+
if (sourceChild.nodeType !== Node.ELEMENT_NODE) {
|
|
3259
|
+
if (targetChild.nodeValue !== sourceChild.nodeValue) {
|
|
3260
|
+
targetChild.nodeValue = sourceChild.nodeValue;
|
|
3261
|
+
}
|
|
3262
|
+
continue;
|
|
3263
|
+
}
|
|
3264
|
+
const targetEl = targetChild;
|
|
3265
|
+
syncAttributes(targetEl, sourceChild);
|
|
3266
|
+
if (!skipChildrenOf(targetEl)) {
|
|
3267
|
+
morphChildren(targetEl, sourceChild, skipChildrenOf);
|
|
3268
|
+
}
|
|
3269
|
+
}
|
|
3270
|
+
while (target.childNodes.length > sourceChildren.length) {
|
|
3271
|
+
target.removeChild(target.lastChild);
|
|
3272
|
+
}
|
|
3273
|
+
};
|
|
3274
|
+
function morphHtml(container, html, attrOverrides = [], skipChildrenOf) {
|
|
3275
|
+
const template = container.ownerDocument.createElement("template");
|
|
3276
|
+
template.innerHTML = html;
|
|
3277
|
+
stripIncompleteTagArtifacts(template.content);
|
|
3278
|
+
stripEventHandlerAttrs(template.content);
|
|
3279
|
+
if (attrOverrides.length > 0) {
|
|
3280
|
+
const overridesByAttr = /* @__PURE__ */ new Map();
|
|
3281
|
+
for (const override of attrOverrides) {
|
|
3282
|
+
if (isEventHandlerAttr(override.attr)) continue;
|
|
3283
|
+
const bindingAttr = `${FIELD_ATTR_PREFIX2}${override.attr}`;
|
|
3284
|
+
const fields = overridesByAttr.get(bindingAttr) ?? /* @__PURE__ */ new Map();
|
|
3285
|
+
fields.set(override.name, override);
|
|
3286
|
+
overridesByAttr.set(bindingAttr, fields);
|
|
3287
|
+
}
|
|
3288
|
+
template.content.querySelectorAll("*").forEach((el) => {
|
|
3289
|
+
for (const attr of Array.from(el.attributes)) {
|
|
3290
|
+
const override = overridesByAttr.get(attr.name)?.get(attr.value.trim());
|
|
3291
|
+
if (!override) continue;
|
|
3292
|
+
if (el.closest("[data-puck-array]")) return;
|
|
3293
|
+
el.setAttribute(override.attr, override.value);
|
|
3294
|
+
}
|
|
3295
|
+
});
|
|
3296
|
+
}
|
|
3297
|
+
if (skipChildrenOf) {
|
|
3298
|
+
morphChildren(container, template.content, skipChildrenOf);
|
|
3299
|
+
return;
|
|
3300
|
+
}
|
|
3301
|
+
const parsedTextFields = new Set(
|
|
3302
|
+
getAnnotations(html).fields.filter((field) => field.binding === "text").map((field) => field.name)
|
|
3329
3303
|
);
|
|
3304
|
+
morphChildren(
|
|
3305
|
+
container,
|
|
3306
|
+
template.content,
|
|
3307
|
+
(el) => ownsItsChildren(el, parsedTextFields)
|
|
3308
|
+
);
|
|
3309
|
+
}
|
|
3310
|
+
|
|
3311
|
+
// src/lib/design/observer-guard.ts
|
|
3312
|
+
init_react_import();
|
|
3313
|
+
var wrapScriptWithObserverGuard = (script) => {
|
|
3314
|
+
if (!script.includes("MutationObserver")) return script;
|
|
3315
|
+
return `(function () {
|
|
3316
|
+
var __NativeMutationObserver = window.MutationObserver;
|
|
3317
|
+
function MutationObserver(callback) {
|
|
3318
|
+
var observed = [];
|
|
3319
|
+
var inner = new __NativeMutationObserver(function (records) {
|
|
3320
|
+
inner.disconnect();
|
|
3321
|
+
try {
|
|
3322
|
+
callback(records, inner);
|
|
3323
|
+
} finally {
|
|
3324
|
+
for (var i = 0; i < observed.length; i++) {
|
|
3325
|
+
__nativeObserve.call(inner, observed[i][0], observed[i][1]);
|
|
3326
|
+
}
|
|
3327
|
+
}
|
|
3328
|
+
});
|
|
3329
|
+
var __nativeObserve = inner.observe;
|
|
3330
|
+
inner.observe = function (target, options) {
|
|
3331
|
+
observed.push([target, options]);
|
|
3332
|
+
return __nativeObserve.call(inner, target, options);
|
|
3333
|
+
};
|
|
3334
|
+
return inner;
|
|
3335
|
+
}
|
|
3336
|
+
${script}
|
|
3337
|
+
})();`;
|
|
3330
3338
|
};
|
|
3331
3339
|
|
|
3332
3340
|
// src/lib/design/registration-store.ts
|
|
@@ -3402,7 +3410,7 @@ init_react_import();
|
|
|
3402
3410
|
var import_core2 = require("@puckeditor/core");
|
|
3403
3411
|
var CONTENT_EDITABLE_ATTR = "data-puck-content-editable";
|
|
3404
3412
|
var isInlineEditingDisabled = (el) => el.closest(`[${CONTENT_EDITABLE_ATTR}="false"]`) !== null;
|
|
3405
|
-
var
|
|
3413
|
+
var cssEscape = (value) => typeof CSS !== "undefined" && CSS.escape ? CSS.escape(value) : value.replace(/["\\]/g, "\\$&");
|
|
3406
3414
|
var queryScopedFields = (entry, selector) => Array.from(entry.querySelectorAll(selector)).filter((el) => {
|
|
3407
3415
|
if (el.closest("[data-puck-array]")) return false;
|
|
3408
3416
|
const closestSlot = el.closest("[data-puck-slot]");
|
|
@@ -3410,7 +3418,7 @@ var queryScopedFields = (entry, selector) => Array.from(entry.querySelectorAll(s
|
|
|
3410
3418
|
return true;
|
|
3411
3419
|
});
|
|
3412
3420
|
var findOwnArrayContainer = (entry, arrayName) => {
|
|
3413
|
-
const selector = `[data-puck-array="${
|
|
3421
|
+
const selector = `[data-puck-array="${cssEscape(arrayName)}"]`;
|
|
3414
3422
|
for (const el of entry.querySelectorAll(selector)) {
|
|
3415
3423
|
const closestSlot = el.closest("[data-puck-slot]");
|
|
3416
3424
|
if (!closestSlot || !entry.contains(closestSlot)) return el;
|
|
@@ -3425,7 +3433,7 @@ var inlineEditModeFor = (field) => {
|
|
|
3425
3433
|
const type = field.shape?.type ?? field.fieldType;
|
|
3426
3434
|
return type === "richtext" ? "richtext" : type === "number" ? "number" : "text";
|
|
3427
3435
|
};
|
|
3428
|
-
var textFieldSelector = (field) => field.format === "json" ? `[${
|
|
3436
|
+
var textFieldSelector = (field) => field.format === "json" ? `[${cssEscape(`data-puck-field-${field.name}`)}]` : `[data-puck-field-name="${cssEscape(field.name)}"]`;
|
|
3429
3437
|
var isHTMLElement = (el) => {
|
|
3430
3438
|
const HTMLElementCtor = el.ownerDocument.defaultView?.HTMLElement;
|
|
3431
3439
|
return !!HTMLElementCtor && el instanceof HTMLElementCtor;
|
|
@@ -3451,6 +3459,29 @@ var syncFieldValues = (entry, fields, props) => {
|
|
|
3451
3459
|
});
|
|
3452
3460
|
}
|
|
3453
3461
|
};
|
|
3462
|
+
var claimedHostStyles = /* @__PURE__ */ new WeakMap();
|
|
3463
|
+
var claimHostStyles = (el, applyWhiteSpace) => {
|
|
3464
|
+
if (!claimedHostStyles.has(el)) {
|
|
3465
|
+
claimedHostStyles.set(el, {
|
|
3466
|
+
cursor: el.style.cursor,
|
|
3467
|
+
whiteSpace: applyWhiteSpace ? el.style.whiteSpace : null
|
|
3468
|
+
});
|
|
3469
|
+
}
|
|
3470
|
+
applyHostStyles(el);
|
|
3471
|
+
};
|
|
3472
|
+
var applyHostStyles = (el) => {
|
|
3473
|
+
const claimed = claimedHostStyles.get(el);
|
|
3474
|
+
if (!claimed) return;
|
|
3475
|
+
el.style.cursor = "text";
|
|
3476
|
+
if (claimed.whiteSpace !== null) el.style.whiteSpace = "pre-wrap";
|
|
3477
|
+
};
|
|
3478
|
+
var releaseHostStyles = (el) => {
|
|
3479
|
+
const claimed = claimedHostStyles.get(el);
|
|
3480
|
+
if (!claimed) return;
|
|
3481
|
+
el.style.cursor = claimed.cursor;
|
|
3482
|
+
if (claimed.whiteSpace !== null) el.style.whiteSpace = claimed.whiteSpace;
|
|
3483
|
+
claimedHostStyles.delete(el);
|
|
3484
|
+
};
|
|
3454
3485
|
var attachInlineEditing = (el, {
|
|
3455
3486
|
componentId,
|
|
3456
3487
|
propPath,
|
|
@@ -3463,8 +3494,7 @@ var attachInlineEditing = (el, {
|
|
|
3463
3494
|
const syncEditable = () => {
|
|
3464
3495
|
el.contentEditable = hovering || focused ? mode === "richtext" ? "true" : "plaintext-only" : "false";
|
|
3465
3496
|
};
|
|
3466
|
-
|
|
3467
|
-
el.style.cursor = "text";
|
|
3497
|
+
claimHostStyles(el, mode !== "richtext");
|
|
3468
3498
|
syncEditable();
|
|
3469
3499
|
let lastValidNumberText = el.innerText.replaceAll(/\n/gm, "");
|
|
3470
3500
|
const handleInput = () => {
|
|
@@ -3542,7 +3572,7 @@ var attachInlineEditing = (el, {
|
|
|
3542
3572
|
el.removeEventListener("mouseout", handleMouseOut, true);
|
|
3543
3573
|
el.removeEventListener("focus", handleFocus);
|
|
3544
3574
|
el.removeEventListener("blur", handleBlur);
|
|
3545
|
-
el
|
|
3575
|
+
releaseHostStyles(el);
|
|
3546
3576
|
el.removeAttribute("contenteditable");
|
|
3547
3577
|
cleanupPortal?.();
|
|
3548
3578
|
};
|
|
@@ -3608,7 +3638,7 @@ var wireArrayItemEditing = ({
|
|
|
3608
3638
|
const mode = inlineEditModeFor(field);
|
|
3609
3639
|
const registration = wiring.get(target);
|
|
3610
3640
|
if (registration?.propPath === propPath && registration.mode === mode) {
|
|
3611
|
-
target
|
|
3641
|
+
applyHostStyles(target);
|
|
3612
3642
|
continue;
|
|
3613
3643
|
}
|
|
3614
3644
|
registration?.cleanup();
|
|
@@ -3674,15 +3704,7 @@ var parseStyleString = (cssText) => {
|
|
|
3674
3704
|
return style;
|
|
3675
3705
|
};
|
|
3676
3706
|
var isEventHandlerAttr2 = (name) => /^on/i.test(name);
|
|
3677
|
-
var
|
|
3678
|
-
var fieldContentFor = (attribs, fields) => {
|
|
3679
|
-
for (const name of Object.keys(fields)) {
|
|
3680
|
-
if (attribs[`${FIELD_ATTR_PREFIX3}${name}`] !== void 0) return name;
|
|
3681
|
-
if (attribs["data-puck-field-name"] === name) return name;
|
|
3682
|
-
}
|
|
3683
|
-
return void 0;
|
|
3684
|
-
};
|
|
3685
|
-
var nodeToReact = (node, slots, fields, key) => {
|
|
3707
|
+
var nodeToReact = (node, slots, key) => {
|
|
3686
3708
|
if (node.type === "text") {
|
|
3687
3709
|
return node.data;
|
|
3688
3710
|
}
|
|
@@ -3713,17 +3735,13 @@ var nodeToReact = (node, slots, fields, key) => {
|
|
|
3713
3735
|
if (VOID_ELEMENTS.has(tag)) {
|
|
3714
3736
|
return (0, import_react22.createElement)(tag, props);
|
|
3715
3737
|
}
|
|
3716
|
-
const
|
|
3717
|
-
if (fieldName !== void 0) {
|
|
3718
|
-
return (0, import_react22.createElement)(tag, props, fields[fieldName]);
|
|
3719
|
-
}
|
|
3720
|
-
const children = el.children.map((child, i) => nodeToReact(child, slots, fields, i)).filter((c) => c !== null);
|
|
3738
|
+
const children = el.children.map((child, i) => nodeToReact(child, slots, i)).filter((c) => c !== null);
|
|
3721
3739
|
return (0, import_react22.createElement)(tag, props, ...children);
|
|
3722
3740
|
};
|
|
3723
|
-
var htmlToReactTree = (html, slots
|
|
3741
|
+
var htmlToReactTree = (html, slots) => {
|
|
3724
3742
|
if (!html) return null;
|
|
3725
3743
|
const doc = (0, import_htmlparser22.parseDocument)(html);
|
|
3726
|
-
const children = doc.children.map((child, i) => nodeToReact(child, slots,
|
|
3744
|
+
const children = doc.children.map((child, i) => nodeToReact(child, slots, i)).filter((c) => c !== null);
|
|
3727
3745
|
if (children.length === 0) return null;
|
|
3728
3746
|
if (children.length === 1) return children[0];
|
|
3729
3747
|
return (0, import_react22.createElement)(import_react22.Fragment, null, ...children);
|
|
@@ -3762,7 +3780,7 @@ var SlotPortal = ({
|
|
|
3762
3780
|
[slotStyle]
|
|
3763
3781
|
);
|
|
3764
3782
|
(0, import_react23.useEffect)(() => {
|
|
3765
|
-
const el = entry.querySelector(`[data-puck-slot="${
|
|
3783
|
+
const el = entry.querySelector(`[data-puck-slot="${cssEscape(slotName)}"]`);
|
|
3766
3784
|
if (el !== lastTarget.current) {
|
|
3767
3785
|
el?.replaceChildren();
|
|
3768
3786
|
lastTarget.current = el;
|
|
@@ -3780,32 +3798,10 @@ var SlotPortal = ({
|
|
|
3780
3798
|
);
|
|
3781
3799
|
};
|
|
3782
3800
|
|
|
3783
|
-
// src/lib/design/field-portal.tsx
|
|
3784
|
-
init_react_import();
|
|
3785
|
-
var import_react24 = require("react");
|
|
3786
|
-
var import_react_dom2 = require("react-dom");
|
|
3787
|
-
var FieldPortal = ({
|
|
3788
|
-
entry,
|
|
3789
|
-
html,
|
|
3790
|
-
selector,
|
|
3791
|
-
children
|
|
3792
|
-
}) => {
|
|
3793
|
-
const [target, setTarget] = (0, import_react24.useState)(null);
|
|
3794
|
-
const lastTarget = (0, import_react24.useRef)(null);
|
|
3795
|
-
(0, import_react24.useEffect)(() => {
|
|
3796
|
-
const el = queryScopedFields(entry, selector)[0] ?? null;
|
|
3797
|
-
if (el !== lastTarget.current) {
|
|
3798
|
-
el?.replaceChildren();
|
|
3799
|
-
lastTarget.current = el;
|
|
3800
|
-
setTarget(el);
|
|
3801
|
-
}
|
|
3802
|
-
}, [entry, html, selector]);
|
|
3803
|
-
if (!target) return null;
|
|
3804
|
-
return (0, import_react_dom2.createPortal)(children, target);
|
|
3805
|
-
};
|
|
3806
|
-
|
|
3807
3801
|
// src/lib/design/component.tsx
|
|
3808
3802
|
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
3803
|
+
var DESIGN_COMPONENT = Symbol("puck-ai.designComponent");
|
|
3804
|
+
var isDesignComponent = (config) => !!config?.[DESIGN_COMPONENT];
|
|
3809
3805
|
var streamingValues = /* @__PURE__ */ new Map();
|
|
3810
3806
|
var instanceKey = (name, instanceId) => `${name}:${typeof instanceId === "string" ? instanceId : ""}`;
|
|
3811
3807
|
var getRegistrationSlotFields = (reg) => {
|
|
@@ -3830,9 +3826,9 @@ function createDesignComponentConfig(registration) {
|
|
|
3830
3826
|
registrationStore.apply(registration);
|
|
3831
3827
|
}
|
|
3832
3828
|
const slotFields = getRegistrationSlotFields(registration);
|
|
3833
|
-
|
|
3829
|
+
const componentConfig = {
|
|
3834
3830
|
...registration.label ? { label: registration.label } : {},
|
|
3835
|
-
fields: { ...slotFields
|
|
3831
|
+
fields: { ...slotFields },
|
|
3836
3832
|
defaultProps: { ...registration.defaultProps ?? {} },
|
|
3837
3833
|
resolveData: (data, { trigger }) => {
|
|
3838
3834
|
if (trigger !== "replace" && trigger !== "insert" && trigger !== "force") {
|
|
@@ -3891,6 +3887,8 @@ function createDesignComponentConfig(registration) {
|
|
|
3891
3887
|
},
|
|
3892
3888
|
render: (renderProps) => renderProps.puck?.isEditing ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(EditorEntry, { ...renderProps }) : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Entry, { ...renderProps, getPuck: null })
|
|
3893
3889
|
};
|
|
3890
|
+
componentConfig[DESIGN_COMPONENT] = true;
|
|
3891
|
+
return componentConfig;
|
|
3894
3892
|
function EditorEntry(renderProps) {
|
|
3895
3893
|
const getPuck = (0, import_core3.useGetPuck)();
|
|
3896
3894
|
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Entry, { ...renderProps, getPuck });
|
|
@@ -3902,11 +3900,11 @@ function createDesignComponentConfig(registration) {
|
|
|
3902
3900
|
style,
|
|
3903
3901
|
...props
|
|
3904
3902
|
}) {
|
|
3905
|
-
const getSnapshot = (0,
|
|
3903
|
+
const getSnapshot = (0, import_react24.useCallback)(
|
|
3906
3904
|
() => registrationStore.get(name) ?? registration,
|
|
3907
3905
|
[]
|
|
3908
3906
|
);
|
|
3909
|
-
const reg = (0,
|
|
3907
|
+
const reg = (0, import_react24.useSyncExternalStore)(
|
|
3910
3908
|
registrationStore.subscribe,
|
|
3911
3909
|
getSnapshot,
|
|
3912
3910
|
getSnapshot
|
|
@@ -3914,10 +3912,10 @@ function createDesignComponentConfig(registration) {
|
|
|
3914
3912
|
const html = reg.html ?? "";
|
|
3915
3913
|
const styles = reg.styles;
|
|
3916
3914
|
const script = reg.script;
|
|
3917
|
-
const [entryEl, setEntryEl] = (0,
|
|
3918
|
-
const scriptRef = (0,
|
|
3919
|
-
const annotations = (0,
|
|
3920
|
-
const { attrFields, arrayFields, attrSig, arraySig } = (0,
|
|
3915
|
+
const [entryEl, setEntryEl] = (0, import_react24.useState)(null);
|
|
3916
|
+
const scriptRef = (0, import_react24.useRef)(null);
|
|
3917
|
+
const annotations = (0, import_react24.useMemo)(() => getAnnotations(html), [html]);
|
|
3918
|
+
const { attrFields, arrayFields, attrSig, arraySig } = (0, import_react24.useMemo)(() => {
|
|
3921
3919
|
const attr = [];
|
|
3922
3920
|
const arrays = [];
|
|
3923
3921
|
for (const field of annotations.fields) {
|
|
@@ -3939,86 +3937,56 @@ function createDesignComponentConfig(registration) {
|
|
|
3939
3937
|
arraySig: JSON.stringify(arrays)
|
|
3940
3938
|
};
|
|
3941
3939
|
}, [props, annotations]);
|
|
3942
|
-
const
|
|
3943
|
-
const out = [];
|
|
3944
|
-
for (const field of annotations.fields) {
|
|
3945
|
-
if (field.binding !== "text") continue;
|
|
3946
|
-
const value = getDeepValue(props, field.name);
|
|
3947
|
-
if (!import_react25.default.isValidElement(value)) continue;
|
|
3948
|
-
out.push({
|
|
3949
|
-
name: field.name,
|
|
3950
|
-
selector: textFieldSelector(field),
|
|
3951
|
-
node: value
|
|
3952
|
-
});
|
|
3953
|
-
}
|
|
3954
|
-
return out;
|
|
3955
|
-
}, [annotations, props]);
|
|
3956
|
-
const storedProps = (0, import_react25.useMemo)(
|
|
3957
|
-
() => getPuck ? getPuck().getItemById(id)?.props : void 0,
|
|
3958
|
-
[getPuck, id, props]
|
|
3959
|
-
);
|
|
3960
|
-
const editableFields = (0, import_react25.useMemo)(() => {
|
|
3961
|
-
const mounted = new Set(nodeFields.map((f) => f.name));
|
|
3962
|
-
return annotations.fields.filter((field) => {
|
|
3963
|
-
if (mounted.has(field.name)) return false;
|
|
3964
|
-
if (field.binding === "array") return true;
|
|
3965
|
-
const type = field.shape?.type;
|
|
3966
|
-
if (type && !isBuiltInFieldType(type)) return false;
|
|
3967
|
-
if (!storedProps) return true;
|
|
3968
|
-
return getDeepValue(props, field.name) === getDeepValue(storedProps, field.name);
|
|
3969
|
-
});
|
|
3970
|
-
}, [annotations, nodeFields, props, storedProps]);
|
|
3971
|
-
const patchedHtml = (0, import_react25.useMemo)(() => {
|
|
3940
|
+
const patchedHtml = (0, import_react24.useMemo)(() => {
|
|
3972
3941
|
if (puck.isEditing) return html;
|
|
3973
3942
|
return patchHtmlAnnotations(html, props);
|
|
3974
3943
|
}, [html, props, puck.isEditing]);
|
|
3975
|
-
const fieldValueAttrs = (0,
|
|
3944
|
+
const fieldValueAttrs = (0, import_react24.useMemo)(() => {
|
|
3976
3945
|
const attrs = {};
|
|
3977
3946
|
attrs["data-puck-design"] = name;
|
|
3978
3947
|
for (const field of annotations.fields) {
|
|
3979
3948
|
const value = getDeepValue(props, field.name);
|
|
3980
3949
|
if (value === void 0 || value === null) continue;
|
|
3981
3950
|
if (!isValidFieldName(field.name)) continue;
|
|
3982
|
-
if (import_react25.default.isValidElement(value)) continue;
|
|
3983
3951
|
attrs[`data-puck-field-value-${field.name}`] = typeof value === "string" || typeof value === "number" ? String(value) : JSON.stringify(value);
|
|
3984
3952
|
}
|
|
3985
3953
|
return attrs;
|
|
3986
3954
|
}, [annotations, props, puck.isEditing]);
|
|
3987
|
-
const editorEntryNode = (0,
|
|
3955
|
+
const editorEntryNode = (0, import_react24.useMemo)(
|
|
3988
3956
|
() => puck.isEditing ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { ref: setEntryEl }) : null,
|
|
3989
3957
|
[puck.isEditing]
|
|
3990
3958
|
);
|
|
3991
|
-
(0,
|
|
3959
|
+
(0, import_react24.useEffect)(() => {
|
|
3992
3960
|
if (!puck.isEditing || !getPuck) return;
|
|
3993
3961
|
getPuck().resolveDataById(id, "force");
|
|
3994
3962
|
}, [reg, puck.isEditing, getPuck, id]);
|
|
3995
|
-
const fieldWiring = (0,
|
|
3996
|
-
const morphed = (0,
|
|
3997
|
-
(0,
|
|
3963
|
+
const fieldWiring = (0, import_react24.useRef)(/* @__PURE__ */ new Map());
|
|
3964
|
+
const morphed = (0, import_react24.useRef)(null);
|
|
3965
|
+
(0, import_react24.useLayoutEffect)(() => {
|
|
3998
3966
|
if (!puck.isEditing || !entryEl) return;
|
|
3999
3967
|
if (morphed.current?.el !== entryEl || morphed.current?.html !== html || morphed.current?.attrSig !== attrSig) {
|
|
4000
3968
|
morphed.current = { el: entryEl, html, attrSig };
|
|
4001
3969
|
morphHtml(entryEl, html, attrFields);
|
|
4002
3970
|
for (const el of fieldWiring.current.keys()) {
|
|
4003
|
-
if (el.isConnected) el
|
|
3971
|
+
if (el.isConnected) applyHostStyles(el);
|
|
4004
3972
|
}
|
|
4005
3973
|
}
|
|
4006
3974
|
syncFieldValues(entryEl, annotations.fields, props);
|
|
4007
3975
|
if (getPuck) {
|
|
4008
|
-
wireFieldEditing(entryEl,
|
|
3976
|
+
wireFieldEditing(entryEl, annotations.fields, fieldWiring.current, {
|
|
4009
3977
|
componentId: id,
|
|
4010
3978
|
getPuck
|
|
4011
3979
|
});
|
|
4012
3980
|
}
|
|
4013
3981
|
});
|
|
4014
|
-
(0,
|
|
3982
|
+
(0, import_react24.useEffect)(
|
|
4015
3983
|
() => () => {
|
|
4016
3984
|
fieldWiring.current.forEach((cleanup) => cleanup());
|
|
4017
3985
|
fieldWiring.current.clear();
|
|
4018
3986
|
},
|
|
4019
3987
|
[]
|
|
4020
3988
|
);
|
|
4021
|
-
(0,
|
|
3989
|
+
(0, import_react24.useEffect)(() => {
|
|
4022
3990
|
if (!entryEl || !puck.isEditing) return;
|
|
4023
3991
|
for (const attr of Array.from(entryEl.attributes)) {
|
|
4024
3992
|
if ((attr.name === "data-puck-design" || attr.name.startsWith("data-puck-field-value-")) && !(attr.name in fieldValueAttrs)) {
|
|
@@ -4031,10 +3999,10 @@ function createDesignComponentConfig(registration) {
|
|
|
4031
3999
|
}
|
|
4032
4000
|
}
|
|
4033
4001
|
}, [entryEl, fieldValueAttrs]);
|
|
4034
|
-
const appliedArrayHtml = (0,
|
|
4035
|
-
const arrayItemWiring = (0,
|
|
4036
|
-
const appliedArrays = (0,
|
|
4037
|
-
(0,
|
|
4002
|
+
const appliedArrayHtml = (0, import_react24.useRef)(/* @__PURE__ */ new WeakMap());
|
|
4003
|
+
const arrayItemWiring = (0, import_react24.useRef)({});
|
|
4004
|
+
const appliedArrays = (0, import_react24.useRef)(null);
|
|
4005
|
+
(0, import_react24.useEffect)(() => {
|
|
4038
4006
|
if (!puck.isEditing || !entryEl || !getPuck) return;
|
|
4039
4007
|
if (appliedArrays.current?.el === entryEl && appliedArrays.current?.html === html && appliedArrays.current?.sig === arraySig) {
|
|
4040
4008
|
return;
|
|
@@ -4086,7 +4054,7 @@ function createDesignComponentConfig(registration) {
|
|
|
4086
4054
|
id,
|
|
4087
4055
|
getPuck
|
|
4088
4056
|
]);
|
|
4089
|
-
(0,
|
|
4057
|
+
(0, import_react24.useEffect)(
|
|
4090
4058
|
() => () => {
|
|
4091
4059
|
Object.values(arrayItemWiring.current).forEach(
|
|
4092
4060
|
(wiring) => wiring.forEach(({ cleanup }) => cleanup())
|
|
@@ -4094,7 +4062,7 @@ function createDesignComponentConfig(registration) {
|
|
|
4094
4062
|
},
|
|
4095
4063
|
[]
|
|
4096
4064
|
);
|
|
4097
|
-
(0,
|
|
4065
|
+
(0, import_react24.useEffect)(() => {
|
|
4098
4066
|
if (!script || !entryEl) return;
|
|
4099
4067
|
scriptRef.current?.remove();
|
|
4100
4068
|
const doc = entryEl.ownerDocument;
|
|
@@ -4121,30 +4089,16 @@ function createDesignComponentConfig(registration) {
|
|
|
4121
4089
|
);
|
|
4122
4090
|
}
|
|
4123
4091
|
}
|
|
4124
|
-
const fieldContent = {};
|
|
4125
|
-
for (const { name: name2, node } of nodeFields) {
|
|
4126
|
-
fieldContent[name2] = node;
|
|
4127
|
-
}
|
|
4128
4092
|
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
|
|
4129
4093
|
styles && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("style", { children: styles }),
|
|
4130
4094
|
style && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("style", { children: style }),
|
|
4131
|
-
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { ref: setEntryEl, ...fieldValueAttrs, children: htmlToReactTree(patchedHtml, slotContent
|
|
4095
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { ref: setEntryEl, ...fieldValueAttrs, children: htmlToReactTree(patchedHtml, slotContent) })
|
|
4132
4096
|
] });
|
|
4133
4097
|
}
|
|
4134
4098
|
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
|
|
4135
4099
|
styles && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("style", { children: styles }),
|
|
4136
4100
|
style && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("style", { children: style }),
|
|
4137
4101
|
editorEntryNode,
|
|
4138
|
-
entryEl && nodeFields.map(({ name: name2, selector, node }) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
4139
|
-
FieldPortal,
|
|
4140
|
-
{
|
|
4141
|
-
entry: entryEl,
|
|
4142
|
-
html,
|
|
4143
|
-
selector,
|
|
4144
|
-
children: node
|
|
4145
|
-
},
|
|
4146
|
-
name2
|
|
4147
|
-
)),
|
|
4148
4102
|
entryEl && annotations.slots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
4149
4103
|
SlotPortal,
|
|
4150
4104
|
{
|
|
@@ -4163,7 +4117,7 @@ function createDesignComponentConfig(registration) {
|
|
|
4163
4117
|
|
|
4164
4118
|
// src/lib/design/globals.tsx
|
|
4165
4119
|
init_react_import();
|
|
4166
|
-
var
|
|
4120
|
+
var import_react25 = require("react");
|
|
4167
4121
|
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
4168
4122
|
function getDynamicConfigGlobals(dynamicConfig) {
|
|
4169
4123
|
if (typeof dynamicConfig !== "object" || dynamicConfig === null) return {};
|
|
@@ -4173,13 +4127,15 @@ function getDynamicConfigGlobals(dynamicConfig) {
|
|
|
4173
4127
|
...typeof script === "string" ? { script } : {}
|
|
4174
4128
|
};
|
|
4175
4129
|
}
|
|
4130
|
+
var INLINE_EDIT_RESET = ":where([data-puck-design] [contenteditable]){overflow-wrap:inherit;line-break:inherit;-webkit-nbsp-mode:inherit}";
|
|
4176
4131
|
function DesignGlobals({
|
|
4177
4132
|
styles,
|
|
4178
|
-
script
|
|
4133
|
+
script,
|
|
4134
|
+
isEditing
|
|
4179
4135
|
}) {
|
|
4180
|
-
const scriptRef = (0,
|
|
4181
|
-
const hostRef = (0,
|
|
4182
|
-
(0,
|
|
4136
|
+
const scriptRef = (0, import_react25.useRef)(null);
|
|
4137
|
+
const hostRef = (0, import_react25.useRef)(null);
|
|
4138
|
+
(0, import_react25.useEffect)(() => {
|
|
4183
4139
|
if (!script) return;
|
|
4184
4140
|
scriptRef.current?.remove();
|
|
4185
4141
|
const doc = hostRef.current?.ownerDocument ?? document;
|
|
@@ -4193,6 +4149,7 @@ function DesignGlobals({
|
|
|
4193
4149
|
};
|
|
4194
4150
|
}, [script]);
|
|
4195
4151
|
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
|
|
4152
|
+
isEditing && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("style", { children: INLINE_EDIT_RESET }),
|
|
4196
4153
|
styles && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("style", { children: styles }),
|
|
4197
4154
|
script && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { ref: hostRef, style: { display: "none" } })
|
|
4198
4155
|
] });
|
|
@@ -4205,7 +4162,14 @@ function withDesignGlobals(root) {
|
|
|
4205
4162
|
const render = (props) => {
|
|
4206
4163
|
const { styles, script } = getDynamicConfigGlobals(props._dynamicConfig);
|
|
4207
4164
|
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
|
|
4208
|
-
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
4165
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
4166
|
+
DesignGlobals,
|
|
4167
|
+
{
|
|
4168
|
+
styles,
|
|
4169
|
+
script,
|
|
4170
|
+
isEditing: props.puck?.isEditing
|
|
4171
|
+
}
|
|
4172
|
+
),
|
|
4209
4173
|
userRender ? userRender(props) : props.children
|
|
4210
4174
|
] });
|
|
4211
4175
|
};
|
|
@@ -4319,7 +4283,7 @@ function syncDesignComponents(getPuck) {
|
|
|
4319
4283
|
ensureDynamicConfigField(config);
|
|
4320
4284
|
for (const [name, persistedReg] of Object.entries(persisted)) {
|
|
4321
4285
|
const prev = lastSynced.get(name);
|
|
4322
|
-
if (registrationStore.has(name) && (prev === persistedReg || registrationContentEqual(prev, persistedReg))) {
|
|
4286
|
+
if (registrationStore.has(name) && config.components[name] && (prev === persistedReg || registrationContentEqual(prev, persistedReg))) {
|
|
4323
4287
|
lastSynced.set(name, persistedReg);
|
|
4324
4288
|
continue;
|
|
4325
4289
|
}
|
|
@@ -4343,18 +4307,17 @@ function syncDesignComponents(getPuck) {
|
|
|
4343
4307
|
};
|
|
4344
4308
|
}
|
|
4345
4309
|
}
|
|
4346
|
-
config.components[name].fields =
|
|
4347
|
-
...getSlotFields(registration.html ?? ""),
|
|
4348
|
-
...getTransformableFields(registration)
|
|
4349
|
-
};
|
|
4310
|
+
config.components[name].fields = getSlotFields(registration.html ?? "");
|
|
4350
4311
|
}
|
|
4351
4312
|
let hasRemovals = false;
|
|
4352
4313
|
for (const [name] of registrationStore.getAll()) {
|
|
4353
4314
|
if (!(name in persisted)) {
|
|
4354
4315
|
registrationStore.delete(name);
|
|
4355
4316
|
lastSynced.delete(name);
|
|
4356
|
-
|
|
4357
|
-
|
|
4317
|
+
if (isDesignComponent(config.components[name])) {
|
|
4318
|
+
delete config.components[name];
|
|
4319
|
+
hasRemovals = true;
|
|
4320
|
+
}
|
|
4358
4321
|
}
|
|
4359
4322
|
}
|
|
4360
4323
|
if (createdSettled) {
|
|
@@ -4474,12 +4437,145 @@ var waitForIframeReady = async (root, imageTimeout = 1e4) => {
|
|
|
4474
4437
|
await waitForNextPaint(document2);
|
|
4475
4438
|
};
|
|
4476
4439
|
|
|
4440
|
+
// src/lib/capture-screenshot.ts
|
|
4441
|
+
init_react_import();
|
|
4442
|
+
var import_html2canvas_pro = __toESM(require("html2canvas-pro"));
|
|
4443
|
+
|
|
4444
|
+
// src/lib/screenshot-size.ts
|
|
4445
|
+
init_react_import();
|
|
4446
|
+
var MAX_WEBP_DIMENSION = 16383;
|
|
4447
|
+
var CAPTURE_SCALE = 2;
|
|
4448
|
+
var getFitRatio = (width, height, dimensionLimit = MAX_WEBP_DIMENSION) => {
|
|
4449
|
+
if (width <= 0 || height <= 0) return 1;
|
|
4450
|
+
return Math.min(1, dimensionLimit / Math.max(width, height));
|
|
4451
|
+
};
|
|
4452
|
+
var getCaptureScale = (width, height, scale) => scale * getFitRatio(width * scale, height * scale);
|
|
4453
|
+
var scaleDimension = (value, ratio) => Math.max(1, Math.floor(value * ratio));
|
|
4454
|
+
var getDocumentSize = (root) => {
|
|
4455
|
+
const { body, documentElement } = root.ownerDocument;
|
|
4456
|
+
return {
|
|
4457
|
+
width: Math.max(
|
|
4458
|
+
body?.scrollWidth ?? 0,
|
|
4459
|
+
body?.offsetWidth ?? 0,
|
|
4460
|
+
body?.clientWidth ?? 0,
|
|
4461
|
+
documentElement?.scrollWidth ?? 0,
|
|
4462
|
+
documentElement?.offsetWidth ?? 0,
|
|
4463
|
+
documentElement?.clientWidth ?? 0
|
|
4464
|
+
),
|
|
4465
|
+
height: Math.max(
|
|
4466
|
+
body?.scrollHeight ?? 0,
|
|
4467
|
+
body?.offsetHeight ?? 0,
|
|
4468
|
+
body?.clientHeight ?? 0,
|
|
4469
|
+
documentElement?.scrollHeight ?? 0,
|
|
4470
|
+
documentElement?.offsetHeight ?? 0,
|
|
4471
|
+
documentElement?.clientHeight ?? 0
|
|
4472
|
+
)
|
|
4473
|
+
};
|
|
4474
|
+
};
|
|
4475
|
+
|
|
4476
|
+
// src/lib/capture-screenshot.ts
|
|
4477
|
+
var editorOnlyClassPrefixes = ["_DraggableComponent--hover", "_ActionBar"];
|
|
4478
|
+
var releaseCanvas = (canvas) => {
|
|
4479
|
+
canvas.width = 0;
|
|
4480
|
+
canvas.height = 0;
|
|
4481
|
+
};
|
|
4482
|
+
var drawScaled = (source, ratio) => {
|
|
4483
|
+
const target = document.createElement("canvas");
|
|
4484
|
+
target.width = scaleDimension(source.width, ratio);
|
|
4485
|
+
target.height = scaleDimension(source.height, ratio);
|
|
4486
|
+
const ctx2 = target.getContext("2d");
|
|
4487
|
+
if (!ctx2) {
|
|
4488
|
+
releaseCanvas(target);
|
|
4489
|
+
return source;
|
|
4490
|
+
}
|
|
4491
|
+
ctx2.imageSmoothingEnabled = true;
|
|
4492
|
+
ctx2.imageSmoothingQuality = "high";
|
|
4493
|
+
ctx2.drawImage(source, 0, 0, target.width, target.height);
|
|
4494
|
+
return target;
|
|
4495
|
+
};
|
|
4496
|
+
var fitCanvas = (canvas) => {
|
|
4497
|
+
let remaining = getFitRatio(canvas.width, canvas.height);
|
|
4498
|
+
if (remaining >= 1) return canvas;
|
|
4499
|
+
let current = canvas;
|
|
4500
|
+
while (remaining < 0.5) {
|
|
4501
|
+
const next = drawScaled(current, 0.5);
|
|
4502
|
+
if (current !== canvas) releaseCanvas(current);
|
|
4503
|
+
current = next;
|
|
4504
|
+
remaining *= 2;
|
|
4505
|
+
}
|
|
4506
|
+
const fitted = drawScaled(current, remaining);
|
|
4507
|
+
if (current !== canvas) releaseCanvas(current);
|
|
4508
|
+
return fitted;
|
|
4509
|
+
};
|
|
4510
|
+
var toWebp = (canvas, quality) => new Promise((resolve, reject) => {
|
|
4511
|
+
canvas.toBlob(
|
|
4512
|
+
(blob) => {
|
|
4513
|
+
if (blob && blob.size > 0) {
|
|
4514
|
+
resolve(blob);
|
|
4515
|
+
return;
|
|
4516
|
+
}
|
|
4517
|
+
reject(
|
|
4518
|
+
new Error(
|
|
4519
|
+
`Could not encode a ${canvas.width}x${canvas.height} canvas as WebP`
|
|
4520
|
+
)
|
|
4521
|
+
);
|
|
4522
|
+
},
|
|
4523
|
+
"image/webp",
|
|
4524
|
+
quality
|
|
4525
|
+
);
|
|
4526
|
+
});
|
|
4527
|
+
var captureScreenshot = async (root, { scale = CAPTURE_SCALE, quality = 0.8, width } = {}) => {
|
|
4528
|
+
const documentSize = getDocumentSize(root);
|
|
4529
|
+
const safeWebPScale = getCaptureScale(
|
|
4530
|
+
width ?? documentSize.width,
|
|
4531
|
+
documentSize.height,
|
|
4532
|
+
scale
|
|
4533
|
+
);
|
|
4534
|
+
const canvas = await (0, import_html2canvas_pro.default)(root, {
|
|
4535
|
+
scale: safeWebPScale,
|
|
4536
|
+
backgroundColor: "#ffffff",
|
|
4537
|
+
...width === void 0 ? {} : { width, windowWidth: width },
|
|
4538
|
+
foreignObjectRendering: false,
|
|
4539
|
+
imageTimeout: 3e4,
|
|
4540
|
+
logging: false,
|
|
4541
|
+
allowTaint: false,
|
|
4542
|
+
useCORS: true,
|
|
4543
|
+
scrollY: 0,
|
|
4544
|
+
ignoreElements: (el) => Array.from(el.classList).some(
|
|
4545
|
+
(c) => editorOnlyClassPrefixes.some((prefix) => c.startsWith(prefix))
|
|
4546
|
+
)
|
|
4547
|
+
});
|
|
4548
|
+
const fitted = fitCanvas(canvas);
|
|
4549
|
+
try {
|
|
4550
|
+
return await toWebp(fitted, quality);
|
|
4551
|
+
} finally {
|
|
4552
|
+
if (fitted !== canvas) releaseCanvas(fitted);
|
|
4553
|
+
releaseCanvas(canvas);
|
|
4554
|
+
}
|
|
4555
|
+
};
|
|
4556
|
+
|
|
4557
|
+
// src/lib/client-tool-response.ts
|
|
4558
|
+
init_react_import();
|
|
4559
|
+
async function postClientToolResponse(host, body) {
|
|
4560
|
+
const response = await fetch(`${host.replace(/\/+$/, "")}/tool`, {
|
|
4561
|
+
method: "POST",
|
|
4562
|
+
headers: { "Content-Type": "application/json" },
|
|
4563
|
+
body: JSON.stringify(body)
|
|
4564
|
+
});
|
|
4565
|
+
if (!response.ok) {
|
|
4566
|
+
throw new Error(
|
|
4567
|
+
`Client tool endpoint returned ${response.status} ${response.statusText}`.trim()
|
|
4568
|
+
);
|
|
4569
|
+
}
|
|
4570
|
+
}
|
|
4571
|
+
|
|
4477
4572
|
// src/components/Chat/index.tsx
|
|
4478
4573
|
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
4479
4574
|
var q = (0, import_qler.default)();
|
|
4480
4575
|
var DEFAULT_API_VERSION = "v2";
|
|
4481
4576
|
var BUILD_OP_DEBOUNCE_MS = 1e3 / 60;
|
|
4482
|
-
var
|
|
4577
|
+
var CLIENT_TOOL_ENDPOINT_UNAVAILABLE_ERROR_MESSAGE = "Unable to verify the page data. Please enable the `/chat/tool` endpoint on the server and try again.";
|
|
4578
|
+
var PLUGIN_AI_VERSION = true ? "0.9.0-canary.fb1abcf5" : "unknown";
|
|
4483
4579
|
var BENCHMARK = false;
|
|
4484
4580
|
var prefixedUlid = (prefix = "") => `${prefix ? `${prefix}_` : ""}${(0, import_ulid.ulid)()}`;
|
|
4485
4581
|
var getClassName18 = getClassNameFactory("Chat", styles_module_default);
|
|
@@ -4502,28 +4598,32 @@ function Chat2(props) {
|
|
|
4502
4598
|
} = chat ?? {};
|
|
4503
4599
|
const puckDispatch = usePuck((s) => s.dispatch);
|
|
4504
4600
|
const getPuck = (0, import_core5.useGetPuck)();
|
|
4505
|
-
const localChatId = (0,
|
|
4506
|
-
const inputRef = (0,
|
|
4507
|
-
const pluginRef = (0,
|
|
4508
|
-
const [mode, setMode] = (0,
|
|
4509
|
-
const modeRef = (0,
|
|
4601
|
+
const localChatId = (0, import_react27.useRef)("");
|
|
4602
|
+
const inputRef = (0, import_react27.useRef)(null);
|
|
4603
|
+
const pluginRef = (0, import_react27.useRef)(null);
|
|
4604
|
+
const [mode, setMode] = (0, import_react27.useState)(defaultMode);
|
|
4605
|
+
const modeRef = (0, import_react27.useRef)(mode);
|
|
4510
4606
|
const designModeVisible = typeof designMode === "boolean" ? designMode : designMode.visible ?? false;
|
|
4511
|
-
(0,
|
|
4607
|
+
(0, import_react27.useEffect)(() => {
|
|
4512
4608
|
modeRef.current = mode;
|
|
4513
4609
|
}, [mode]);
|
|
4514
4610
|
const puckData = usePuck((s) => s.appState.data);
|
|
4515
|
-
(0,
|
|
4611
|
+
(0, import_react27.useEffect)(() => {
|
|
4516
4612
|
syncDesignComponents(getPuck);
|
|
4517
4613
|
}, [puckData, getPuck]);
|
|
4518
|
-
const [error, setError] = (0,
|
|
4519
|
-
const [userError, setUserError] = (0,
|
|
4520
|
-
const
|
|
4521
|
-
const
|
|
4522
|
-
const
|
|
4523
|
-
const
|
|
4524
|
-
const
|
|
4525
|
-
const
|
|
4526
|
-
const
|
|
4614
|
+
const [error, setError] = (0, import_react27.useState)();
|
|
4615
|
+
const [userError, setUserError] = (0, import_react27.useState)();
|
|
4616
|
+
const clientToolEndpointUnavailableRef = (0, import_react27.useRef)(false);
|
|
4617
|
+
const stopChatRef = (0, import_react27.useRef)(null);
|
|
4618
|
+
const [composerAttachments, setComposerAttachments] = (0, import_react27.useState)([]);
|
|
4619
|
+
const removedAttachmentClientIdsRef = (0, import_react27.useRef)(/* @__PURE__ */ new Set());
|
|
4620
|
+
const uploadControllersRef = (0, import_react27.useRef)(/* @__PURE__ */ new Map());
|
|
4621
|
+
const pendingBuildOpsRef = (0, import_react27.useRef)([]);
|
|
4622
|
+
const lastStreamActivityRef = (0, import_react27.useRef)(0);
|
|
4623
|
+
const hiddenSinceRef = (0, import_react27.useRef)(null);
|
|
4624
|
+
const [toolStatus, setToolStatus] = (0, import_react27.useState)({});
|
|
4625
|
+
const [subagentState, setSubagentState] = (0, import_react27.useState)({});
|
|
4626
|
+
const attachmentConfig = (0, import_react27.useMemo)(
|
|
4527
4627
|
() => ({
|
|
4528
4628
|
accept: attachments?.accept ?? defaultAttachmentAccept,
|
|
4529
4629
|
enabled: attachments?.enabled ?? true,
|
|
@@ -4533,14 +4633,14 @@ function Chat2(props) {
|
|
|
4533
4633
|
}),
|
|
4534
4634
|
[attachments, host]
|
|
4535
4635
|
);
|
|
4536
|
-
(0,
|
|
4636
|
+
(0, import_react27.useEffect)(
|
|
4537
4637
|
() => () => {
|
|
4538
4638
|
uploadControllersRef.current.forEach((controller) => controller.abort());
|
|
4539
4639
|
uploadControllersRef.current.clear();
|
|
4540
4640
|
},
|
|
4541
4641
|
[]
|
|
4542
4642
|
);
|
|
4543
|
-
const deleteAttachment = (0,
|
|
4643
|
+
const deleteAttachment = (0, import_react27.useCallback)(
|
|
4544
4644
|
async (attachmentId) => {
|
|
4545
4645
|
try {
|
|
4546
4646
|
await fetch(`${attachmentConfig.endpoint}/${attachmentId}`, {
|
|
@@ -4552,7 +4652,7 @@ function Chat2(props) {
|
|
|
4552
4652
|
},
|
|
4553
4653
|
[attachmentConfig.endpoint]
|
|
4554
4654
|
);
|
|
4555
|
-
const uploadScreenshot = (0,
|
|
4655
|
+
const uploadScreenshot = (0, import_react27.useCallback)(
|
|
4556
4656
|
async (width, bucketUrl) => {
|
|
4557
4657
|
try {
|
|
4558
4658
|
const iframeDocument = document?.getElementById("preview-frame")?.contentDocument?.documentElement ?? null;
|
|
@@ -4560,24 +4660,7 @@ function Chat2(props) {
|
|
|
4560
4660
|
throw new Error("Preview frame not found");
|
|
4561
4661
|
}
|
|
4562
4662
|
await waitForIframeReady(iframeDocument);
|
|
4563
|
-
const
|
|
4564
|
-
scale: 2,
|
|
4565
|
-
backgroundColor: "#ffffff",
|
|
4566
|
-
width,
|
|
4567
|
-
windowWidth: width,
|
|
4568
|
-
foreignObjectRendering: false,
|
|
4569
|
-
imageTimeout: 3e4,
|
|
4570
|
-
logging: false,
|
|
4571
|
-
allowTaint: false,
|
|
4572
|
-
useCORS: true,
|
|
4573
|
-
scrollY: 0,
|
|
4574
|
-
ignoreElements: (el) => Array.from(el.classList).some(
|
|
4575
|
-
(c) => c.startsWith("_DraggableComponent--hover") || c.startsWith("_ActionBar")
|
|
4576
|
-
)
|
|
4577
|
-
});
|
|
4578
|
-
const image = canvas.toDataURL("image/webp", 0.8);
|
|
4579
|
-
const imageResponse = await fetch(image);
|
|
4580
|
-
const blob = await imageResponse.blob();
|
|
4663
|
+
const blob = await captureScreenshot(iframeDocument, { width });
|
|
4581
4664
|
const uploadResponse = await fetch(bucketUrl, {
|
|
4582
4665
|
method: "PUT",
|
|
4583
4666
|
body: blob
|
|
@@ -4624,15 +4707,50 @@ function Chat2(props) {
|
|
|
4624
4707
|
BUILD_OP_DEBOUNCE_MS,
|
|
4625
4708
|
{ maxWait: BUILD_OP_DEBOUNCE_MS }
|
|
4626
4709
|
);
|
|
4627
|
-
const queueBuildOp = (0,
|
|
4710
|
+
const queueBuildOp = (0, import_react27.useCallback)(
|
|
4628
4711
|
(operation) => {
|
|
4629
4712
|
pendingBuildOpsRef.current.push(operation);
|
|
4630
4713
|
debouncedFlushBuildOps();
|
|
4631
4714
|
},
|
|
4632
4715
|
[debouncedFlushBuildOps]
|
|
4633
4716
|
);
|
|
4634
|
-
const
|
|
4717
|
+
const handleClientToolEndpointUnavailable = (0, import_react27.useCallback)(() => {
|
|
4718
|
+
if (clientToolEndpointUnavailableRef.current) return;
|
|
4719
|
+
clientToolEndpointUnavailableRef.current = true;
|
|
4720
|
+
setError(CLIENT_TOOL_ENDPOINT_UNAVAILABLE_ERROR_MESSAGE);
|
|
4721
|
+
console.error(CLIENT_TOOL_ENDPOINT_UNAVAILABLE_ERROR_MESSAGE);
|
|
4722
|
+
setToolStatus((current) => {
|
|
4723
|
+
let changed = false;
|
|
4724
|
+
const next = {};
|
|
4725
|
+
for (const [id, toolState] of Object.entries(current)) {
|
|
4726
|
+
if (toolState.loading) {
|
|
4727
|
+
changed = true;
|
|
4728
|
+
next[id] = {
|
|
4729
|
+
...toolState,
|
|
4730
|
+
loading: false,
|
|
4731
|
+
label: "Verification unavailable"
|
|
4732
|
+
};
|
|
4733
|
+
} else {
|
|
4734
|
+
next[id] = toolState;
|
|
4735
|
+
}
|
|
4736
|
+
}
|
|
4737
|
+
return changed ? next : current;
|
|
4738
|
+
});
|
|
4739
|
+
stopChatRef.current?.();
|
|
4740
|
+
}, []);
|
|
4741
|
+
const sendClientToolResponse = (0, import_react27.useCallback)(
|
|
4742
|
+
async (body) => {
|
|
4743
|
+
try {
|
|
4744
|
+
await postClientToolResponse(host, body);
|
|
4745
|
+
} catch {
|
|
4746
|
+
handleClientToolEndpointUnavailable();
|
|
4747
|
+
}
|
|
4748
|
+
},
|
|
4749
|
+
[handleClientToolEndpointUnavailable, host]
|
|
4750
|
+
);
|
|
4751
|
+
const processData = (0, import_react27.useCallback)(
|
|
4635
4752
|
(dataPart) => {
|
|
4753
|
+
lastStreamActivityRef.current = Date.now();
|
|
4636
4754
|
switch (dataPart.type) {
|
|
4637
4755
|
case "data-new-chat-created": {
|
|
4638
4756
|
localChatId.current = dataPart.data.chatId;
|
|
@@ -4663,13 +4781,9 @@ function Chat2(props) {
|
|
|
4663
4781
|
debouncedFlushBuildOps.flush();
|
|
4664
4782
|
q.wait().then(() => {
|
|
4665
4783
|
const { appState } = getPuck();
|
|
4666
|
-
return
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
body: JSON.stringify({
|
|
4670
|
-
id: requestId,
|
|
4671
|
-
responses: [{ action, output: appState.data }]
|
|
4672
|
-
})
|
|
4784
|
+
return sendClientToolResponse({
|
|
4785
|
+
id: requestId,
|
|
4786
|
+
responses: [{ action, output: appState.data }]
|
|
4673
4787
|
});
|
|
4674
4788
|
}).catch((e) => {
|
|
4675
4789
|
console.error("Failed to respond to client request:", e);
|
|
@@ -4686,22 +4800,7 @@ function Chat2(props) {
|
|
|
4686
4800
|
throw new Error("Preview frame not found");
|
|
4687
4801
|
}
|
|
4688
4802
|
await waitForIframeReady(iframeDocument);
|
|
4689
|
-
const
|
|
4690
|
-
scale: 2,
|
|
4691
|
-
backgroundColor: "#ffffff",
|
|
4692
|
-
foreignObjectRendering: false,
|
|
4693
|
-
imageTimeout: 3e4,
|
|
4694
|
-
logging: false,
|
|
4695
|
-
allowTaint: false,
|
|
4696
|
-
useCORS: true,
|
|
4697
|
-
scrollY: 0,
|
|
4698
|
-
ignoreElements: (el) => Array.from(el.classList).some(
|
|
4699
|
-
(c) => c.startsWith("_DraggableComponent--hover") || c.startsWith("_ActionBar")
|
|
4700
|
-
)
|
|
4701
|
-
});
|
|
4702
|
-
const image = canvas.toDataURL("image/webp", 0.8);
|
|
4703
|
-
const imageResponse = await fetch(image);
|
|
4704
|
-
const blob = await imageResponse.blob();
|
|
4803
|
+
const blob = await captureScreenshot(iframeDocument);
|
|
4705
4804
|
const uploadResponse = await fetch(putUrl, {
|
|
4706
4805
|
method: "PUT",
|
|
4707
4806
|
body: blob
|
|
@@ -4711,16 +4810,16 @@ function Chat2(props) {
|
|
|
4711
4810
|
`Upload failed with status ${uploadResponse.status}`
|
|
4712
4811
|
);
|
|
4713
4812
|
}
|
|
4714
|
-
return
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
body: JSON.stringify({
|
|
4718
|
-
id: requestId,
|
|
4719
|
-
responses: [{ action, output: { sizeBytes: blob.size } }]
|
|
4720
|
-
})
|
|
4813
|
+
return sendClientToolResponse({
|
|
4814
|
+
id: requestId,
|
|
4815
|
+
responses: [{ action, output: { sizeBytes: blob.size } }]
|
|
4721
4816
|
});
|
|
4722
4817
|
}).catch((e) => {
|
|
4723
4818
|
console.error("Failed to respond to client request:", e);
|
|
4819
|
+
return sendClientToolResponse({
|
|
4820
|
+
id: requestId,
|
|
4821
|
+
responses: [{ action, output: { sizeBytes: 0 } }]
|
|
4822
|
+
});
|
|
4724
4823
|
});
|
|
4725
4824
|
}
|
|
4726
4825
|
return;
|
|
@@ -4764,6 +4863,7 @@ function Chat2(props) {
|
|
|
4764
4863
|
getPuck,
|
|
4765
4864
|
puckDispatch,
|
|
4766
4865
|
queueBuildOp,
|
|
4866
|
+
sendClientToolResponse,
|
|
4767
4867
|
uploadScreenshot
|
|
4768
4868
|
]
|
|
4769
4869
|
);
|
|
@@ -4833,12 +4933,14 @@ function Chat2(props) {
|
|
|
4833
4933
|
if (BENCHMARK) {
|
|
4834
4934
|
console.timeEnd("chat");
|
|
4835
4935
|
}
|
|
4836
|
-
|
|
4936
|
+
if (!clientToolEndpointUnavailableRef.current) {
|
|
4937
|
+
setError(e.message);
|
|
4938
|
+
}
|
|
4837
4939
|
},
|
|
4838
4940
|
onFinish: (options) => {
|
|
4839
4941
|
debouncedFlushBuildOps.flush();
|
|
4840
4942
|
q.wait().then(() => {
|
|
4841
|
-
if (!options.isAbort) {
|
|
4943
|
+
if (!options.isAbort || clientToolEndpointUnavailableRef.current) {
|
|
4842
4944
|
puckDispatch({
|
|
4843
4945
|
type: "set",
|
|
4844
4946
|
state: getPuck().appState,
|
|
@@ -4853,18 +4955,69 @@ function Chat2(props) {
|
|
|
4853
4955
|
});
|
|
4854
4956
|
}
|
|
4855
4957
|
});
|
|
4856
|
-
(0,
|
|
4857
|
-
|
|
4958
|
+
(0, import_react27.useEffect)(() => {
|
|
4959
|
+
stopChatRef.current = stop;
|
|
4960
|
+
return () => {
|
|
4961
|
+
stopChatRef.current = null;
|
|
4858
4962
|
stop();
|
|
4859
|
-
}
|
|
4860
|
-
|
|
4861
|
-
);
|
|
4862
|
-
|
|
4863
|
-
|
|
4963
|
+
};
|
|
4964
|
+
}, [stop]);
|
|
4965
|
+
const statusRef = (0, import_react27.useRef)(status);
|
|
4966
|
+
(0, import_react27.useEffect)(() => {
|
|
4967
|
+
statusRef.current = status;
|
|
4968
|
+
}, [status]);
|
|
4969
|
+
(0, import_react27.useEffect)(() => {
|
|
4970
|
+
lastStreamActivityRef.current = Date.now();
|
|
4971
|
+
}, [messages]);
|
|
4972
|
+
(0, import_react27.useEffect)(() => {
|
|
4973
|
+
const FROZEN_HIDDEN_MS = 3 * 6e4;
|
|
4974
|
+
const RESUME_GRACE_MS = 12e3;
|
|
4975
|
+
const isStreaming = () => statusRef.current === "streaming" || statusRef.current === "submitted";
|
|
4976
|
+
let graceTimer;
|
|
4977
|
+
const recoverIfSevered = () => {
|
|
4978
|
+
if (!isStreaming()) return;
|
|
4979
|
+
if (Date.now() - lastStreamActivityRef.current < RESUME_GRACE_MS) return;
|
|
4980
|
+
stop();
|
|
4981
|
+
setToolStatus((current) => {
|
|
4982
|
+
let changed = false;
|
|
4983
|
+
const next = {};
|
|
4984
|
+
for (const [id, toolState] of Object.entries(current)) {
|
|
4985
|
+
if (toolState.loading) {
|
|
4986
|
+
changed = true;
|
|
4987
|
+
next[id] = { ...toolState, loading: false, label: "Interrupted" };
|
|
4988
|
+
} else {
|
|
4989
|
+
next[id] = toolState;
|
|
4990
|
+
}
|
|
4991
|
+
}
|
|
4992
|
+
return changed ? next : current;
|
|
4993
|
+
});
|
|
4994
|
+
};
|
|
4995
|
+
const onVisibilityChange = () => {
|
|
4996
|
+
if (document.hidden) {
|
|
4997
|
+
hiddenSinceRef.current = isStreaming() ? Date.now() : null;
|
|
4998
|
+
return;
|
|
4999
|
+
}
|
|
5000
|
+
const hiddenSince = hiddenSinceRef.current;
|
|
5001
|
+
hiddenSinceRef.current = null;
|
|
5002
|
+
if (graceTimer) clearTimeout(graceTimer);
|
|
5003
|
+
if (hiddenSince === null || Date.now() - hiddenSince < FROZEN_HIDDEN_MS) {
|
|
5004
|
+
return;
|
|
5005
|
+
}
|
|
5006
|
+
lastStreamActivityRef.current = 0;
|
|
5007
|
+
graceTimer = setTimeout(recoverIfSevered, RESUME_GRACE_MS);
|
|
5008
|
+
};
|
|
5009
|
+
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
5010
|
+
return () => {
|
|
5011
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
5012
|
+
if (graceTimer) clearTimeout(graceTimer);
|
|
5013
|
+
};
|
|
5014
|
+
}, [stop]);
|
|
5015
|
+
const [forcedStatus, setForcedStatus] = (0, import_react27.useState)();
|
|
5016
|
+
const resolvedStatus = (0, import_react27.useMemo)(
|
|
4864
5017
|
() => forcedStatus ?? status,
|
|
4865
5018
|
[status, forcedStatus]
|
|
4866
5019
|
);
|
|
4867
|
-
(0,
|
|
5020
|
+
(0, import_react27.useEffect)(() => {
|
|
4868
5021
|
if (!scrollTrackingId) return;
|
|
4869
5022
|
dispatchScrollTrackingEvent({
|
|
4870
5023
|
id: scrollTrackingId,
|
|
@@ -4877,7 +5030,7 @@ function Chat2(props) {
|
|
|
4877
5030
|
});
|
|
4878
5031
|
};
|
|
4879
5032
|
}, [resolvedStatus, scrollTrackingId]);
|
|
4880
|
-
(0,
|
|
5033
|
+
(0, import_react27.useEffect)(() => {
|
|
4881
5034
|
window.__PUCK_AI = {
|
|
4882
5035
|
processData,
|
|
4883
5036
|
setMessages,
|
|
@@ -4909,6 +5062,8 @@ function Chat2(props) {
|
|
|
4909
5062
|
if (!text && readyAttachments.length === 0) {
|
|
4910
5063
|
return false;
|
|
4911
5064
|
}
|
|
5065
|
+
clientToolEndpointUnavailableRef.current = false;
|
|
5066
|
+
setError("");
|
|
4912
5067
|
setUserError("");
|
|
4913
5068
|
if (chat?.onSubmit) {
|
|
4914
5069
|
try {
|
|
@@ -5086,7 +5241,7 @@ function Chat2(props) {
|
|
|
5086
5241
|
if (!target?.attachmentId) return;
|
|
5087
5242
|
await deleteAttachment(target.attachmentId);
|
|
5088
5243
|
};
|
|
5089
|
-
const messagesWithStatuses = (0,
|
|
5244
|
+
const messagesWithStatuses = (0, import_react27.useMemo)(() => {
|
|
5090
5245
|
return messages.map((msg) => {
|
|
5091
5246
|
return {
|
|
5092
5247
|
...msg,
|
|
@@ -5148,6 +5303,7 @@ function Chat2(props) {
|
|
|
5148
5303
|
),
|
|
5149
5304
|
error,
|
|
5150
5305
|
handleRetry: () => {
|
|
5306
|
+
clientToolEndpointUnavailableRef.current = false;
|
|
5151
5307
|
setError("");
|
|
5152
5308
|
regenerate();
|
|
5153
5309
|
},
|
|
@@ -5270,8 +5426,8 @@ function AttachmentComposer({
|
|
|
5270
5426
|
maxFiles,
|
|
5271
5427
|
onChange
|
|
5272
5428
|
}) {
|
|
5273
|
-
const id = (0,
|
|
5274
|
-
const inputId = (0,
|
|
5429
|
+
const id = (0, import_react27.useId)();
|
|
5430
|
+
const inputId = (0, import_react27.useMemo)(() => `attachment-input-${id}`, []);
|
|
5275
5431
|
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: getClassName18("attachmentControls"), children: [
|
|
5276
5432
|
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
5277
5433
|
"input",
|
|
@@ -5371,7 +5527,7 @@ function isScrolledIntoView(el) {
|
|
|
5371
5527
|
|
|
5372
5528
|
// src/components/ScrollTracking/ScrollTracking.tsx
|
|
5373
5529
|
init_react_import();
|
|
5374
|
-
var
|
|
5530
|
+
var import_react29 = require("react");
|
|
5375
5531
|
|
|
5376
5532
|
// src/lib/scroll-into-view-local.ts
|
|
5377
5533
|
init_react_import();
|
|
@@ -5394,9 +5550,9 @@ function scrollIntoViewLocal(el, win, behavior = "smooth") {
|
|
|
5394
5550
|
|
|
5395
5551
|
// src/lib/use-frame-mutation-observer.ts
|
|
5396
5552
|
init_react_import();
|
|
5397
|
-
var
|
|
5553
|
+
var import_react28 = require("react");
|
|
5398
5554
|
function useFrameMutationObserver(callback) {
|
|
5399
|
-
return (0,
|
|
5555
|
+
return (0, import_react28.useCallback)(() => {
|
|
5400
5556
|
const frame = document?.getElementById(
|
|
5401
5557
|
"preview-frame"
|
|
5402
5558
|
);
|
|
@@ -5441,9 +5597,9 @@ var ScrollTracking = ({
|
|
|
5441
5597
|
children,
|
|
5442
5598
|
trackingId
|
|
5443
5599
|
}) => {
|
|
5444
|
-
const followedRefs = (0,
|
|
5445
|
-
const enabledRef = (0,
|
|
5446
|
-
(0,
|
|
5600
|
+
const followedRefs = (0, import_react29.useRef)([]);
|
|
5601
|
+
const enabledRef = (0, import_react29.useRef)(false);
|
|
5602
|
+
(0, import_react29.useEffect)(() => {
|
|
5447
5603
|
return subscribeToScrollTrackingEvents(({ id, enabled }) => {
|
|
5448
5604
|
if (id !== trackingId) return;
|
|
5449
5605
|
enabledRef.current = enabled;
|
|
@@ -5462,7 +5618,7 @@ var ScrollTracking = ({
|
|
|
5462
5618
|
});
|
|
5463
5619
|
}
|
|
5464
5620
|
});
|
|
5465
|
-
(0,
|
|
5621
|
+
(0, import_react29.useEffect)(() => {
|
|
5466
5622
|
follow();
|
|
5467
5623
|
}, [follow]);
|
|
5468
5624
|
return children;
|
|
@@ -5475,7 +5631,7 @@ var import_core7 = require("@puckeditor/core");
|
|
|
5475
5631
|
// src/components/ManageComponents/index.tsx
|
|
5476
5632
|
init_react_import();
|
|
5477
5633
|
var import_core6 = require("@puckeditor/core");
|
|
5478
|
-
var
|
|
5634
|
+
var import_react30 = require("react");
|
|
5479
5635
|
|
|
5480
5636
|
// css-module:/home/runner/work/platform/platform/packages/plugin-ai/src/components/ManageComponents/styles.module.css#css-module
|
|
5481
5637
|
init_react_import();
|
|
@@ -5484,7 +5640,7 @@ var styles_module_default10 = { "ManageComponents-cta": "_ManageComponents-cta_x
|
|
|
5484
5640
|
// src/components/ManageComponents/index.tsx
|
|
5485
5641
|
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
5486
5642
|
var cx10 = getClassNameFactory2("ManageComponents", styles_module_default10);
|
|
5487
|
-
var useRegistrations = () => (0,
|
|
5643
|
+
var useRegistrations = () => (0, import_react30.useSyncExternalStore)(
|
|
5488
5644
|
registrationStore.subscribe,
|
|
5489
5645
|
() => registrationStore.getAll(),
|
|
5490
5646
|
() => registrationStore.getAll()
|
|
@@ -5492,9 +5648,9 @@ var useRegistrations = () => (0, import_react31.useSyncExternalStore)(
|
|
|
5492
5648
|
function ManageModalContent({ onClose }) {
|
|
5493
5649
|
const getPuck = (0, import_core6.useGetPuck)();
|
|
5494
5650
|
const { visible, setVisible } = useModal();
|
|
5495
|
-
const [confirmTarget, setConfirmTarget] = (0,
|
|
5651
|
+
const [confirmTarget, setConfirmTarget] = (0, import_react30.useState)(null);
|
|
5496
5652
|
const entries = useRegistrations();
|
|
5497
|
-
(0,
|
|
5653
|
+
(0, import_react30.useEffect)(() => {
|
|
5498
5654
|
if (!visible) onClose();
|
|
5499
5655
|
}, [visible, onClose]);
|
|
5500
5656
|
const handleDelete = (name) => {
|
|
@@ -5549,9 +5705,9 @@ function ManageModalContent({ onClose }) {
|
|
|
5549
5705
|
] }) });
|
|
5550
5706
|
}
|
|
5551
5707
|
function ManageComponentsCta() {
|
|
5552
|
-
const [open, setOpen] = (0,
|
|
5708
|
+
const [open, setOpen] = (0, import_react30.useState)(false);
|
|
5553
5709
|
const entries = useRegistrations();
|
|
5554
|
-
const handleClose = (0,
|
|
5710
|
+
const handleClose = (0, import_react30.useCallback)(() => setOpen(false), []);
|
|
5555
5711
|
if (entries.length === 0) return null;
|
|
5556
5712
|
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
|
|
5557
5713
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("button", { className: cx10("cta"), onClick: () => setOpen(true), type: "button", children: [
|