@extend-ai/react-xlsx 0.16.3 → 0.16.5

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 CHANGED
@@ -3114,6 +3114,17 @@ function applyChartOrigins(chartsByWorkbookSheetIndex, chartOriginsById, archive
3114
3114
  });
3115
3115
  }
3116
3116
  }
3117
+ function hydrateWorkbookChartStyles(chartsByWorkbookSheetIndex, imageAssets) {
3118
+ const chartOriginsById = /* @__PURE__ */ new Map();
3119
+ applyChartOrigins(chartsByWorkbookSheetIndex, chartOriginsById, imageAssets.archive, imageAssets.sheetOrigins);
3120
+ for (const charts of chartsByWorkbookSheetIndex) {
3121
+ for (const chart of charts) {
3122
+ applyChartStyleFromXml(chart, chart.chartPath, imageAssets.archive, imageAssets.themePalette);
3123
+ applyBuiltinChartDefaults(chart, imageAssets.themePalette);
3124
+ }
3125
+ }
3126
+ return chartOriginsById;
3127
+ }
3117
3128
  function loadWorkbookChartAssets(workbook, imageAssets, visibleSheetIndexByWorkbookSheetIndex, showHiddenSheets = false) {
3118
3129
  const excludedChartIds = /* @__PURE__ */ new Set();
3119
3130
  const chartsByWorkbookSheetIndex = Array.from({ length: workbook.sheetCount }, (_, workbookSheetIndex) => {
@@ -3214,21 +3225,14 @@ function loadWorkbookChartAssets(workbook, imageAssets, visibleSheetIndexByWorkb
3214
3225
  });
3215
3226
  const chartsheets = Array.isArray(workbook.chartsheets) ? workbook.chartsheets.map((entry, index) => normalizeChartsheet(entry, index)) : [];
3216
3227
  const tabs = buildTabs(workbook, chartsheets, visibleSheetIndexByWorkbookSheetIndex, showHiddenSheets);
3217
- const chartOriginsById = /* @__PURE__ */ new Map();
3228
+ const chartOriginsById = imageAssets ? hydrateWorkbookChartStyles(chartsByWorkbookSheetIndex, imageAssets) : /* @__PURE__ */ new Map();
3218
3229
  if (imageAssets) {
3219
- applyChartOrigins(chartsByWorkbookSheetIndex, chartOriginsById, imageAssets.archive, imageAssets.sheetOrigins);
3220
3230
  for (let index = 0; index < chartsByWorkbookSheetIndex.length; index += 1) {
3221
3231
  chartsByWorkbookSheetIndex[index] = (chartsByWorkbookSheetIndex[index] ?? []).filter((chart) => !excludedChartIds.has(chart.id));
3222
3232
  }
3223
3233
  for (const id of excludedChartIds) {
3224
3234
  chartOriginsById.delete(id);
3225
3235
  }
3226
- for (const charts of chartsByWorkbookSheetIndex) {
3227
- for (const chart of charts) {
3228
- applyChartStyleFromXml(chart, chart.chartPath, imageAssets.archive, imageAssets.themePalette);
3229
- applyBuiltinChartDefaults(chart, imageAssets.themePalette);
3230
- }
3231
- }
3232
3236
  } else {
3233
3237
  for (let index = 0; index < chartsByWorkbookSheetIndex.length; index += 1) {
3234
3238
  chartsByWorkbookSheetIndex[index] = (chartsByWorkbookSheetIndex[index] ?? []).filter((chart) => !excludedChartIds.has(chart.id));
@@ -5942,11 +5946,11 @@ function parseShapeNode(shapeNode, fallbackAnchor, drawingRelationships, theme,
5942
5946
  zIndex
5943
5947
  };
5944
5948
  }
5945
- function parseAnchorContents(anchorNode, fallbackAnchor, drawingRelationships, archive, contentTypes, objectUrls, workbookSheetIndex, theme, ids, imageOriginsById, anchorIndex, sheetState, parentGroup = null) {
5949
+ function parseAnchorContents(anchorNode, fallbackAnchor, drawingRelationships, archive, contentTypes, objectUrls, workbookSheetIndex, theme, ids, imageOriginsById, anchorIndex, sheetState, drawingPath, parentGroup = null, picturePath = []) {
5946
5950
  const images = [];
5947
5951
  const shapes = [];
5948
5952
  const mediaPaths = /* @__PURE__ */ new Set();
5949
- Array.from(anchorNode.childNodes).filter(isElementNode2).forEach((child) => {
5953
+ Array.from(anchorNode.childNodes).filter(isElementNode2).forEach((child, childIndex) => {
5950
5954
  if (child.localName === "pic") {
5951
5955
  const imageId = `sheet-${workbookSheetIndex}-${ids.image}`;
5952
5956
  const parsed = parsePictureNode(
@@ -5967,6 +5971,8 @@ function parseAnchorContents(anchorNode, fallbackAnchor, drawingRelationships, a
5967
5971
  mediaPaths.add(parsed.mediaPath);
5968
5972
  imageOriginsById.set(imageId, {
5969
5973
  anchorIndex,
5974
+ drawingPath,
5975
+ picturePath: [...picturePath, childIndex],
5970
5976
  workbookSheetIndex
5971
5977
  });
5972
5978
  }
@@ -6026,7 +6032,9 @@ function parseAnchorContents(anchorNode, fallbackAnchor, drawingRelationships, a
6026
6032
  imageOriginsById,
6027
6033
  anchorIndex,
6028
6034
  sheetState,
6029
- nextGroup
6035
+ drawingPath,
6036
+ nextGroup,
6037
+ [...picturePath, childIndex]
6030
6038
  );
6031
6039
  parsedGroup.images.forEach((image) => images.push(image));
6032
6040
  parsedGroup.shapes.forEach((shape) => shapes.push(shape));
@@ -6082,7 +6090,8 @@ function parseDrawingObjects(archive, contentTypes, drawingPath, objectUrls, wor
6082
6090
  ids,
6083
6091
  imageOriginsById,
6084
6092
  anchorIndex,
6085
- sheetState
6093
+ sheetState,
6094
+ drawingPath
6086
6095
  );
6087
6096
  parsed.images.forEach((image) => images.push(image));
6088
6097
  parsed.shapes.forEach((shape) => shapes.push(shape));
@@ -6241,6 +6250,9 @@ function updateWorkbookImageAnchor(assets, imageId, anchor) {
6241
6250
  }
6242
6251
  const attachments = assets.sheetOrigins[origin.workbookSheetIndex]?.attachments ?? [];
6243
6252
  for (const attachment of attachments) {
6253
+ if (attachment.drawingPath !== origin.drawingPath) {
6254
+ continue;
6255
+ }
6244
6256
  const drawingXml = readArchiveText2(assets.archive, attachment.drawingPath);
6245
6257
  if (!drawingXml) {
6246
6258
  continue;
@@ -6251,10 +6263,45 @@ function updateWorkbookImageAnchor(assets, imageId, anchor) {
6251
6263
  }
6252
6264
  const anchorNodes = createImageAnchorNodes(drawingDocument);
6253
6265
  const anchorNode = anchorNodes[origin.anchorIndex];
6254
- if (!anchorNode || !getFirstChild(anchorNode, "pic")) {
6266
+ if (!anchorNode) {
6255
6267
  continue;
6256
6268
  }
6257
- updateAnchorNode2(anchorNode, anchor);
6269
+ let pictureNode = anchorNode;
6270
+ let parentGroup = null;
6271
+ let groupAnchor = parseAnchor(anchorNode);
6272
+ for (const childIndex of origin.picturePath) {
6273
+ const child = Array.from(pictureNode.childNodes).filter(isElementNode2)[childIndex];
6274
+ if (!child || !groupAnchor) {
6275
+ break;
6276
+ }
6277
+ pictureNode = child;
6278
+ if (child.localName === "grpSp") {
6279
+ parentGroup = parseGroupTransform(
6280
+ child,
6281
+ parentGroup,
6282
+ groupAnchor,
6283
+ assets.sheetStatesByWorkbookSheetIndex[origin.workbookSheetIndex] ?? null
6284
+ );
6285
+ groupAnchor = rectToAbsoluteAnchor(parentGroup);
6286
+ }
6287
+ }
6288
+ if (pictureNode.localName !== "pic") {
6289
+ continue;
6290
+ }
6291
+ if (parentGroup) {
6292
+ const transform = getFirstDescendant(pictureNode, "xfrm");
6293
+ const off = transform ? getFirstChild(transform, "off") : null;
6294
+ const ext = transform ? getFirstChild(transform, "ext") : null;
6295
+ if (anchor.kind !== "absolute" || !off || !ext || !parentGroup.scaleX || !parentGroup.scaleY) {
6296
+ continue;
6297
+ }
6298
+ off.setAttribute("x", String(Math.round(parentGroup.chX + (anchor.positionEmu.x - parentGroup.x) / parentGroup.scaleX)));
6299
+ off.setAttribute("y", String(Math.round(parentGroup.chY + (anchor.positionEmu.y - parentGroup.y) / parentGroup.scaleY)));
6300
+ ext.setAttribute("cx", String(Math.max(0, Math.round(anchor.sizeEmu.cx / parentGroup.scaleX))));
6301
+ ext.setAttribute("cy", String(Math.max(0, Math.round(anchor.sizeEmu.cy / parentGroup.scaleY))));
6302
+ } else {
6303
+ updateAnchorNode2(anchorNode, anchor);
6304
+ }
6258
6305
  assets.archive[attachment.drawingPath] = (0, import_fflate2.strToU8)(serializeXml2(drawingDocument));
6259
6306
  assets.dirtyArchivePaths.add(normalizeArchivePath2(attachment.drawingPath));
6260
6307
  const imageList = assets.imagesByWorkbookSheetIndex[origin.workbookSheetIndex] ?? [];
@@ -6365,15 +6412,21 @@ function appendSheetDrawingReference(sheetDocument, relationshipId) {
6365
6412
  }
6366
6413
  const drawingNode = sheetDocument.createElementNS(SPREADSHEET_NS, "drawing");
6367
6414
  drawingNode.setAttributeNS(REL_NS, "r:id", relationshipId);
6368
- const extLst = getFirstChild(worksheet, "extLst");
6369
- if (extLst) {
6370
- worksheet.insertBefore(drawingNode, extLst);
6371
- return;
6372
- }
6373
- worksheet.appendChild(drawingNode);
6415
+ const successorNames = /* @__PURE__ */ new Set([
6416
+ "legacyDrawing",
6417
+ "legacyDrawingHF",
6418
+ "picture",
6419
+ "oleObjects",
6420
+ "controls",
6421
+ "webPublishItems",
6422
+ "tableParts",
6423
+ "extLst"
6424
+ ]);
6425
+ const successor = Array.from(worksheet.childNodes).find((node) => isElementNode2(node) && node.namespaceURI === SPREADSHEET_NS && successorNames.has(node.localName));
6426
+ worksheet.insertBefore(drawingNode, successor ?? null);
6374
6427
  }
6375
6428
  function mergeWorkbookImageAssets(savedBytes, sourceAssets, sheetOrigins) {
6376
- if (!sourceAssets || sourceAssets.dirtyArchivePaths.size === 0) {
6429
+ if (!sourceAssets) {
6377
6430
  return cloneBytes(savedBytes);
6378
6431
  }
6379
6432
  try {
@@ -6384,9 +6437,31 @@ function mergeWorkbookImageAssets(savedBytes, sourceAssets, sheetOrigins) {
6384
6437
  if (!targetContentTypesDocument) {
6385
6438
  return cloneBytes(savedBytes);
6386
6439
  }
6440
+ const copiedParts = /* @__PURE__ */ new Set();
6441
+ const copyDrawingPart = (path) => {
6442
+ const normalizedPath = normalizeArchivePath2(path);
6443
+ const bytes = sourceAssets.archive[normalizedPath];
6444
+ if (!bytes || copiedParts.has(normalizedPath)) {
6445
+ return;
6446
+ }
6447
+ copiedParts.add(normalizedPath);
6448
+ archive[normalizedPath] = cloneBytes(bytes);
6449
+ mergeContentTypeForPath(targetContentTypesDocument, originalContentTypesDocument, normalizedPath);
6450
+ const relsPath = relsPathForDocument(normalizedPath);
6451
+ const relsBytes = sourceAssets.archive[relsPath];
6452
+ if (!relsBytes) {
6453
+ return;
6454
+ }
6455
+ archive[relsPath] = cloneBytes(relsBytes);
6456
+ mergeContentTypeForPath(targetContentTypesDocument, originalContentTypesDocument, relsPath);
6457
+ for (const relationship of parseRelationships(sourceAssets.archive, relsPath, normalizedPath).values()) {
6458
+ if (relationship.targetMode !== "External" && !relationship.type.endsWith("/hyperlink")) {
6459
+ copyDrawingPart(relationship.target);
6460
+ }
6461
+ }
6462
+ };
6387
6463
  sheetOrigins.forEach((origin, workbookSheetIndex) => {
6388
- const hasDirtyAttachment = origin?.attachments.some((attachment) => sourceAssets.dirtyArchivePaths.has(normalizeArchivePath2(attachment.drawingPath)) || attachment.drawingRelsPath && sourceAssets.dirtyArchivePaths.has(normalizeArchivePath2(attachment.drawingRelsPath)) || attachment.mediaPaths.some((path) => sourceAssets.dirtyArchivePaths.has(normalizeArchivePath2(path))));
6389
- if (!origin?.attachments.length || !hasDirtyAttachment) {
6464
+ if (!origin?.attachments.length) {
6390
6465
  return;
6391
6466
  }
6392
6467
  const currentSheet = workbookSheets[workbookSheetIndex];
@@ -6409,23 +6484,7 @@ function mergeWorkbookImageAssets(savedBytes, sourceAssets, sheetOrigins) {
6409
6484
  if (!drawingBytes) {
6410
6485
  return;
6411
6486
  }
6412
- archive[attachment.drawingPath] = cloneBytes(drawingBytes);
6413
- mergeContentTypeForPath(targetContentTypesDocument, originalContentTypesDocument, attachment.drawingPath);
6414
- if (attachment.drawingRelsPath) {
6415
- const drawingRelsBytes = sourceAssets.archive[attachment.drawingRelsPath];
6416
- if (drawingRelsBytes) {
6417
- archive[attachment.drawingRelsPath] = cloneBytes(drawingRelsBytes);
6418
- mergeContentTypeForPath(targetContentTypesDocument, originalContentTypesDocument, attachment.drawingRelsPath);
6419
- }
6420
- }
6421
- attachment.mediaPaths.forEach((mediaPath) => {
6422
- const mediaBytes = sourceAssets.archive[mediaPath];
6423
- if (!mediaBytes) {
6424
- return;
6425
- }
6426
- archive[mediaPath] = cloneBytes(mediaBytes);
6427
- mergeContentTypeForPath(targetContentTypesDocument, originalContentTypesDocument, mediaPath);
6428
- });
6487
+ copyDrawingPart(attachment.drawingPath);
6429
6488
  const relationshipId = nextRelationshipId(relDocument);
6430
6489
  const relationshipNode = relDocument.createElementNS(PKG_REL_NS, "Relationship");
6431
6490
  relationshipNode.setAttribute("Id", relationshipId);
@@ -6487,7 +6546,7 @@ function markerFromOffset(offsetPx, getSizePx) {
6487
6546
  let remaining = Math.max(0, offsetPx);
6488
6547
  let index = 0;
6489
6548
  while (remaining > 0) {
6490
- const size = Math.max(1, getSizePx(index));
6549
+ const size = Math.max(0, getSizePx(index));
6491
6550
  if (remaining < size) {
6492
6551
  break;
6493
6552
  }
@@ -8524,6 +8583,10 @@ function useXlsxViewerController(options) {
8524
8583
  if (requestToken !== chartLoadRequestTokenRef.current) {
8525
8584
  return;
8526
8585
  }
8586
+ if (imageAssetsRef.current && !effectiveSkipXmlParsing) {
8587
+ const chartOriginsById = hydrateWorkbookChartStyles(result.chartsByWorkbookSheetIndex, imageAssetsRef.current);
8588
+ chartAssetsRef.current = { ...result, chartOriginsById };
8589
+ }
8527
8590
  setChartsByWorkbookSheetIndex(result.chartsByWorkbookSheetIndex);
8528
8591
  setChartsheets(result.chartsheets);
8529
8592
  setTabs(result.tabs);
@@ -8739,13 +8802,14 @@ function useXlsxViewerController(options) {
8739
8802
  return;
8740
8803
  }
8741
8804
  setImageAssets(workerImageAssets);
8805
+ const chartOriginsById = workerImageAssets ? hydrateWorkbookChartStyles(snapshot.chartsByWorkbookSheetIndex, workerImageAssets) : /* @__PURE__ */ new Map();
8742
8806
  setFormControlsByWorkbookSheetIndex(snapshot.formControlsByWorkbookSheetIndex);
8743
8807
  setWorkbook(null);
8744
8808
  setSheets(snapshot.sheets);
8745
8809
  setChartsByWorkbookSheetIndex(snapshot.chartsByWorkbookSheetIndex);
8746
8810
  setChartsheets(snapshot.chartsheets);
8747
8811
  setTabs(snapshot.tabs);
8748
- chartAssetsRef.current = null;
8812
+ chartAssetsRef.current = { ...snapshot, chartOriginsById };
8749
8813
  setWorkerTablesByWorkbookSheetIndex(snapshot.tablesByWorkbookSheetIndex);
8750
8814
  setShouldAutoCalculate(false);
8751
8815
  setIsWorkerBacked(true);
@@ -8957,6 +9021,9 @@ function useXlsxViewerController(options) {
8957
9021
  if (!effectiveSkipXmlParsing && hasIncompleteWorkerChartSnapshot(snapshot)) {
8958
9022
  throw new Error("Worker chart payload incomplete");
8959
9023
  }
9024
+ const workerImageAssets = effectiveSkipXmlParsing ? null : parseWorkbookImageAssets(new Uint8Array(deferredBuffer));
9025
+ setImageAssets(workerImageAssets);
9026
+ const chartOriginsById = workerImageAssets ? hydrateWorkbookChartStyles(snapshot.chartsByWorkbookSheetIndex, workerImageAssets) : /* @__PURE__ */ new Map();
8960
9027
  deferredBufferRef.current = null;
8961
9028
  setDeferredLoadFileSize(null);
8962
9029
  setWorkbook(null);
@@ -8964,7 +9031,7 @@ function useXlsxViewerController(options) {
8964
9031
  setChartsByWorkbookSheetIndex(snapshot.chartsByWorkbookSheetIndex);
8965
9032
  setChartsheets(snapshot.chartsheets);
8966
9033
  setTabs(snapshot.tabs);
8967
- chartAssetsRef.current = null;
9034
+ chartAssetsRef.current = { ...snapshot, chartOriginsById };
8968
9035
  setFormControlsByWorkbookSheetIndex(snapshot.formControlsByWorkbookSheetIndex);
8969
9036
  setWorkerTablesByWorkbookSheetIndex(snapshot.tablesByWorkbookSheetIndex);
8970
9037
  setShouldAutoCalculate(false);
@@ -10055,7 +10122,7 @@ function useXlsxViewerController(options) {
10055
10122
  width: Math.max(1, right - left)
10056
10123
  };
10057
10124
  }, [getColumnWidthPx, getRowHeightPx]);
10058
- const setChartRect = React.useCallback((id, rect) => {
10125
+ const setChartRect = React.useCallback((id, rect, layout) => {
10059
10126
  const hydratedChartAssets = ensureChartAssetsHydrated(workbook, sheets);
10060
10127
  console.info("[react-xlsx debug] setChartRect", {
10061
10128
  hasActiveSheet: Boolean(activeSheet),
@@ -10084,8 +10151,8 @@ function useXlsxViewerController(options) {
10084
10151
  const nextAnchor = rectToImageAnchor(rect, currentChart.anchor, {
10085
10152
  contentOffsetLeft: GRID_ROW_HEADER_WIDTH,
10086
10153
  contentOffsetTop: GRID_HEADER_HEIGHT,
10087
- getColumnWidthPx: (col) => getColumnWidthPx(worksheet, col),
10088
- getRowHeightPx: (row) => getRowHeightPx(worksheet, row)
10154
+ getColumnWidthPx: (col) => layout?.columnWidths[col] ?? getColumnWidthPx(worksheet, col),
10155
+ getRowHeightPx: (row) => layout?.rowHeights[row] ?? getRowHeightPx(worksheet, row)
10089
10156
  });
10090
10157
  recordHistoryBeforeMutation();
10091
10158
  const didUpdateAnchor = updateWorkbookChartAnchor(imageAssetsRef.current, hydratedChartAssets, id, nextAnchor);
@@ -10104,7 +10171,7 @@ function useXlsxViewerController(options) {
10104
10171
  sheets,
10105
10172
  workbook
10106
10173
  ]);
10107
- const setImageRect = React.useCallback((id, rect) => {
10174
+ const setImageRect = React.useCallback((id, rect, layout) => {
10108
10175
  if (readOnly || !workbook || !activeSheet || !imageAssetsRef.current) {
10109
10176
  return;
10110
10177
  }
@@ -10116,8 +10183,8 @@ function useXlsxViewerController(options) {
10116
10183
  const nextAnchor = rectToImageAnchor(rect, currentImage.anchor, {
10117
10184
  contentOffsetLeft: GRID_ROW_HEADER_WIDTH,
10118
10185
  contentOffsetTop: GRID_HEADER_HEIGHT,
10119
- getColumnWidthPx: (col) => getColumnWidthPx(worksheet, col),
10120
- getRowHeightPx: (row) => getRowHeightPx(worksheet, row)
10186
+ getColumnWidthPx: (col) => layout?.columnWidths[col] ?? getColumnWidthPx(worksheet, col),
10187
+ getRowHeightPx: (row) => layout?.rowHeights[row] ?? getRowHeightPx(worksheet, row)
10121
10188
  });
10122
10189
  recordHistoryBeforeMutation();
10123
10190
  if (!updateWorkbookImageAnchor(imageAssetsRef.current, id, nextAnchor)) {
@@ -11726,6 +11793,12 @@ function resolveCellTextClipOverscan(overscan, usesWrappedText) {
11726
11793
  };
11727
11794
  }
11728
11795
 
11796
+ // src/scroll-display-limit.ts
11797
+ function growScrollDisplayLimit(current, growth, maximum, readOnly) {
11798
+ const nextLimit = current + growth;
11799
+ return readOnly ? Math.max(current, Math.min(maximum, nextLimit)) : nextLimit;
11800
+ }
11801
+
11729
11802
  // src/chart-renderer.tsx
11730
11803
  var import_d3_hierarchy = require("d3-hierarchy");
11731
11804
  var import_d3_geo = require("d3-geo");
@@ -24197,6 +24270,8 @@ function XlsxGrid({
24197
24270
  const pendingSelectionDragCleanupRef = React4.useRef(null);
24198
24271
  const fillDragCleanupRef = React4.useRef(null);
24199
24272
  const cachedScrollerRectRef = React4.useRef(null);
24273
+ const installImageInteractionListenersRef = React4.useRef(installImageInteractionListeners);
24274
+ const installChartInteractionListenersRef = React4.useRef(installChartInteractionListeners);
24200
24275
  const imageInteractionCleanupRef = React4.useRef(null);
24201
24276
  const imageInteractionRef = React4.useRef(null);
24202
24277
  const chartInteractionCleanupRef = React4.useRef(null);
@@ -25184,6 +25259,10 @@ function XlsxGrid({
25184
25259
  React4.useEffect(() => {
25185
25260
  readOnlyRef.current = readOnly;
25186
25261
  }, [readOnly]);
25262
+ React4.useLayoutEffect(() => {
25263
+ installImageInteractionListenersRef.current = installImageInteractionListeners;
25264
+ installChartInteractionListenersRef.current = installChartInteractionListeners;
25265
+ });
25187
25266
  React4.useEffect(() => {
25188
25267
  chartPreviewRectRef.current = chartPreviewRect;
25189
25268
  }, [chartPreviewRect]);
@@ -25471,16 +25550,14 @@ function XlsxGrid({
25471
25550
  const shouldSyncDrawingViewportImmediately = Math.abs(currentScroller.scrollLeft - paintedViewport.left) > CANVAS_IMMEDIATE_VIEWPORT_SYNC_THRESHOLD_PX || Math.abs(currentScroller.scrollTop - paintedViewport.top) > CANVAS_IMMEDIATE_VIEWPORT_SYNC_THRESHOLD_PX;
25472
25551
  syncDrawingViewport(currentScroller, { immediate: shouldSyncDrawingViewportImmediately });
25473
25552
  if (currentScroller.scrollHeight - (currentScroller.scrollTop + currentScroller.clientHeight) < OPEN_GRID_VERTICAL_EDGE_PX) {
25474
- setDisplayRowLimit((current) => {
25475
- const nextLimit = current + OPEN_GRID_ROW_GROWTH;
25476
- return readOnly && current < maxRowDisplayLimit ? Math.min(maxRowDisplayLimit, nextLimit) : nextLimit;
25477
- });
25553
+ setDisplayRowLimit(
25554
+ (current) => growScrollDisplayLimit(current, OPEN_GRID_ROW_GROWTH, maxRowDisplayLimit, readOnly)
25555
+ );
25478
25556
  }
25479
25557
  if (currentScroller.scrollWidth - (currentScroller.scrollLeft + currentScroller.clientWidth) < OPEN_GRID_HORIZONTAL_EDGE_PX) {
25480
- setDisplayColLimit((current) => {
25481
- const nextLimit = current + OPEN_GRID_COL_GROWTH;
25482
- return readOnly && current < maxColDisplayLimit ? Math.min(maxColDisplayLimit, nextLimit) : nextLimit;
25483
- });
25558
+ setDisplayColLimit(
25559
+ (current) => growScrollDisplayLimit(current, OPEN_GRID_COL_GROWTH, maxColDisplayLimit, readOnly)
25560
+ );
25484
25561
  }
25485
25562
  }, [maxColDisplayLimit, maxRowDisplayLimit, readOnly, syncDrawingViewport]);
25486
25563
  React4.useEffect(() => {
@@ -29297,7 +29374,7 @@ function XlsxGrid({
29297
29374
  setInteractionMode("select");
29298
29375
  document.body.style.cursor = "move";
29299
29376
  document.body.style.userSelect = "none";
29300
- installChartInteractionListeners(event.pointerId);
29377
+ installChartInteractionListenersRef.current(event.pointerId);
29301
29378
  }, [focusGrid, selectChart]);
29302
29379
  const startChartResize = React4.useCallback((event, chart, rect, handle) => {
29303
29380
  if (readOnlyRef.current || chart.editable === false || event.button !== 0) {
@@ -29323,7 +29400,7 @@ function XlsxGrid({
29323
29400
  setInteractionMode("select");
29324
29401
  document.body.style.cursor = String(IMAGE_HANDLE_CURSOR[handle]);
29325
29402
  document.body.style.userSelect = "none";
29326
- installChartInteractionListeners(event.pointerId);
29403
+ installChartInteractionListenersRef.current(event.pointerId);
29327
29404
  }, [focusGrid, selectChart]);
29328
29405
  const startImageMove = React4.useCallback((event, image, rect) => {
29329
29406
  if (event.button !== 0) {
@@ -29351,7 +29428,7 @@ function XlsxGrid({
29351
29428
  setInteractionMode("select");
29352
29429
  document.body.style.cursor = "move";
29353
29430
  document.body.style.userSelect = "none";
29354
- installImageInteractionListeners(event.pointerId);
29431
+ installImageInteractionListenersRef.current(event.pointerId);
29355
29432
  }, [focusGrid, selectImage]);
29356
29433
  const startImageResize = React4.useCallback((event, image, rect, handle) => {
29357
29434
  if (readOnlyRef.current || image.editable === false || event.button !== 0) {
@@ -29377,7 +29454,7 @@ function XlsxGrid({
29377
29454
  setInteractionMode("select");
29378
29455
  document.body.style.cursor = String(IMAGE_HANDLE_CURSOR[handle]);
29379
29456
  document.body.style.userSelect = "none";
29380
- installImageInteractionListeners(event.pointerId);
29457
+ installImageInteractionListenersRef.current(event.pointerId);
29381
29458
  }, [focusGrid, selectImage]);
29382
29459
  const handleImageClick = React4.useCallback((image) => {
29383
29460
  if (skipNextImageClickRef.current === image.id) {
@@ -30745,7 +30822,10 @@ function XlsxGrid({
30745
30822
  skipNextImageClickRef.current = interaction.imageId;
30746
30823
  }
30747
30824
  if (interaction.didMove && finalRect) {
30748
- setImageRect(interaction.imageId, toLogicalRect(finalRect));
30825
+ setImageRect(interaction.imageId, toLogicalRect(finalRect), {
30826
+ columnWidths: actualColWidths,
30827
+ rowHeights: actualRowHeights
30828
+ });
30749
30829
  }
30750
30830
  }
30751
30831
  imagePreviewRectRef.current = null;
@@ -30822,7 +30902,10 @@ function XlsxGrid({
30822
30902
  skipNextChartClickRef.current = interaction.chartId;
30823
30903
  }
30824
30904
  if (interaction.didMove && finalRect) {
30825
- setChartRect(interaction.chartId, toLogicalRect(finalRect));
30905
+ setChartRect(interaction.chartId, toLogicalRect(finalRect), {
30906
+ columnWidths: actualColWidths,
30907
+ rowHeights: actualRowHeights
30908
+ });
30826
30909
  }
30827
30910
  }
30828
30911
  chartPreviewRectRef.current = null;