@extend-ai/react-xlsx 0.9.0 → 0.9.2

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
@@ -21579,6 +21579,9 @@ function XlsxGrid({
21579
21579
  const selectionCommitFrameRef = React4.useRef(null);
21580
21580
  const selectionRef = React4.useRef(null);
21581
21581
  const editingCellRef = React4.useRef(null);
21582
+ const commitEditingRef = React4.useRef(() => {
21583
+ });
21584
+ const editingInputRef = React4.useRef(null);
21582
21585
  const readOnlyRef = React4.useRef(readOnly);
21583
21586
  const committedZoomScaleRef = React4.useRef(zoomScale);
21584
21587
  const gestureZoomScaleRef = React4.useRef(zoomScale);
@@ -21602,8 +21605,10 @@ function XlsxGrid({
21602
21605
  const resizeFrameRef = React4.useRef(null);
21603
21606
  const pendingResizePreviewRef = React4.useRef(null);
21604
21607
  const selectionDragRef = React4.useRef(null);
21608
+ const pendingSelectionDragRef = React4.useRef(null);
21605
21609
  const fillDragRef = React4.useRef(null);
21606
21610
  const selectionDragCleanupRef = React4.useRef(null);
21611
+ const pendingSelectionDragCleanupRef = React4.useRef(null);
21607
21612
  const fillDragCleanupRef = React4.useRef(null);
21608
21613
  const cachedScrollerRectRef = React4.useRef(null);
21609
21614
  const imageInteractionCleanupRef = React4.useRef(null);
@@ -22456,6 +22461,18 @@ function XlsxGrid({
22456
22461
  React4.useEffect(() => {
22457
22462
  editingCellRef.current = editingCell;
22458
22463
  }, [editingCell]);
22464
+ React4.useLayoutEffect(() => {
22465
+ if (!editingCell) {
22466
+ return;
22467
+ }
22468
+ const input = editingInputRef.current;
22469
+ if (!input) {
22470
+ return;
22471
+ }
22472
+ input.focus();
22473
+ const caret = input.value.length;
22474
+ input.setSelectionRange(caret, caret);
22475
+ }, [editingCell]);
22459
22476
  React4.useEffect(() => {
22460
22477
  readOnlyRef.current = readOnly;
22461
22478
  }, [readOnly]);
@@ -22525,7 +22542,7 @@ function XlsxGrid({
22525
22542
  }, [displayedSelection]);
22526
22543
  React4.useEffect(() => {
22527
22544
  const previewRange = selectionPreviewRangeRef.current;
22528
- if (!previewRange || selectionDragRef.current || fillDragRef.current) {
22545
+ if (!previewRange || pendingSelectionDragRef.current || selectionDragRef.current || fillDragRef.current) {
22529
22546
  return;
22530
22547
  }
22531
22548
  if (normalizedSelection && rangesEqual(previewRange, normalizedSelection)) {
@@ -23132,14 +23149,17 @@ function XlsxGrid({
23132
23149
  }
23133
23150
  }, []);
23134
23151
  React4.useEffect(() => {
23152
+ pendingSelectionDragCleanupRef.current?.();
23135
23153
  selectionDragCleanupRef.current?.();
23136
23154
  fillDragCleanupRef.current?.();
23137
23155
  chartInteractionCleanupRef.current?.();
23138
23156
  imageInteractionCleanupRef.current?.();
23157
+ pendingSelectionDragCleanupRef.current = null;
23139
23158
  selectionDragCleanupRef.current = null;
23140
23159
  fillDragCleanupRef.current = null;
23141
23160
  chartInteractionCleanupRef.current = null;
23142
23161
  imageInteractionCleanupRef.current = null;
23162
+ pendingSelectionDragRef.current = null;
23143
23163
  selectionDragRef.current = null;
23144
23164
  fillDragRef.current = null;
23145
23165
  chartInteractionRef.current = null;
@@ -23215,6 +23235,9 @@ function XlsxGrid({
23215
23235
  setEditingValue("");
23216
23236
  focusGrid();
23217
23237
  }, [focusGrid]);
23238
+ React4.useEffect(() => {
23239
+ commitEditingRef.current = commitEditing;
23240
+ }, [commitEditing]);
23218
23241
  const [, startBatchTransition] = React4.useTransition();
23219
23242
  const [, startSelectionTransition] = React4.useTransition();
23220
23243
  const [asyncViewportRowBatch, setAsyncViewportRowBatch] = React4.useState(null);
@@ -24327,6 +24350,101 @@ function XlsxGrid({
24327
24350
  }
24328
24351
  return normalizeRange2({ start: dragState.anchor, end: cell });
24329
24352
  }
24353
+ function updateSelectionDragPreview(clientX, clientY) {
24354
+ const dragState = selectionDragRef.current;
24355
+ if (!dragState) {
24356
+ return;
24357
+ }
24358
+ const nextCell = resolveDraggedSelectionCell(dragState, clientX, clientY);
24359
+ if (!nextCell) {
24360
+ return;
24361
+ }
24362
+ const nextRange = buildDraggedSelectionRange(dragState, nextCell);
24363
+ if (!nextRange || rangesEqual(nextRange, dragState.previewRange)) {
24364
+ return;
24365
+ }
24366
+ dragState.previewRange = nextRange;
24367
+ selectionPreviewRangeRef.current = nextRange;
24368
+ displayedSelectionRef.current = nextRange;
24369
+ applyPreviewOverlay(nextRange);
24370
+ }
24371
+ function clearPendingSelectionDrag() {
24372
+ const cleanup = pendingSelectionDragCleanupRef.current;
24373
+ pendingSelectionDragCleanupRef.current = null;
24374
+ pendingSelectionDragRef.current = null;
24375
+ cleanup?.();
24376
+ }
24377
+ function finishPendingSelectionDrag() {
24378
+ const pendingState = pendingSelectionDragRef.current;
24379
+ clearPendingSelectionDrag();
24380
+ if (pendingState && !pendingState.committedOnPointerDown) {
24381
+ commitSelectionRange(pendingState.previewRange);
24382
+ }
24383
+ }
24384
+ function promotePendingSelectionDrag(clientX, clientY) {
24385
+ const pendingState = pendingSelectionDragRef.current;
24386
+ if (!pendingState) {
24387
+ return;
24388
+ }
24389
+ clearPendingSelectionDrag();
24390
+ cachedScrollerRectRef.current = scrollRef.current?.getBoundingClientRect() ?? null;
24391
+ pendingState.didDrag = true;
24392
+ selectionDragRef.current = pendingState;
24393
+ selectionPreviewRangeRef.current = pendingState.previewRange;
24394
+ displayedSelectionRef.current = pendingState.previewRange;
24395
+ setInteractionMode("select");
24396
+ document.body.style.userSelect = "none";
24397
+ installSelectionDragListeners(pendingState.pointerId);
24398
+ updateSelectionDragPreview(clientX, clientY);
24399
+ }
24400
+ function installPendingSelectionDragListeners(pointerId, target) {
24401
+ const existingCleanup = pendingSelectionDragCleanupRef.current;
24402
+ pendingSelectionDragCleanupRef.current = null;
24403
+ existingCleanup?.();
24404
+ const pointerTarget = target;
24405
+ try {
24406
+ pointerTarget.setPointerCapture?.(pointerId);
24407
+ } catch {
24408
+ }
24409
+ const handlePointerMove = (event) => {
24410
+ const pointerEvent = event;
24411
+ if (pointerEvent.pointerId !== pointerId) {
24412
+ return;
24413
+ }
24414
+ const pendingState = pendingSelectionDragRef.current;
24415
+ if (!pendingState) {
24416
+ return;
24417
+ }
24418
+ const deltaX = Math.abs(pointerEvent.clientX - pendingState.startClientX);
24419
+ const deltaY = Math.abs(pointerEvent.clientY - pendingState.startClientY);
24420
+ if (deltaX < SELECTION_DRAG_THRESHOLD_PX && deltaY < SELECTION_DRAG_THRESHOLD_PX) {
24421
+ return;
24422
+ }
24423
+ event.preventDefault();
24424
+ promotePendingSelectionDrag(pointerEvent.clientX, pointerEvent.clientY);
24425
+ };
24426
+ const handlePointerEnd = (event) => {
24427
+ const pointerEvent = event;
24428
+ if (pointerEvent.pointerId !== pointerId) {
24429
+ return;
24430
+ }
24431
+ finishPendingSelectionDrag();
24432
+ };
24433
+ target.addEventListener("pointermove", handlePointerMove);
24434
+ target.addEventListener("pointerup", handlePointerEnd);
24435
+ target.addEventListener("pointercancel", handlePointerEnd);
24436
+ pendingSelectionDragCleanupRef.current = () => {
24437
+ target.removeEventListener("pointermove", handlePointerMove);
24438
+ target.removeEventListener("pointerup", handlePointerEnd);
24439
+ target.removeEventListener("pointercancel", handlePointerEnd);
24440
+ try {
24441
+ if (pointerTarget.hasPointerCapture?.(pointerId)) {
24442
+ pointerTarget.releasePointerCapture?.(pointerId);
24443
+ }
24444
+ } catch {
24445
+ }
24446
+ };
24447
+ }
24330
24448
  function installSelectionDragListeners(pointerId) {
24331
24449
  selectionDragCleanupRef.current?.();
24332
24450
  let pendingClientPoint = null;
@@ -24350,18 +24468,7 @@ function XlsxGrid({
24350
24468
  }
24351
24469
  dragState.didDrag = true;
24352
24470
  }
24353
- const nextCell = resolveDraggedSelectionCell(dragState, pendingPoint.x, pendingPoint.y);
24354
- if (!nextCell) {
24355
- return;
24356
- }
24357
- const nextRange = buildDraggedSelectionRange(dragState, nextCell);
24358
- if (!nextRange || rangesEqual(nextRange, dragState.previewRange)) {
24359
- return;
24360
- }
24361
- dragState.previewRange = nextRange;
24362
- selectionPreviewRangeRef.current = nextRange;
24363
- displayedSelectionRef.current = nextRange;
24364
- applyPreviewOverlay(nextRange);
24471
+ updateSelectionDragPreview(pendingPoint.x, pendingPoint.y);
24365
24472
  };
24366
24473
  const handlePointerMove = (event) => {
24367
24474
  if (event.pointerId !== pointerId) {
@@ -24517,12 +24624,16 @@ function XlsxGrid({
24517
24624
  const initialRange = normalizeRange2({ start: anchor, end: targetCell });
24518
24625
  const isActive = isSameCell(activeCellRef.current, targetCell);
24519
24626
  const committedOnPointerDown = !isActive || !editingCellRef.current;
24627
+ if (editingCellRef.current && !isActive) {
24628
+ commitEditingRef.current();
24629
+ }
24520
24630
  const pointerOrigin = targetCell.row === cell.row && targetCell.col === cell.col ? resolveCellPointerOrigin(cell, event.currentTarget.getBoundingClientRect(), event.clientX, event.clientY) : resolveCellPointerOriginFromClient(targetCell, event.clientX, event.clientY);
24521
24631
  const originOverlayRect = targetCell.row === cell.row && targetCell.col === cell.col ? resolveMountedCellOverlayRect(event.currentTarget) : resolveOverlayRect(initialRange);
24522
24632
  if (!pointerOrigin) {
24523
24633
  return;
24524
24634
  }
24525
24635
  startCellSelection(
24636
+ event.currentTarget,
24526
24637
  event.pointerId,
24527
24638
  anchor,
24528
24639
  "cell",
@@ -24570,6 +24681,7 @@ function XlsxGrid({
24570
24681
  return;
24571
24682
  }
24572
24683
  startCellSelection(
24684
+ event.currentTarget,
24573
24685
  event.pointerId,
24574
24686
  { row: anchorRow, col: firstVisibleCol },
24575
24687
  "row",
@@ -24600,6 +24712,7 @@ function XlsxGrid({
24600
24712
  return;
24601
24713
  }
24602
24714
  startCellSelection(
24715
+ event.currentTarget,
24603
24716
  event.pointerId,
24604
24717
  { row: firstVisibleRow, col: anchorCol },
24605
24718
  "column",
@@ -24872,12 +24985,16 @@ function XlsxGrid({
24872
24985
  const initialRange = normalizeRange2({ start: anchor, end: cell });
24873
24986
  const isActive = isSameCell(activeCellRef.current, cell);
24874
24987
  const committedOnPointerDown = !isActive || !editingCellRef.current;
24988
+ if (editingCellRef.current && !isActive) {
24989
+ commitEditingRef.current();
24990
+ }
24875
24991
  const rowIndex = rowIndexByActual.get(cell.row);
24876
24992
  const colIndex = colIndexByActual.get(cell.col);
24877
24993
  if (rowIndex === void 0 || colIndex === void 0) {
24878
24994
  return;
24879
24995
  }
24880
24996
  startCellSelection(
24997
+ event.currentTarget,
24881
24998
  event.pointerId,
24882
24999
  anchor,
24883
25000
  "cell",
@@ -24955,6 +25072,7 @@ function XlsxGrid({
24955
25072
  return;
24956
25073
  }
24957
25074
  startCellSelection(
25075
+ event.currentTarget,
24958
25076
  event.pointerId,
24959
25077
  { row: firstVisibleRow, col: anchorCol },
24960
25078
  "column",
@@ -25012,6 +25130,7 @@ function XlsxGrid({
25012
25130
  return;
25013
25131
  }
25014
25132
  startCellSelection(
25133
+ event.currentTarget,
25015
25134
  event.pointerId,
25016
25135
  { row: anchorRow, col: firstVisibleCol },
25017
25136
  "row",
@@ -27254,9 +27373,10 @@ function XlsxGrid({
27254
27373
  setGlobalCursor("row-resize");
27255
27374
  document.body.style.userSelect = "none";
27256
27375
  }
27257
- function startCellSelection(pointerId, anchor, axis, originCell, pointerOrigin, originOverlayRect, committedOnPointerDown, initialRange, startClientX, startClientY) {
27258
- cachedScrollerRectRef.current = scrollRef.current?.getBoundingClientRect() ?? null;
27259
- selectionDragRef.current = {
27376
+ function startCellSelection(target, pointerId, anchor, axis, originCell, pointerOrigin, originOverlayRect, committedOnPointerDown, initialRange, startClientX, startClientY) {
27377
+ clearPendingSelectionDrag();
27378
+ const previewRange = normalizeRange2(initialRange);
27379
+ pendingSelectionDragRef.current = {
27260
27380
  anchor,
27261
27381
  axis,
27262
27382
  contentScaleX: pointerOrigin.contentScaleX,
@@ -27268,16 +27388,14 @@ function XlsxGrid({
27268
27388
  originContentX: pointerOrigin.originContentX,
27269
27389
  originContentY: pointerOrigin.originContentY,
27270
27390
  pointerId,
27271
- previewRange: normalizeRange2(initialRange),
27391
+ previewRange,
27272
27392
  startClientX,
27273
27393
  startClientY
27274
27394
  };
27275
- selectionPreviewRangeRef.current = normalizeRange2(initialRange);
27276
- displayedSelectionRef.current = selectionPreviewRangeRef.current;
27277
- applyPreviewOverlay(selectionPreviewRangeRef.current);
27278
- setInteractionMode("select");
27279
- document.body.style.userSelect = "none";
27280
- installSelectionDragListeners(pointerId);
27395
+ selectionPreviewRangeRef.current = previewRange;
27396
+ displayedSelectionRef.current = previewRange;
27397
+ applyPreviewOverlay(previewRange);
27398
+ installPendingSelectionDragListeners(pointerId, target);
27281
27399
  }
27282
27400
  function resolveFillRange(sourceRange, cell) {
27283
27401
  const normalizedSource = normalizeRange2(sourceRange);
@@ -27833,52 +27951,62 @@ function XlsxGrid({
27833
27951
  ),
27834
27952
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("canvas", { ref: cornerHeaderCanvasRef, style: canvasCornerHeaderStyle })
27835
27953
  ] }),
27836
- editingCell && editingOverlayRect ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
27837
- "div",
27838
- {
27839
- style: {
27840
- left: editingOverlayRect.left,
27841
- position: "absolute",
27842
- top: editingOverlayRect.top,
27843
- width: editingOverlayRect.width,
27844
- height: editingOverlayRect.height,
27845
- zIndex: 28
27846
- },
27847
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
27848
- "input",
27849
- {
27850
- autoFocus: true,
27851
- onBlur: commitEditing,
27852
- onChange: (event) => setEditingValue(event.target.value),
27853
- onKeyDown: (event) => {
27854
- event.stopPropagation();
27855
- if (event.key === "Enter") {
27856
- event.preventDefault();
27857
- commitEditing();
27858
- return;
27859
- }
27860
- if (event.key === "Escape") {
27861
- event.preventDefault();
27862
- cancelEditing();
27863
- }
27864
- },
27865
- style: {
27866
- backgroundColor: resolveSheetSurface(activeSheet, palette),
27867
- border: 0,
27868
- boxShadow: `inset 0 0 0 ${selectionBorderWidth}px ${selectionStroke}`,
27869
- color: "#000000",
27870
- font: resolveCanvasFont(getCellData(editingCell.row, editingCell.col).style, 12 * zoomFactor),
27871
- height: "100%",
27872
- margin: 0,
27873
- outline: "none",
27874
- padding: scaleCssLengthExpression(DEFAULT_CELL_PADDING, zoomFactor),
27875
- width: "100%"
27876
- },
27877
- value: editingValue
27878
- }
27879
- )
27880
- }
27881
- ) : null,
27954
+ editingCell && editingOverlayRect ? (() => {
27955
+ const editingCellStyle = getCellData(editingCell.row, editingCell.col).style;
27956
+ const editingBackground = typeof editingCellStyle.backgroundColor === "string" ? editingCellStyle.backgroundColor : resolveSheetSurface(activeSheet, palette);
27957
+ const editingColor = typeof editingCellStyle.color === "string" ? editingCellStyle.color : resolveReadableTextColor(null, editingBackground, palette);
27958
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
27959
+ "div",
27960
+ {
27961
+ style: {
27962
+ left: editingOverlayRect.left,
27963
+ position: "absolute",
27964
+ top: editingOverlayRect.top,
27965
+ width: editingOverlayRect.width,
27966
+ height: editingOverlayRect.height,
27967
+ zIndex: 28
27968
+ },
27969
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
27970
+ "input",
27971
+ {
27972
+ ref: editingInputRef,
27973
+ autoFocus: true,
27974
+ onBlur: commitEditing,
27975
+ onChange: (event) => setEditingValue(event.target.value),
27976
+ onKeyDown: (event) => {
27977
+ event.stopPropagation();
27978
+ if (event.key === "Enter") {
27979
+ event.preventDefault();
27980
+ commitEditing();
27981
+ return;
27982
+ }
27983
+ if (event.key === "Escape") {
27984
+ event.preventDefault();
27985
+ cancelEditing();
27986
+ }
27987
+ },
27988
+ style: {
27989
+ backgroundColor: editingBackground,
27990
+ border: 0,
27991
+ boxShadow: `inset 0 0 0 ${selectionBorderWidth}px ${selectionStroke}`,
27992
+ boxSizing: "border-box",
27993
+ color: editingColor,
27994
+ display: "block",
27995
+ font: resolveCanvasFont(editingCellStyle, 12 * zoomFactor),
27996
+ height: "100%",
27997
+ margin: 0,
27998
+ minHeight: 0,
27999
+ outline: "none",
28000
+ overflow: "hidden",
28001
+ padding: scaleCssLengthExpression(DEFAULT_CELL_PADDING, zoomFactor),
28002
+ width: "100%"
28003
+ },
28004
+ value: editingValue
28005
+ }
28006
+ )
28007
+ }
28008
+ );
28009
+ })() : null,
27882
28010
  activeCellAdornment && activeCellAdornmentRect ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
27883
28011
  "div",
27884
28012
  {