@extend-ai/react-xlsx 0.17.1 → 0.17.3

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.js CHANGED
@@ -6656,13 +6656,52 @@ function hasUnresolvedSheetReferences(workbook) {
6656
6656
  }
6657
6657
  return false;
6658
6658
  }
6659
+ function collectFormulaCellsWithSavedValues(workbook) {
6660
+ const positions = [];
6661
+ for (let sheetIdx = 0; sheetIdx < workbook.sheetCount; sheetIdx += 1) {
6662
+ let sheet;
6663
+ try {
6664
+ sheet = workbook.getSheet(sheetIdx);
6665
+ } catch {
6666
+ continue;
6667
+ }
6668
+ const cells = sheet.formulaCells;
6669
+ if (!Array.isArray(cells)) {
6670
+ continue;
6671
+ }
6672
+ for (const cell of cells) {
6673
+ if (typeof cell?.row !== "number" || typeof cell?.col !== "number") {
6674
+ continue;
6675
+ }
6676
+ let saved;
6677
+ try {
6678
+ saved = sheet.getCalculatedValueAt(cell.row, cell.col);
6679
+ } catch {
6680
+ continue;
6681
+ }
6682
+ if (!saved.is_empty && !saved.is_error) {
6683
+ positions.push({ sheetIdx, row: cell.row, col: cell.col });
6684
+ }
6685
+ }
6686
+ }
6687
+ return positions;
6688
+ }
6689
+ function anyBecameError(workbook, positions) {
6690
+ return positions.some(({ sheetIdx, row, col }) => {
6691
+ try {
6692
+ return workbook.getSheet(sheetIdx).getCalculatedValueAt(row, col).is_error;
6693
+ } catch {
6694
+ return false;
6695
+ }
6696
+ });
6697
+ }
6659
6698
  function safeCalculate(workbook, options = {}) {
6660
6699
  if (hasUnresolvedSheetReferences(workbook)) {
6661
6700
  return { workbook, calculated: false, skipReason: "unresolved-sheet-refs" };
6662
6701
  }
6702
+ const withSavedValues = options.reparse ? collectFormulaCellsWithSavedValues(workbook) : [];
6663
6703
  try {
6664
6704
  workbook.calculate();
6665
- return { workbook, calculated: true, skipReason: null };
6666
6705
  } catch (err) {
6667
6706
  console.warn("[react-xlsx] workbook.calculate() trapped; falling back to cached formula values", err);
6668
6707
  if (options.reparse) {
@@ -6674,6 +6713,14 @@ function safeCalculate(workbook, options = {}) {
6674
6713
  }
6675
6714
  return { workbook, calculated: false, skipReason: "calculate-trapped" };
6676
6715
  }
6716
+ if (options.reparse && anyBecameError(workbook, withSavedValues)) {
6717
+ try {
6718
+ return { workbook: options.reparse(), calculated: false, skipReason: "calculate-regressed" };
6719
+ } catch (reparseErr) {
6720
+ console.warn("[react-xlsx] workbook reparse after calculate regression failed", reparseErr);
6721
+ }
6722
+ }
6723
+ return { workbook, calculated: true, skipReason: null };
6677
6724
  }
6678
6725
  function tryRecalculate(workbook) {
6679
6726
  try {
@@ -24448,6 +24495,9 @@ function XlsxGrid({
24448
24495
  const canvasCornerOverlayContentRef = React4.useRef(null);
24449
24496
  const canvasImageCacheRef = React4.useRef(/* @__PURE__ */ new Map());
24450
24497
  const selectionOverlayRef = React4.useRef(null);
24498
+ const selectionPaneContentRefs = React4.useRef(/* @__PURE__ */ new Map());
24499
+ const selectionPaneOverlayRefs = React4.useRef(/* @__PURE__ */ new Map());
24500
+ const selectionPaneFillHandleRefs = React4.useRef(/* @__PURE__ */ new Map());
24451
24501
  const canvasSelectionLayerRef = React4.useRef(null);
24452
24502
  const activeValidationOverlayRef = React4.useRef(null);
24453
24503
  const fillHandleRef = React4.useRef(null);
@@ -24709,15 +24759,17 @@ function XlsxGrid({
24709
24759
  shouldTransform ? "transform" : ""
24710
24760
  );
24711
24761
  };
24712
- const applyOverlayTransform = (element, baseTranslateX, baseTranslateY, paneLeft, paneTop, anchorX, anchorY) => {
24762
+ const applyOverlayTransform = (pane, element, baseTranslateX, baseTranslateY, paneLeft, paneTop, anchorX, anchorY) => {
24713
24763
  const translateX = resolveLiveTranslation(baseTranslateX, anchorX, paneLeft);
24714
24764
  const translateY = resolveLiveTranslation(baseTranslateY, anchorY, paneTop);
24715
- applyElementTransform(
24716
- element,
24717
- liveZoomScale2 !== 1 ? `translate3d(${translateX}px, ${translateY}px, 0) scale(${liveZoomScale2})` : `translate3d(${baseTranslateX}px, ${baseTranslateY}px, 0)`,
24718
- "transform",
24719
- "0 0"
24720
- );
24765
+ for (const content of [element, selectionPaneContentRefs.current.get(pane) ?? null]) {
24766
+ applyElementTransform(
24767
+ content,
24768
+ liveZoomScale2 !== 1 ? `translate3d(${translateX}px, ${translateY}px, 0) scale(${liveZoomScale2})` : `translate3d(${baseTranslateX}px, ${baseTranslateY}px, 0)`,
24769
+ "transform",
24770
+ "0 0"
24771
+ );
24772
+ }
24721
24773
  };
24722
24774
  const liveScrollBodyViewportWidth = Math.max(0, nextLiveViewport.width - liveFrozenPaneRight);
24723
24775
  const liveScrollBodyViewportHeight = Math.max(0, nextLiveViewport.height - liveFrozenPaneBottom);
@@ -24814,6 +24866,7 @@ function XlsxGrid({
24814
24866
  0
24815
24867
  );
24816
24868
  applyOverlayTransform(
24869
+ "scroll",
24817
24870
  canvasScrollOverlayContentRef.current,
24818
24871
  -nextLiveViewport.left - liveFrozenPaneRight,
24819
24872
  -nextLiveViewport.top - liveFrozenPaneBottom,
@@ -24823,6 +24876,7 @@ function XlsxGrid({
24823
24876
  liveZoomAnchorY
24824
24877
  );
24825
24878
  applyOverlayTransform(
24879
+ "top",
24826
24880
  canvasTopOverlayContentRef.current,
24827
24881
  -nextLiveViewport.left - liveFrozenPaneRight,
24828
24882
  -liveDisplayHeaderHeight,
@@ -24832,6 +24886,7 @@ function XlsxGrid({
24832
24886
  0
24833
24887
  );
24834
24888
  applyOverlayTransform(
24889
+ "left",
24835
24890
  canvasLeftOverlayContentRef.current,
24836
24891
  -liveDisplayRowHeaderWidth,
24837
24892
  -nextLiveViewport.top - liveFrozenPaneBottom,
@@ -24841,6 +24896,7 @@ function XlsxGrid({
24841
24896
  liveZoomAnchorY
24842
24897
  );
24843
24898
  applyOverlayTransform(
24899
+ "corner",
24844
24900
  canvasCornerOverlayContentRef.current,
24845
24901
  -liveDisplayRowHeaderWidth,
24846
24902
  -liveDisplayHeaderHeight,
@@ -27454,36 +27510,46 @@ function XlsxGrid({
27454
27510
  colHeaderCellRefs.current.delete(actualCol);
27455
27511
  }, [experimentalCanvas, palette.headerSurface]);
27456
27512
  const applyPreviewOverlay = React4.useCallback((range, options) => {
27457
- const overlay = selectionOverlayRef.current;
27458
- if (!overlay || !range) {
27513
+ const overlays = experimentalCanvas ? [...selectionPaneOverlayRefs.current.values()] : [selectionOverlayRef.current];
27514
+ if (!range) {
27459
27515
  if (options?.updateHeaderSelection !== false) {
27460
27516
  applyHeaderSelection(range);
27461
27517
  }
27462
27518
  return;
27463
27519
  }
27464
- const nextRect = options?.preferGeometry ? resolveGeometryOverlayRect(range) ?? resolveOverlayRect(range) : selectionDragRef.current?.didDrag || fillDragRef.current ? resolveDragPreviewRect(range) ?? resolveGeometryOverlayRect(range) ?? resolveOverlayRect(range) : resolveOverlayRect(range);
27520
+ const nextRect = experimentalCanvas || options?.preferGeometry ? resolveGeometryOverlayRect(range) ?? resolveOverlayRect(range) : selectionDragRef.current?.didDrag || fillDragRef.current ? resolveDragPreviewRect(range) ?? resolveGeometryOverlayRect(range) ?? resolveOverlayRect(range) : resolveOverlayRect(range);
27465
27521
  if (!nextRect) {
27466
27522
  if (options?.updateHeaderSelection !== false) {
27467
27523
  applyHeaderSelection(range);
27468
27524
  }
27469
27525
  return;
27470
27526
  }
27471
- overlay.style.left = `${nextRect.left}px`;
27472
- overlay.style.top = `${nextRect.top}px`;
27473
- overlay.style.width = `${nextRect.width}px`;
27474
- overlay.style.height = `${nextRect.height}px`;
27475
- overlay.style.opacity = "1";
27476
- overlay.style.visibility = "visible";
27477
- const fillHandle = fillHandleRef.current;
27478
- if (fillHandle) {
27479
- fillHandle.style.left = `${nextRect.left + nextRect.width - 4 * zoomFactor}px`;
27480
- fillHandle.style.top = `${nextRect.top + nextRect.height - 4 * zoomFactor}px`;
27527
+ for (const overlay of overlays) {
27528
+ if (overlay) {
27529
+ overlay.style.left = `${nextRect.left}px`;
27530
+ overlay.style.top = `${nextRect.top}px`;
27531
+ overlay.style.width = `${nextRect.width}px`;
27532
+ overlay.style.height = `${nextRect.height}px`;
27533
+ overlay.style.opacity = "1";
27534
+ overlay.style.visibility = "visible";
27535
+ }
27536
+ }
27537
+ const fillHandles = experimentalCanvas ? [...selectionPaneFillHandleRefs.current.values()] : [fillHandleRef.current];
27538
+ for (const fillHandle of fillHandles) {
27539
+ if (fillHandle) {
27540
+ fillHandle.style.left = `${nextRect.left + nextRect.width - 4 * zoomFactor}px`;
27541
+ fillHandle.style.top = `${nextRect.top + nextRect.height - 4 * zoomFactor}px`;
27542
+ }
27481
27543
  }
27482
27544
  if (options?.updateHeaderSelection !== false) {
27483
27545
  applyHeaderSelection(range);
27484
27546
  }
27485
- }, [applyHeaderSelection, resolveDragPreviewRect, resolveGeometryOverlayRect, resolveOverlayRect, zoomFactor]);
27547
+ }, [applyHeaderSelection, experimentalCanvas, resolveDragPreviewRect, resolveGeometryOverlayRect, resolveOverlayRect, zoomFactor]);
27486
27548
  const applyPreviewOverlayFromElement = React4.useCallback((element, range) => {
27549
+ if (experimentalCanvas) {
27550
+ applyPreviewOverlay(range);
27551
+ return;
27552
+ }
27487
27553
  const overlay = selectionOverlayRef.current;
27488
27554
  if (!overlay) {
27489
27555
  return;
@@ -27505,7 +27571,7 @@ function XlsxGrid({
27505
27571
  fillHandle.style.top = `${nextRect.top + nextRect.height - 4 * zoomFactor}px`;
27506
27572
  }
27507
27573
  applyHeaderSelection(range);
27508
- }, [applyHeaderSelection, resolveMountedCellOverlayRect, resolveOverlayRect, zoomFactor]);
27574
+ }, [applyHeaderSelection, applyPreviewOverlay, experimentalCanvas, resolveMountedCellOverlayRect, resolveOverlayRect, zoomFactor]);
27509
27575
  const syncActiveValidationOverlay = React4.useCallback((cell) => {
27510
27576
  const overlay = activeValidationOverlayRef.current;
27511
27577
  if (!overlay || !cell || editingCellRef.current || selectionDragRef.current || fillDragRef.current) {
@@ -27939,9 +28005,11 @@ function XlsxGrid({
27939
28005
  const overlayRange = selectionPreviewRangeRef.current ?? displayedSelection;
27940
28006
  if (!overlayRange || !wrapperRef.current) {
27941
28007
  applyHeaderSelection(null);
27942
- if (selectionOverlayRef.current) {
27943
- selectionOverlayRef.current.style.opacity = "0";
27944
- selectionOverlayRef.current.style.visibility = "hidden";
28008
+ for (const overlay of [selectionOverlayRef.current, ...selectionPaneOverlayRefs.current.values()]) {
28009
+ if (overlay) {
28010
+ overlay.style.opacity = "0";
28011
+ overlay.style.visibility = "hidden";
28012
+ }
27945
28013
  }
27946
28014
  return;
27947
28015
  }
@@ -31622,12 +31690,104 @@ function XlsxGrid({
31622
31690
  index
31623
31691
  )
31624
31692
  ] : []);
31625
- const drawingOverlayPanes = experimentalCanvas && hasCanvasDomDrawingOverlays || rangeHighlightNodes.length > 0 ? /* @__PURE__ */ jsx3("div", { style: { ...canvasBodyViewportLayerStyle, zIndex: experimentalCanvas ? 23 : 34 }, children: [
31693
+ function renderSelectionOverlay(pane) {
31694
+ return /* @__PURE__ */ jsxs3(Fragment4, { children: [
31695
+ /* @__PURE__ */ jsx3(
31696
+ "div",
31697
+ {
31698
+ ref: pane ? (element) => {
31699
+ if (element) {
31700
+ selectionPaneOverlayRefs.current.set(pane, element);
31701
+ } else {
31702
+ selectionPaneOverlayRefs.current.delete(pane);
31703
+ }
31704
+ } : selectionOverlayRef,
31705
+ style: {
31706
+ backgroundColor: selectionFill,
31707
+ boxSizing: "border-box",
31708
+ boxShadow: `inset 0 0 0 ${selectionBorderWidth}px ${selectionStroke}`,
31709
+ contain: "layout paint",
31710
+ height: resolvedSelectionOverlay?.height ?? 0,
31711
+ left: resolvedSelectionOverlay?.left ?? 0,
31712
+ opacity: resolvedSelectionOverlay ? 1 : 0,
31713
+ pointerEvents: "none",
31714
+ position: "absolute",
31715
+ top: resolvedSelectionOverlay?.top ?? 0,
31716
+ transition: canvasSelectionTransition,
31717
+ visibility: resolvedSelectionOverlay ? "visible" : "hidden",
31718
+ willChange: shouldAnimateCanvasSelectionGeometry ? "left, top, width, height" : void 0,
31719
+ width: resolvedSelectionOverlay?.width ?? 0,
31720
+ zIndex: 24
31721
+ }
31722
+ }
31723
+ ),
31724
+ /* @__PURE__ */ jsx3(
31725
+ "div",
31726
+ {
31727
+ ref: pane ? (element) => {
31728
+ if (element) {
31729
+ selectionPaneFillHandleRefs.current.set(pane, element);
31730
+ } else {
31731
+ selectionPaneFillHandleRefs.current.delete(pane);
31732
+ }
31733
+ } : fillHandleRef,
31734
+ onPointerDown: (event) => {
31735
+ if (readOnly || event.button !== 0 || !normalizedSelection || !resolvedSelectionOverlay) {
31736
+ return;
31737
+ }
31738
+ event.preventDefault();
31739
+ event.stopPropagation();
31740
+ startFillDrag(event.pointerId, normalizedSelection);
31741
+ },
31742
+ style: {
31743
+ backgroundColor: selectionStroke,
31744
+ border: `${Math.max(1, zoomFactor)}px solid ${palette.surface}`,
31745
+ contain: "layout paint",
31746
+ cursor: "crosshair",
31747
+ display: !readOnly && resolvedSelectionOverlay ? "block" : "none",
31748
+ height: 8 * zoomFactor,
31749
+ left: resolvedSelectionOverlay ? resolvedSelectionOverlay.left + resolvedSelectionOverlay.width - 4 * zoomFactor : 0,
31750
+ pointerEvents: "auto",
31751
+ position: "absolute",
31752
+ top: resolvedSelectionOverlay ? resolvedSelectionOverlay.top + resolvedSelectionOverlay.height - 4 * zoomFactor : 0,
31753
+ transition: shouldAnimateCanvasSelectionGeometry ? "left 120ms cubic-bezier(0.22, 1, 0.36, 1), top 120ms cubic-bezier(0.22, 1, 0.36, 1)" : "none",
31754
+ willChange: shouldAnimateCanvasSelectionGeometry ? "left, top" : void 0,
31755
+ width: 8 * zoomFactor,
31756
+ zIndex: 25
31757
+ }
31758
+ }
31759
+ )
31760
+ ] });
31761
+ }
31762
+ const overlayPanes = [
31626
31763
  { pane: "scroll", style: canvasScrollOverlayPaneStyle, ref: canvasScrollOverlayContentRef, left: -drawingViewport.left - frozenPaneRight, top: -drawingViewport.top - frozenPaneBottom },
31627
31764
  { pane: "top", style: canvasTopOverlayPaneStyle, ref: canvasTopOverlayContentRef, left: -drawingViewport.left - frozenPaneRight, top: -displayHeaderHeight },
31628
31765
  { pane: "left", style: canvasLeftOverlayPaneStyle, ref: canvasLeftOverlayContentRef, left: -displayRowHeaderWidth, top: -drawingViewport.top - frozenPaneBottom },
31629
31766
  { pane: "corner", style: canvasCornerOverlayPaneStyle, ref: canvasCornerOverlayContentRef, left: -displayRowHeaderWidth, top: -displayHeaderHeight }
31630
- ].map(({ pane, style, ref, left, top }) => /* @__PURE__ */ jsx3("div", { style, children: /* @__PURE__ */ jsxs3(
31767
+ ];
31768
+ const selectionOverlayPanes = experimentalCanvas ? /* @__PURE__ */ jsx3("div", { style: { ...canvasBodyViewportLayerStyle, zIndex: 40 }, children: overlayPanes.map(({ pane, style, left, top }) => /* @__PURE__ */ jsx3("div", { style, children: /* @__PURE__ */ jsx3(
31769
+ "div",
31770
+ {
31771
+ ref: (element) => {
31772
+ if (element) {
31773
+ selectionPaneContentRefs.current.set(pane, element);
31774
+ } else {
31775
+ selectionPaneContentRefs.current.delete(pane);
31776
+ }
31777
+ },
31778
+ style: {
31779
+ height: sheetContentHeight,
31780
+ left: 0,
31781
+ position: "absolute",
31782
+ top: 0,
31783
+ transform: `translate(${left}px, ${top}px)`,
31784
+ transformOrigin: "0 0",
31785
+ width: totalWidth
31786
+ },
31787
+ children: renderSelectionOverlay(pane)
31788
+ }
31789
+ ) }, pane)) }) : null;
31790
+ const drawingOverlayPanes = experimentalCanvas && hasCanvasDomDrawingOverlays || rangeHighlightNodes.length > 0 ? /* @__PURE__ */ jsx3("div", { style: { ...canvasBodyViewportLayerStyle, zIndex: experimentalCanvas ? 23 : 34 }, children: overlayPanes.map(({ pane, style, ref, left, top }) => /* @__PURE__ */ jsx3("div", { style, children: /* @__PURE__ */ jsxs3(
31631
31791
  "div",
31632
31792
  {
31633
31793
  ref,
@@ -31681,6 +31841,7 @@ function XlsxGrid({
31681
31841
  /* @__PURE__ */ jsx3("div", { style: scrollOverlayStyle, children: paneDrawingNodes.scroll })
31682
31842
  ] }) : null,
31683
31843
  drawingOverlayPanes,
31844
+ selectionOverlayPanes,
31684
31845
  experimentalCanvas ? /* @__PURE__ */ jsxs3(Fragment4, { children: [
31685
31846
  /* @__PURE__ */ jsxs3("div", { style: canvasBodyViewportLayerStyle, children: [
31686
31847
  /* @__PURE__ */ jsx3(
@@ -32013,29 +32174,7 @@ function XlsxGrid({
32013
32174
  zIndex: 24
32014
32175
  },
32015
32176
  children: [
32016
- /* @__PURE__ */ jsx3(
32017
- "div",
32018
- {
32019
- ref: selectionOverlayRef,
32020
- style: {
32021
- backgroundColor: selectionFill,
32022
- boxSizing: "border-box",
32023
- boxShadow: `inset 0 0 0 ${selectionBorderWidth}px ${selectionStroke}`,
32024
- contain: "layout paint",
32025
- height: resolvedSelectionOverlay?.height ?? 0,
32026
- left: resolvedSelectionOverlay?.left ?? 0,
32027
- opacity: resolvedSelectionOverlay ? 1 : 0,
32028
- pointerEvents: "none",
32029
- position: "absolute",
32030
- top: resolvedSelectionOverlay?.top ?? 0,
32031
- transition: canvasSelectionTransition,
32032
- visibility: resolvedSelectionOverlay ? "visible" : "hidden",
32033
- willChange: shouldAnimateCanvasSelectionGeometry ? "left, top, width, height" : void 0,
32034
- width: resolvedSelectionOverlay?.width ?? 0,
32035
- zIndex: 24
32036
- }
32037
- }
32038
- ),
32177
+ !experimentalCanvas ? renderSelectionOverlay() : null,
32039
32178
  activeCellOverlay != null && activeCellOverlayRect ? /* @__PURE__ */ jsx3(
32040
32179
  "div",
32041
32180
  {
@@ -32075,36 +32214,6 @@ function XlsxGrid({
32075
32214
  },
32076
32215
  children: "\u25BE"
32077
32216
  }
32078
- ),
32079
- /* @__PURE__ */ jsx3(
32080
- "div",
32081
- {
32082
- ref: fillHandleRef,
32083
- onPointerDown: (event) => {
32084
- if (readOnly || event.button !== 0 || !normalizedSelection || !resolvedSelectionOverlay) {
32085
- return;
32086
- }
32087
- event.preventDefault();
32088
- event.stopPropagation();
32089
- startFillDrag(event.pointerId, normalizedSelection);
32090
- },
32091
- style: {
32092
- backgroundColor: selectionStroke,
32093
- border: `${Math.max(1, zoomFactor)}px solid ${palette.surface}`,
32094
- contain: "layout paint",
32095
- cursor: "crosshair",
32096
- display: !readOnly && resolvedSelectionOverlay ? "block" : "none",
32097
- height: 8 * zoomFactor,
32098
- left: resolvedSelectionOverlay ? resolvedSelectionOverlay.left + resolvedSelectionOverlay.width - 4 * zoomFactor : 0,
32099
- pointerEvents: "auto",
32100
- position: "absolute",
32101
- top: resolvedSelectionOverlay ? resolvedSelectionOverlay.top + resolvedSelectionOverlay.height - 4 * zoomFactor : 0,
32102
- transition: shouldAnimateCanvasSelectionGeometry ? "left 120ms cubic-bezier(0.22, 1, 0.36, 1), top 120ms cubic-bezier(0.22, 1, 0.36, 1)" : "none",
32103
- willChange: shouldAnimateCanvasSelectionGeometry ? "left, top" : void 0,
32104
- width: 8 * zoomFactor,
32105
- zIndex: 25
32106
- }
32107
- }
32108
32217
  )
32109
32218
  ]
32110
32219
  }