@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.js CHANGED
@@ -6373,13 +6373,58 @@ function tryRecalculate(workbook) {
6373
6373
 
6374
6374
  // src/wasm.ts
6375
6375
  var wasmModulePromise = null;
6376
+ var hasConfiguredWasmSource = false;
6377
+ var configuredWasmSource;
6378
+ var configuredWorkerWasmSource;
6379
+ function bufferSourceToArrayBuffer(source) {
6380
+ if (source instanceof ArrayBuffer) {
6381
+ return source.slice(0);
6382
+ }
6383
+ const bytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength);
6384
+ const copy = new Uint8Array(bytes);
6385
+ return copy.buffer;
6386
+ }
6387
+ function sourceToWorkerSource(source) {
6388
+ if (typeof source === "string") {
6389
+ return source;
6390
+ }
6391
+ if (typeof URL !== "undefined" && source instanceof URL) {
6392
+ return source.href;
6393
+ }
6394
+ if (typeof Request !== "undefined" && source instanceof Request) {
6395
+ return source.url;
6396
+ }
6397
+ if (source instanceof ArrayBuffer || ArrayBuffer.isView(source)) {
6398
+ return bufferSourceToArrayBuffer(source);
6399
+ }
6400
+ if (typeof WebAssembly !== "undefined" && source instanceof WebAssembly.Module) {
6401
+ return source;
6402
+ }
6403
+ return void 0;
6404
+ }
6405
+ function setWasmSource(source) {
6406
+ hasConfiguredWasmSource = true;
6407
+ configuredWasmSource = source;
6408
+ configuredWorkerWasmSource = sourceToWorkerSource(source);
6409
+ }
6410
+ function initWasm(source) {
6411
+ if (source !== void 0) {
6412
+ setWasmSource(source);
6413
+ }
6414
+ return getSheetsWasmModule();
6415
+ }
6416
+ function canUseConfiguredWasmSourceInWorker() {
6417
+ return !hasConfiguredWasmSource || configuredWorkerWasmSource !== void 0;
6418
+ }
6419
+ function getConfiguredWorkerWasmSource() {
6420
+ return configuredWorkerWasmSource;
6421
+ }
6376
6422
  function getSheetsWasmModule() {
6377
6423
  if (!wasmModulePromise) {
6378
6424
  wasmModulePromise = import("@dukelib/sheets-wasm").then(async (mod) => {
6379
- try {
6380
- const wasmAsset = await import("@dukelib/sheets-wasm/duke_sheets_wasm_bg.wasm?url");
6381
- await mod.default(wasmAsset.default);
6382
- } catch {
6425
+ if (configuredWasmSource !== void 0) {
6426
+ await mod.default(configuredWasmSource);
6427
+ } else {
6383
6428
  await mod.default();
6384
6429
  }
6385
6430
  return mod;
@@ -6428,7 +6473,8 @@ var XlsxWorkerClient = class {
6428
6473
  payload: {
6429
6474
  buffer: workerBuffer,
6430
6475
  showHiddenSheets,
6431
- skipXmlParsing
6476
+ skipXmlParsing,
6477
+ wasmSource: getConfiguredWorkerWasmSource()
6432
6478
  },
6433
6479
  type: "load"
6434
6480
  }, [workerBuffer]);
@@ -6447,7 +6493,8 @@ var XlsxWorkerClient = class {
6447
6493
  payload: {
6448
6494
  buffer: workerBuffer,
6449
6495
  showHiddenSheets,
6450
- skipXmlParsing
6496
+ skipXmlParsing,
6497
+ wasmSource: getConfiguredWorkerWasmSource()
6451
6498
  },
6452
6499
  type: "parseCharts"
6453
6500
  }, [workerBuffer]);
@@ -7794,7 +7841,7 @@ function useXlsxViewerController(options) {
7794
7841
  const shouldDeferLoading = deferLoadingAboveBytes > 0;
7795
7842
  const readOnly = requestedReadOnly || forcedReadOnly;
7796
7843
  const canResizeReadOnly = requestedReadOnly && allowResizeInReadOnly && !forcedReadOnly;
7797
- const workerSupported = useWorker && typeof Worker !== "undefined";
7844
+ const workerSupported = useWorker && typeof Worker !== "undefined" && canUseConfiguredWasmSourceInWorker();
7798
7845
  const shouldUseWorker = workerSupported && forcedReadOnly;
7799
7846
  const shouldForceReadOnlyForBuffer = React.useCallback((bufferByteLength) => !requestedReadOnly && readOnlyAboveBytes > 0 && bufferByteLength > readOnlyAboveBytes, [readOnlyAboveBytes, requestedReadOnly]);
7800
7847
  const disposeWorkerClient = React.useCallback(() => {
@@ -17344,13 +17391,16 @@ function rangesEqual(left, right) {
17344
17391
  function isPrintableKey(event) {
17345
17392
  return event.key.length === 1 && !event.altKey && !event.ctrlKey && !event.metaKey;
17346
17393
  }
17347
- function isInteractiveFocusTarget(target, container) {
17394
+ function getInteractiveFocusTarget(target) {
17348
17395
  if (!(target instanceof Element)) {
17349
- return false;
17396
+ return null;
17350
17397
  }
17351
- const interactiveElement = target.closest(
17398
+ return target.closest(
17352
17399
  "a[href], button, input, select, textarea, [contenteditable=''], [contenteditable='true'], [role='button'], [role='menu'], [role='menuitem'], [role='textbox'], [tabindex]:not([tabindex='-1'])"
17353
17400
  );
17401
+ }
17402
+ function isInteractiveFocusTarget(target, container) {
17403
+ const interactiveElement = getInteractiveFocusTarget(target);
17354
17404
  return Boolean(interactiveElement && interactiveElement !== container && container.contains(interactiveElement));
17355
17405
  }
17356
17406
  function buildPrefixSums(values) {
@@ -21056,8 +21106,10 @@ function GridRow({
21056
21106
  onCellClick,
21057
21107
  onCellDoubleClick,
21058
21108
  onCellPointerDown,
21109
+ onEditingBlur,
21059
21110
  onEditingCancel,
21060
21111
  onEditingCommit,
21112
+ onEditingNavigate,
21061
21113
  onEditingValueChange,
21062
21114
  onRowHeaderRef,
21063
21115
  onRowPointerDown,
@@ -21343,7 +21395,7 @@ function GridRow({
21343
21395
  "input",
21344
21396
  {
21345
21397
  autoFocus: true,
21346
- onBlur: onEditingCommit,
21398
+ onBlur: onEditingBlur,
21347
21399
  onChange: (event) => onEditingValueChange(event.target.value),
21348
21400
  onKeyDown: (event) => {
21349
21401
  event.stopPropagation();
@@ -21355,6 +21407,11 @@ function GridRow({
21355
21407
  if (event.key === "Escape") {
21356
21408
  event.preventDefault();
21357
21409
  onEditingCancel();
21410
+ return;
21411
+ }
21412
+ if (event.key === "ArrowDown" || event.key === "ArrowLeft" || event.key === "ArrowRight" || event.key === "ArrowUp") {
21413
+ event.preventDefault();
21414
+ onEditingNavigate(event.key, event.currentTarget.value);
21358
21415
  }
21359
21416
  },
21360
21417
  style: {
@@ -21430,7 +21487,7 @@ function GridRow({
21430
21487
  ] });
21431
21488
  }
21432
21489
  var MemoGridRow = React4.memo(GridRow, (prev, next) => {
21433
- 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) {
21490
+ 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) {
21434
21491
  return false;
21435
21492
  }
21436
21493
  const prevEditingCol = prev.editingCell?.row === prev.actualRow ? prev.editingCell.col : -1;
@@ -21531,6 +21588,9 @@ function XlsxGrid({
21531
21588
  const scrollRef = React4.useRef(null);
21532
21589
  const wrapperRef = React4.useRef(null);
21533
21590
  const tableRef = React4.useRef(null);
21591
+ const gridKeyboardActiveRef = React4.useRef(false);
21592
+ const gridKeyboardHandlerRef = React4.useRef(null);
21593
+ const axisSelectionRef = React4.useRef(null);
21534
21594
  const scrollBodyCanvasRef = React4.useRef(null);
21535
21595
  const topBodyCanvasRef = React4.useRef(null);
21536
21596
  const leftBodyCanvasRef = React4.useRef(null);
@@ -23172,9 +23232,50 @@ function XlsxGrid({
23172
23232
  selectionPreviewRangeRef.current = null;
23173
23233
  setInteractionMode("idle");
23174
23234
  }, [activeSheetIndex, clearGlobalCursor, revision]);
23175
- const focusGrid = React4.useCallback((options) => {
23176
- scrollRef.current?.focus(options);
23235
+ const focusGridElement = React4.useCallback((element, options) => {
23236
+ if (document.activeElement !== element) {
23237
+ element.focus(options ?? { preventScroll: true });
23238
+ }
23177
23239
  }, []);
23240
+ const focusGrid = React4.useCallback((options) => {
23241
+ const scroller = scrollRef.current;
23242
+ if (scroller) {
23243
+ gridKeyboardActiveRef.current = true;
23244
+ focusGridElement(scroller, options);
23245
+ }
23246
+ }, [focusGridElement]);
23247
+ React4.useEffect(() => {
23248
+ const handleDocumentPointerDown = (event) => {
23249
+ const scroller = scrollRef.current;
23250
+ if (!scroller || !(event.target instanceof Node) || !scroller.contains(event.target)) {
23251
+ gridKeyboardActiveRef.current = false;
23252
+ return;
23253
+ }
23254
+ if (isInteractiveFocusTarget(event.target, scroller)) {
23255
+ gridKeyboardActiveRef.current = false;
23256
+ return;
23257
+ }
23258
+ gridKeyboardActiveRef.current = true;
23259
+ focusGridElement(scroller);
23260
+ };
23261
+ const handleDocumentKeyDown = (event) => {
23262
+ if (!gridKeyboardActiveRef.current || event.defaultPrevented) {
23263
+ return;
23264
+ }
23265
+ const scroller = scrollRef.current;
23266
+ const interactiveTarget = getInteractiveFocusTarget(event.target);
23267
+ if (!scroller || interactiveTarget && interactiveTarget !== scroller) {
23268
+ return;
23269
+ }
23270
+ gridKeyboardHandlerRef.current?.(event);
23271
+ };
23272
+ document.addEventListener("pointerdown", handleDocumentPointerDown, true);
23273
+ document.addEventListener("keydown", handleDocumentKeyDown);
23274
+ return () => {
23275
+ document.removeEventListener("pointerdown", handleDocumentPointerDown, true);
23276
+ document.removeEventListener("keydown", handleDocumentKeyDown);
23277
+ };
23278
+ }, [focusGridElement]);
23178
23279
  const openHyperlink = React4.useCallback((target, location) => {
23179
23280
  const internalTarget = parseInternalSheetLink(location ?? target);
23180
23281
  if (internalTarget) {
@@ -23213,21 +23314,74 @@ function XlsxGrid({
23213
23314
  return;
23214
23315
  }
23215
23316
  if (readOnly) {
23317
+ editingCellRef.current = null;
23216
23318
  setEditingCell(null);
23217
23319
  setEditingValue("");
23218
23320
  focusGrid();
23219
23321
  return;
23220
23322
  }
23221
23323
  setCellValue(editingCell, editingValue);
23324
+ editingCellRef.current = null;
23222
23325
  setEditingCell(null);
23223
23326
  setEditingValue("");
23224
23327
  focusGrid();
23225
23328
  }, [editingCell, editingValue, focusGrid, readOnly, setCellValue]);
23226
23329
  const cancelEditing = React4.useCallback(() => {
23330
+ editingCellRef.current = null;
23227
23331
  setEditingCell(null);
23228
23332
  setEditingValue("");
23229
23333
  focusGrid();
23230
23334
  }, [focusGrid]);
23335
+ const handleEditingBlur = React4.useCallback(() => {
23336
+ if (!editingCellRef.current) {
23337
+ return;
23338
+ }
23339
+ commitEditing();
23340
+ }, [commitEditing]);
23341
+ const handleEditingNavigate = React4.useCallback((key, value) => {
23342
+ const cell = editingCellRef.current;
23343
+ if (!cell) {
23344
+ return;
23345
+ }
23346
+ const currentRowIndex = rowIndexByActual.get(cell.row);
23347
+ const currentColIndex = colIndexByActual.get(cell.col);
23348
+ if (currentRowIndex === void 0 || currentColIndex === void 0) {
23349
+ if (!readOnlyRef.current) {
23350
+ setCellValue(cell, value);
23351
+ }
23352
+ editingCellRef.current = null;
23353
+ setEditingCell(null);
23354
+ setEditingValue("");
23355
+ focusGrid();
23356
+ return;
23357
+ }
23358
+ let nextRowIndex = currentRowIndex;
23359
+ let nextColIndex = currentColIndex;
23360
+ switch (key) {
23361
+ case "ArrowDown":
23362
+ nextRowIndex += 1;
23363
+ break;
23364
+ case "ArrowLeft":
23365
+ nextColIndex -= 1;
23366
+ break;
23367
+ case "ArrowRight":
23368
+ nextColIndex += 1;
23369
+ break;
23370
+ case "ArrowUp":
23371
+ nextRowIndex -= 1;
23372
+ break;
23373
+ default:
23374
+ return;
23375
+ }
23376
+ if (!readOnlyRef.current) {
23377
+ setCellValue(cell, value);
23378
+ }
23379
+ editingCellRef.current = null;
23380
+ setEditingCell(null);
23381
+ setEditingValue("");
23382
+ moveSelection(nextRowIndex, nextColIndex, false);
23383
+ focusGrid();
23384
+ }, [colIndexByActual, focusGrid, rowIndexByActual, setCellValue, visibleCols, visibleRows]);
23231
23385
  React4.useEffect(() => {
23232
23386
  commitEditingRef.current = commitEditing;
23233
23387
  }, [commitEditing]);
@@ -24200,6 +24354,7 @@ function XlsxGrid({
24200
24354
  overlay.style.visibility = "visible";
24201
24355
  }, [getCellData, resolveOverlayRect, zoomFactor]);
24202
24356
  const commitSelectionRange = React4.useCallback((range) => {
24357
+ gridKeyboardActiveRef.current = true;
24203
24358
  const normalized = normalizeRange2(range);
24204
24359
  if (selectionRef.current && rangesEqual(selectionRef.current, normalized) && isSameCell(activeCellRef.current, normalized.end) && selectedChartIdRef.current === null && selectedImageIdRef.current === null) {
24205
24360
  return;
@@ -24493,6 +24648,23 @@ function XlsxGrid({
24493
24648
  if (nextRange && (dragState?.didDrag || !dragState?.committedOnPointerDown)) {
24494
24649
  selectionPreviewRangeRef.current = nextRange;
24495
24650
  displayedSelectionRef.current = nextRange;
24651
+ if (dragState?.axis === "column") {
24652
+ const normalized = normalizeRange2(nextRange);
24653
+ axisSelectionRef.current = {
24654
+ axis: "column",
24655
+ startCol: normalized.start.col,
24656
+ endCol: normalized.end.col
24657
+ };
24658
+ } else if (dragState?.axis === "row") {
24659
+ const normalized = normalizeRange2(nextRange);
24660
+ axisSelectionRef.current = {
24661
+ axis: "row",
24662
+ startRow: normalized.start.row,
24663
+ endRow: normalized.end.row
24664
+ };
24665
+ } else {
24666
+ axisSelectionRef.current = null;
24667
+ }
24496
24668
  commitSelectionRange(nextRange);
24497
24669
  } else if (!nextRange) {
24498
24670
  selectionPreviewRangeRef.current = null;
@@ -24611,6 +24783,7 @@ function XlsxGrid({
24611
24783
  }
24612
24784
  event.preventDefault();
24613
24785
  focusGrid();
24786
+ axisSelectionRef.current = null;
24614
24787
  const targetCell = event.currentTarget.colSpan > 1 || event.currentTarget.rowSpan > 1 ? resolvePointerCellFromGeometry(event.clientX, event.clientY) ?? cell : cell;
24615
24788
  const currentSelection = selectionRef.current;
24616
24789
  const anchor = event.shiftKey && currentSelection ? currentSelection.start : targetCell;
@@ -24686,6 +24859,7 @@ function XlsxGrid({
24686
24859
  event.clientX,
24687
24860
  event.clientY
24688
24861
  );
24862
+ axisSelectionRef.current = { axis: "row", startRow: anchorRow, endRow: actualRow };
24689
24863
  commitSelectionRange(initialRange);
24690
24864
  }, [commitSelectionRange, firstVisibleCol, focusGrid, lastVisibleCol, resolveRowPointerOrigin]);
24691
24865
  const handleColumnPointerDown = React4.useCallback((event, actualCol) => {
@@ -24717,6 +24891,7 @@ function XlsxGrid({
24717
24891
  event.clientX,
24718
24892
  event.clientY
24719
24893
  );
24894
+ axisSelectionRef.current = { axis: "column", startCol: anchorCol, endCol: actualCol };
24720
24895
  commitSelectionRange(initialRange);
24721
24896
  }, [commitSelectionRange, firstVisibleRow, focusGrid, lastVisibleRow, resolveColumnPointerOrigin]);
24722
24897
  const handleRowResizePointerDown = React4.useCallback((event, actualRow, rowHeight) => {
@@ -24973,6 +25148,7 @@ function XlsxGrid({
24973
25148
  }
24974
25149
  event.preventDefault();
24975
25150
  focusGrid();
25151
+ axisSelectionRef.current = null;
24976
25152
  const currentSelection = selectionRef.current;
24977
25153
  const anchor = event.shiftKey && currentSelection ? currentSelection.start : cell;
24978
25154
  const initialRange = normalizeRange2({ start: anchor, end: cell });
@@ -25082,6 +25258,7 @@ function XlsxGrid({
25082
25258
  event.clientX,
25083
25259
  event.clientY
25084
25260
  );
25261
+ axisSelectionRef.current = { axis: "column", startCol: anchorCol, endCol: actualCol };
25085
25262
  commitSelectionRange(initialRange);
25086
25263
  }, [
25087
25264
  colIndexByActual,
@@ -25140,6 +25317,7 @@ function XlsxGrid({
25140
25317
  event.clientX,
25141
25318
  event.clientY
25142
25319
  );
25320
+ axisSelectionRef.current = { axis: "row", startRow: anchorRow, endRow: actualRow };
25143
25321
  commitSelectionRange(initialRange);
25144
25322
  }, [
25145
25323
  colPrefixSums,
@@ -27646,6 +27824,11 @@ function XlsxGrid({
27646
27824
  if (nextRow === void 0 || nextCol === void 0) {
27647
27825
  return;
27648
27826
  }
27827
+ const nextRange = { start: { row: nextRow, col: nextCol }, end: { row: nextRow, col: nextCol } };
27828
+ axisSelectionRef.current = null;
27829
+ selectionPreviewRangeRef.current = null;
27830
+ displayedSelectionRef.current = nextRange;
27831
+ applyPreviewOverlay(nextRange);
27649
27832
  selectCell({ row: nextRow, col: nextCol }, extend ? { extend: true } : void 0);
27650
27833
  ensureCellVisible(clampedRowIndex, clampedColIndex);
27651
27834
  }
@@ -27669,6 +27852,214 @@ function XlsxGrid({
27669
27852
  const targetOffset = direction > 0 ? currentOffset + viewportWidth : currentOffset - viewportWidth;
27670
27853
  return Math.max(0, Math.min(findIndexForOffsetPrefix(colPrefixSums, targetOffset), visibleCols.length - 1));
27671
27854
  }
27855
+ function resolveColumnSelectionNavigation(eventKey) {
27856
+ const axisSelection = axisSelectionRef.current;
27857
+ if (axisSelection?.axis !== "column" || firstVisibleRow === void 0) {
27858
+ return null;
27859
+ }
27860
+ const startCol = Math.min(axisSelection.startCol, axisSelection.endCol);
27861
+ const endCol = Math.max(axisSelection.startCol, axisSelection.endCol);
27862
+ const targetCol = eventKey === "ArrowLeft" ? startCol - 1 : eventKey === "ArrowRight" ? endCol + 1 : null;
27863
+ if (targetCol === null) {
27864
+ return null;
27865
+ }
27866
+ const rowIndex = rowIndexByActual.get(firstVisibleRow);
27867
+ const colIndex = colIndexByActual.get(targetCol);
27868
+ if (rowIndex === void 0 || colIndex === void 0) {
27869
+ return null;
27870
+ }
27871
+ return { colIndex, rowIndex };
27872
+ }
27873
+ function resolveRowSelectionNavigation(eventKey) {
27874
+ const axisSelection = axisSelectionRef.current;
27875
+ if (axisSelection?.axis !== "row" || firstVisibleCol === void 0) {
27876
+ return null;
27877
+ }
27878
+ const startRow = Math.min(axisSelection.startRow, axisSelection.endRow);
27879
+ const endRow = Math.max(axisSelection.startRow, axisSelection.endRow);
27880
+ const targetRow = eventKey === "ArrowUp" ? startRow - 1 : eventKey === "ArrowDown" ? endRow + 1 : null;
27881
+ if (targetRow === null) {
27882
+ return null;
27883
+ }
27884
+ const rowIndex = rowIndexByActual.get(targetRow);
27885
+ const colIndex = colIndexByActual.get(firstVisibleCol);
27886
+ if (rowIndex === void 0 || colIndex === void 0) {
27887
+ return null;
27888
+ }
27889
+ return { colIndex, rowIndex };
27890
+ }
27891
+ function handleGridKeyDown(event) {
27892
+ if (editingCell) {
27893
+ return;
27894
+ }
27895
+ if (!readOnly && (event.metaKey || event.ctrlKey) && !event.altKey) {
27896
+ const normalizedKey = event.key.toLowerCase();
27897
+ if (normalizedKey === "z" && event.shiftKey) {
27898
+ event.preventDefault();
27899
+ redo();
27900
+ return;
27901
+ }
27902
+ if (normalizedKey === "z") {
27903
+ event.preventDefault();
27904
+ undo();
27905
+ return;
27906
+ }
27907
+ if (normalizedKey === "y") {
27908
+ event.preventDefault();
27909
+ redo();
27910
+ return;
27911
+ }
27912
+ }
27913
+ const currentCell = resolveCurrentCell();
27914
+ if (!currentCell) {
27915
+ return;
27916
+ }
27917
+ const currentRowIndex = rowIndexByActual.get(currentCell.row) ?? 0;
27918
+ const currentColIndex = colIndexByActual.get(currentCell.col) ?? 0;
27919
+ const isCommandNavigation = event.ctrlKey || event.metaKey;
27920
+ if (!readOnly && isPrintableKey(event)) {
27921
+ event.preventDefault();
27922
+ startEditing(currentCell, event.key);
27923
+ return;
27924
+ }
27925
+ switch (event.key) {
27926
+ case "ArrowDown":
27927
+ event.preventDefault();
27928
+ if (!event.shiftKey && !isCommandNavigation) {
27929
+ const target = resolveRowSelectionNavigation(event.key);
27930
+ if (target) {
27931
+ moveSelection(target.rowIndex, target.colIndex, false);
27932
+ break;
27933
+ }
27934
+ }
27935
+ moveSelection(
27936
+ isCommandNavigation ? rowIndexByActual.get(resolveLastUsedVisibleIndex(visibleRows, activeSheet?.maxUsedRow ?? -1)) ?? visibleRows.length - 1 : currentRowIndex + 1,
27937
+ currentColIndex,
27938
+ event.shiftKey
27939
+ );
27940
+ break;
27941
+ case "ArrowUp":
27942
+ event.preventDefault();
27943
+ if (!event.shiftKey && !isCommandNavigation) {
27944
+ const target = resolveRowSelectionNavigation(event.key);
27945
+ if (target) {
27946
+ moveSelection(target.rowIndex, target.colIndex, false);
27947
+ break;
27948
+ }
27949
+ }
27950
+ moveSelection(
27951
+ isCommandNavigation ? rowIndexByActual.get(resolveFirstUsedVisibleIndex(visibleRows, activeSheet?.minUsedRow ?? -1)) ?? 0 : currentRowIndex - 1,
27952
+ currentColIndex,
27953
+ event.shiftKey
27954
+ );
27955
+ break;
27956
+ case "ArrowLeft":
27957
+ event.preventDefault();
27958
+ if (!event.shiftKey && !isCommandNavigation) {
27959
+ const target = resolveColumnSelectionNavigation(event.key);
27960
+ if (target) {
27961
+ moveSelection(target.rowIndex, target.colIndex, false);
27962
+ break;
27963
+ }
27964
+ }
27965
+ moveSelection(
27966
+ currentRowIndex,
27967
+ isCommandNavigation ? colIndexByActual.get(resolveFirstUsedVisibleIndex(visibleCols, activeSheet?.minUsedCol ?? -1)) ?? 0 : currentColIndex - 1,
27968
+ event.shiftKey
27969
+ );
27970
+ break;
27971
+ case "ArrowRight":
27972
+ event.preventDefault();
27973
+ if (!event.shiftKey && !isCommandNavigation) {
27974
+ const target = resolveColumnSelectionNavigation(event.key);
27975
+ if (target) {
27976
+ moveSelection(target.rowIndex, target.colIndex, false);
27977
+ break;
27978
+ }
27979
+ }
27980
+ moveSelection(
27981
+ currentRowIndex,
27982
+ isCommandNavigation ? colIndexByActual.get(resolveLastUsedVisibleIndex(visibleCols, activeSheet?.maxUsedCol ?? -1)) ?? visibleCols.length - 1 : currentColIndex + 1,
27983
+ event.shiftKey
27984
+ );
27985
+ break;
27986
+ case "Home":
27987
+ event.preventDefault();
27988
+ moveSelection(
27989
+ isCommandNavigation ? rowIndexByActual.get(resolveFirstUsedVisibleIndex(visibleRows, activeSheet?.minUsedRow ?? -1)) ?? 0 : currentRowIndex,
27990
+ colIndexByActual.get(resolveFirstUsedVisibleIndex(visibleCols, activeSheet?.minUsedCol ?? -1)) ?? 0,
27991
+ event.shiftKey
27992
+ );
27993
+ break;
27994
+ case "End":
27995
+ event.preventDefault();
27996
+ moveSelection(
27997
+ isCommandNavigation ? rowIndexByActual.get(resolveLastUsedVisibleIndex(visibleRows, activeSheet?.maxUsedRow ?? -1)) ?? visibleRows.length - 1 : currentRowIndex,
27998
+ colIndexByActual.get(resolveLastUsedVisibleIndex(visibleCols, activeSheet?.maxUsedCol ?? -1)) ?? visibleCols.length - 1,
27999
+ event.shiftKey
28000
+ );
28001
+ break;
28002
+ case "PageDown":
28003
+ event.preventDefault();
28004
+ if (event.altKey) {
28005
+ moveSelection(currentRowIndex, resolvePageColIndex(currentColIndex, 1), event.shiftKey);
28006
+ break;
28007
+ }
28008
+ moveSelection(resolvePageRowIndex(currentRowIndex, 1), currentColIndex, event.shiftKey);
28009
+ break;
28010
+ case "PageUp":
28011
+ event.preventDefault();
28012
+ if (event.altKey) {
28013
+ moveSelection(currentRowIndex, resolvePageColIndex(currentColIndex, -1), event.shiftKey);
28014
+ break;
28015
+ }
28016
+ moveSelection(resolvePageRowIndex(currentRowIndex, -1), currentColIndex, event.shiftKey);
28017
+ break;
28018
+ case "Tab":
28019
+ event.preventDefault();
28020
+ if (event.shiftKey) {
28021
+ moveSelection(
28022
+ currentColIndex > 0 ? currentRowIndex : currentRowIndex - 1,
28023
+ currentColIndex > 0 ? currentColIndex - 1 : visibleCols.length - 1,
28024
+ false
28025
+ );
28026
+ } else {
28027
+ moveSelection(
28028
+ currentColIndex < visibleCols.length - 1 ? currentRowIndex : currentRowIndex + 1,
28029
+ currentColIndex < visibleCols.length - 1 ? currentColIndex + 1 : 0,
28030
+ false
28031
+ );
28032
+ }
28033
+ break;
28034
+ case "Enter":
28035
+ event.preventDefault();
28036
+ if (event.metaKey || event.ctrlKey || event.altKey) {
28037
+ break;
28038
+ }
28039
+ if (event.shiftKey) {
28040
+ moveSelection(currentRowIndex - 1, currentColIndex, false);
28041
+ break;
28042
+ }
28043
+ moveSelection(currentRowIndex + 1, currentColIndex, false);
28044
+ break;
28045
+ case "Backspace":
28046
+ case "Delete":
28047
+ if (!readOnly) {
28048
+ event.preventDefault();
28049
+ clearSelectedCells();
28050
+ }
28051
+ break;
28052
+ case "F2":
28053
+ if (!readOnly) {
28054
+ event.preventDefault();
28055
+ startEditing(currentCell);
28056
+ }
28057
+ break;
28058
+ default:
28059
+ break;
28060
+ }
28061
+ }
28062
+ gridKeyboardHandlerRef.current = handleGridKeyDown;
27672
28063
  const scrollerViewportProps = {
27673
28064
  key: activeTabIndex,
27674
28065
  ref: scrollRef,
@@ -27704,153 +28095,20 @@ function XlsxGrid({
27704
28095
  if (isInteractiveFocusTarget(event.target, event.currentTarget)) {
27705
28096
  return;
27706
28097
  }
27707
- if (document.activeElement !== event.currentTarget) {
27708
- event.currentTarget.focus({ preventScroll: true });
27709
- }
28098
+ gridKeyboardActiveRef.current = true;
28099
+ focusGridElement(event.currentTarget);
27710
28100
  },
27711
- onKeyDown: (event) => {
27712
- if (editingCell) {
27713
- return;
27714
- }
27715
- if (!readOnly && (event.metaKey || event.ctrlKey) && !event.altKey) {
27716
- const normalizedKey = event.key.toLowerCase();
27717
- if (normalizedKey === "z" && event.shiftKey) {
27718
- event.preventDefault();
27719
- redo();
27720
- return;
27721
- }
27722
- if (normalizedKey === "z") {
27723
- event.preventDefault();
27724
- undo();
27725
- return;
27726
- }
27727
- if (normalizedKey === "y") {
27728
- event.preventDefault();
27729
- redo();
27730
- return;
27731
- }
27732
- }
27733
- const currentCell = resolveCurrentCell();
27734
- if (!currentCell) {
27735
- return;
27736
- }
27737
- const currentRowIndex = rowIndexByActual.get(currentCell.row) ?? 0;
27738
- const currentColIndex = colIndexByActual.get(currentCell.col) ?? 0;
27739
- const isCommandNavigation = event.ctrlKey || event.metaKey;
27740
- if (!readOnly && isPrintableKey(event)) {
27741
- event.preventDefault();
27742
- startEditing(currentCell, event.key);
28101
+ onClickCapture: (event) => {
28102
+ if (isInteractiveFocusTarget(event.target, event.currentTarget)) {
27743
28103
  return;
27744
28104
  }
27745
- switch (event.key) {
27746
- case "ArrowDown":
27747
- event.preventDefault();
27748
- moveSelection(
27749
- isCommandNavigation ? rowIndexByActual.get(resolveLastUsedVisibleIndex(visibleRows, activeSheet?.maxUsedRow ?? -1)) ?? visibleRows.length - 1 : currentRowIndex + 1,
27750
- currentColIndex,
27751
- event.shiftKey
27752
- );
27753
- break;
27754
- case "ArrowUp":
27755
- event.preventDefault();
27756
- moveSelection(
27757
- isCommandNavigation ? rowIndexByActual.get(resolveFirstUsedVisibleIndex(visibleRows, activeSheet?.minUsedRow ?? -1)) ?? 0 : currentRowIndex - 1,
27758
- currentColIndex,
27759
- event.shiftKey
27760
- );
27761
- break;
27762
- case "ArrowLeft":
27763
- event.preventDefault();
27764
- moveSelection(
27765
- currentRowIndex,
27766
- isCommandNavigation ? colIndexByActual.get(resolveFirstUsedVisibleIndex(visibleCols, activeSheet?.minUsedCol ?? -1)) ?? 0 : currentColIndex - 1,
27767
- event.shiftKey
27768
- );
27769
- break;
27770
- case "ArrowRight":
27771
- event.preventDefault();
27772
- moveSelection(
27773
- currentRowIndex,
27774
- isCommandNavigation ? colIndexByActual.get(resolveLastUsedVisibleIndex(visibleCols, activeSheet?.maxUsedCol ?? -1)) ?? visibleCols.length - 1 : currentColIndex + 1,
27775
- event.shiftKey
27776
- );
27777
- break;
27778
- case "Home":
27779
- event.preventDefault();
27780
- moveSelection(
27781
- isCommandNavigation ? rowIndexByActual.get(resolveFirstUsedVisibleIndex(visibleRows, activeSheet?.minUsedRow ?? -1)) ?? 0 : currentRowIndex,
27782
- colIndexByActual.get(resolveFirstUsedVisibleIndex(visibleCols, activeSheet?.minUsedCol ?? -1)) ?? 0,
27783
- event.shiftKey
27784
- );
27785
- break;
27786
- case "End":
27787
- event.preventDefault();
27788
- moveSelection(
27789
- isCommandNavigation ? rowIndexByActual.get(resolveLastUsedVisibleIndex(visibleRows, activeSheet?.maxUsedRow ?? -1)) ?? visibleRows.length - 1 : currentRowIndex,
27790
- colIndexByActual.get(resolveLastUsedVisibleIndex(visibleCols, activeSheet?.maxUsedCol ?? -1)) ?? visibleCols.length - 1,
27791
- event.shiftKey
27792
- );
27793
- break;
27794
- case "PageDown":
27795
- event.preventDefault();
27796
- if (event.altKey) {
27797
- moveSelection(currentRowIndex, resolvePageColIndex(currentColIndex, 1), event.shiftKey);
27798
- break;
27799
- }
27800
- moveSelection(resolvePageRowIndex(currentRowIndex, 1), currentColIndex, event.shiftKey);
27801
- break;
27802
- case "PageUp":
27803
- event.preventDefault();
27804
- if (event.altKey) {
27805
- moveSelection(currentRowIndex, resolvePageColIndex(currentColIndex, -1), event.shiftKey);
27806
- break;
27807
- }
27808
- moveSelection(resolvePageRowIndex(currentRowIndex, -1), currentColIndex, event.shiftKey);
27809
- break;
27810
- case "Tab":
27811
- event.preventDefault();
27812
- if (event.shiftKey) {
27813
- moveSelection(
27814
- currentColIndex > 0 ? currentRowIndex : currentRowIndex - 1,
27815
- currentColIndex > 0 ? currentColIndex - 1 : visibleCols.length - 1,
27816
- false
27817
- );
27818
- } else {
27819
- moveSelection(
27820
- currentColIndex < visibleCols.length - 1 ? currentRowIndex : currentRowIndex + 1,
27821
- currentColIndex < visibleCols.length - 1 ? currentColIndex + 1 : 0,
27822
- false
27823
- );
27824
- }
27825
- break;
27826
- case "Enter":
27827
- event.preventDefault();
27828
- if (event.metaKey || event.ctrlKey || event.altKey) {
27829
- break;
27830
- }
27831
- if (event.shiftKey) {
27832
- moveSelection(currentRowIndex - 1, currentColIndex, false);
27833
- break;
27834
- }
27835
- moveSelection(currentRowIndex + 1, currentColIndex, false);
27836
- break;
27837
- case "Backspace":
27838
- case "Delete":
27839
- if (!readOnly) {
27840
- event.preventDefault();
27841
- clearSelectedCells();
27842
- }
27843
- break;
27844
- case "F2":
27845
- if (!readOnly) {
27846
- event.preventDefault();
27847
- startEditing(currentCell);
27848
- }
27849
- break;
27850
- default:
27851
- break;
27852
- }
28105
+ gridKeyboardActiveRef.current = true;
28106
+ focusGridElement(event.currentTarget);
28107
+ },
28108
+ onFocus: () => {
28109
+ gridKeyboardActiveRef.current = true;
27853
28110
  },
28111
+ onKeyDown: handleGridKeyDown,
27854
28112
  onPaste: (event) => {
27855
28113
  if (editingCell || readOnly) {
27856
28114
  return;
@@ -28100,7 +28358,7 @@ function XlsxGrid({
28100
28358
  {
28101
28359
  ref: editingInputRef,
28102
28360
  autoFocus: true,
28103
- onBlur: commitEditing,
28361
+ onBlur: handleEditingBlur,
28104
28362
  onChange: (event) => setEditingValue(event.target.value),
28105
28363
  onKeyDown: (event) => {
28106
28364
  event.stopPropagation();
@@ -28112,6 +28370,11 @@ function XlsxGrid({
28112
28370
  if (event.key === "Escape") {
28113
28371
  event.preventDefault();
28114
28372
  cancelEditing();
28373
+ return;
28374
+ }
28375
+ if (event.key === "ArrowDown" || event.key === "ArrowLeft" || event.key === "ArrowRight" || event.key === "ArrowUp") {
28376
+ event.preventDefault();
28377
+ handleEditingNavigate(event.key, event.currentTarget.value);
28115
28378
  }
28116
28379
  },
28117
28380
  style: {
@@ -28266,8 +28529,10 @@ function XlsxGrid({
28266
28529
  onCellClick: handleCellClick,
28267
28530
  onCellDoubleClick: handleCellDoubleClick,
28268
28531
  onCellPointerDown: handleCellPointerDown,
28532
+ onEditingBlur: handleEditingBlur,
28269
28533
  onEditingCancel: cancelEditing,
28270
28534
  onEditingCommit: commitEditing,
28535
+ onEditingNavigate: handleEditingNavigate,
28271
28536
  onEditingValueChange: setEditingValue,
28272
28537
  headerLabelLiveScale,
28273
28538
  onRowHeaderRef: setRowHeaderRef,
@@ -29522,6 +29787,8 @@ export {
29522
29787
  XlsxFileSizeLimitExceededError,
29523
29788
  XlsxViewer,
29524
29789
  XlsxViewerProvider,
29790
+ initWasm,
29791
+ setWasmSource,
29525
29792
  useXlsxViewer,
29526
29793
  useXlsxViewerCharts,
29527
29794
  useXlsxViewerController,