@extend-ai/react-xlsx 0.10.0 → 0.10.1

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
@@ -17376,6 +17376,15 @@ function rangesEqual(left, right) {
17376
17376
  function isPrintableKey(event) {
17377
17377
  return event.key.length === 1 && !event.altKey && !event.ctrlKey && !event.metaKey;
17378
17378
  }
17379
+ function isInteractiveFocusTarget(target, container) {
17380
+ if (!(target instanceof Element)) {
17381
+ return false;
17382
+ }
17383
+ const interactiveElement = target.closest(
17384
+ "a[href], button, input, select, textarea, [contenteditable=''], [contenteditable='true'], [role='button'], [role='menu'], [role='menuitem'], [role='textbox'], [tabindex]:not([tabindex='-1'])"
17385
+ );
17386
+ return Boolean(interactiveElement && interactiveElement !== container && container.contains(interactiveElement));
17387
+ }
17379
17388
  function buildPrefixSums(values) {
17380
17389
  const prefix = new Array(values.length + 1).fill(0);
17381
17390
  for (let index = 0; index < values.length; index += 1) {
@@ -21053,6 +21062,21 @@ function resolveFirstUsedVisibleIndex(visibleIndices, minUsedIndex) {
21053
21062
  const firstVisibleUsed = visibleIndices.find((index) => index >= minUsedIndex);
21054
21063
  return firstVisibleUsed ?? visibleIndices[0] ?? -1;
21055
21064
  }
21065
+ function resolveLastUsedVisibleIndex(visibleIndices, maxUsedIndex) {
21066
+ if (visibleIndices.length === 0) {
21067
+ return -1;
21068
+ }
21069
+ if (maxUsedIndex < 0) {
21070
+ return visibleIndices[visibleIndices.length - 1] ?? -1;
21071
+ }
21072
+ for (let index = visibleIndices.length - 1; index >= 0; index -= 1) {
21073
+ const visibleIndex = visibleIndices[index];
21074
+ if (visibleIndex !== void 0 && visibleIndex <= maxUsedIndex) {
21075
+ return visibleIndex;
21076
+ }
21077
+ }
21078
+ return visibleIndices[visibleIndices.length - 1] ?? -1;
21079
+ }
21056
21080
  function GridRow({
21057
21081
  actualRow,
21058
21082
  editingCell,
@@ -23180,8 +23204,8 @@ function XlsxGrid({
23180
23204
  selectionPreviewRangeRef.current = null;
23181
23205
  setInteractionMode("idle");
23182
23206
  }, [activeSheetIndex, clearGlobalCursor, revision]);
23183
- const focusGrid = React4.useCallback(() => {
23184
- scrollRef.current?.focus();
23207
+ const focusGrid = React4.useCallback((options) => {
23208
+ scrollRef.current?.focus(options);
23185
23209
  }, []);
23186
23210
  const openHyperlink = React4.useCallback((target, location) => {
23187
23211
  const internalTarget = parseInternalSheetLink(location ?? target);
@@ -27607,17 +27631,85 @@ function XlsxGrid({
27607
27631
  }
27608
27632
  return { row: firstVisibleRow, col: firstVisibleCol };
27609
27633
  }
27634
+ function ensureCellVisible(rowIndex, colIndex) {
27635
+ const scroller = scrollRef.current;
27636
+ if (!scroller) {
27637
+ return;
27638
+ }
27639
+ let nextScrollTop = scroller.scrollTop;
27640
+ let nextScrollLeft = scroller.scrollLeft;
27641
+ const rowStart = displayHeaderHeight + (rowPrefixSums[rowIndex] ?? 0);
27642
+ const rowEnd = displayHeaderHeight + (rowPrefixSums[rowIndex + 1] ?? rowStart);
27643
+ const colStart = displayRowHeaderWidth + (colPrefixSums[colIndex] ?? 0);
27644
+ const colEnd = displayRowHeaderWidth + (colPrefixSums[colIndex + 1] ?? colStart);
27645
+ if (rowEnd > frozenPaneBottom) {
27646
+ const visibleTop = scroller.scrollTop + frozenPaneBottom;
27647
+ const visibleBottom = scroller.scrollTop + scroller.clientHeight;
27648
+ if (rowStart < visibleTop) {
27649
+ nextScrollTop = rowStart - frozenPaneBottom;
27650
+ } else if (rowEnd > visibleBottom) {
27651
+ nextScrollTop = rowEnd - scroller.clientHeight;
27652
+ }
27653
+ }
27654
+ if (colEnd > frozenPaneRight) {
27655
+ const visibleLeft = scroller.scrollLeft + frozenPaneRight;
27656
+ const visibleRight = scroller.scrollLeft + scroller.clientWidth;
27657
+ if (colStart < visibleLeft) {
27658
+ nextScrollLeft = colStart - frozenPaneRight;
27659
+ } else if (colEnd > visibleRight) {
27660
+ nextScrollLeft = colEnd - scroller.clientWidth;
27661
+ }
27662
+ }
27663
+ nextScrollTop = Math.max(0, Math.min(nextScrollTop, scroller.scrollHeight - scroller.clientHeight));
27664
+ nextScrollLeft = Math.max(0, Math.min(nextScrollLeft, scroller.scrollWidth - scroller.clientWidth));
27665
+ if (nextScrollTop !== scroller.scrollTop) {
27666
+ scroller.scrollTop = nextScrollTop;
27667
+ }
27668
+ if (nextScrollLeft !== scroller.scrollLeft) {
27669
+ scroller.scrollLeft = nextScrollLeft;
27670
+ }
27671
+ syncDrawingViewport(scroller, { immediate: true });
27672
+ }
27610
27673
  function moveSelection(nextRowIndex, nextColIndex, extend) {
27611
- const nextRow = visibleRows[nextRowIndex];
27612
- const nextCol = visibleCols[nextColIndex];
27674
+ const clampedRowIndex = Math.max(0, Math.min(nextRowIndex, visibleRows.length - 1));
27675
+ const clampedColIndex = Math.max(0, Math.min(nextColIndex, visibleCols.length - 1));
27676
+ const nextRow = visibleRows[clampedRowIndex];
27677
+ const nextCol = visibleCols[clampedColIndex];
27613
27678
  if (nextRow === void 0 || nextCol === void 0) {
27614
27679
  return;
27615
27680
  }
27616
27681
  selectCell({ row: nextRow, col: nextCol }, extend ? { extend: true } : void 0);
27682
+ ensureCellVisible(clampedRowIndex, clampedColIndex);
27683
+ }
27684
+ function resolvePageRowIndex(currentRowIndex, direction) {
27685
+ const scroller = scrollRef.current;
27686
+ const viewportHeight = Math.max(
27687
+ displayDefaultRowHeight,
27688
+ (scroller?.clientHeight ?? displayDefaultRowHeight * 20) - frozenPaneBottom
27689
+ );
27690
+ const currentOffset = rowPrefixSums[currentRowIndex] ?? 0;
27691
+ const targetOffset = direction > 0 ? currentOffset + viewportHeight : currentOffset - viewportHeight;
27692
+ return Math.max(0, Math.min(findIndexForOffsetPrefix(rowPrefixSums, targetOffset), visibleRows.length - 1));
27693
+ }
27694
+ function resolvePageColIndex(currentColIndex, direction) {
27695
+ const scroller = scrollRef.current;
27696
+ const viewportWidth = Math.max(
27697
+ displayDefaultColWidth,
27698
+ (scroller?.clientWidth ?? displayDefaultColWidth * 8) - frozenPaneRight
27699
+ );
27700
+ const currentOffset = colPrefixSums[currentColIndex] ?? 0;
27701
+ const targetOffset = direction > 0 ? currentOffset + viewportWidth : currentOffset - viewportWidth;
27702
+ return Math.max(0, Math.min(findIndexForOffsetPrefix(colPrefixSums, targetOffset), visibleCols.length - 1));
27617
27703
  }
27618
27704
  const scrollerViewportProps = {
27619
27705
  key: activeTabIndex,
27620
27706
  ref: scrollRef,
27707
+ "aria-colcount": Math.max(activeSheet?.colCount ?? 0, displayColLimit),
27708
+ "aria-keyshortcuts": "ArrowUp ArrowDown ArrowLeft ArrowRight Home End PageUp PageDown Control+Home Control+End",
27709
+ "aria-label": activeSheet ? `${activeSheet.name} worksheet grid` : "Workbook grid",
27710
+ "aria-readonly": readOnly,
27711
+ "aria-rowcount": Math.max(activeSheet?.rowCount ?? 0, displayRowLimit),
27712
+ role: "grid",
27621
27713
  onScroll: handleScrollerScroll,
27622
27714
  onCopy: (event) => {
27623
27715
  if (editingCell) {
@@ -27637,6 +27729,17 @@ function XlsxGrid({
27637
27729
  }
27638
27730
  void copySelectionToClipboard();
27639
27731
  },
27732
+ onPointerDownCapture: (event) => {
27733
+ if (event.button !== 0) {
27734
+ return;
27735
+ }
27736
+ if (isInteractiveFocusTarget(event.target, event.currentTarget)) {
27737
+ return;
27738
+ }
27739
+ if (document.activeElement !== event.currentTarget) {
27740
+ event.currentTarget.focus({ preventScroll: true });
27741
+ }
27742
+ },
27640
27743
  onKeyDown: (event) => {
27641
27744
  if (editingCell) {
27642
27745
  return;
@@ -27665,6 +27768,7 @@ function XlsxGrid({
27665
27768
  }
27666
27769
  const currentRowIndex = rowIndexByActual.get(currentCell.row) ?? 0;
27667
27770
  const currentColIndex = colIndexByActual.get(currentCell.col) ?? 0;
27771
+ const isCommandNavigation = event.ctrlKey || event.metaKey;
27668
27772
  if (!readOnly && isPrintableKey(event)) {
27669
27773
  event.preventDefault();
27670
27774
  startEditing(currentCell, event.key);
@@ -27673,38 +27777,94 @@ function XlsxGrid({
27673
27777
  switch (event.key) {
27674
27778
  case "ArrowDown":
27675
27779
  event.preventDefault();
27676
- moveSelection(Math.min(currentRowIndex + 1, visibleRows.length - 1), currentColIndex, event.shiftKey);
27780
+ moveSelection(
27781
+ isCommandNavigation ? rowIndexByActual.get(resolveLastUsedVisibleIndex(visibleRows, activeSheet?.maxUsedRow ?? -1)) ?? visibleRows.length - 1 : currentRowIndex + 1,
27782
+ currentColIndex,
27783
+ event.shiftKey
27784
+ );
27677
27785
  break;
27678
27786
  case "ArrowUp":
27679
27787
  event.preventDefault();
27680
- moveSelection(Math.max(currentRowIndex - 1, 0), currentColIndex, event.shiftKey);
27788
+ moveSelection(
27789
+ isCommandNavigation ? rowIndexByActual.get(resolveFirstUsedVisibleIndex(visibleRows, activeSheet?.minUsedRow ?? -1)) ?? 0 : currentRowIndex - 1,
27790
+ currentColIndex,
27791
+ event.shiftKey
27792
+ );
27681
27793
  break;
27682
27794
  case "ArrowLeft":
27683
27795
  event.preventDefault();
27684
- moveSelection(currentRowIndex, Math.max(currentColIndex - 1, 0), event.shiftKey);
27796
+ moveSelection(
27797
+ currentRowIndex,
27798
+ isCommandNavigation ? colIndexByActual.get(resolveFirstUsedVisibleIndex(visibleCols, activeSheet?.minUsedCol ?? -1)) ?? 0 : currentColIndex - 1,
27799
+ event.shiftKey
27800
+ );
27685
27801
  break;
27686
27802
  case "ArrowRight":
27687
27803
  event.preventDefault();
27688
- moveSelection(currentRowIndex, Math.min(currentColIndex + 1, visibleCols.length - 1), event.shiftKey);
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
+ );
27689
27817
  break;
27690
- case "Tab":
27818
+ case "End":
27691
27819
  event.preventDefault();
27692
27820
  moveSelection(
27693
- currentRowIndex,
27694
- event.shiftKey ? Math.max(currentColIndex - 1, 0) : Math.min(currentColIndex + 1, visibleCols.length - 1),
27695
- false
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
27696
27824
  );
27697
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;
27698
27858
  case "Enter":
27699
27859
  event.preventDefault();
27700
27860
  if (event.metaKey || event.ctrlKey || event.altKey) {
27701
27861
  break;
27702
27862
  }
27703
27863
  if (event.shiftKey) {
27704
- moveSelection(Math.max(currentRowIndex - 1, 0), currentColIndex, false);
27864
+ moveSelection(currentRowIndex - 1, currentColIndex, false);
27705
27865
  break;
27706
27866
  }
27707
- moveSelection(Math.min(currentRowIndex + 1, visibleRows.length - 1), currentColIndex, false);
27867
+ moveSelection(currentRowIndex + 1, currentColIndex, false);
27708
27868
  break;
27709
27869
  case "Backspace":
27710
27870
  case "Delete":