@pixldocs/canvas-renderer 0.5.300 → 0.5.302

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.
@@ -191,6 +191,26 @@ function removeNodeFromTree(children, id) {
191
191
  return node;
192
192
  });
193
193
  }
194
+ function pruneEmptyGroups(children) {
195
+ const prunedGroupIds = /* @__PURE__ */ new Set();
196
+ const walk = (nodes) => {
197
+ const next = [];
198
+ for (const node of nodes) {
199
+ if (isGroup(node)) {
200
+ const prunedChildren = walk(node.children);
201
+ if (prunedChildren.length === 0) {
202
+ prunedGroupIds.add(node.id);
203
+ continue;
204
+ }
205
+ next.push({ ...node, children: prunedChildren });
206
+ } else {
207
+ next.push(node);
208
+ }
209
+ }
210
+ return next;
211
+ };
212
+ return { children: walk(children), prunedGroupIds };
213
+ }
194
214
  function addNodeToTree(children, node, parentId, index) {
195
215
  if (!parentId) {
196
216
  if (index !== void 0) {
@@ -1504,8 +1524,16 @@ const useEditorStore = create((set, get) => ({
1504
1524
  if (rootLevelIds.has(id)) ;
1505
1525
  nextChildren = removeNodeFromTree(nextChildren, id);
1506
1526
  }
1527
+ const { children: prunedChildren, prunedGroupIds } = pruneEmptyGroups(nextChildren);
1528
+ nextChildren = prunedChildren;
1529
+ for (const gid of prunedGroupIds) {
1530
+ allDeletedIds.add(gid);
1531
+ if (rootLevelIds.has(gid)) ;
1532
+ }
1507
1533
  let nextCanvas = updateCurrentPageChildren(state.canvas, () => nextChildren);
1508
- nextCanvas.selectedIds = state.canvas.selectedIds.filter((id) => !ids.includes(id));
1534
+ nextCanvas.selectedIds = state.canvas.selectedIds.filter(
1535
+ (id) => !allDeletedIds.has(id) && !prunedGroupIds.has(id)
1536
+ );
1509
1537
  if (nextCanvas.themeConfig) {
1510
1538
  const remainingProps = nextCanvas.themeConfig.properties.filter((p) => !allDeletedIds.has(p.elementId));
1511
1539
  if (remainingProps.length !== nextCanvas.themeConfig.properties.length) {
@@ -11259,6 +11287,41 @@ const PageCanvas = forwardRef(
11259
11287
  const [groupResizeState, setGroupResizeState] = useState(null);
11260
11288
  const [groupOverlayLiveBounds, setGroupOverlayLiveBounds] = useState(null);
11261
11289
  const setGroupOverlayLiveBoundsRef = useRef(setGroupOverlayLiveBounds);
11290
+ const restoreSuppressedGroupMemberVisuals = useCallback(() => {
11291
+ const list = suppressGroupMemberBordersRef.current;
11292
+ if (!list || list.length === 0) return;
11293
+ for (const member of list) {
11294
+ const origBorders = member.__pixldocsOrigHasBorders;
11295
+ const origControls = member.__pixldocsOrigHasControls;
11296
+ const origLockX = member.__pixldocsOrigLockScalingX;
11297
+ if (origBorders !== void 0) member.hasBorders = origBorders;
11298
+ else member.hasBorders = true;
11299
+ if (origControls !== void 0) member.hasControls = origControls;
11300
+ else member.hasControls = true;
11301
+ if (origLockX !== void 0) {
11302
+ member.lockScalingX = origLockX;
11303
+ member.lockScalingY = member.__pixldocsOrigLockScalingY;
11304
+ }
11305
+ delete member.__pixldocsOrigHasBorders;
11306
+ delete member.__pixldocsOrigHasControls;
11307
+ delete member.__pixldocsOrigLockScalingX;
11308
+ delete member.__pixldocsOrigLockScalingY;
11309
+ }
11310
+ suppressGroupMemberBordersRef.current = [];
11311
+ }, []);
11312
+ const clearCanvasActiveVisuals = useCallback((fc) => {
11313
+ setGroupOverlayLiveBoundsRef.current(null);
11314
+ restoreSuppressedGroupMemberVisuals();
11315
+ try {
11316
+ fc.discardActiveObject();
11317
+ const topContext = fc.contextTop;
11318
+ if (topContext && typeof fc.clearContext === "function") {
11319
+ fc.clearContext(topContext);
11320
+ }
11321
+ fc.requestRenderAll();
11322
+ } catch {
11323
+ }
11324
+ }, [restoreSuppressedGroupMemberVisuals]);
11262
11325
  const skipSelectionClearOnDiscardRef = useRef(false);
11263
11326
  const skipActiveSelectionBakeOnClearRef = useRef(false);
11264
11327
  const preserveEditingScopeOnSelectionClearRef = useRef(false);
@@ -11347,6 +11410,34 @@ const PageCanvas = forwardRef(
11347
11410
  useEffect(() => {
11348
11411
  selectedIdsRef.current = selectedIds;
11349
11412
  }, [selectedIds]);
11413
+ useEffect(() => {
11414
+ const fc = fabricRef.current;
11415
+ if (!fc || !isActive || !currentPage) return;
11416
+ const pageChildren2 = currentPage.children ?? [];
11417
+ const hasMissingSelection = selectedIds.some((id) => !findNodeById(pageChildren2, id));
11418
+ const activeEditingGroupId = fc.__activeEditingGroupId ?? null;
11419
+ const activeEditingGroupMissing = !!activeEditingGroupId && !findNodeById(pageChildren2, activeEditingGroupId);
11420
+ const drilledGroupMissing = !!drilledGroupIdRef.current && !findNodeById(pageChildren2, drilledGroupIdRef.current);
11421
+ const hasGroupEditContext = !!activeEditingGroupId || !!drilledGroupIdRef.current;
11422
+ if (selectedIds.length === 0 && !hasGroupEditContext || hasMissingSelection || activeEditingGroupMissing || drilledGroupMissing) {
11423
+ fc.__activeEditingGroupId = null;
11424
+ drilledGroupIdRef.current = null;
11425
+ setDrilledGroupBounds(null);
11426
+ preserveActiveSelectionAfterTransformRef.current = null;
11427
+ recentGroupSelectionRestoreRef.current = null;
11428
+ clearCanvasActiveVisuals(fc);
11429
+ } else if (hasGroupEditContext) {
11430
+ requestAnimationFrame(() => {
11431
+ var _a2;
11432
+ if (fabricRef.current !== fc) return;
11433
+ try {
11434
+ (_a2 = fc.__updateDrilledGroupOutline) == null ? void 0 : _a2.call(fc);
11435
+ } catch {
11436
+ }
11437
+ fc.requestRenderAll();
11438
+ });
11439
+ }
11440
+ }, [selectedIds, currentPage, isActive, clearCanvasActiveVisuals]);
11350
11441
  useEffect(() => {
11351
11442
  isActiveRef.current = isActive;
11352
11443
  if (isEditorMode && isActive && fabricRef.current) ;
@@ -15248,7 +15339,7 @@ const PageCanvas = forwardRef(
15248
15339
  visibilityUpdateInProgressRef.current = false;
15249
15340
  }
15250
15341
  doSyncRef.current = () => {
15251
- var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j;
15342
+ var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k;
15252
15343
  const shouldSkipUpdates2 = syncLockedRef.current || editLockRef.current;
15253
15344
  const state = useEditorStore.getState();
15254
15345
  const elementsToSync = elements;
@@ -15273,10 +15364,20 @@ const PageCanvas = forwardRef(
15273
15364
  const activeBeforeSync = fc.getActiveObject();
15274
15365
  const transformSelectionId = preserveSelectionAfterTransformIdRef.current;
15275
15366
  const isTransforming2 = !!fc._currentTransform;
15276
- const activeSelectionSnapshot = activeBeforeSync instanceof fabric.ActiveSelection ? {
15367
+ const rawActiveSelectionSnapshot = activeBeforeSync instanceof fabric.ActiveSelection ? {
15277
15368
  memberIds: activeBeforeSync.getObjects().map((o) => getObjectId(o)).filter((id) => !!id && id !== "__background__"),
15278
15369
  groupSelectionId: activeBeforeSync.__pixldocsGroupSelection
15279
15370
  } : preserveActiveSelectionAfterTransformRef.current;
15371
+ const activeSelectionSnapshot = rawActiveSelectionSnapshot ? (() => {
15372
+ let memberIds = rawActiveSelectionSnapshot.memberIds.filter((id) => allElementIds.has(id));
15373
+ const groupSelectionId = rawActiveSelectionSnapshot.groupSelectionId;
15374
+ if (groupSelectionId) {
15375
+ const groupNode = findNodeById(pageTree, groupSelectionId);
15376
+ if (!groupNode || !isGroup(groupNode)) return null;
15377
+ memberIds = getAllElementIds(groupNode.children ?? []).filter((id) => allElementIds.has(id));
15378
+ }
15379
+ return memberIds.length > 0 ? { ...rawActiveSelectionSnapshot, memberIds, groupSelectionId } : null;
15380
+ })() : null;
15280
15381
  if (syncTriggeredByPanelRef.current && !transformSelectionId && !shouldSkipUpdates2 && !isTransforming2) {
15281
15382
  const activeObj = fc.getActiveObject();
15282
15383
  const activeObjId = activeObj ? getObjectId(activeObj) : null;
@@ -16070,6 +16171,12 @@ const PageCanvas = forwardRef(
16070
16171
  }
16071
16172
  }
16072
16173
  }
16174
+ if (fc.__activeEditingGroupId) {
16175
+ try {
16176
+ (_k = fc.__updateDrilledGroupOutline) == null ? void 0 : _k.call(fc);
16177
+ } catch {
16178
+ }
16179
+ }
16073
16180
  const recentGroupRestore = recentGroupSelectionRestoreRef.current;
16074
16181
  if ((recentGroupRestore == null ? void 0 : recentGroupRestore.groupSelectionId) && recentGroupRestore.expiresAt > Date.now()) {
16075
16182
  restoreGroupSelectionSnapshot(recentGroupRestore);
@@ -23997,9 +24104,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
23997
24104
  }
23998
24105
  return svgString;
23999
24106
  }
24000
- const resolvedPackageVersion = "0.5.300";
24107
+ const resolvedPackageVersion = "0.5.302";
24001
24108
  const PACKAGE_VERSION = resolvedPackageVersion;
24002
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.300";
24109
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.302";
24003
24110
  const roundParityValue = (value) => {
24004
24111
  if (typeof value !== "number") return value;
24005
24112
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -24813,7 +24920,7 @@ class PixldocsRenderer {
24813
24920
  await this.waitForCanvasScene(container, cloned, i);
24814
24921
  }
24815
24922
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
24816
- const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-Bgb4ctNH.js");
24923
+ const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-Bje676YF.js");
24817
24924
  const prepared = preparePagesForExport(
24818
24925
  cloned.pages,
24819
24926
  canvasWidth,
@@ -27133,7 +27240,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
27133
27240
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
27134
27241
  sanitizeSvgTreeForPdf(svgToDraw);
27135
27242
  try {
27136
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-Bgb4ctNH.js");
27243
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-Bje676YF.js");
27137
27244
  try {
27138
27245
  await logTextMeasurementDiagnostic(svgToDraw);
27139
27246
  } catch {
@@ -27533,4 +27640,4 @@ export {
27533
27640
  buildTeaserBlurFlatKeys as y,
27534
27641
  collectFontDescriptorsFromConfig as z
27535
27642
  };
27536
- //# sourceMappingURL=index-DSa_E6-5.js.map
27643
+ //# sourceMappingURL=index-ZeWTxoUj.js.map