@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.cjs
CHANGED
|
@@ -2203,6 +2203,18 @@ const useEditorStore = zustand.create((set, get) => ({
|
|
|
2203
2203
|
const committed = commitFromState(state, nextCanvas);
|
|
2204
2204
|
return { canvas: nextCanvas, ...committed };
|
|
2205
2205
|
}),
|
|
2206
|
+
setPageBoundRepeatablePage: (pageId, repeatablePageId) => set((state) => {
|
|
2207
|
+
const updatedPages = state.canvas.pages.map((p) => {
|
|
2208
|
+
if (p.id !== pageId) return p;
|
|
2209
|
+
const next = { ...p };
|
|
2210
|
+
if (repeatablePageId) next.boundRepeatablePageId = repeatablePageId;
|
|
2211
|
+
else delete next.boundRepeatablePageId;
|
|
2212
|
+
return next;
|
|
2213
|
+
});
|
|
2214
|
+
const nextCanvas = { ...state.canvas, pages: updatedPages };
|
|
2215
|
+
const committed = commitFromState(state, nextCanvas);
|
|
2216
|
+
return { canvas: nextCanvas, ...committed };
|
|
2217
|
+
}),
|
|
2206
2218
|
moveElementsToPage: (elementIds, targetPageId) => set((state) => {
|
|
2207
2219
|
const currentPage = getCurrentPageFromCanvas(state.canvas);
|
|
2208
2220
|
const nodesToMove = [];
|
|
@@ -2347,7 +2359,8 @@ const useEditorStore = zustand.create((set, get) => ({
|
|
|
2347
2359
|
id: p.id,
|
|
2348
2360
|
name: p.name,
|
|
2349
2361
|
children,
|
|
2350
|
-
settings: { backgroundColor: "#ffffff", ...p.settings }
|
|
2362
|
+
settings: { backgroundColor: "#ffffff", ...p.settings },
|
|
2363
|
+
...p.boundRepeatablePageId ? { boundRepeatablePageId: p.boundRepeatablePageId } : {}
|
|
2351
2364
|
};
|
|
2352
2365
|
});
|
|
2353
2366
|
pagesWithPositions = pagesWithPositions.map((p) => {
|
|
@@ -8785,13 +8798,14 @@ function formDefSectionsToInferred(schemaSections, repeatableNodeMap) {
|
|
|
8785
8798
|
const labelPrefix = rawPrefix.startsWith("field_") ? rawPrefix : `field_${rawPrefix}`;
|
|
8786
8799
|
const treeNodeId = repeatableNodeMap == null ? void 0 : repeatableNodeMap.get(def.label.trim().toLowerCase());
|
|
8787
8800
|
const prefix = treeNodeId ? `field_${treeNodeId}` : labelPrefix;
|
|
8801
|
+
const minEntries = def.minEntries != null ? Math.max(0, def.minEntries) : 1;
|
|
8788
8802
|
const section = {
|
|
8789
8803
|
id: def.id,
|
|
8790
8804
|
label: def.label,
|
|
8791
8805
|
order: def.order ?? 0,
|
|
8792
8806
|
type: "repeatable",
|
|
8793
8807
|
templateKeyPrefix: prefix,
|
|
8794
|
-
minEntries
|
|
8808
|
+
minEntries,
|
|
8795
8809
|
maxEntries: def.maxEntries,
|
|
8796
8810
|
entryFields: def.fields.map((f, i) => ({
|
|
8797
8811
|
key: f.key,
|
|
@@ -8801,7 +8815,8 @@ function formDefSectionsToInferred(schemaSections, repeatableNodeMap) {
|
|
|
8801
8815
|
templateKey: f.key,
|
|
8802
8816
|
placeholder: f.placeholder
|
|
8803
8817
|
})),
|
|
8804
|
-
|
|
8818
|
+
// Honor minEntries: 0 — start with no entries, user adds via "+ Add" button.
|
|
8819
|
+
initialEntryCount: minEntries,
|
|
8805
8820
|
parentId
|
|
8806
8821
|
};
|
|
8807
8822
|
if (treeNodeId) section.treeNodeId = treeNodeId;
|
|
@@ -9357,11 +9372,11 @@ function idPrefix(node) {
|
|
|
9357
9372
|
if (t === "shape") return "shape";
|
|
9358
9373
|
return "el";
|
|
9359
9374
|
}
|
|
9360
|
-
function cloneNodeWithNewIds$1(node) {
|
|
9375
|
+
function cloneNodeWithNewIds$1(node, cloneSuffix) {
|
|
9361
9376
|
const oldToNew = /* @__PURE__ */ new Map();
|
|
9362
9377
|
function clone(n) {
|
|
9363
9378
|
var _a;
|
|
9364
|
-
const newId = generateId(idPrefix(n));
|
|
9379
|
+
const newId = cloneSuffix ? `${baseId(n.id)}__c${cloneSuffix}` : generateId(idPrefix(n));
|
|
9365
9380
|
oldToNew.set(n.id, newId);
|
|
9366
9381
|
const base = baseId(n.id);
|
|
9367
9382
|
const withMeta = { ...n, id: newId, __baseNodeId: base, __sourceId: n.id };
|
|
@@ -9527,12 +9542,12 @@ function getNestedRepeatableEntryCount(parentId, parentIndex, childId, formValue
|
|
|
9527
9542
|
}
|
|
9528
9543
|
return Math.max(1, maxIndex);
|
|
9529
9544
|
}
|
|
9530
|
-
function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsFromSchema, repeatableEntryCounts, repeatableNestedEntryCounts, displayFormatMap) {
|
|
9545
|
+
function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsFromSchema, repeatableEntryCounts, repeatableNestedEntryCounts, displayFormatMap, repeatablePagesFromSchema) {
|
|
9531
9546
|
var _a, _b, _c, _d, _e;
|
|
9532
9547
|
const cloned = JSON.parse(JSON.stringify(config));
|
|
9533
9548
|
if (!cloned.pages) return cloned;
|
|
9534
9549
|
const dynamicFields = cloned.dynamicFields;
|
|
9535
|
-
|
|
9550
|
+
let pages = cloned.pages;
|
|
9536
9551
|
const repeatableList = (repeatableSectionsFromSchema == null ? void 0 : repeatableSectionsFromSchema.length) ? repeatableSectionsFromSchema : getRepeatableFromConfig(pages);
|
|
9537
9552
|
const nodeIds = repeatableList.map((r) => r.nodeId);
|
|
9538
9553
|
const entryCountFromList = (baseNodeId) => {
|
|
@@ -9575,7 +9590,7 @@ function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsF
|
|
|
9575
9590
|
const N = Math.max(1, countFromState ?? getRepeatableEntryCount(baseNodeId, formValues));
|
|
9576
9591
|
const clones = [];
|
|
9577
9592
|
for (let i = 1; i <= N; i++) {
|
|
9578
|
-
const [clone, oldToNew] = cloneNodeWithNewIds$1(node);
|
|
9593
|
+
const [clone, oldToNew] = cloneNodeWithNewIds$1(node, `${baseNodeId}_e${i}`);
|
|
9579
9594
|
delete clone.repeatableSection;
|
|
9580
9595
|
clones.push(clone);
|
|
9581
9596
|
const newToOriginal = /* @__PURE__ */ new Map();
|
|
@@ -9611,7 +9626,7 @@ function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsF
|
|
|
9611
9626
|
const phase1Map = phase1NewToOriginal.get(`${parentBaseNodeId}_${parentIndex1Based}`);
|
|
9612
9627
|
const clones = [];
|
|
9613
9628
|
for (let i = 1; i <= N; i++) {
|
|
9614
|
-
const [clone, oldToNew] = cloneNodeWithNewIds$1(node);
|
|
9629
|
+
const [clone, oldToNew] = cloneNodeWithNewIds$1(node, `${parentBaseNodeId}_p${parentIndex1Based}_${baseNodeId}_e${i}`);
|
|
9615
9630
|
delete clone.repeatableSection;
|
|
9616
9631
|
clones.push(clone);
|
|
9617
9632
|
for (const [oldId, newId] of oldToNew) {
|
|
@@ -9825,9 +9840,20 @@ function applyFormDataToConfig(config, mappings, formValues, repeatableSectionsF
|
|
|
9825
9840
|
}
|
|
9826
9841
|
}
|
|
9827
9842
|
}
|
|
9843
|
+
const repeatablePagePrefixSet = new Set(
|
|
9844
|
+
[].map((p) => `field_${p.templateKeyPrefix}_`)
|
|
9845
|
+
);
|
|
9828
9846
|
if (dynamicFields == null ? void 0 : dynamicFields.length) {
|
|
9829
9847
|
for (const key of Object.keys(formValues)) {
|
|
9830
9848
|
if (NESTED_REPEATABLE_KEY_REGEX.test(key)) continue;
|
|
9849
|
+
let isPageKey = false;
|
|
9850
|
+
for (const pfx of repeatablePagePrefixSet) {
|
|
9851
|
+
if (key.startsWith(pfx)) {
|
|
9852
|
+
isPageKey = true;
|
|
9853
|
+
break;
|
|
9854
|
+
}
|
|
9855
|
+
}
|
|
9856
|
+
if (isPageKey) continue;
|
|
9831
9857
|
const match = key.match(REPEATABLE_KEY_REGEX);
|
|
9832
9858
|
if (!match) continue;
|
|
9833
9859
|
const [, nodeId, indexStr, fieldId] = match;
|
|
@@ -10734,6 +10760,7 @@ function PixldocsPreview(props) {
|
|
|
10734
10760
|
const [resolvedConfig, setResolvedConfig] = react.useState(null);
|
|
10735
10761
|
const [isLoading, setIsLoading] = react.useState(false);
|
|
10736
10762
|
const [fontsReady, setFontsReady] = react.useState(false);
|
|
10763
|
+
const [fontsReadyVersion, setFontsReadyVersion] = react.useState(0);
|
|
10737
10764
|
const isResolveMode = !("config" in props && props.config);
|
|
10738
10765
|
react.useEffect(() => {
|
|
10739
10766
|
if (!isResolveMode) {
|
|
@@ -10744,6 +10771,7 @@ function PixldocsPreview(props) {
|
|
|
10744
10771
|
if (!p.templateId || !p.formSchemaId || !p.supabaseUrl || !p.supabaseAnonKey) return;
|
|
10745
10772
|
let cancelled = false;
|
|
10746
10773
|
setIsLoading(true);
|
|
10774
|
+
setFontsReady(false);
|
|
10747
10775
|
resolveFromForm({
|
|
10748
10776
|
templateId: p.templateId,
|
|
10749
10777
|
formSchemaId: p.formSchemaId,
|
|
@@ -10785,7 +10813,28 @@ function PixldocsPreview(props) {
|
|
|
10785
10813
|
]);
|
|
10786
10814
|
const config = isResolveMode ? resolvedConfig : props.config;
|
|
10787
10815
|
react.useEffect(() => {
|
|
10788
|
-
|
|
10816
|
+
var _a, _b;
|
|
10817
|
+
if (!config) return;
|
|
10818
|
+
let cancelled = false;
|
|
10819
|
+
const bump = () => {
|
|
10820
|
+
if (cancelled) return;
|
|
10821
|
+
clearMeasurementCache();
|
|
10822
|
+
setFontsReadyVersion((v) => v + 1);
|
|
10823
|
+
};
|
|
10824
|
+
(_b = (_a = document.fonts) == null ? void 0 : _a.ready) == null ? void 0 : _b.then(bump);
|
|
10825
|
+
const timeoutId = window.setTimeout(bump, 350);
|
|
10826
|
+
return () => {
|
|
10827
|
+
cancelled = true;
|
|
10828
|
+
window.clearTimeout(timeoutId);
|
|
10829
|
+
};
|
|
10830
|
+
}, [config]);
|
|
10831
|
+
const previewKey = react.useMemo(() => `${pageIndex}-${fontsReadyVersion}`, [pageIndex, fontsReadyVersion]);
|
|
10832
|
+
react.useEffect(() => {
|
|
10833
|
+
if (isResolveMode) return;
|
|
10834
|
+
if (!config) {
|
|
10835
|
+
setFontsReady(false);
|
|
10836
|
+
return;
|
|
10837
|
+
}
|
|
10789
10838
|
setFontsReady(false);
|
|
10790
10839
|
ensureFontsForResolvedConfig(config).then(() => setFontsReady(true)).catch(() => setFontsReady(true));
|
|
10791
10840
|
}, [isResolveMode, config]);
|
|
@@ -10793,6 +10842,9 @@ function PixldocsPreview(props) {
|
|
|
10793
10842
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { ...style, display: "flex", alignItems: "center", justifyContent: "center", minHeight: 200 }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "#888", fontSize: 14 }, children: "Loading preview..." }) });
|
|
10794
10843
|
}
|
|
10795
10844
|
if (!config) return null;
|
|
10845
|
+
if (!fontsReady) {
|
|
10846
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { ...style, display: "flex", alignItems: "center", justifyContent: "center", minHeight: 200 }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "#888", fontSize: 14 }, children: "Loading preview..." }) });
|
|
10847
|
+
}
|
|
10796
10848
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
10797
10849
|
PreviewCanvas,
|
|
10798
10850
|
{
|
|
@@ -10802,7 +10854,8 @@ function PixldocsPreview(props) {
|
|
|
10802
10854
|
absoluteZoom,
|
|
10803
10855
|
onDynamicFieldClick,
|
|
10804
10856
|
onReady
|
|
10805
|
-
}
|
|
10857
|
+
},
|
|
10858
|
+
previewKey
|
|
10806
10859
|
) });
|
|
10807
10860
|
}
|
|
10808
10861
|
class PixldocsRenderer {
|