@extend-ai/react-xlsx 0.10.1 → 0.10.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.cjs CHANGED
@@ -34,6 +34,8 @@ __export(index_exports, {
34
34
  XlsxFileSizeLimitExceededError: () => XlsxFileSizeLimitExceededError,
35
35
  XlsxViewer: () => XlsxViewer,
36
36
  XlsxViewerProvider: () => XlsxViewerProvider,
37
+ initWasm: () => initWasm,
38
+ setWasmSource: () => setWasmSource,
37
39
  useXlsxViewer: () => useXlsxViewer,
38
40
  useXlsxViewerCharts: () => useXlsxViewerCharts,
39
41
  useXlsxViewerController: () => useXlsxViewerController,
@@ -6421,13 +6423,58 @@ function tryRecalculate(workbook) {
6421
6423
 
6422
6424
  // src/wasm.ts
6423
6425
  var wasmModulePromise = null;
6426
+ var hasConfiguredWasmSource = false;
6427
+ var configuredWasmSource;
6428
+ var configuredWorkerWasmSource;
6429
+ function bufferSourceToArrayBuffer(source) {
6430
+ if (source instanceof ArrayBuffer) {
6431
+ return source.slice(0);
6432
+ }
6433
+ const bytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength);
6434
+ const copy = new Uint8Array(bytes);
6435
+ return copy.buffer;
6436
+ }
6437
+ function sourceToWorkerSource(source) {
6438
+ if (typeof source === "string") {
6439
+ return source;
6440
+ }
6441
+ if (typeof URL !== "undefined" && source instanceof URL) {
6442
+ return source.href;
6443
+ }
6444
+ if (typeof Request !== "undefined" && source instanceof Request) {
6445
+ return source.url;
6446
+ }
6447
+ if (source instanceof ArrayBuffer || ArrayBuffer.isView(source)) {
6448
+ return bufferSourceToArrayBuffer(source);
6449
+ }
6450
+ if (typeof WebAssembly !== "undefined" && source instanceof WebAssembly.Module) {
6451
+ return source;
6452
+ }
6453
+ return void 0;
6454
+ }
6455
+ function setWasmSource(source) {
6456
+ hasConfiguredWasmSource = true;
6457
+ configuredWasmSource = source;
6458
+ configuredWorkerWasmSource = sourceToWorkerSource(source);
6459
+ }
6460
+ function initWasm(source) {
6461
+ if (source !== void 0) {
6462
+ setWasmSource(source);
6463
+ }
6464
+ return getSheetsWasmModule();
6465
+ }
6466
+ function canUseConfiguredWasmSourceInWorker() {
6467
+ return !hasConfiguredWasmSource || configuredWorkerWasmSource !== void 0;
6468
+ }
6469
+ function getConfiguredWorkerWasmSource() {
6470
+ return configuredWorkerWasmSource;
6471
+ }
6424
6472
  function getSheetsWasmModule() {
6425
6473
  if (!wasmModulePromise) {
6426
6474
  wasmModulePromise = import("@dukelib/sheets-wasm").then(async (mod) => {
6427
- try {
6428
- const wasmAsset = await import("@dukelib/sheets-wasm/duke_sheets_wasm_bg.wasm?url");
6429
- await mod.default(wasmAsset.default);
6430
- } catch {
6475
+ if (configuredWasmSource !== void 0) {
6476
+ await mod.default(configuredWasmSource);
6477
+ } else {
6431
6478
  await mod.default();
6432
6479
  }
6433
6480
  return mod;
@@ -6477,7 +6524,8 @@ var XlsxWorkerClient = class {
6477
6524
  payload: {
6478
6525
  buffer: workerBuffer,
6479
6526
  showHiddenSheets,
6480
- skipXmlParsing
6527
+ skipXmlParsing,
6528
+ wasmSource: getConfiguredWorkerWasmSource()
6481
6529
  },
6482
6530
  type: "load"
6483
6531
  }, [workerBuffer]);
@@ -6496,7 +6544,8 @@ var XlsxWorkerClient = class {
6496
6544
  payload: {
6497
6545
  buffer: workerBuffer,
6498
6546
  showHiddenSheets,
6499
- skipXmlParsing
6547
+ skipXmlParsing,
6548
+ wasmSource: getConfiguredWorkerWasmSource()
6500
6549
  },
6501
6550
  type: "parseCharts"
6502
6551
  }, [workerBuffer]);
@@ -7843,7 +7892,7 @@ function useXlsxViewerController(options) {
7843
7892
  const shouldDeferLoading = deferLoadingAboveBytes > 0;
7844
7893
  const readOnly = requestedReadOnly || forcedReadOnly;
7845
7894
  const canResizeReadOnly = requestedReadOnly && allowResizeInReadOnly && !forcedReadOnly;
7846
- const workerSupported = useWorker && typeof Worker !== "undefined";
7895
+ const workerSupported = useWorker && typeof Worker !== "undefined" && canUseConfiguredWasmSourceInWorker();
7847
7896
  const shouldUseWorker = workerSupported && forcedReadOnly;
7848
7897
  const shouldForceReadOnlyForBuffer = React.useCallback((bufferByteLength) => !requestedReadOnly && readOnlyAboveBytes > 0 && bufferByteLength > readOnlyAboveBytes, [readOnlyAboveBytes, requestedReadOnly]);
7849
7898
  const disposeWorkerClient = React.useCallback(() => {
@@ -17376,13 +17425,16 @@ function rangesEqual(left, right) {
17376
17425
  function isPrintableKey(event) {
17377
17426
  return event.key.length === 1 && !event.altKey && !event.ctrlKey && !event.metaKey;
17378
17427
  }
17379
- function isInteractiveFocusTarget(target, container) {
17428
+ function getInteractiveFocusTarget(target) {
17380
17429
  if (!(target instanceof Element)) {
17381
- return false;
17430
+ return null;
17382
17431
  }
17383
- const interactiveElement = target.closest(
17432
+ return target.closest(
17384
17433
  "a[href], button, input, select, textarea, [contenteditable=''], [contenteditable='true'], [role='button'], [role='menu'], [role='menuitem'], [role='textbox'], [tabindex]:not([tabindex='-1'])"
17385
17434
  );
17435
+ }
17436
+ function isInteractiveFocusTarget(target, container) {
17437
+ const interactiveElement = getInteractiveFocusTarget(target);
17386
17438
  return Boolean(interactiveElement && interactiveElement !== container && container.contains(interactiveElement));
17387
17439
  }
17388
17440
  function buildPrefixSums(values) {
@@ -21088,8 +21140,10 @@ function GridRow({
21088
21140
  onCellClick,
21089
21141
  onCellDoubleClick,
21090
21142
  onCellPointerDown,
21143
+ onEditingBlur,
21091
21144
  onEditingCancel,
21092
21145
  onEditingCommit,
21146
+ onEditingNavigate,
21093
21147
  onEditingValueChange,
21094
21148
  onRowHeaderRef,
21095
21149
  onRowPointerDown,
@@ -21375,7 +21429,7 @@ function GridRow({
21375
21429
  "input",
21376
21430
  {
21377
21431
  autoFocus: true,
21378
- onBlur: onEditingCommit,
21432
+ onBlur: onEditingBlur,
21379
21433
  onChange: (event) => onEditingValueChange(event.target.value),
21380
21434
  onKeyDown: (event) => {
21381
21435
  event.stopPropagation();
@@ -21387,6 +21441,11 @@ function GridRow({
21387
21441
  if (event.key === "Escape") {
21388
21442
  event.preventDefault();
21389
21443
  onEditingCancel();
21444
+ return;
21445
+ }
21446
+ if (event.key === "ArrowDown" || event.key === "ArrowLeft" || event.key === "ArrowRight" || event.key === "ArrowUp") {
21447
+ event.preventDefault();
21448
+ onEditingNavigate(event.key, event.currentTarget.value);
21390
21449
  }
21391
21450
  },
21392
21451
  style: {
@@ -21462,7 +21521,7 @@ function GridRow({
21462
21521
  ] });
21463
21522
  }
21464
21523
  var MemoGridRow = React4.memo(GridRow, (prev, next) => {
21465
- if (prev.actualRow !== next.actualRow || prev.rowHeight !== next.rowHeight || prev.headerLabelLiveScale !== next.headerLabelLiveScale || prev.palette !== next.palette || prev.readOnly !== next.readOnly || prev.visibleCols !== next.visibleCols || prev.leadingSpacerWidth !== next.leadingSpacerWidth || prev.rowHeaderWidth !== next.rowHeaderWidth || prev.stickyLeftByCol !== next.stickyLeftByCol || prev.stickyTop !== next.stickyTop || prev.trailingSpacerWidth !== next.trailingSpacerWidth || prev.zoomFactor !== next.zoomFactor || prev.getCellData !== next.getCellData || prev.onCellClick !== next.onCellClick || prev.onCellDoubleClick !== next.onCellDoubleClick || prev.onCellPointerDown !== next.onCellPointerDown || prev.onEditingCancel !== next.onEditingCancel || prev.onEditingCommit !== next.onEditingCommit || prev.onEditingValueChange !== next.onEditingValueChange || prev.onRowHeaderRef !== next.onRowHeaderRef || prev.onRowPointerDown !== next.onRowPointerDown || prev.onRowResizePointerDown !== next.onRowResizePointerDown || prev.renderCellAdornment !== next.renderCellAdornment) {
21524
+ if (prev.actualRow !== next.actualRow || prev.rowHeight !== next.rowHeight || prev.headerLabelLiveScale !== next.headerLabelLiveScale || prev.palette !== next.palette || prev.readOnly !== next.readOnly || prev.visibleCols !== next.visibleCols || prev.leadingSpacerWidth !== next.leadingSpacerWidth || prev.rowHeaderWidth !== next.rowHeaderWidth || prev.stickyLeftByCol !== next.stickyLeftByCol || prev.stickyTop !== next.stickyTop || prev.trailingSpacerWidth !== next.trailingSpacerWidth || prev.zoomFactor !== next.zoomFactor || prev.getCellData !== next.getCellData || prev.onCellClick !== next.onCellClick || prev.onCellDoubleClick !== next.onCellDoubleClick || prev.onCellPointerDown !== next.onCellPointerDown || prev.onEditingBlur !== next.onEditingBlur || prev.onEditingCancel !== next.onEditingCancel || prev.onEditingCommit !== next.onEditingCommit || prev.onEditingNavigate !== next.onEditingNavigate || prev.onEditingValueChange !== next.onEditingValueChange || prev.onRowHeaderRef !== next.onRowHeaderRef || prev.onRowPointerDown !== next.onRowPointerDown || prev.onRowResizePointerDown !== next.onRowResizePointerDown || prev.renderCellAdornment !== next.renderCellAdornment) {
21466
21525
  return false;
21467
21526
  }
21468
21527
  const prevEditingCol = prev.editingCell?.row === prev.actualRow ? prev.editingCell.col : -1;
@@ -21563,6 +21622,9 @@ function XlsxGrid({
21563
21622
  const scrollRef = React4.useRef(null);
21564
21623
  const wrapperRef = React4.useRef(null);
21565
21624
  const tableRef = React4.useRef(null);
21625
+ const gridKeyboardActiveRef = React4.useRef(false);
21626
+ const gridKeyboardHandlerRef = React4.useRef(null);
21627
+ const axisSelectionRef = React4.useRef(null);
21566
21628
  const scrollBodyCanvasRef = React4.useRef(null);
21567
21629
  const topBodyCanvasRef = React4.useRef(null);
21568
21630
  const leftBodyCanvasRef = React4.useRef(null);
@@ -23204,9 +23266,50 @@ function XlsxGrid({
23204
23266
  selectionPreviewRangeRef.current = null;
23205
23267
  setInteractionMode("idle");
23206
23268
  }, [activeSheetIndex, clearGlobalCursor, revision]);
23207
- const focusGrid = React4.useCallback((options) => {
23208
- scrollRef.current?.focus(options);
23269
+ const focusGridElement = React4.useCallback((element, options) => {
23270
+ if (document.activeElement !== element) {
23271
+ element.focus(options ?? { preventScroll: true });
23272
+ }
23209
23273
  }, []);
23274
+ const focusGrid = React4.useCallback((options) => {
23275
+ const scroller = scrollRef.current;
23276
+ if (scroller) {
23277
+ gridKeyboardActiveRef.current = true;
23278
+ focusGridElement(scroller, options);
23279
+ }
23280
+ }, [focusGridElement]);
23281
+ React4.useEffect(() => {
23282
+ const handleDocumentPointerDown = (event) => {
23283
+ const scroller = scrollRef.current;
23284
+ if (!scroller || !(event.target instanceof Node) || !scroller.contains(event.target)) {
23285
+ gridKeyboardActiveRef.current = false;
23286
+ return;
23287
+ }
23288
+ if (isInteractiveFocusTarget(event.target, scroller)) {
23289
+ gridKeyboardActiveRef.current = false;
23290
+ return;
23291
+ }
23292
+ gridKeyboardActiveRef.current = true;
23293
+ focusGridElement(scroller);
23294
+ };
23295
+ const handleDocumentKeyDown = (event) => {
23296
+ if (!gridKeyboardActiveRef.current || event.defaultPrevented) {
23297
+ return;
23298
+ }
23299
+ const scroller = scrollRef.current;
23300
+ const interactiveTarget = getInteractiveFocusTarget(event.target);
23301
+ if (!scroller || interactiveTarget && interactiveTarget !== scroller) {
23302
+ return;
23303
+ }
23304
+ gridKeyboardHandlerRef.current?.(event);
23305
+ };
23306
+ document.addEventListener("pointerdown", handleDocumentPointerDown, true);
23307
+ document.addEventListener("keydown", handleDocumentKeyDown);
23308
+ return () => {
23309
+ document.removeEventListener("pointerdown", handleDocumentPointerDown, true);
23310
+ document.removeEventListener("keydown", handleDocumentKeyDown);
23311
+ };
23312
+ }, [focusGridElement]);
23210
23313
  const openHyperlink = React4.useCallback((target, location) => {
23211
23314
  const internalTarget = parseInternalSheetLink(location ?? target);
23212
23315
  if (internalTarget) {
@@ -23245,21 +23348,74 @@ function XlsxGrid({
23245
23348
  return;
23246
23349
  }
23247
23350
  if (readOnly) {
23351
+ editingCellRef.current = null;
23248
23352
  setEditingCell(null);
23249
23353
  setEditingValue("");
23250
23354
  focusGrid();
23251
23355
  return;
23252
23356
  }
23253
23357
  setCellValue(editingCell, editingValue);
23358
+ editingCellRef.current = null;
23254
23359
  setEditingCell(null);
23255
23360
  setEditingValue("");
23256
23361
  focusGrid();
23257
23362
  }, [editingCell, editingValue, focusGrid, readOnly, setCellValue]);
23258
23363
  const cancelEditing = React4.useCallback(() => {
23364
+ editingCellRef.current = null;
23259
23365
  setEditingCell(null);
23260
23366
  setEditingValue("");
23261
23367
  focusGrid();
23262
23368
  }, [focusGrid]);
23369
+ const handleEditingBlur = React4.useCallback(() => {
23370
+ if (!editingCellRef.current) {
23371
+ return;
23372
+ }
23373
+ commitEditing();
23374
+ }, [commitEditing]);
23375
+ const handleEditingNavigate = React4.useCallback((key, value) => {
23376
+ const cell = editingCellRef.current;
23377
+ if (!cell) {
23378
+ return;
23379
+ }
23380
+ const currentRowIndex = rowIndexByActual.get(cell.row);
23381
+ const currentColIndex = colIndexByActual.get(cell.col);
23382
+ if (currentRowIndex === void 0 || currentColIndex === void 0) {
23383
+ if (!readOnlyRef.current) {
23384
+ setCellValue(cell, value);
23385
+ }
23386
+ editingCellRef.current = null;
23387
+ setEditingCell(null);
23388
+ setEditingValue("");
23389
+ focusGrid();
23390
+ return;
23391
+ }
23392
+ let nextRowIndex = currentRowIndex;
23393
+ let nextColIndex = currentColIndex;
23394
+ switch (key) {
23395
+ case "ArrowDown":
23396
+ nextRowIndex += 1;
23397
+ break;
23398
+ case "ArrowLeft":
23399
+ nextColIndex -= 1;
23400
+ break;
23401
+ case "ArrowRight":
23402
+ nextColIndex += 1;
23403
+ break;
23404
+ case "ArrowUp":
23405
+ nextRowIndex -= 1;
23406
+ break;
23407
+ default:
23408
+ return;
23409
+ }
23410
+ if (!readOnlyRef.current) {
23411
+ setCellValue(cell, value);
23412
+ }
23413
+ editingCellRef.current = null;
23414
+ setEditingCell(null);
23415
+ setEditingValue("");
23416
+ moveSelection(nextRowIndex, nextColIndex, false);
23417
+ focusGrid();
23418
+ }, [colIndexByActual, focusGrid, rowIndexByActual, setCellValue, visibleCols, visibleRows]);
23263
23419
  React4.useEffect(() => {
23264
23420
  commitEditingRef.current = commitEditing;
23265
23421
  }, [commitEditing]);
@@ -24232,6 +24388,7 @@ function XlsxGrid({
24232
24388
  overlay.style.visibility = "visible";
24233
24389
  }, [getCellData, resolveOverlayRect, zoomFactor]);
24234
24390
  const commitSelectionRange = React4.useCallback((range) => {
24391
+ gridKeyboardActiveRef.current = true;
24235
24392
  const normalized = normalizeRange2(range);
24236
24393
  if (selectionRef.current && rangesEqual(selectionRef.current, normalized) && isSameCell(activeCellRef.current, normalized.end) && selectedChartIdRef.current === null && selectedImageIdRef.current === null) {
24237
24394
  return;
@@ -24525,6 +24682,23 @@ function XlsxGrid({
24525
24682
  if (nextRange && (dragState?.didDrag || !dragState?.committedOnPointerDown)) {
24526
24683
  selectionPreviewRangeRef.current = nextRange;
24527
24684
  displayedSelectionRef.current = nextRange;
24685
+ if (dragState?.axis === "column") {
24686
+ const normalized = normalizeRange2(nextRange);
24687
+ axisSelectionRef.current = {
24688
+ axis: "column",
24689
+ startCol: normalized.start.col,
24690
+ endCol: normalized.end.col
24691
+ };
24692
+ } else if (dragState?.axis === "row") {
24693
+ const normalized = normalizeRange2(nextRange);
24694
+ axisSelectionRef.current = {
24695
+ axis: "row",
24696
+ startRow: normalized.start.row,
24697
+ endRow: normalized.end.row
24698
+ };
24699
+ } else {
24700
+ axisSelectionRef.current = null;
24701
+ }
24528
24702
  commitSelectionRange(nextRange);
24529
24703
  } else if (!nextRange) {
24530
24704
  selectionPreviewRangeRef.current = null;
@@ -24643,6 +24817,7 @@ function XlsxGrid({
24643
24817
  }
24644
24818
  event.preventDefault();
24645
24819
  focusGrid();
24820
+ axisSelectionRef.current = null;
24646
24821
  const targetCell = event.currentTarget.colSpan > 1 || event.currentTarget.rowSpan > 1 ? resolvePointerCellFromGeometry(event.clientX, event.clientY) ?? cell : cell;
24647
24822
  const currentSelection = selectionRef.current;
24648
24823
  const anchor = event.shiftKey && currentSelection ? currentSelection.start : targetCell;
@@ -24718,6 +24893,7 @@ function XlsxGrid({
24718
24893
  event.clientX,
24719
24894
  event.clientY
24720
24895
  );
24896
+ axisSelectionRef.current = { axis: "row", startRow: anchorRow, endRow: actualRow };
24721
24897
  commitSelectionRange(initialRange);
24722
24898
  }, [commitSelectionRange, firstVisibleCol, focusGrid, lastVisibleCol, resolveRowPointerOrigin]);
24723
24899
  const handleColumnPointerDown = React4.useCallback((event, actualCol) => {
@@ -24749,6 +24925,7 @@ function XlsxGrid({
24749
24925
  event.clientX,
24750
24926
  event.clientY
24751
24927
  );
24928
+ axisSelectionRef.current = { axis: "column", startCol: anchorCol, endCol: actualCol };
24752
24929
  commitSelectionRange(initialRange);
24753
24930
  }, [commitSelectionRange, firstVisibleRow, focusGrid, lastVisibleRow, resolveColumnPointerOrigin]);
24754
24931
  const handleRowResizePointerDown = React4.useCallback((event, actualRow, rowHeight) => {
@@ -25005,6 +25182,7 @@ function XlsxGrid({
25005
25182
  }
25006
25183
  event.preventDefault();
25007
25184
  focusGrid();
25185
+ axisSelectionRef.current = null;
25008
25186
  const currentSelection = selectionRef.current;
25009
25187
  const anchor = event.shiftKey && currentSelection ? currentSelection.start : cell;
25010
25188
  const initialRange = normalizeRange2({ start: anchor, end: cell });
@@ -25114,6 +25292,7 @@ function XlsxGrid({
25114
25292
  event.clientX,
25115
25293
  event.clientY
25116
25294
  );
25295
+ axisSelectionRef.current = { axis: "column", startCol: anchorCol, endCol: actualCol };
25117
25296
  commitSelectionRange(initialRange);
25118
25297
  }, [
25119
25298
  colIndexByActual,
@@ -25172,6 +25351,7 @@ function XlsxGrid({
25172
25351
  event.clientX,
25173
25352
  event.clientY
25174
25353
  );
25354
+ axisSelectionRef.current = { axis: "row", startRow: anchorRow, endRow: actualRow };
25175
25355
  commitSelectionRange(initialRange);
25176
25356
  }, [
25177
25357
  colPrefixSums,
@@ -27678,6 +27858,11 @@ function XlsxGrid({
27678
27858
  if (nextRow === void 0 || nextCol === void 0) {
27679
27859
  return;
27680
27860
  }
27861
+ const nextRange = { start: { row: nextRow, col: nextCol }, end: { row: nextRow, col: nextCol } };
27862
+ axisSelectionRef.current = null;
27863
+ selectionPreviewRangeRef.current = null;
27864
+ displayedSelectionRef.current = nextRange;
27865
+ applyPreviewOverlay(nextRange);
27681
27866
  selectCell({ row: nextRow, col: nextCol }, extend ? { extend: true } : void 0);
27682
27867
  ensureCellVisible(clampedRowIndex, clampedColIndex);
27683
27868
  }
@@ -27701,6 +27886,214 @@ function XlsxGrid({
27701
27886
  const targetOffset = direction > 0 ? currentOffset + viewportWidth : currentOffset - viewportWidth;
27702
27887
  return Math.max(0, Math.min(findIndexForOffsetPrefix(colPrefixSums, targetOffset), visibleCols.length - 1));
27703
27888
  }
27889
+ function resolveColumnSelectionNavigation(eventKey) {
27890
+ const axisSelection = axisSelectionRef.current;
27891
+ if (axisSelection?.axis !== "column" || firstVisibleRow === void 0) {
27892
+ return null;
27893
+ }
27894
+ const startCol = Math.min(axisSelection.startCol, axisSelection.endCol);
27895
+ const endCol = Math.max(axisSelection.startCol, axisSelection.endCol);
27896
+ const targetCol = eventKey === "ArrowLeft" ? startCol - 1 : eventKey === "ArrowRight" ? endCol + 1 : null;
27897
+ if (targetCol === null) {
27898
+ return null;
27899
+ }
27900
+ const rowIndex = rowIndexByActual.get(firstVisibleRow);
27901
+ const colIndex = colIndexByActual.get(targetCol);
27902
+ if (rowIndex === void 0 || colIndex === void 0) {
27903
+ return null;
27904
+ }
27905
+ return { colIndex, rowIndex };
27906
+ }
27907
+ function resolveRowSelectionNavigation(eventKey) {
27908
+ const axisSelection = axisSelectionRef.current;
27909
+ if (axisSelection?.axis !== "row" || firstVisibleCol === void 0) {
27910
+ return null;
27911
+ }
27912
+ const startRow = Math.min(axisSelection.startRow, axisSelection.endRow);
27913
+ const endRow = Math.max(axisSelection.startRow, axisSelection.endRow);
27914
+ const targetRow = eventKey === "ArrowUp" ? startRow - 1 : eventKey === "ArrowDown" ? endRow + 1 : null;
27915
+ if (targetRow === null) {
27916
+ return null;
27917
+ }
27918
+ const rowIndex = rowIndexByActual.get(targetRow);
27919
+ const colIndex = colIndexByActual.get(firstVisibleCol);
27920
+ if (rowIndex === void 0 || colIndex === void 0) {
27921
+ return null;
27922
+ }
27923
+ return { colIndex, rowIndex };
27924
+ }
27925
+ function handleGridKeyDown(event) {
27926
+ if (editingCell) {
27927
+ return;
27928
+ }
27929
+ if (!readOnly && (event.metaKey || event.ctrlKey) && !event.altKey) {
27930
+ const normalizedKey = event.key.toLowerCase();
27931
+ if (normalizedKey === "z" && event.shiftKey) {
27932
+ event.preventDefault();
27933
+ redo();
27934
+ return;
27935
+ }
27936
+ if (normalizedKey === "z") {
27937
+ event.preventDefault();
27938
+ undo();
27939
+ return;
27940
+ }
27941
+ if (normalizedKey === "y") {
27942
+ event.preventDefault();
27943
+ redo();
27944
+ return;
27945
+ }
27946
+ }
27947
+ const currentCell = resolveCurrentCell();
27948
+ if (!currentCell) {
27949
+ return;
27950
+ }
27951
+ const currentRowIndex = rowIndexByActual.get(currentCell.row) ?? 0;
27952
+ const currentColIndex = colIndexByActual.get(currentCell.col) ?? 0;
27953
+ const isCommandNavigation = event.ctrlKey || event.metaKey;
27954
+ if (!readOnly && isPrintableKey(event)) {
27955
+ event.preventDefault();
27956
+ startEditing(currentCell, event.key);
27957
+ return;
27958
+ }
27959
+ switch (event.key) {
27960
+ case "ArrowDown":
27961
+ event.preventDefault();
27962
+ if (!event.shiftKey && !isCommandNavigation) {
27963
+ const target = resolveRowSelectionNavigation(event.key);
27964
+ if (target) {
27965
+ moveSelection(target.rowIndex, target.colIndex, false);
27966
+ break;
27967
+ }
27968
+ }
27969
+ moveSelection(
27970
+ isCommandNavigation ? rowIndexByActual.get(resolveLastUsedVisibleIndex(visibleRows, activeSheet?.maxUsedRow ?? -1)) ?? visibleRows.length - 1 : currentRowIndex + 1,
27971
+ currentColIndex,
27972
+ event.shiftKey
27973
+ );
27974
+ break;
27975
+ case "ArrowUp":
27976
+ event.preventDefault();
27977
+ if (!event.shiftKey && !isCommandNavigation) {
27978
+ const target = resolveRowSelectionNavigation(event.key);
27979
+ if (target) {
27980
+ moveSelection(target.rowIndex, target.colIndex, false);
27981
+ break;
27982
+ }
27983
+ }
27984
+ moveSelection(
27985
+ isCommandNavigation ? rowIndexByActual.get(resolveFirstUsedVisibleIndex(visibleRows, activeSheet?.minUsedRow ?? -1)) ?? 0 : currentRowIndex - 1,
27986
+ currentColIndex,
27987
+ event.shiftKey
27988
+ );
27989
+ break;
27990
+ case "ArrowLeft":
27991
+ event.preventDefault();
27992
+ if (!event.shiftKey && !isCommandNavigation) {
27993
+ const target = resolveColumnSelectionNavigation(event.key);
27994
+ if (target) {
27995
+ moveSelection(target.rowIndex, target.colIndex, false);
27996
+ break;
27997
+ }
27998
+ }
27999
+ moveSelection(
28000
+ currentRowIndex,
28001
+ isCommandNavigation ? colIndexByActual.get(resolveFirstUsedVisibleIndex(visibleCols, activeSheet?.minUsedCol ?? -1)) ?? 0 : currentColIndex - 1,
28002
+ event.shiftKey
28003
+ );
28004
+ break;
28005
+ case "ArrowRight":
28006
+ event.preventDefault();
28007
+ if (!event.shiftKey && !isCommandNavigation) {
28008
+ const target = resolveColumnSelectionNavigation(event.key);
28009
+ if (target) {
28010
+ moveSelection(target.rowIndex, target.colIndex, false);
28011
+ break;
28012
+ }
28013
+ }
28014
+ moveSelection(
28015
+ currentRowIndex,
28016
+ isCommandNavigation ? colIndexByActual.get(resolveLastUsedVisibleIndex(visibleCols, activeSheet?.maxUsedCol ?? -1)) ?? visibleCols.length - 1 : currentColIndex + 1,
28017
+ event.shiftKey
28018
+ );
28019
+ break;
28020
+ case "Home":
28021
+ event.preventDefault();
28022
+ moveSelection(
28023
+ isCommandNavigation ? rowIndexByActual.get(resolveFirstUsedVisibleIndex(visibleRows, activeSheet?.minUsedRow ?? -1)) ?? 0 : currentRowIndex,
28024
+ colIndexByActual.get(resolveFirstUsedVisibleIndex(visibleCols, activeSheet?.minUsedCol ?? -1)) ?? 0,
28025
+ event.shiftKey
28026
+ );
28027
+ break;
28028
+ case "End":
28029
+ event.preventDefault();
28030
+ moveSelection(
28031
+ isCommandNavigation ? rowIndexByActual.get(resolveLastUsedVisibleIndex(visibleRows, activeSheet?.maxUsedRow ?? -1)) ?? visibleRows.length - 1 : currentRowIndex,
28032
+ colIndexByActual.get(resolveLastUsedVisibleIndex(visibleCols, activeSheet?.maxUsedCol ?? -1)) ?? visibleCols.length - 1,
28033
+ event.shiftKey
28034
+ );
28035
+ break;
28036
+ case "PageDown":
28037
+ event.preventDefault();
28038
+ if (event.altKey) {
28039
+ moveSelection(currentRowIndex, resolvePageColIndex(currentColIndex, 1), event.shiftKey);
28040
+ break;
28041
+ }
28042
+ moveSelection(resolvePageRowIndex(currentRowIndex, 1), currentColIndex, event.shiftKey);
28043
+ break;
28044
+ case "PageUp":
28045
+ event.preventDefault();
28046
+ if (event.altKey) {
28047
+ moveSelection(currentRowIndex, resolvePageColIndex(currentColIndex, -1), event.shiftKey);
28048
+ break;
28049
+ }
28050
+ moveSelection(resolvePageRowIndex(currentRowIndex, -1), currentColIndex, event.shiftKey);
28051
+ break;
28052
+ case "Tab":
28053
+ event.preventDefault();
28054
+ if (event.shiftKey) {
28055
+ moveSelection(
28056
+ currentColIndex > 0 ? currentRowIndex : currentRowIndex - 1,
28057
+ currentColIndex > 0 ? currentColIndex - 1 : visibleCols.length - 1,
28058
+ false
28059
+ );
28060
+ } else {
28061
+ moveSelection(
28062
+ currentColIndex < visibleCols.length - 1 ? currentRowIndex : currentRowIndex + 1,
28063
+ currentColIndex < visibleCols.length - 1 ? currentColIndex + 1 : 0,
28064
+ false
28065
+ );
28066
+ }
28067
+ break;
28068
+ case "Enter":
28069
+ event.preventDefault();
28070
+ if (event.metaKey || event.ctrlKey || event.altKey) {
28071
+ break;
28072
+ }
28073
+ if (event.shiftKey) {
28074
+ moveSelection(currentRowIndex - 1, currentColIndex, false);
28075
+ break;
28076
+ }
28077
+ moveSelection(currentRowIndex + 1, currentColIndex, false);
28078
+ break;
28079
+ case "Backspace":
28080
+ case "Delete":
28081
+ if (!readOnly) {
28082
+ event.preventDefault();
28083
+ clearSelectedCells();
28084
+ }
28085
+ break;
28086
+ case "F2":
28087
+ if (!readOnly) {
28088
+ event.preventDefault();
28089
+ startEditing(currentCell);
28090
+ }
28091
+ break;
28092
+ default:
28093
+ break;
28094
+ }
28095
+ }
28096
+ gridKeyboardHandlerRef.current = handleGridKeyDown;
27704
28097
  const scrollerViewportProps = {
27705
28098
  key: activeTabIndex,
27706
28099
  ref: scrollRef,
@@ -27736,153 +28129,20 @@ function XlsxGrid({
27736
28129
  if (isInteractiveFocusTarget(event.target, event.currentTarget)) {
27737
28130
  return;
27738
28131
  }
27739
- if (document.activeElement !== event.currentTarget) {
27740
- event.currentTarget.focus({ preventScroll: true });
27741
- }
28132
+ gridKeyboardActiveRef.current = true;
28133
+ focusGridElement(event.currentTarget);
27742
28134
  },
27743
- onKeyDown: (event) => {
27744
- if (editingCell) {
27745
- return;
27746
- }
27747
- if (!readOnly && (event.metaKey || event.ctrlKey) && !event.altKey) {
27748
- const normalizedKey = event.key.toLowerCase();
27749
- if (normalizedKey === "z" && event.shiftKey) {
27750
- event.preventDefault();
27751
- redo();
27752
- return;
27753
- }
27754
- if (normalizedKey === "z") {
27755
- event.preventDefault();
27756
- undo();
27757
- return;
27758
- }
27759
- if (normalizedKey === "y") {
27760
- event.preventDefault();
27761
- redo();
27762
- return;
27763
- }
27764
- }
27765
- const currentCell = resolveCurrentCell();
27766
- if (!currentCell) {
27767
- return;
27768
- }
27769
- const currentRowIndex = rowIndexByActual.get(currentCell.row) ?? 0;
27770
- const currentColIndex = colIndexByActual.get(currentCell.col) ?? 0;
27771
- const isCommandNavigation = event.ctrlKey || event.metaKey;
27772
- if (!readOnly && isPrintableKey(event)) {
27773
- event.preventDefault();
27774
- startEditing(currentCell, event.key);
28135
+ onClickCapture: (event) => {
28136
+ if (isInteractiveFocusTarget(event.target, event.currentTarget)) {
27775
28137
  return;
27776
28138
  }
27777
- switch (event.key) {
27778
- case "ArrowDown":
27779
- event.preventDefault();
27780
- moveSelection(
27781
- isCommandNavigation ? rowIndexByActual.get(resolveLastUsedVisibleIndex(visibleRows, activeSheet?.maxUsedRow ?? -1)) ?? visibleRows.length - 1 : currentRowIndex + 1,
27782
- currentColIndex,
27783
- event.shiftKey
27784
- );
27785
- break;
27786
- case "ArrowUp":
27787
- event.preventDefault();
27788
- moveSelection(
27789
- isCommandNavigation ? rowIndexByActual.get(resolveFirstUsedVisibleIndex(visibleRows, activeSheet?.minUsedRow ?? -1)) ?? 0 : currentRowIndex - 1,
27790
- currentColIndex,
27791
- event.shiftKey
27792
- );
27793
- break;
27794
- case "ArrowLeft":
27795
- event.preventDefault();
27796
- moveSelection(
27797
- currentRowIndex,
27798
- isCommandNavigation ? colIndexByActual.get(resolveFirstUsedVisibleIndex(visibleCols, activeSheet?.minUsedCol ?? -1)) ?? 0 : currentColIndex - 1,
27799
- event.shiftKey
27800
- );
27801
- break;
27802
- case "ArrowRight":
27803
- event.preventDefault();
27804
- moveSelection(
27805
- currentRowIndex,
27806
- isCommandNavigation ? colIndexByActual.get(resolveLastUsedVisibleIndex(visibleCols, activeSheet?.maxUsedCol ?? -1)) ?? visibleCols.length - 1 : currentColIndex + 1,
27807
- event.shiftKey
27808
- );
27809
- break;
27810
- case "Home":
27811
- event.preventDefault();
27812
- moveSelection(
27813
- isCommandNavigation ? rowIndexByActual.get(resolveFirstUsedVisibleIndex(visibleRows, activeSheet?.minUsedRow ?? -1)) ?? 0 : currentRowIndex,
27814
- colIndexByActual.get(resolveFirstUsedVisibleIndex(visibleCols, activeSheet?.minUsedCol ?? -1)) ?? 0,
27815
- event.shiftKey
27816
- );
27817
- break;
27818
- case "End":
27819
- event.preventDefault();
27820
- moveSelection(
27821
- isCommandNavigation ? rowIndexByActual.get(resolveLastUsedVisibleIndex(visibleRows, activeSheet?.maxUsedRow ?? -1)) ?? visibleRows.length - 1 : currentRowIndex,
27822
- colIndexByActual.get(resolveLastUsedVisibleIndex(visibleCols, activeSheet?.maxUsedCol ?? -1)) ?? visibleCols.length - 1,
27823
- event.shiftKey
27824
- );
27825
- break;
27826
- case "PageDown":
27827
- event.preventDefault();
27828
- if (event.altKey) {
27829
- moveSelection(currentRowIndex, resolvePageColIndex(currentColIndex, 1), event.shiftKey);
27830
- break;
27831
- }
27832
- moveSelection(resolvePageRowIndex(currentRowIndex, 1), currentColIndex, event.shiftKey);
27833
- break;
27834
- case "PageUp":
27835
- event.preventDefault();
27836
- if (event.altKey) {
27837
- moveSelection(currentRowIndex, resolvePageColIndex(currentColIndex, -1), event.shiftKey);
27838
- break;
27839
- }
27840
- moveSelection(resolvePageRowIndex(currentRowIndex, -1), currentColIndex, event.shiftKey);
27841
- break;
27842
- case "Tab":
27843
- event.preventDefault();
27844
- if (event.shiftKey) {
27845
- moveSelection(
27846
- currentColIndex > 0 ? currentRowIndex : currentRowIndex - 1,
27847
- currentColIndex > 0 ? currentColIndex - 1 : visibleCols.length - 1,
27848
- false
27849
- );
27850
- } else {
27851
- moveSelection(
27852
- currentColIndex < visibleCols.length - 1 ? currentRowIndex : currentRowIndex + 1,
27853
- currentColIndex < visibleCols.length - 1 ? currentColIndex + 1 : 0,
27854
- false
27855
- );
27856
- }
27857
- break;
27858
- case "Enter":
27859
- event.preventDefault();
27860
- if (event.metaKey || event.ctrlKey || event.altKey) {
27861
- break;
27862
- }
27863
- if (event.shiftKey) {
27864
- moveSelection(currentRowIndex - 1, currentColIndex, false);
27865
- break;
27866
- }
27867
- moveSelection(currentRowIndex + 1, currentColIndex, false);
27868
- break;
27869
- case "Backspace":
27870
- case "Delete":
27871
- if (!readOnly) {
27872
- event.preventDefault();
27873
- clearSelectedCells();
27874
- }
27875
- break;
27876
- case "F2":
27877
- if (!readOnly) {
27878
- event.preventDefault();
27879
- startEditing(currentCell);
27880
- }
27881
- break;
27882
- default:
27883
- break;
27884
- }
28139
+ gridKeyboardActiveRef.current = true;
28140
+ focusGridElement(event.currentTarget);
28141
+ },
28142
+ onFocus: () => {
28143
+ gridKeyboardActiveRef.current = true;
27885
28144
  },
28145
+ onKeyDown: handleGridKeyDown,
27886
28146
  onPaste: (event) => {
27887
28147
  if (editingCell || readOnly) {
27888
28148
  return;
@@ -28132,7 +28392,7 @@ function XlsxGrid({
28132
28392
  {
28133
28393
  ref: editingInputRef,
28134
28394
  autoFocus: true,
28135
- onBlur: commitEditing,
28395
+ onBlur: handleEditingBlur,
28136
28396
  onChange: (event) => setEditingValue(event.target.value),
28137
28397
  onKeyDown: (event) => {
28138
28398
  event.stopPropagation();
@@ -28144,6 +28404,11 @@ function XlsxGrid({
28144
28404
  if (event.key === "Escape") {
28145
28405
  event.preventDefault();
28146
28406
  cancelEditing();
28407
+ return;
28408
+ }
28409
+ if (event.key === "ArrowDown" || event.key === "ArrowLeft" || event.key === "ArrowRight" || event.key === "ArrowUp") {
28410
+ event.preventDefault();
28411
+ handleEditingNavigate(event.key, event.currentTarget.value);
28147
28412
  }
28148
28413
  },
28149
28414
  style: {
@@ -28298,8 +28563,10 @@ function XlsxGrid({
28298
28563
  onCellClick: handleCellClick,
28299
28564
  onCellDoubleClick: handleCellDoubleClick,
28300
28565
  onCellPointerDown: handleCellPointerDown,
28566
+ onEditingBlur: handleEditingBlur,
28301
28567
  onEditingCancel: cancelEditing,
28302
28568
  onEditingCommit: commitEditing,
28569
+ onEditingNavigate: handleEditingNavigate,
28303
28570
  onEditingValueChange: setEditingValue,
28304
28571
  headerLabelLiveScale,
28305
28572
  onRowHeaderRef: setRowHeaderRef,
@@ -29555,6 +29822,8 @@ function DefaultXlsxToolbar() {
29555
29822
  XlsxFileSizeLimitExceededError,
29556
29823
  XlsxViewer,
29557
29824
  XlsxViewerProvider,
29825
+ initWasm,
29826
+ setWasmSource,
29558
29827
  useXlsxViewer,
29559
29828
  useXlsxViewerCharts,
29560
29829
  useXlsxViewerController,