@pixldocs/canvas-renderer 0.5.244 → 0.5.246

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.
@@ -11102,7 +11102,9 @@ const PageCanvas = forwardRef(
11102
11102
  const isSyncingSelectionToFabricRef = useRef(false);
11103
11103
  const suppressGroupMemberBordersRef = useRef([]);
11104
11104
  const editingTextIdRef = useRef(null);
11105
- const pendingTextEditOnUpRef = useRef(null);
11105
+ const selectAllTextOnEditingEnterRef = useRef(null);
11106
+ const suppressedTextEditObjectsRef = useRef([]);
11107
+ const suppressTextDoubleClickUntilRef = useRef(0);
11106
11108
  const syncLockedRef = useRef(false);
11107
11109
  const editLockRef = useRef(false);
11108
11110
  const editLockCountRef = useRef(0);
@@ -11120,6 +11122,8 @@ const PageCanvas = forwardRef(
11120
11122
  const [guides, setGuides] = useState([]);
11121
11123
  const [gridResizeLabel, setGridResizeLabel] = useState(null);
11122
11124
  const [hoverBounds, setHoverBounds] = useState(null);
11125
+ const [drilledGroupBounds, setDrilledGroupBounds] = useState(null);
11126
+ const drilledGroupIdRef = useRef(null);
11123
11127
  const [rotationLabel, setRotationLabel] = useState(null);
11124
11128
  const [sizeLabel, setSizeLabel] = useState(null);
11125
11129
  const [ready, setReady] = useState(false);
@@ -11809,6 +11813,44 @@ const PageCanvas = forwardRef(
11809
11813
  });
11810
11814
  fabricCanvas.hoverCursor = "default";
11811
11815
  fabricCanvas.moveCursor = "move";
11816
+ const suppressTextEditForClick = (textbox) => {
11817
+ if (!textbox) return;
11818
+ textbox.selected = false;
11819
+ textbox.__lastSelected = false;
11820
+ textbox.__corner = void 0;
11821
+ textbox.__pixldocsSuppressNextEdit = true;
11822
+ suppressTextDoubleClickUntilRef.current = Date.now() + 350;
11823
+ if (!suppressedTextEditObjectsRef.current.some((entry) => entry.textbox === textbox)) {
11824
+ suppressedTextEditObjectsRef.current.push({ textbox, editable: textbox.editable });
11825
+ }
11826
+ textbox.editable = false;
11827
+ };
11828
+ const restoreSuppressedTextEditObjects = () => {
11829
+ const entries = suppressedTextEditObjectsRef.current.splice(0);
11830
+ for (const { textbox, editable } of entries) {
11831
+ try {
11832
+ textbox.editable = editable;
11833
+ delete textbox.__pixldocsSuppressNextEdit;
11834
+ } catch {
11835
+ }
11836
+ }
11837
+ };
11838
+ const restoreSuppressedTextEditObjectsSoon = () => {
11839
+ requestAnimationFrame(() => {
11840
+ restoreSuppressedTextEditObjects();
11841
+ });
11842
+ };
11843
+ const selectAllActiveTextbox = (textbox) => {
11844
+ var _a2;
11845
+ try {
11846
+ textbox.selectAll();
11847
+ } catch {
11848
+ const len = ((_a2 = textbox.text) == null ? void 0 : _a2.length) ?? 0;
11849
+ textbox.selectionStart = 0;
11850
+ textbox.selectionEnd = len;
11851
+ }
11852
+ fabricCanvas.requestRenderAll();
11853
+ };
11812
11854
  if (!allowSelection) {
11813
11855
  fabricCanvas.selection = false;
11814
11856
  fabricCanvas.on("selection:created", () => {
@@ -11987,16 +12029,29 @@ const PageCanvas = forwardRef(
11987
12029
  }
11988
12030
  });
11989
12031
  fabricCanvas.on("object:scaling", () => {
12032
+ var _a2;
11990
12033
  fabricCanvas.__isUserTransforming = true;
12034
+ if (drilledGroupIdRef.current) {
12035
+ try {
12036
+ (_a2 = fabricCanvas.__updateDrilledGroupOutline) == null ? void 0 : _a2.call(fabricCanvas);
12037
+ } catch {
12038
+ }
12039
+ }
11991
12040
  });
11992
12041
  fabricCanvas.on("object:moving", () => {
11993
- var _a2;
12042
+ var _a2, _b2;
11994
12043
  fabricCanvas.__isUserTransforming = true;
11995
12044
  didTransformRef.current = true;
12045
+ if (drilledGroupIdRef.current) {
12046
+ try {
12047
+ (_a2 = fabricCanvas.__updateDrilledGroupOutline) == null ? void 0 : _a2.call(fabricCanvas);
12048
+ } catch {
12049
+ }
12050
+ }
11996
12051
  const active = fabricCanvas.getActiveObject();
11997
12052
  if (!active) return;
11998
12053
  const state = useEditorStore.getState();
11999
- const canvasPage = (_a2 = state.canvas.pages) == null ? void 0 : _a2.find((p) => p.id === pageId);
12054
+ const canvasPage = (_b2 = state.canvas.pages) == null ? void 0 : _b2.find((p) => p.id === pageId);
12000
12055
  const children = (canvasPage == null ? void 0 : canvasPage.children) ?? [];
12001
12056
  if (!canvasPage) return;
12002
12057
  const ids = state.canvas.selectedIds ?? [];
@@ -12027,8 +12082,15 @@ const PageCanvas = forwardRef(
12027
12082
  }
12028
12083
  });
12029
12084
  fabricCanvas.on("object:rotating", () => {
12085
+ var _a2;
12030
12086
  fabricCanvas.__isUserTransforming = true;
12031
12087
  didTransformRef.current = true;
12088
+ if (drilledGroupIdRef.current) {
12089
+ try {
12090
+ (_a2 = fabricCanvas.__updateDrilledGroupOutline) == null ? void 0 : _a2.call(fabricCanvas);
12091
+ } catch {
12092
+ }
12093
+ }
12032
12094
  });
12033
12095
  const syncSelectionToStore = () => {
12034
12096
  var _a2, _b2, _c, _d;
@@ -12239,7 +12301,7 @@ const PageCanvas = forwardRef(
12239
12301
  }
12240
12302
  });
12241
12303
  fabricCanvas.on("mouse:dblclick", (opt) => {
12242
- var _a2, _b2;
12304
+ var _a2, _b2, _c;
12243
12305
  const target = opt == null ? void 0 : opt.target;
12244
12306
  if (!target) return;
12245
12307
  if (target.isEditing) return;
@@ -12334,6 +12396,10 @@ const PageCanvas = forwardRef(
12334
12396
  }
12335
12397
  const selectedId = selectionIdx < 0 ? childId : chain[selectionIdx].id;
12336
12398
  selectElements([selectedId], false, false);
12399
+ try {
12400
+ (_c = fabricCanvas.__updateDrilledGroupOutline) == null ? void 0 : _c.call(fabricCanvas);
12401
+ } catch {
12402
+ }
12337
12403
  });
12338
12404
  fabricCanvas.on("selection:cleared", () => {
12339
12405
  if (!isActiveRef.current || isRebuildingRef.current || !allowSelection) return;
@@ -12341,6 +12407,8 @@ const PageCanvas = forwardRef(
12341
12407
  groupBoundsResizingRef.current = false;
12342
12408
  if (!preserveEditingScopeOnSelectionClearRef.current) {
12343
12409
  fabricCanvas.__activeEditingGroupId = null;
12410
+ setDrilledGroupBounds(null);
12411
+ drilledGroupIdRef.current = null;
12344
12412
  }
12345
12413
  const preservedGroupSelection = preserveActiveSelectionAfterTransformRef.current;
12346
12414
  const shouldRestoreGroupSelection = !!((preservedGroupSelection == null ? void 0 : preservedGroupSelection.groupSelectionId) && (!preservedGroupSelection.expiresAt || preservedGroupSelection.expiresAt > Date.now()));
@@ -12744,8 +12812,35 @@ const PageCanvas = forwardRef(
12744
12812
  }
12745
12813
  return pick;
12746
12814
  };
12815
+ const updateDrilledGroupOutline = () => {
12816
+ const gid = fabricCanvas.__activeEditingGroupId ?? null;
12817
+ drilledGroupIdRef.current = gid;
12818
+ if (!gid) {
12819
+ setDrilledGroupBounds(null);
12820
+ return;
12821
+ }
12822
+ const pageNow = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId);
12823
+ const node = pageNow ? findNodeById(pageNow.children ?? [], gid) : null;
12824
+ if (!node || !isGroup(node) || node.backgroundColor) {
12825
+ setDrilledGroupBounds(null);
12826
+ return;
12827
+ }
12828
+ const b = groupFabricUnionBBox(node);
12829
+ if (!b) {
12830
+ setDrilledGroupBounds(null);
12831
+ return;
12832
+ }
12833
+ setDrilledGroupBounds({
12834
+ left: b.left,
12835
+ top: b.top,
12836
+ width: b.right - b.left,
12837
+ height: b.bottom - b.top
12838
+ });
12839
+ };
12840
+ fabricCanvas.__updateDrilledGroupOutline = updateDrilledGroupOutline;
12747
12841
  fabricCanvas.on("mouse:down:before", (opt) => {
12748
12842
  var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
12843
+ const activeBeforeMouseDown = fabricCanvas.getActiveObject();
12749
12844
  if (editLockRef.current) {
12750
12845
  const active = fabricCanvas.getActiveObject();
12751
12846
  if (active && (((_a2 = active._ct) == null ? void 0 : _a2.isCropGroup) || active.__cropGroup)) {
@@ -12771,6 +12866,9 @@ const PageCanvas = forwardRef(
12771
12866
  targetId = childId;
12772
12867
  }
12773
12868
  }
12869
+ if (target instanceof fabric.Textbox && targetId && targetId !== "__background__" && activeBeforeMouseDown === target && !target.isEditing && !target.__corner && !isMultiSelectModifier(opt.e)) {
12870
+ selectAllTextOnEditingEnterRef.current = targetId;
12871
+ }
12774
12872
  const activeEditingGroupId = fabricCanvas.__activeEditingGroupId ?? null;
12775
12873
  const pageNow = useEditorStore.getState().canvas.pages.find((p) => p.id === pageId);
12776
12874
  const childrenNow = (pageNow == null ? void 0 : pageNow.children) ?? [];
@@ -12878,7 +12976,15 @@ const PageCanvas = forwardRef(
12878
12976
  opt.target = effectiveTarget;
12879
12977
  pendingGroupPromotionRef.current = null;
12880
12978
  pendingGroupDrillInRef.current = { groupId: drillGroup.id, childId: effectiveTargetId, target: effectiveTarget };
12979
+ if (effectiveTarget instanceof fabric.Textbox) {
12980
+ suppressTextEditForClick(effectiveTarget);
12981
+ } else {
12982
+ effectiveTarget.selected = false;
12983
+ effectiveTarget.__lastSelected = false;
12984
+ effectiveTarget.__corner = void 0;
12985
+ }
12881
12986
  selectElements([effectiveTargetId], false, false);
12987
+ updateDrilledGroupOutline();
12882
12988
  fabricCanvas.requestRenderAll();
12883
12989
  }
12884
12990
  } else if (!target || targetId === "__background__") {
@@ -13019,7 +13125,6 @@ const PageCanvas = forwardRef(
13019
13125
  lockEdits();
13020
13126
  }
13021
13127
  const o = fabricCanvas.getActiveObject();
13022
- pendingTextEditOnUpRef.current = null;
13023
13128
  if (!o) return;
13024
13129
  o.__lockScaleDuringCrop = false;
13025
13130
  });
@@ -13046,6 +13151,13 @@ const PageCanvas = forwardRef(
13046
13151
  (_b2 = (_a2 = pendingDrillIn.target).set) == null ? void 0 : _b2.call(_a2, { selectable: true, evented: true, hasBorders: true, hasControls: true });
13047
13152
  fabricCanvas.setActiveObject(pendingDrillIn.target);
13048
13153
  pendingDrillIn.target.setCoords();
13154
+ if (pendingDrillIn.target instanceof fabric.Textbox) {
13155
+ suppressTextEditForClick(pendingDrillIn.target);
13156
+ } else {
13157
+ pendingDrillIn.target.selected = false;
13158
+ pendingDrillIn.target.__lastSelected = false;
13159
+ pendingDrillIn.target.__corner = void 0;
13160
+ }
13049
13161
  fabricCanvas.requestRenderAll();
13050
13162
  } finally {
13051
13163
  requestAnimationFrame(() => {
@@ -13053,6 +13165,7 @@ const PageCanvas = forwardRef(
13053
13165
  });
13054
13166
  }
13055
13167
  selectElements([pendingDrillIn.childId], false, false);
13168
+ updateDrilledGroupOutline();
13056
13169
  }
13057
13170
  }
13058
13171
  const pendingPromotion = pendingGroupPromotionRef.current;
@@ -13117,6 +13230,7 @@ const PageCanvas = forwardRef(
13117
13230
  syncLockedRef.current = false;
13118
13231
  }, 0);
13119
13232
  unlockEditsSoon();
13233
+ restoreSuppressedTextEditObjectsSoon();
13120
13234
  if (allowDynamicFieldClick && onDynamicFieldClick && e.target) {
13121
13235
  const clickedId = getObjectId(e.target);
13122
13236
  if (clickedId && dynamicFieldIds.includes(clickedId)) {
@@ -14403,6 +14517,9 @@ const PageCanvas = forwardRef(
14403
14517
  else if (active instanceof fabric.ActiveSelection && active.getObjects().length === 1 && active.getObjects()[0] instanceof fabric.Textbox) target = active.getObjects()[0];
14404
14518
  }
14405
14519
  if (target && target instanceof fabric.Textbox) {
14520
+ if (Date.now() < suppressTextDoubleClickUntilRef.current || target.__pixldocsSuppressNextEdit) {
14521
+ return;
14522
+ }
14406
14523
  const elementId = getObjectId(target);
14407
14524
  if (target.__formattingEnabled === true || target.editable === false) {
14408
14525
  toast.info("Inline formatting is on — edit the text in the right panel.", {
@@ -14419,7 +14536,21 @@ const PageCanvas = forwardRef(
14419
14536
  const target = e.target;
14420
14537
  if (target && target instanceof fabric.Textbox) {
14421
14538
  const elementId = getObjectId(target);
14539
+ if (target.__pixldocsSuppressNextEdit) {
14540
+ try {
14541
+ target.exitEditing();
14542
+ } catch {
14543
+ }
14544
+ editingTextIdRef.current = null;
14545
+ setEditingText(false);
14546
+ fabricCanvas.requestRenderAll();
14547
+ return;
14548
+ }
14422
14549
  editingTextIdRef.current = elementId || null;
14550
+ if (elementId && selectAllTextOnEditingEnterRef.current === elementId) {
14551
+ selectAllTextOnEditingEnterRef.current = null;
14552
+ selectAllActiveTextbox(target);
14553
+ }
14423
14554
  setEditingText(true);
14424
14555
  }
14425
14556
  });
@@ -17181,6 +17312,28 @@ const PageCanvas = forwardRef(
17181
17312
  )
17182
17313
  }
17183
17314
  ),
17315
+ drilledGroupBounds && /* @__PURE__ */ jsx(
17316
+ "svg",
17317
+ {
17318
+ className: "absolute inset-0 pointer-events-none",
17319
+ style: { width: scaledWidth, height: scaledHeight },
17320
+ viewBox: `0 0 ${canvasWidth} ${canvasHeight}`,
17321
+ children: /* @__PURE__ */ jsx(
17322
+ "rect",
17323
+ {
17324
+ x: drilledGroupBounds.left,
17325
+ y: drilledGroupBounds.top,
17326
+ width: drilledGroupBounds.width,
17327
+ height: drilledGroupBounds.height,
17328
+ fill: "none",
17329
+ stroke: "rgba(100, 116, 139, 0.7)",
17330
+ strokeWidth: 1,
17331
+ strokeDasharray: "4 4",
17332
+ vectorEffect: "non-scaling-stroke"
17333
+ }
17334
+ )
17335
+ }
17336
+ ),
17184
17337
  canvas.projectSettings.showGrid && (() => {
17185
17338
  const ps = canvas.projectSettings;
17186
17339
  const gx = Math.max(1, ps.gridSizeX ?? ps.gridSize ?? 0);
@@ -23292,9 +23445,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
23292
23445
  }
23293
23446
  return svgString;
23294
23447
  }
23295
- const resolvedPackageVersion = "0.5.244";
23448
+ const resolvedPackageVersion = "0.5.246";
23296
23449
  const PACKAGE_VERSION = resolvedPackageVersion;
23297
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.244";
23450
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.246";
23298
23451
  const roundParityValue = (value) => {
23299
23452
  if (typeof value !== "number") return value;
23300
23453
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -24108,7 +24261,7 @@ class PixldocsRenderer {
24108
24261
  await this.waitForCanvasScene(container, cloned, i);
24109
24262
  }
24110
24263
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
24111
- const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-BWQ8fyXp.js");
24264
+ const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-D91zbb8z.js");
24112
24265
  const prepared = preparePagesForExport(
24113
24266
  cloned.pages,
24114
24267
  canvasWidth,
@@ -26428,7 +26581,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
26428
26581
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
26429
26582
  sanitizeSvgTreeForPdf(svgToDraw);
26430
26583
  try {
26431
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-BWQ8fyXp.js");
26584
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-D91zbb8z.js");
26432
26585
  try {
26433
26586
  await logTextMeasurementDiagnostic(svgToDraw);
26434
26587
  } catch {
@@ -26828,4 +26981,4 @@ export {
26828
26981
  buildTeaserBlurFlatKeys as y,
26829
26982
  collectFontDescriptorsFromConfig as z
26830
26983
  };
26831
- //# sourceMappingURL=index-xJBNIfjT.js.map
26984
+ //# sourceMappingURL=index-krO2Qm7P.js.map