@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.js CHANGED
@@ -17344,6 +17344,15 @@ function rangesEqual(left, right) {
17344
17344
  function isPrintableKey(event) {
17345
17345
  return event.key.length === 1 && !event.altKey && !event.ctrlKey && !event.metaKey;
17346
17346
  }
17347
+ function isInteractiveFocusTarget(target, container) {
17348
+ if (!(target instanceof Element)) {
17349
+ return false;
17350
+ }
17351
+ const interactiveElement = target.closest(
17352
+ "a[href], button, input, select, textarea, [contenteditable=''], [contenteditable='true'], [role='button'], [role='menu'], [role='menuitem'], [role='textbox'], [tabindex]:not([tabindex='-1'])"
17353
+ );
17354
+ return Boolean(interactiveElement && interactiveElement !== container && container.contains(interactiveElement));
17355
+ }
17347
17356
  function buildPrefixSums(values) {
17348
17357
  const prefix = new Array(values.length + 1).fill(0);
17349
17358
  for (let index = 0; index < values.length; index += 1) {
@@ -21021,6 +21030,21 @@ function resolveFirstUsedVisibleIndex(visibleIndices, minUsedIndex) {
21021
21030
  const firstVisibleUsed = visibleIndices.find((index) => index >= minUsedIndex);
21022
21031
  return firstVisibleUsed ?? visibleIndices[0] ?? -1;
21023
21032
  }
21033
+ function resolveLastUsedVisibleIndex(visibleIndices, maxUsedIndex) {
21034
+ if (visibleIndices.length === 0) {
21035
+ return -1;
21036
+ }
21037
+ if (maxUsedIndex < 0) {
21038
+ return visibleIndices[visibleIndices.length - 1] ?? -1;
21039
+ }
21040
+ for (let index = visibleIndices.length - 1; index >= 0; index -= 1) {
21041
+ const visibleIndex = visibleIndices[index];
21042
+ if (visibleIndex !== void 0 && visibleIndex <= maxUsedIndex) {
21043
+ return visibleIndex;
21044
+ }
21045
+ }
21046
+ return visibleIndices[visibleIndices.length - 1] ?? -1;
21047
+ }
21024
21048
  function GridRow({
21025
21049
  actualRow,
21026
21050
  editingCell,
@@ -23148,8 +23172,8 @@ function XlsxGrid({
23148
23172
  selectionPreviewRangeRef.current = null;
23149
23173
  setInteractionMode("idle");
23150
23174
  }, [activeSheetIndex, clearGlobalCursor, revision]);
23151
- const focusGrid = React4.useCallback(() => {
23152
- scrollRef.current?.focus();
23175
+ const focusGrid = React4.useCallback((options) => {
23176
+ scrollRef.current?.focus(options);
23153
23177
  }, []);
23154
23178
  const openHyperlink = React4.useCallback((target, location) => {
23155
23179
  const internalTarget = parseInternalSheetLink(location ?? target);
@@ -27575,17 +27599,85 @@ function XlsxGrid({
27575
27599
  }
27576
27600
  return { row: firstVisibleRow, col: firstVisibleCol };
27577
27601
  }
27602
+ function ensureCellVisible(rowIndex, colIndex) {
27603
+ const scroller = scrollRef.current;
27604
+ if (!scroller) {
27605
+ return;
27606
+ }
27607
+ let nextScrollTop = scroller.scrollTop;
27608
+ let nextScrollLeft = scroller.scrollLeft;
27609
+ const rowStart = displayHeaderHeight + (rowPrefixSums[rowIndex] ?? 0);
27610
+ const rowEnd = displayHeaderHeight + (rowPrefixSums[rowIndex + 1] ?? rowStart);
27611
+ const colStart = displayRowHeaderWidth + (colPrefixSums[colIndex] ?? 0);
27612
+ const colEnd = displayRowHeaderWidth + (colPrefixSums[colIndex + 1] ?? colStart);
27613
+ if (rowEnd > frozenPaneBottom) {
27614
+ const visibleTop = scroller.scrollTop + frozenPaneBottom;
27615
+ const visibleBottom = scroller.scrollTop + scroller.clientHeight;
27616
+ if (rowStart < visibleTop) {
27617
+ nextScrollTop = rowStart - frozenPaneBottom;
27618
+ } else if (rowEnd > visibleBottom) {
27619
+ nextScrollTop = rowEnd - scroller.clientHeight;
27620
+ }
27621
+ }
27622
+ if (colEnd > frozenPaneRight) {
27623
+ const visibleLeft = scroller.scrollLeft + frozenPaneRight;
27624
+ const visibleRight = scroller.scrollLeft + scroller.clientWidth;
27625
+ if (colStart < visibleLeft) {
27626
+ nextScrollLeft = colStart - frozenPaneRight;
27627
+ } else if (colEnd > visibleRight) {
27628
+ nextScrollLeft = colEnd - scroller.clientWidth;
27629
+ }
27630
+ }
27631
+ nextScrollTop = Math.max(0, Math.min(nextScrollTop, scroller.scrollHeight - scroller.clientHeight));
27632
+ nextScrollLeft = Math.max(0, Math.min(nextScrollLeft, scroller.scrollWidth - scroller.clientWidth));
27633
+ if (nextScrollTop !== scroller.scrollTop) {
27634
+ scroller.scrollTop = nextScrollTop;
27635
+ }
27636
+ if (nextScrollLeft !== scroller.scrollLeft) {
27637
+ scroller.scrollLeft = nextScrollLeft;
27638
+ }
27639
+ syncDrawingViewport(scroller, { immediate: true });
27640
+ }
27578
27641
  function moveSelection(nextRowIndex, nextColIndex, extend) {
27579
- const nextRow = visibleRows[nextRowIndex];
27580
- const nextCol = visibleCols[nextColIndex];
27642
+ const clampedRowIndex = Math.max(0, Math.min(nextRowIndex, visibleRows.length - 1));
27643
+ const clampedColIndex = Math.max(0, Math.min(nextColIndex, visibleCols.length - 1));
27644
+ const nextRow = visibleRows[clampedRowIndex];
27645
+ const nextCol = visibleCols[clampedColIndex];
27581
27646
  if (nextRow === void 0 || nextCol === void 0) {
27582
27647
  return;
27583
27648
  }
27584
27649
  selectCell({ row: nextRow, col: nextCol }, extend ? { extend: true } : void 0);
27650
+ ensureCellVisible(clampedRowIndex, clampedColIndex);
27651
+ }
27652
+ function resolvePageRowIndex(currentRowIndex, direction) {
27653
+ const scroller = scrollRef.current;
27654
+ const viewportHeight = Math.max(
27655
+ displayDefaultRowHeight,
27656
+ (scroller?.clientHeight ?? displayDefaultRowHeight * 20) - frozenPaneBottom
27657
+ );
27658
+ const currentOffset = rowPrefixSums[currentRowIndex] ?? 0;
27659
+ const targetOffset = direction > 0 ? currentOffset + viewportHeight : currentOffset - viewportHeight;
27660
+ return Math.max(0, Math.min(findIndexForOffsetPrefix(rowPrefixSums, targetOffset), visibleRows.length - 1));
27661
+ }
27662
+ function resolvePageColIndex(currentColIndex, direction) {
27663
+ const scroller = scrollRef.current;
27664
+ const viewportWidth = Math.max(
27665
+ displayDefaultColWidth,
27666
+ (scroller?.clientWidth ?? displayDefaultColWidth * 8) - frozenPaneRight
27667
+ );
27668
+ const currentOffset = colPrefixSums[currentColIndex] ?? 0;
27669
+ const targetOffset = direction > 0 ? currentOffset + viewportWidth : currentOffset - viewportWidth;
27670
+ return Math.max(0, Math.min(findIndexForOffsetPrefix(colPrefixSums, targetOffset), visibleCols.length - 1));
27585
27671
  }
27586
27672
  const scrollerViewportProps = {
27587
27673
  key: activeTabIndex,
27588
27674
  ref: scrollRef,
27675
+ "aria-colcount": Math.max(activeSheet?.colCount ?? 0, displayColLimit),
27676
+ "aria-keyshortcuts": "ArrowUp ArrowDown ArrowLeft ArrowRight Home End PageUp PageDown Control+Home Control+End",
27677
+ "aria-label": activeSheet ? `${activeSheet.name} worksheet grid` : "Workbook grid",
27678
+ "aria-readonly": readOnly,
27679
+ "aria-rowcount": Math.max(activeSheet?.rowCount ?? 0, displayRowLimit),
27680
+ role: "grid",
27589
27681
  onScroll: handleScrollerScroll,
27590
27682
  onCopy: (event) => {
27591
27683
  if (editingCell) {
@@ -27605,6 +27697,17 @@ function XlsxGrid({
27605
27697
  }
27606
27698
  void copySelectionToClipboard();
27607
27699
  },
27700
+ onPointerDownCapture: (event) => {
27701
+ if (event.button !== 0) {
27702
+ return;
27703
+ }
27704
+ if (isInteractiveFocusTarget(event.target, event.currentTarget)) {
27705
+ return;
27706
+ }
27707
+ if (document.activeElement !== event.currentTarget) {
27708
+ event.currentTarget.focus({ preventScroll: true });
27709
+ }
27710
+ },
27608
27711
  onKeyDown: (event) => {
27609
27712
  if (editingCell) {
27610
27713
  return;
@@ -27633,6 +27736,7 @@ function XlsxGrid({
27633
27736
  }
27634
27737
  const currentRowIndex = rowIndexByActual.get(currentCell.row) ?? 0;
27635
27738
  const currentColIndex = colIndexByActual.get(currentCell.col) ?? 0;
27739
+ const isCommandNavigation = event.ctrlKey || event.metaKey;
27636
27740
  if (!readOnly && isPrintableKey(event)) {
27637
27741
  event.preventDefault();
27638
27742
  startEditing(currentCell, event.key);
@@ -27641,38 +27745,94 @@ function XlsxGrid({
27641
27745
  switch (event.key) {
27642
27746
  case "ArrowDown":
27643
27747
  event.preventDefault();
27644
- moveSelection(Math.min(currentRowIndex + 1, visibleRows.length - 1), currentColIndex, event.shiftKey);
27748
+ moveSelection(
27749
+ isCommandNavigation ? rowIndexByActual.get(resolveLastUsedVisibleIndex(visibleRows, activeSheet?.maxUsedRow ?? -1)) ?? visibleRows.length - 1 : currentRowIndex + 1,
27750
+ currentColIndex,
27751
+ event.shiftKey
27752
+ );
27645
27753
  break;
27646
27754
  case "ArrowUp":
27647
27755
  event.preventDefault();
27648
- moveSelection(Math.max(currentRowIndex - 1, 0), currentColIndex, event.shiftKey);
27756
+ moveSelection(
27757
+ isCommandNavigation ? rowIndexByActual.get(resolveFirstUsedVisibleIndex(visibleRows, activeSheet?.minUsedRow ?? -1)) ?? 0 : currentRowIndex - 1,
27758
+ currentColIndex,
27759
+ event.shiftKey
27760
+ );
27649
27761
  break;
27650
27762
  case "ArrowLeft":
27651
27763
  event.preventDefault();
27652
- moveSelection(currentRowIndex, Math.max(currentColIndex - 1, 0), event.shiftKey);
27764
+ moveSelection(
27765
+ currentRowIndex,
27766
+ isCommandNavigation ? colIndexByActual.get(resolveFirstUsedVisibleIndex(visibleCols, activeSheet?.minUsedCol ?? -1)) ?? 0 : currentColIndex - 1,
27767
+ event.shiftKey
27768
+ );
27653
27769
  break;
27654
27770
  case "ArrowRight":
27655
27771
  event.preventDefault();
27656
- moveSelection(currentRowIndex, Math.min(currentColIndex + 1, visibleCols.length - 1), event.shiftKey);
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
+ );
27657
27785
  break;
27658
- case "Tab":
27786
+ case "End":
27659
27787
  event.preventDefault();
27660
27788
  moveSelection(
27661
- currentRowIndex,
27662
- event.shiftKey ? Math.max(currentColIndex - 1, 0) : Math.min(currentColIndex + 1, visibleCols.length - 1),
27663
- false
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
27664
27792
  );
27665
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;
27666
27826
  case "Enter":
27667
27827
  event.preventDefault();
27668
27828
  if (event.metaKey || event.ctrlKey || event.altKey) {
27669
27829
  break;
27670
27830
  }
27671
27831
  if (event.shiftKey) {
27672
- moveSelection(Math.max(currentRowIndex - 1, 0), currentColIndex, false);
27832
+ moveSelection(currentRowIndex - 1, currentColIndex, false);
27673
27833
  break;
27674
27834
  }
27675
- moveSelection(Math.min(currentRowIndex + 1, visibleRows.length - 1), currentColIndex, false);
27835
+ moveSelection(currentRowIndex + 1, currentColIndex, false);
27676
27836
  break;
27677
27837
  case "Backspace":
27678
27838
  case "Delete":