@pixldocs/canvas-renderer 0.5.179 → 0.5.180
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/README.md +42 -0
- package/dist/{index-BBOaToIA.cjs → index-B9NOXCTL.cjs} +148 -10
- package/dist/index-B9NOXCTL.cjs.map +1 -0
- package/dist/{index-C3W71an-.js → index-DdrxSxRr.js} +148 -10
- package/dist/index-DdrxSxRr.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/{vectorPdfExport-Be8MJ_2c.cjs → vectorPdfExport-B8qiTpn8.cjs} +4 -4
- package/dist/{vectorPdfExport-Be8MJ_2c.cjs.map → vectorPdfExport-B8qiTpn8.cjs.map} +1 -1
- package/dist/{vectorPdfExport-FmQQMHmX.js → vectorPdfExport-DCZJhOmn.js} +4 -4
- package/dist/{vectorPdfExport-FmQQMHmX.js.map → vectorPdfExport-DCZJhOmn.js.map} +1 -1
- package/package.json +1 -1
- package/dist/index-BBOaToIA.cjs.map +0 -1
- package/dist/index-C3W71an-.js.map +0 -1
package/README.md
CHANGED
|
@@ -206,6 +206,48 @@ const result = await renderer.renderPdf(templateConfig, { title: 'My Doc' });
|
|
|
206
206
|
|
|
207
207
|
## API Reference
|
|
208
208
|
|
|
209
|
+
### Form schema shape (V2 `sectionState`)
|
|
210
|
+
|
|
211
|
+
`sectionState` accepts entries for both **repeatable sections** and
|
|
212
|
+
**repeatable pages**. Both look the same on the wire — an array of entry
|
|
213
|
+
objects keyed by the section/page `id`:
|
|
214
|
+
|
|
215
|
+
```ts
|
|
216
|
+
sectionState = {
|
|
217
|
+
// single section
|
|
218
|
+
personal: { name: 'Jane' },
|
|
219
|
+
|
|
220
|
+
// repeatable section (e.g. Experience)
|
|
221
|
+
experience: [
|
|
222
|
+
{ title: 'Designer', company: 'Acme' },
|
|
223
|
+
{ title: 'Lead', company: 'Beta' },
|
|
224
|
+
],
|
|
225
|
+
|
|
226
|
+
// repeatable PAGE (e.g. Photo Page) — same shape as above, but at render
|
|
227
|
+
// time the bound template page is cloned once per entry.
|
|
228
|
+
photo_page: [
|
|
229
|
+
{ caption: 'Cover' },
|
|
230
|
+
{ caption: 'Back' },
|
|
231
|
+
],
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Fetch the schema from the Pixldocs form API to discover what keys/fields are
|
|
236
|
+
expected. The response exposes repeatable pages as a dedicated
|
|
237
|
+
`schema.repeatablePages[]` array (each entry mirrors a repeatable section:
|
|
238
|
+
`id`, `label`, `order`, `templateKeyPrefix`, `minEntries`, `maxEntries`,
|
|
239
|
+
`entryFields`).
|
|
240
|
+
|
|
241
|
+
```ts
|
|
242
|
+
const res = await fetch(
|
|
243
|
+
`${SUPABASE_URL}/functions/v1/form-api?form_schema_id=${SCHEMA_ID}&action=schema`,
|
|
244
|
+
{ headers: { apikey: SUPABASE_ANON_KEY } },
|
|
245
|
+
).then((r) => r.json());
|
|
246
|
+
|
|
247
|
+
res.schema.sections // single + repeatable sections
|
|
248
|
+
res.schema.repeatablePages // repeatable pages (clone-per-entry)
|
|
249
|
+
```
|
|
250
|
+
|
|
209
251
|
### `PixldocsPreview` (React Component)
|
|
210
252
|
|
|
211
253
|
| Prop | Type | Default | Description |
|
|
@@ -484,9 +484,19 @@ function resolveStackGroupEffectivePositions(group, pageChildren, options) {
|
|
|
484
484
|
const gap = group.stackSpacing ?? 8;
|
|
485
485
|
const padTop = group.paddingTop ?? 0;
|
|
486
486
|
const padLeft = group.paddingLeft ?? 0;
|
|
487
|
+
const padRight = group.paddingRight ?? 0;
|
|
488
|
+
const padBottom = group.paddingBottom ?? 0;
|
|
489
|
+
const justify = group.justifyContent ?? "start";
|
|
490
|
+
const align = group.alignItems ?? "start";
|
|
491
|
+
const isVertical = isVerticalStackLayoutMode(mode);
|
|
487
492
|
const kids = group.children ?? [];
|
|
488
493
|
const out = /* @__PURE__ */ new Map();
|
|
489
|
-
|
|
494
|
+
const sizes = /* @__PURE__ */ new Map();
|
|
495
|
+
for (const c of kids) {
|
|
496
|
+
const b = getNodeBounds(c, pageChildren);
|
|
497
|
+
sizes.set(c.id, { width: b.width, height: b.height });
|
|
498
|
+
}
|
|
499
|
+
if (isVertical) {
|
|
490
500
|
let prevBottom = padTop;
|
|
491
501
|
let firstSeen = false;
|
|
492
502
|
for (let i = 0; i < kids.length; i++) {
|
|
@@ -498,7 +508,7 @@ function resolveStackGroupEffectivePositions(group, pageChildren, options) {
|
|
|
498
508
|
const effectiveTop = !firstSeen ? padTop + storedTop + mTop : prevBottom + gap + storedTop + mTop;
|
|
499
509
|
firstSeen = true;
|
|
500
510
|
out.set(child.id, { top: effectiveTop, left: padLeft + storedLeft + mLeft });
|
|
501
|
-
const h =
|
|
511
|
+
const h = sizes.get(child.id).height;
|
|
502
512
|
prevBottom = effectiveTop + h + (child.marginBottom ?? 0);
|
|
503
513
|
}
|
|
504
514
|
} else {
|
|
@@ -513,10 +523,99 @@ function resolveStackGroupEffectivePositions(group, pageChildren, options) {
|
|
|
513
523
|
const effectiveLeft = !firstSeen ? padLeft + storedLeft + mLeft : prevRight + gap + storedLeft + mLeft;
|
|
514
524
|
firstSeen = true;
|
|
515
525
|
out.set(child.id, { top: padTop + storedTop + mTop, left: effectiveLeft });
|
|
516
|
-
const w =
|
|
526
|
+
const w = sizes.get(child.id).width;
|
|
517
527
|
prevRight = effectiveLeft + w + (child.marginRight ?? 0);
|
|
518
528
|
}
|
|
519
529
|
}
|
|
530
|
+
const containerW = typeof group.width === "number" ? group.width : void 0;
|
|
531
|
+
const containerH = typeof group.height === "number" ? group.height : void 0;
|
|
532
|
+
const mainContainer = isVertical ? containerH : containerW;
|
|
533
|
+
const crossContainer = isVertical ? containerW : containerH;
|
|
534
|
+
if (align !== "start" && crossContainer != null && kids.length > 0) {
|
|
535
|
+
const crossPad0 = isVertical ? padLeft : padTop;
|
|
536
|
+
const crossPadEnd = isVertical ? padRight : padBottom;
|
|
537
|
+
const innerCross = Math.max(0, crossContainer - crossPad0 - crossPadEnd);
|
|
538
|
+
for (const child of kids) {
|
|
539
|
+
const pos = out.get(child.id);
|
|
540
|
+
if (!pos) continue;
|
|
541
|
+
const sz = sizes.get(child.id);
|
|
542
|
+
const childCross = isVertical ? sz.width : sz.height;
|
|
543
|
+
let crossPos;
|
|
544
|
+
if (align === "stretch") {
|
|
545
|
+
crossPos = crossPad0;
|
|
546
|
+
} else if (align === "center") {
|
|
547
|
+
crossPos = crossPad0 + (innerCross - childCross) / 2;
|
|
548
|
+
} else {
|
|
549
|
+
crossPos = crossPad0 + (innerCross - childCross);
|
|
550
|
+
}
|
|
551
|
+
if (isVertical) {
|
|
552
|
+
out.set(child.id, { top: pos.top, left: crossPos });
|
|
553
|
+
} else {
|
|
554
|
+
out.set(child.id, { top: crossPos, left: pos.left });
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
if (justify !== "start" && mainContainer != null && kids.length > 0) {
|
|
559
|
+
const mainPad0 = isVertical ? padTop : padLeft;
|
|
560
|
+
const mainPadEnd = isVertical ? padBottom : padRight;
|
|
561
|
+
const innerMain = Math.max(0, mainContainer - mainPad0 - mainPadEnd);
|
|
562
|
+
let totalMain = 0;
|
|
563
|
+
for (let i = 0; i < kids.length; i++) {
|
|
564
|
+
const child = kids[i];
|
|
565
|
+
const sz = sizes.get(child.id);
|
|
566
|
+
totalMain += isVertical ? sz.height : sz.width;
|
|
567
|
+
const marginStart = isVertical ? child.marginTop ?? 0 : child.marginLeft ?? 0;
|
|
568
|
+
const marginEnd = isVertical ? child.marginBottom ?? 0 : child.marginRight ?? 0;
|
|
569
|
+
totalMain += marginStart + marginEnd;
|
|
570
|
+
}
|
|
571
|
+
const baseGapTotal = gap * Math.max(0, kids.length - 1);
|
|
572
|
+
const free = innerMain - totalMain - baseGapTotal;
|
|
573
|
+
let offset = 0;
|
|
574
|
+
let extraGap = 0;
|
|
575
|
+
if (free > 0) {
|
|
576
|
+
switch (justify) {
|
|
577
|
+
case "center":
|
|
578
|
+
offset = free / 2;
|
|
579
|
+
break;
|
|
580
|
+
case "end":
|
|
581
|
+
offset = free;
|
|
582
|
+
break;
|
|
583
|
+
case "space-between":
|
|
584
|
+
if (kids.length > 1) extraGap = free / (kids.length - 1);
|
|
585
|
+
else offset = free / 2;
|
|
586
|
+
break;
|
|
587
|
+
case "space-around":
|
|
588
|
+
if (kids.length > 0) {
|
|
589
|
+
extraGap = free / kids.length;
|
|
590
|
+
offset = extraGap / 2;
|
|
591
|
+
}
|
|
592
|
+
break;
|
|
593
|
+
case "space-evenly":
|
|
594
|
+
extraGap = free / (kids.length + 1);
|
|
595
|
+
offset = extraGap;
|
|
596
|
+
break;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
if (offset !== 0 || extraGap !== 0) {
|
|
600
|
+
let cursor = mainPad0 + offset;
|
|
601
|
+
for (let i = 0; i < kids.length; i++) {
|
|
602
|
+
const child = kids[i];
|
|
603
|
+
const sz = sizes.get(child.id);
|
|
604
|
+
const marginStart = isVertical ? child.marginTop ?? 0 : child.marginLeft ?? 0;
|
|
605
|
+
const marginEnd = isVertical ? child.marginBottom ?? 0 : child.marginRight ?? 0;
|
|
606
|
+
const main = isVertical ? sz.height : sz.width;
|
|
607
|
+
const pos = out.get(child.id);
|
|
608
|
+
if (!pos) continue;
|
|
609
|
+
const startMain = cursor + marginStart;
|
|
610
|
+
if (isVertical) {
|
|
611
|
+
out.set(child.id, { top: startMain, left: pos.left });
|
|
612
|
+
} else {
|
|
613
|
+
out.set(child.id, { top: pos.top, left: startMain });
|
|
614
|
+
}
|
|
615
|
+
cursor = startMain + main + marginEnd + gap + extraGap;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
}
|
|
520
619
|
return out;
|
|
521
620
|
}
|
|
522
621
|
function groupBoundsFromChildren(group, pageChildren, options) {
|
|
@@ -7617,7 +7716,28 @@ const PageCanvas = react.forwardRef(
|
|
|
7617
7716
|
const element = id ? elementById.get(id) : void 0;
|
|
7618
7717
|
if (!element) return;
|
|
7619
7718
|
if (element.overflowPolicy === "auto-shrink") {
|
|
7719
|
+
try {
|
|
7720
|
+
const measured = createText(element);
|
|
7721
|
+
const newFontSize = measured.fontSize;
|
|
7722
|
+
const newWidth = measured.width;
|
|
7723
|
+
const currentFontSize = obj.fontSize;
|
|
7724
|
+
if (typeof newFontSize === "number" && newFontSize > 0 && newFontSize !== currentFontSize) {
|
|
7725
|
+
obj.set({ fontSize: newFontSize });
|
|
7726
|
+
if (typeof newWidth === "number" && newWidth > 0) {
|
|
7727
|
+
obj.width = newWidth;
|
|
7728
|
+
}
|
|
7729
|
+
obj.initDimensions();
|
|
7730
|
+
obj.setCoords();
|
|
7731
|
+
didReflow = true;
|
|
7732
|
+
}
|
|
7733
|
+
} catch {
|
|
7734
|
+
}
|
|
7620
7735
|
obj.dirty = true;
|
|
7736
|
+
try {
|
|
7737
|
+
obj._forceClearCache = true;
|
|
7738
|
+
if (typeof obj._clearCache === "function") obj._clearCache();
|
|
7739
|
+
} catch {
|
|
7740
|
+
}
|
|
7621
7741
|
return;
|
|
7622
7742
|
}
|
|
7623
7743
|
const targetWidth = Math.max(1, Number(element.width) > 0 ? Number(element.width) : Number(obj.width ?? 200));
|
|
@@ -9230,9 +9350,26 @@ const PageCanvas = react.forwardRef(
|
|
|
9230
9350
|
const needsCropGroupFadeUpdate = isCropGroup2 && fadeKeyChanged;
|
|
9231
9351
|
const hadUrlBefore = storedImageUrl && String(storedImageUrl).trim() !== "";
|
|
9232
9352
|
if (!hasUrl && hadUrlBefore) {
|
|
9233
|
-
const
|
|
9353
|
+
const resolvedSizeImg = (pageChildren == null ? void 0 : pageChildren.length) ? getNodeBounds(element, pageChildren) : { width: typeof element.width === "number" ? element.width : 200, height: typeof element.height === "number" ? element.height : 50 };
|
|
9354
|
+
const hasExplicitSize = typeof element.width === "number" && Number.isFinite(element.width) && element.width > 0 && typeof element.height === "number" && Number.isFinite(element.height) && element.height > 0;
|
|
9355
|
+
const minVisiblePlaceholder = hasExplicitSize ? 1 : 20;
|
|
9356
|
+
const nextWidth = Math.max(minVisiblePlaceholder, Number(resolvedSizeImg.width) || 200);
|
|
9357
|
+
const nextHeight = Math.max(minVisiblePlaceholder, Number(resolvedSizeImg.height) || 50);
|
|
9358
|
+
const storePosImg = pageChildren ? (() => {
|
|
9359
|
+
const node = findNodeById(pageChildren, element.id);
|
|
9360
|
+
return node ? getAbsoluteBounds(node, pageChildren) : { left: element.left ?? 0, top: element.top ?? 0 };
|
|
9361
|
+
})() : { left: element.left ?? 0, top: element.top ?? 0 };
|
|
9362
|
+
const elementForPlaceholder = { ...element, width: nextWidth, height: nextHeight };
|
|
9363
|
+
const placeholder = isCropGroup2 ? createImagePlaceholderForGroup(elementForPlaceholder) : createImagePlaceholder(elementForPlaceholder);
|
|
9234
9364
|
setObjectData(placeholder, element.id);
|
|
9235
9365
|
placeholder.__imageSrc = "";
|
|
9366
|
+
placeholder.set({
|
|
9367
|
+
left: storePosImg.left + nextWidth / 2,
|
|
9368
|
+
top: storePosImg.top + nextHeight / 2,
|
|
9369
|
+
originX: "center",
|
|
9370
|
+
originY: "center"
|
|
9371
|
+
});
|
|
9372
|
+
placeholder.setCoords();
|
|
9236
9373
|
const idx = fc.getObjects().indexOf(existingObj);
|
|
9237
9374
|
fc.remove(existingObj);
|
|
9238
9375
|
if (idx >= 0) {
|
|
@@ -11756,7 +11893,8 @@ function formDefSectionsToInferred(schemaSections, repeatableNodeMap) {
|
|
|
11756
11893
|
// Honor minEntries: 0 — start with no entries, user adds via "+ Add" button.
|
|
11757
11894
|
initialEntryCount: minEntries,
|
|
11758
11895
|
parentId,
|
|
11759
|
-
entryNameFieldKey: def.entryNameFieldKey
|
|
11896
|
+
entryNameFieldKey: def.entryNameFieldKey,
|
|
11897
|
+
isRepeatablePage: def.isRepeatablePage
|
|
11760
11898
|
};
|
|
11761
11899
|
if (treeNodeId) section.treeNodeId = treeNodeId;
|
|
11762
11900
|
sections.push(section);
|
|
@@ -16360,9 +16498,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
|
|
|
16360
16498
|
}
|
|
16361
16499
|
return svgString;
|
|
16362
16500
|
}
|
|
16363
|
-
const resolvedPackageVersion = "0.5.
|
|
16501
|
+
const resolvedPackageVersion = "0.5.180";
|
|
16364
16502
|
const PACKAGE_VERSION = resolvedPackageVersion;
|
|
16365
|
-
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.
|
|
16503
|
+
const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.180";
|
|
16366
16504
|
const roundParityValue = (value) => {
|
|
16367
16505
|
if (typeof value !== "number") return value;
|
|
16368
16506
|
return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
|
|
@@ -16864,7 +17002,7 @@ class PixldocsRenderer {
|
|
|
16864
17002
|
await this.waitForCanvasScene(container, cloned, i);
|
|
16865
17003
|
}
|
|
16866
17004
|
console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
|
|
16867
|
-
const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-
|
|
17005
|
+
const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-B8qiTpn8.cjs"));
|
|
16868
17006
|
const prepared = preparePagesForExport(
|
|
16869
17007
|
cloned.pages,
|
|
16870
17008
|
canvasWidth,
|
|
@@ -19009,7 +19147,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
|
|
|
19009
19147
|
if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
|
|
19010
19148
|
sanitizeSvgTreeForPdf(svgToDraw);
|
|
19011
19149
|
try {
|
|
19012
|
-
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-
|
|
19150
|
+
const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-B8qiTpn8.cjs"));
|
|
19013
19151
|
try {
|
|
19014
19152
|
await logTextMeasurementDiagnostic(svgToDraw);
|
|
19015
19153
|
} catch {
|
|
@@ -19402,4 +19540,4 @@ exports.setAutoShrinkDebug = setAutoShrinkDebug;
|
|
|
19402
19540
|
exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
|
|
19403
19541
|
exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
|
|
19404
19542
|
exports.warmTemplateFromForm = warmTemplateFromForm;
|
|
19405
|
-
//# sourceMappingURL=index-
|
|
19543
|
+
//# sourceMappingURL=index-B9NOXCTL.cjs.map
|