@pixldocs/canvas-renderer 0.4.9 → 0.5.0
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.cjs +64 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +64 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2184,6 +2184,18 @@ const useEditorStore = create((set, get) => ({
|
|
|
2184
2184
|
const committed = commitFromState(state, nextCanvas);
|
|
2185
2185
|
return { canvas: nextCanvas, ...committed };
|
|
2186
2186
|
}),
|
|
2187
|
+
setPageBoundRepeatablePage: (pageId, repeatablePageId) => set((state) => {
|
|
2188
|
+
const updatedPages = state.canvas.pages.map((p) => {
|
|
2189
|
+
if (p.id !== pageId) return p;
|
|
2190
|
+
const next = { ...p };
|
|
2191
|
+
if (repeatablePageId) next.boundRepeatablePageId = repeatablePageId;
|
|
2192
|
+
else delete next.boundRepeatablePageId;
|
|
2193
|
+
return next;
|
|
2194
|
+
});
|
|
2195
|
+
const nextCanvas = { ...state.canvas, pages: updatedPages };
|
|
2196
|
+
const committed = commitFromState(state, nextCanvas);
|
|
2197
|
+
return { canvas: nextCanvas, ...committed };
|
|
2198
|
+
}),
|
|
2187
2199
|
moveElementsToPage: (elementIds, targetPageId) => set((state) => {
|
|
2188
2200
|
const currentPage = getCurrentPageFromCanvas(state.canvas);
|
|
2189
2201
|
const nodesToMove = [];
|
|
@@ -2328,7 +2340,8 @@ const useEditorStore = create((set, get) => ({
|
|
|
2328
2340
|
id: p.id,
|
|
2329
2341
|
name: p.name,
|
|
2330
2342
|
children,
|
|
2331
|
-
settings: { backgroundColor: "#ffffff", ...p.settings }
|
|
2343
|
+
settings: { backgroundColor: "#ffffff", ...p.settings },
|
|
2344
|
+
...p.boundRepeatablePageId ? { boundRepeatablePageId: p.boundRepeatablePageId } : {}
|
|
2332
2345
|
};
|
|
2333
2346
|
});
|
|
2334
2347
|
pagesWithPositions = pagesWithPositions.map((p) => {
|
|
@@ -8766,13 +8779,14 @@ function formDefSectionsToInferred(schemaSections, repeatableNodeMap) {
|
|
|
8766
8779
|
const labelPrefix = rawPrefix.startsWith("field_") ? rawPrefix : `field_${rawPrefix}`;
|
|
8767
8780
|
const treeNodeId = repeatableNodeMap == null ? void 0 : repeatableNodeMap.get(def.label.trim().toLowerCase());
|
|
8768
8781
|
const prefix = treeNodeId ? `field_${treeNodeId}` : labelPrefix;
|
|
8782
|
+
const minEntries = def.minEntries != null ? Math.max(0, def.minEntries) : 1;
|
|
8769
8783
|
const section = {
|
|
8770
8784
|
id: def.id,
|
|
8771
8785
|
label: def.label,
|
|
8772
8786
|
order: def.order ?? 0,
|
|
8773
8787
|
type: "repeatable",
|
|
8774
8788
|
templateKeyPrefix: prefix,
|
|
8775
|
-
minEntries
|
|
8789
|
+
minEntries,
|
|
8776
8790
|
maxEntries: def.maxEntries,
|
|
8777
8791
|
entryFields: def.fields.map((f, i) => ({
|
|
8778
8792
|
key: f.key,
|
|
@@ -8782,7 +8796,8 @@ function formDefSectionsToInferred(schemaSections, repeatableNodeMap) {
|
|
|
8782
8796
|
templateKey: f.key,
|
|
8783
8797
|
placeholder: f.placeholder
|
|
8784
8798
|
})),
|
|
8785
|
-
|
|
8799
|
+
// Honor minEntries: 0 — start with no entries, user adds via "+ Add" button.
|
|
8800
|
+
initialEntryCount: minEntries,
|
|
8786
8801
|
parentId
|
|
8787
8802
|
};
|
|
8788
8803
|
if (treeNodeId) section.treeNodeId = treeNodeId;
|
|
@@ -9338,11 +9353,11 @@ function idPrefix(node) {
|
|
|
9338
9353
|
if (t === "shape") return "shape";
|
|
9339
9354
|
return "el";
|
|
9340
9355
|
}
|
|
9341
|
-
function cloneNodeWithNewIds$1(node) {
|
|
9356
|
+
function cloneNodeWithNewIds$1(node, cloneSuffix) {
|
|
9342
9357
|
const oldToNew = /* @__PURE__ */ new Map();
|
|
9343
9358
|
function clone(n) {
|
|
9344
9359
|
var _a;
|
|
9345
|
-
const newId = generateId(idPrefix(n));
|
|
9360
|
+
const newId = cloneSuffix ? `${baseId(n.id)}__c${cloneSuffix}` : generateId(idPrefix(n));
|
|
9346
9361
|
oldToNew.set(n.id, newId);
|
|
9347
9362
|
const base = baseId(n.id);
|
|
9348
9363
|
const withMeta = { ...n, id: newId, __baseNodeId: base, __sourceId: n.id };
|
|
@@ -9508,12 +9523,12 @@ function getNestedRepeatableEntryCount(parentId, parentIndex, childId, formValue
|
|
|
9508
9523
|
}
|
|
9509
9524
|
return Math.max(1, maxIndex);
|
|
9510
9525
|
}
|
|
9511
|
-
function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsFromSchema, repeatableEntryCounts, repeatableNestedEntryCounts, displayFormatMap) {
|
|
9526
|
+
function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsFromSchema, repeatableEntryCounts, repeatableNestedEntryCounts, displayFormatMap, repeatablePagesFromSchema) {
|
|
9512
9527
|
var _a, _b, _c, _d, _e;
|
|
9513
9528
|
const cloned = JSON.parse(JSON.stringify(config));
|
|
9514
9529
|
if (!cloned.pages) return cloned;
|
|
9515
9530
|
const dynamicFields = cloned.dynamicFields;
|
|
9516
|
-
|
|
9531
|
+
let pages = cloned.pages;
|
|
9517
9532
|
const repeatableList = (repeatableSectionsFromSchema == null ? void 0 : repeatableSectionsFromSchema.length) ? repeatableSectionsFromSchema : getRepeatableFromConfig(pages);
|
|
9518
9533
|
const nodeIds = repeatableList.map((r) => r.nodeId);
|
|
9519
9534
|
const entryCountFromList = (baseNodeId) => {
|
|
@@ -9556,7 +9571,7 @@ function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsF
|
|
|
9556
9571
|
const N = Math.max(1, countFromState ?? getRepeatableEntryCount(baseNodeId, formValues));
|
|
9557
9572
|
const clones = [];
|
|
9558
9573
|
for (let i = 1; i <= N; i++) {
|
|
9559
|
-
const [clone, oldToNew] = cloneNodeWithNewIds$1(node);
|
|
9574
|
+
const [clone, oldToNew] = cloneNodeWithNewIds$1(node, `${baseNodeId}_e${i}`);
|
|
9560
9575
|
delete clone.repeatableSection;
|
|
9561
9576
|
clones.push(clone);
|
|
9562
9577
|
const newToOriginal = /* @__PURE__ */ new Map();
|
|
@@ -9592,7 +9607,7 @@ function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsF
|
|
|
9592
9607
|
const phase1Map = phase1NewToOriginal.get(`${parentBaseNodeId}_${parentIndex1Based}`);
|
|
9593
9608
|
const clones = [];
|
|
9594
9609
|
for (let i = 1; i <= N; i++) {
|
|
9595
|
-
const [clone, oldToNew] = cloneNodeWithNewIds$1(node);
|
|
9610
|
+
const [clone, oldToNew] = cloneNodeWithNewIds$1(node, `${parentBaseNodeId}_p${parentIndex1Based}_${baseNodeId}_e${i}`);
|
|
9596
9611
|
delete clone.repeatableSection;
|
|
9597
9612
|
clones.push(clone);
|
|
9598
9613
|
for (const [oldId, newId] of oldToNew) {
|
|
@@ -9806,9 +9821,20 @@ function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsF
|
|
|
9806
9821
|
}
|
|
9807
9822
|
}
|
|
9808
9823
|
}
|
|
9824
|
+
const repeatablePagePrefixSet = new Set(
|
|
9825
|
+
[].map((p) => `field_${p.templateKeyPrefix}_`)
|
|
9826
|
+
);
|
|
9809
9827
|
if (dynamicFields == null ? void 0 : dynamicFields.length) {
|
|
9810
9828
|
for (const key of Object.keys(formValues)) {
|
|
9811
9829
|
if (NESTED_REPEATABLE_KEY_REGEX.test(key)) continue;
|
|
9830
|
+
let isPageKey = false;
|
|
9831
|
+
for (const pfx of repeatablePagePrefixSet) {
|
|
9832
|
+
if (key.startsWith(pfx)) {
|
|
9833
|
+
isPageKey = true;
|
|
9834
|
+
break;
|
|
9835
|
+
}
|
|
9836
|
+
}
|
|
9837
|
+
if (isPageKey) continue;
|
|
9812
9838
|
const match = key.match(REPEATABLE_KEY_REGEX);
|
|
9813
9839
|
if (!match) continue;
|
|
9814
9840
|
const [, nodeId, indexStr, fieldId] = match;
|
|
@@ -10715,6 +10741,7 @@ function PixldocsPreview(props) {
|
|
|
10715
10741
|
const [resolvedConfig, setResolvedConfig] = useState(null);
|
|
10716
10742
|
const [isLoading, setIsLoading] = useState(false);
|
|
10717
10743
|
const [fontsReady, setFontsReady] = useState(false);
|
|
10744
|
+
const [fontsReadyVersion, setFontsReadyVersion] = useState(0);
|
|
10718
10745
|
const isResolveMode = !("config" in props && props.config);
|
|
10719
10746
|
useEffect(() => {
|
|
10720
10747
|
if (!isResolveMode) {
|
|
@@ -10725,6 +10752,7 @@ function PixldocsPreview(props) {
|
|
|
10725
10752
|
if (!p.templateId || !p.formSchemaId || !p.supabaseUrl || !p.supabaseAnonKey) return;
|
|
10726
10753
|
let cancelled = false;
|
|
10727
10754
|
setIsLoading(true);
|
|
10755
|
+
setFontsReady(false);
|
|
10728
10756
|
resolveFromForm({
|
|
10729
10757
|
templateId: p.templateId,
|
|
10730
10758
|
formSchemaId: p.formSchemaId,
|
|
@@ -10766,7 +10794,28 @@ function PixldocsPreview(props) {
|
|
|
10766
10794
|
]);
|
|
10767
10795
|
const config = isResolveMode ? resolvedConfig : props.config;
|
|
10768
10796
|
useEffect(() => {
|
|
10769
|
-
|
|
10797
|
+
var _a, _b;
|
|
10798
|
+
if (!config) return;
|
|
10799
|
+
let cancelled = false;
|
|
10800
|
+
const bump = () => {
|
|
10801
|
+
if (cancelled) return;
|
|
10802
|
+
clearMeasurementCache();
|
|
10803
|
+
setFontsReadyVersion((v) => v + 1);
|
|
10804
|
+
};
|
|
10805
|
+
(_b = (_a = document.fonts) == null ? void 0 : _a.ready) == null ? void 0 : _b.then(bump);
|
|
10806
|
+
const timeoutId = window.setTimeout(bump, 350);
|
|
10807
|
+
return () => {
|
|
10808
|
+
cancelled = true;
|
|
10809
|
+
window.clearTimeout(timeoutId);
|
|
10810
|
+
};
|
|
10811
|
+
}, [config]);
|
|
10812
|
+
const previewKey = useMemo(() => `${pageIndex}-${fontsReadyVersion}`, [pageIndex, fontsReadyVersion]);
|
|
10813
|
+
useEffect(() => {
|
|
10814
|
+
if (isResolveMode) return;
|
|
10815
|
+
if (!config) {
|
|
10816
|
+
setFontsReady(false);
|
|
10817
|
+
return;
|
|
10818
|
+
}
|
|
10770
10819
|
setFontsReady(false);
|
|
10771
10820
|
ensureFontsForResolvedConfig(config).then(() => setFontsReady(true)).catch(() => setFontsReady(true));
|
|
10772
10821
|
}, [isResolveMode, config]);
|
|
@@ -10774,6 +10823,9 @@ function PixldocsPreview(props) {
|
|
|
10774
10823
|
return /* @__PURE__ */ jsx("div", { className, style: { ...style, display: "flex", alignItems: "center", justifyContent: "center", minHeight: 200 }, children: /* @__PURE__ */ jsx("div", { style: { color: "#888", fontSize: 14 }, children: "Loading preview..." }) });
|
|
10775
10824
|
}
|
|
10776
10825
|
if (!config) return null;
|
|
10826
|
+
if (!fontsReady) {
|
|
10827
|
+
return /* @__PURE__ */ jsx("div", { className, style: { ...style, display: "flex", alignItems: "center", justifyContent: "center", minHeight: 200 }, children: /* @__PURE__ */ jsx("div", { style: { color: "#888", fontSize: 14 }, children: "Loading preview..." }) });
|
|
10828
|
+
}
|
|
10777
10829
|
return /* @__PURE__ */ jsx("div", { className, style, children: /* @__PURE__ */ jsx(
|
|
10778
10830
|
PreviewCanvas,
|
|
10779
10831
|
{
|
|
@@ -10783,7 +10835,8 @@ function PixldocsPreview(props) {
|
|
|
10783
10835
|
absoluteZoom,
|
|
10784
10836
|
onDynamicFieldClick,
|
|
10785
10837
|
onReady
|
|
10786
|
-
}
|
|
10838
|
+
},
|
|
10839
|
+
previewKey
|
|
10787
10840
|
) });
|
|
10788
10841
|
}
|
|
10789
10842
|
class PixldocsRenderer {
|