@extend-ai/react-xlsx 0.9.2 → 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,
@@ -21433,6 +21457,7 @@ function XlsxGrid({
21433
21457
  renderImage,
21434
21458
  renderImageSelection,
21435
21459
  renderTableHeaderMenu,
21460
+ renderScroller,
21436
21461
  enableGestureZoom = true,
21437
21462
  experimentalCanvas = true,
21438
21463
  selectionColor,
@@ -23147,8 +23172,8 @@ function XlsxGrid({
23147
23172
  selectionPreviewRangeRef.current = null;
23148
23173
  setInteractionMode("idle");
23149
23174
  }, [activeSheetIndex, clearGlobalCursor, revision]);
23150
- const focusGrid = React4.useCallback(() => {
23151
- scrollRef.current?.focus();
23175
+ const focusGrid = React4.useCallback((options) => {
23176
+ scrollRef.current?.focus(options);
23152
23177
  }, []);
23153
23178
  const openHyperlink = React4.useCallback((target, location) => {
23154
23179
  const internalTarget = parseInternalSheetLink(location ?? target);
@@ -27574,708 +27599,842 @@ function XlsxGrid({
27574
27599
  }
27575
27600
  return { row: firstVisibleRow, col: firstVisibleCol };
27576
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
+ }
27577
27641
  function moveSelection(nextRowIndex, nextColIndex, extend) {
27578
- const nextRow = visibleRows[nextRowIndex];
27579
- 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];
27580
27646
  if (nextRow === void 0 || nextCol === void 0) {
27581
27647
  return;
27582
27648
  }
27583
27649
  selectCell({ row: nextRow, col: nextCol }, extend ? { extend: true } : void 0);
27650
+ ensureCellVisible(clampedRowIndex, clampedColIndex);
27584
27651
  }
27585
- return /* @__PURE__ */ jsx3("div", { style: { backgroundColor: palette.canvas, display: "flex", flex: 1, minHeight: 0, minWidth: 0 }, children: /* @__PURE__ */ jsx3(
27586
- "div",
27587
- {
27588
- ref: scrollRef,
27589
- onScroll: handleScrollerScroll,
27590
- onCopy: (event) => {
27591
- if (editingCell) {
27592
- return;
27593
- }
27594
- const clipboard = event.clipboardData;
27595
- const clipboardData = getClipboardData();
27596
- if (!clipboardData) {
27597
- return;
27598
- }
27599
- event.preventDefault();
27600
- if (clipboard) {
27601
- clipboard.setData("text/plain", clipboardData.text);
27602
- clipboard.setData("text/html", clipboardData.html);
27603
- clipboard.setData(INTERNAL_CLIPBOARD_MIME2, clipboardData.structured);
27604
- return;
27605
- }
27606
- void copySelectionToClipboard();
27607
- },
27608
- onKeyDown: (event) => {
27609
- if (editingCell) {
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));
27671
+ }
27672
+ const scrollerViewportProps = {
27673
+ key: activeTabIndex,
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",
27681
+ onScroll: handleScrollerScroll,
27682
+ onCopy: (event) => {
27683
+ if (editingCell) {
27684
+ return;
27685
+ }
27686
+ const clipboard = event.clipboardData;
27687
+ const clipboardData = getClipboardData();
27688
+ if (!clipboardData) {
27689
+ return;
27690
+ }
27691
+ event.preventDefault();
27692
+ if (clipboard) {
27693
+ clipboard.setData("text/plain", clipboardData.text);
27694
+ clipboard.setData("text/html", clipboardData.html);
27695
+ clipboard.setData(INTERNAL_CLIPBOARD_MIME2, clipboardData.structured);
27696
+ return;
27697
+ }
27698
+ void copySelectionToClipboard();
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
+ },
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();
27610
27720
  return;
27611
27721
  }
27612
- if (!readOnly && (event.metaKey || event.ctrlKey) && !event.altKey) {
27613
- const normalizedKey = event.key.toLowerCase();
27614
- if (normalizedKey === "z" && event.shiftKey) {
27615
- event.preventDefault();
27616
- redo();
27617
- return;
27618
- }
27619
- if (normalizedKey === "z") {
27620
- event.preventDefault();
27621
- undo();
27622
- return;
27623
- }
27624
- if (normalizedKey === "y") {
27625
- event.preventDefault();
27626
- redo();
27627
- return;
27628
- }
27629
- }
27630
- const currentCell = resolveCurrentCell();
27631
- if (!currentCell) {
27722
+ if (normalizedKey === "z") {
27723
+ event.preventDefault();
27724
+ undo();
27632
27725
  return;
27633
27726
  }
27634
- const currentRowIndex = rowIndexByActual.get(currentCell.row) ?? 0;
27635
- const currentColIndex = colIndexByActual.get(currentCell.col) ?? 0;
27636
- if (!readOnly && isPrintableKey(event)) {
27727
+ if (normalizedKey === "y") {
27637
27728
  event.preventDefault();
27638
- startEditing(currentCell, event.key);
27729
+ redo();
27639
27730
  return;
27640
27731
  }
27641
- switch (event.key) {
27642
- case "ArrowDown":
27643
- event.preventDefault();
27644
- moveSelection(Math.min(currentRowIndex + 1, visibleRows.length - 1), currentColIndex, event.shiftKey);
27645
- break;
27646
- case "ArrowUp":
27647
- event.preventDefault();
27648
- moveSelection(Math.max(currentRowIndex - 1, 0), currentColIndex, event.shiftKey);
27649
- break;
27650
- case "ArrowLeft":
27651
- event.preventDefault();
27652
- moveSelection(currentRowIndex, Math.max(currentColIndex - 1, 0), event.shiftKey);
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);
27743
+ return;
27744
+ }
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);
27653
27798
  break;
27654
- case "ArrowRight":
27655
- event.preventDefault();
27656
- moveSelection(currentRowIndex, Math.min(currentColIndex + 1, visibleCols.length - 1), event.shiftKey);
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);
27657
27806
  break;
27658
- case "Tab":
27659
- event.preventDefault();
27807
+ }
27808
+ moveSelection(resolvePageRowIndex(currentRowIndex, -1), currentColIndex, event.shiftKey);
27809
+ break;
27810
+ case "Tab":
27811
+ event.preventDefault();
27812
+ if (event.shiftKey) {
27660
27813
  moveSelection(
27661
- currentRowIndex,
27662
- event.shiftKey ? Math.max(currentColIndex - 1, 0) : Math.min(currentColIndex + 1, visibleCols.length - 1),
27814
+ currentColIndex > 0 ? currentRowIndex : currentRowIndex - 1,
27815
+ currentColIndex > 0 ? currentColIndex - 1 : visibleCols.length - 1,
27663
27816
  false
27664
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) {
27665
27829
  break;
27666
- case "Enter":
27667
- event.preventDefault();
27668
- if (event.metaKey || event.ctrlKey || event.altKey) {
27669
- break;
27670
- }
27671
- if (event.shiftKey) {
27672
- moveSelection(Math.max(currentRowIndex - 1, 0), currentColIndex, false);
27673
- break;
27674
- }
27675
- moveSelection(Math.min(currentRowIndex + 1, visibleRows.length - 1), currentColIndex, false);
27676
- break;
27677
- case "Backspace":
27678
- case "Delete":
27679
- if (!readOnly) {
27680
- event.preventDefault();
27681
- clearSelectedCells();
27682
- }
27683
- break;
27684
- case "F2":
27685
- if (!readOnly) {
27686
- event.preventDefault();
27687
- startEditing(currentCell);
27688
- }
27689
- break;
27690
- default:
27830
+ }
27831
+ if (event.shiftKey) {
27832
+ moveSelection(currentRowIndex - 1, currentColIndex, false);
27691
27833
  break;
27692
- }
27693
- },
27694
- onPaste: (event) => {
27695
- if (editingCell || readOnly) {
27696
- return;
27697
- }
27698
- const clipboard = event.clipboardData;
27699
- if (!clipboard) {
27700
- event.preventDefault();
27701
- void pasteFromClipboard();
27702
- return;
27703
- }
27704
- const structuredPayload = clipboard.getData(INTERNAL_CLIPBOARD_MIME2);
27705
- const textPayload = clipboard.getData("text/plain");
27706
- if (!structuredPayload && !textPayload) {
27707
- return;
27708
- }
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
+ }
27853
+ },
27854
+ onPaste: (event) => {
27855
+ if (editingCell || readOnly) {
27856
+ return;
27857
+ }
27858
+ const clipboard = event.clipboardData;
27859
+ if (!clipboard) {
27709
27860
  event.preventDefault();
27710
- if (structuredPayload) {
27711
- pasteStructuredClipboardData(structuredPayload);
27712
- return;
27713
- }
27714
- pasteText(textPayload);
27715
- },
27716
- tabIndex: 0,
27861
+ void pasteFromClipboard();
27862
+ return;
27863
+ }
27864
+ const structuredPayload = clipboard.getData(INTERNAL_CLIPBOARD_MIME2);
27865
+ const textPayload = clipboard.getData("text/plain");
27866
+ if (!structuredPayload && !textPayload) {
27867
+ return;
27868
+ }
27869
+ event.preventDefault();
27870
+ if (structuredPayload) {
27871
+ pasteStructuredClipboardData(structuredPayload);
27872
+ return;
27873
+ }
27874
+ pasteText(textPayload);
27875
+ },
27876
+ tabIndex: 0,
27877
+ style: {
27878
+ ["--xlsx-menu-active"]: selectionFill,
27879
+ ["--xlsx-menu-border"]: palette.strongBorder,
27880
+ ["--xlsx-menu-surface"]: palette.surface,
27881
+ ["--xlsx-selection-header"]: selectionHeaderSurface,
27882
+ backgroundColor: palette.canvas,
27883
+ color: palette.text,
27884
+ cursor: resizeGuide?.type === "column" ? "col-resize" : resizeGuide?.type === "row" ? "row-resize" : void 0,
27885
+ flex: 1,
27886
+ height: "100%",
27887
+ minHeight: 0,
27888
+ minWidth: 0,
27889
+ outline: "none",
27890
+ overflow: "auto",
27891
+ width: "100%"
27892
+ }
27893
+ };
27894
+ const scrollerContent = /* @__PURE__ */ jsx3(
27895
+ "div",
27896
+ {
27717
27897
  style: {
27718
- ["--xlsx-menu-active"]: selectionFill,
27719
- ["--xlsx-menu-border"]: palette.strongBorder,
27720
- ["--xlsx-menu-surface"]: palette.surface,
27721
- ["--xlsx-selection-header"]: selectionHeaderSurface,
27722
- backgroundColor: palette.canvas,
27723
- color: palette.text,
27724
- cursor: resizeGuide?.type === "column" ? "col-resize" : resizeGuide?.type === "row" ? "row-resize" : void 0,
27725
- flex: 1,
27726
- height: "100%",
27727
- minHeight: 0,
27728
- minWidth: 0,
27729
- outline: "none",
27730
- overflow: "auto",
27731
- width: "100%"
27898
+ backgroundColor: resolveSheetSurface(activeSheet, palette),
27899
+ minHeight: "100%",
27900
+ minWidth: "100%",
27901
+ position: "relative",
27902
+ width: totalWidth,
27903
+ height: sheetContentHeight
27732
27904
  },
27733
- children: /* @__PURE__ */ jsx3(
27905
+ children: /* @__PURE__ */ jsxs3(
27734
27906
  "div",
27735
27907
  {
27908
+ ref: wrapperRef,
27736
27909
  style: {
27737
- backgroundColor: resolveSheetSurface(activeSheet, palette),
27738
- minHeight: "100%",
27739
- minWidth: "100%",
27740
- position: "relative",
27741
- width: totalWidth,
27742
- height: sheetContentHeight
27910
+ height: sheetContentHeight,
27911
+ left: 0,
27912
+ position: "absolute",
27913
+ top: 0,
27914
+ transform: !experimentalCanvas && isLiveZooming ? `translate3d(${liveZoomTranslateX}px, ${liveZoomTranslateY}px, 0) scale(${liveZoomScale})` : void 0,
27915
+ transformOrigin: "0 0",
27916
+ transition: "none",
27917
+ willChange: !experimentalCanvas && isLiveZooming ? "transform" : void 0,
27918
+ width: totalWidth
27743
27919
  },
27744
- children: /* @__PURE__ */ jsxs3(
27745
- "div",
27746
- {
27747
- ref: wrapperRef,
27748
- style: {
27749
- height: sheetContentHeight,
27750
- left: 0,
27751
- position: "absolute",
27752
- top: 0,
27753
- transform: !experimentalCanvas && isLiveZooming ? `translate3d(${liveZoomTranslateX}px, ${liveZoomTranslateY}px, 0) scale(${liveZoomScale})` : void 0,
27754
- transformOrigin: "0 0",
27755
- transition: "none",
27756
- willChange: !experimentalCanvas && isLiveZooming ? "transform" : void 0,
27757
- width: totalWidth
27758
- },
27759
- children: [
27760
- showImages && !experimentalCanvas ? /* @__PURE__ */ jsxs3(Fragment4, { children: [
27761
- /* @__PURE__ */ jsx3("div", { style: topOverlayStyle, children: paneDrawingNodes.top }),
27762
- /* @__PURE__ */ jsx3("div", { style: leftOverlayStyle, children: paneDrawingNodes.left }),
27763
- /* @__PURE__ */ jsx3("div", { style: cornerOverlayStyle, children: paneDrawingNodes.corner }),
27764
- /* @__PURE__ */ jsx3("div", { style: scrollOverlayStyle, children: paneDrawingNodes.scroll })
27765
- ] }) : null,
27766
- experimentalCanvas ? /* @__PURE__ */ jsxs3(Fragment4, { children: [
27767
- /* @__PURE__ */ jsxs3("div", { style: canvasBodyViewportLayerStyle, children: [
27768
- /* @__PURE__ */ jsx3(
27769
- "canvas",
27770
- {
27771
- ref: scrollBodyCanvasRef,
27772
- onClick: handleCanvasBodyClick,
27773
- onDoubleClick: handleCanvasBodyDoubleClick,
27774
- onPointerDown: handleCanvasBodyPointerDown,
27775
- style: canvasScrollBodyStyle
27776
- }
27777
- ),
27778
- /* @__PURE__ */ jsx3(
27779
- "canvas",
27780
- {
27781
- ref: topBodyCanvasRef,
27782
- onClick: handleCanvasBodyClick,
27783
- onDoubleClick: handleCanvasBodyDoubleClick,
27784
- onPointerDown: handleCanvasBodyPointerDown,
27785
- style: canvasTopBodyStyle
27786
- }
27787
- ),
27788
- /* @__PURE__ */ jsx3(
27789
- "canvas",
27790
- {
27791
- ref: leftBodyCanvasRef,
27792
- onClick: handleCanvasBodyClick,
27793
- onDoubleClick: handleCanvasBodyDoubleClick,
27794
- onPointerDown: handleCanvasBodyPointerDown,
27795
- style: canvasLeftBodyStyle
27796
- }
27797
- ),
27798
- /* @__PURE__ */ jsx3(
27799
- "canvas",
27800
- {
27801
- ref: cornerBodyCanvasRef,
27802
- onClick: handleCanvasBodyClick,
27803
- onDoubleClick: handleCanvasBodyDoubleClick,
27804
- onPointerDown: handleCanvasBodyPointerDown,
27805
- style: canvasCornerBodyStyle
27806
- }
27807
- ),
27808
- hasCanvasDomDrawingOverlays ? /* @__PURE__ */ jsxs3(Fragment4, { children: [
27809
- /* @__PURE__ */ jsx3("div", { style: canvasScrollOverlayPaneStyle, children: /* @__PURE__ */ jsx3(
27810
- "div",
27811
- {
27812
- ref: canvasScrollOverlayContentRef,
27813
- style: {
27814
- height: sheetContentHeight,
27815
- left: 0,
27816
- pointerEvents: "none",
27817
- position: "absolute",
27818
- top: 0,
27819
- transform: `translate(${-drawingViewport.left - frozenPaneRight}px, ${-drawingViewport.top - frozenPaneBottom}px)`,
27820
- transformOrigin: "0 0",
27821
- width: totalWidth
27822
- },
27823
- children: paneDrawingNodes.scroll
27824
- }
27825
- ) }),
27826
- /* @__PURE__ */ jsx3("div", { style: canvasTopOverlayPaneStyle, children: /* @__PURE__ */ jsx3(
27827
- "div",
27828
- {
27829
- ref: canvasTopOverlayContentRef,
27830
- style: {
27831
- height: sheetContentHeight,
27832
- left: 0,
27833
- pointerEvents: "none",
27834
- position: "absolute",
27835
- top: 0,
27836
- transform: `translate(${-drawingViewport.left - frozenPaneRight}px, ${-displayHeaderHeight}px)`,
27837
- transformOrigin: "0 0",
27838
- width: totalWidth
27839
- },
27840
- children: paneDrawingNodes.top
27841
- }
27842
- ) }),
27843
- /* @__PURE__ */ jsx3("div", { style: canvasLeftOverlayPaneStyle, children: /* @__PURE__ */ jsx3(
27844
- "div",
27845
- {
27846
- ref: canvasLeftOverlayContentRef,
27847
- style: {
27848
- height: sheetContentHeight,
27849
- left: 0,
27850
- pointerEvents: "none",
27851
- position: "absolute",
27852
- top: 0,
27853
- transform: `translate(${-displayRowHeaderWidth}px, ${-drawingViewport.top - frozenPaneBottom}px)`,
27854
- transformOrigin: "0 0",
27855
- width: totalWidth
27856
- },
27857
- children: paneDrawingNodes.left
27858
- }
27859
- ) }),
27860
- /* @__PURE__ */ jsx3("div", { style: canvasCornerOverlayPaneStyle, children: /* @__PURE__ */ jsx3(
27861
- "div",
27862
- {
27863
- ref: canvasCornerOverlayContentRef,
27864
- style: {
27865
- height: sheetContentHeight,
27866
- left: 0,
27867
- pointerEvents: "none",
27868
- position: "absolute",
27869
- top: 0,
27870
- transform: `translate(${-displayRowHeaderWidth}px, ${-displayHeaderHeight}px)`,
27871
- transformOrigin: "0 0",
27872
- width: totalWidth
27873
- },
27874
- children: paneDrawingNodes.corner
27875
- }
27876
- ) })
27877
- ] }) : null
27878
- ] }),
27879
- /* @__PURE__ */ jsxs3("div", { style: canvasHeaderViewportLayerStyle, children: [
27880
- /* @__PURE__ */ jsx3(
27881
- "canvas",
27882
- {
27883
- ref: topFrozenHeaderCanvasRef,
27884
- onPointerLeave: handleCanvasHeaderPointerLeave,
27885
- onPointerMove: handleCanvasColumnHeaderPointerMove,
27886
- onPointerDown: handleCanvasColumnHeaderPointerDown,
27887
- style: canvasTopFrozenHeaderStyle
27888
- }
27889
- ),
27890
- /* @__PURE__ */ jsx3(
27891
- "canvas",
27892
- {
27893
- ref: topScrollHeaderCanvasRef,
27894
- onPointerLeave: handleCanvasHeaderPointerLeave,
27895
- onPointerMove: handleCanvasColumnHeaderPointerMove,
27896
- onPointerDown: handleCanvasColumnHeaderPointerDown,
27897
- style: canvasTopScrollHeaderStyle
27898
- }
27899
- ),
27900
- /* @__PURE__ */ jsx3(
27901
- "canvas",
27902
- {
27903
- ref: leftFrozenHeaderCanvasRef,
27904
- onPointerLeave: handleCanvasHeaderPointerLeave,
27905
- onPointerMove: handleCanvasRowHeaderPointerMove,
27906
- onPointerDown: handleCanvasRowHeaderPointerDown,
27907
- style: canvasLeftFrozenHeaderStyle
27908
- }
27909
- ),
27910
- /* @__PURE__ */ jsx3(
27911
- "canvas",
27912
- {
27913
- ref: leftScrollHeaderCanvasRef,
27914
- onPointerLeave: handleCanvasHeaderPointerLeave,
27915
- onPointerMove: handleCanvasRowHeaderPointerMove,
27916
- onPointerDown: handleCanvasRowHeaderPointerDown,
27917
- style: canvasLeftScrollHeaderStyle
27918
- }
27919
- ),
27920
- /* @__PURE__ */ jsx3("canvas", { ref: cornerHeaderCanvasRef, style: canvasCornerHeaderStyle })
27921
- ] }),
27922
- editingCell && editingOverlayRect ? (() => {
27923
- const editingCellStyle = getCellData(editingCell.row, editingCell.col).style;
27924
- const editingBackground = typeof editingCellStyle.backgroundColor === "string" ? editingCellStyle.backgroundColor : resolveSheetSurface(activeSheet, palette);
27925
- const editingColor = typeof editingCellStyle.color === "string" ? editingCellStyle.color : resolveReadableTextColor(null, editingBackground, palette);
27926
- return /* @__PURE__ */ jsx3(
27927
- "div",
27928
- {
27929
- style: {
27930
- left: editingOverlayRect.left,
27931
- position: "absolute",
27932
- top: editingOverlayRect.top,
27933
- width: editingOverlayRect.width,
27934
- height: editingOverlayRect.height,
27935
- zIndex: 28
27936
- },
27937
- children: /* @__PURE__ */ jsx3(
27938
- "input",
27939
- {
27940
- ref: editingInputRef,
27941
- autoFocus: true,
27942
- onBlur: commitEditing,
27943
- onChange: (event) => setEditingValue(event.target.value),
27944
- onKeyDown: (event) => {
27945
- event.stopPropagation();
27946
- if (event.key === "Enter") {
27947
- event.preventDefault();
27948
- commitEditing();
27949
- return;
27950
- }
27951
- if (event.key === "Escape") {
27952
- event.preventDefault();
27953
- cancelEditing();
27954
- }
27955
- },
27956
- style: {
27957
- backgroundColor: editingBackground,
27958
- border: 0,
27959
- boxShadow: `inset 0 0 0 ${selectionBorderWidth}px ${selectionStroke}`,
27960
- boxSizing: "border-box",
27961
- color: editingColor,
27962
- display: "block",
27963
- font: resolveCanvasFont(editingCellStyle, 12 * zoomFactor),
27964
- height: "100%",
27965
- margin: 0,
27966
- minHeight: 0,
27967
- outline: "none",
27968
- overflow: "hidden",
27969
- padding: scaleCssLengthExpression(DEFAULT_CELL_PADDING, zoomFactor),
27970
- width: "100%"
27971
- },
27972
- value: editingValue
27973
- }
27974
- )
27975
- }
27976
- );
27977
- })() : null,
27978
- activeCellAdornment && activeCellAdornmentRect ? /* @__PURE__ */ jsx3(
27920
+ children: [
27921
+ showImages && !experimentalCanvas ? /* @__PURE__ */ jsxs3(Fragment4, { children: [
27922
+ /* @__PURE__ */ jsx3("div", { style: topOverlayStyle, children: paneDrawingNodes.top }),
27923
+ /* @__PURE__ */ jsx3("div", { style: leftOverlayStyle, children: paneDrawingNodes.left }),
27924
+ /* @__PURE__ */ jsx3("div", { style: cornerOverlayStyle, children: paneDrawingNodes.corner }),
27925
+ /* @__PURE__ */ jsx3("div", { style: scrollOverlayStyle, children: paneDrawingNodes.scroll })
27926
+ ] }) : null,
27927
+ experimentalCanvas ? /* @__PURE__ */ jsxs3(Fragment4, { children: [
27928
+ /* @__PURE__ */ jsxs3("div", { style: canvasBodyViewportLayerStyle, children: [
27929
+ /* @__PURE__ */ jsx3(
27930
+ "canvas",
27931
+ {
27932
+ ref: scrollBodyCanvasRef,
27933
+ onClick: handleCanvasBodyClick,
27934
+ onDoubleClick: handleCanvasBodyDoubleClick,
27935
+ onPointerDown: handleCanvasBodyPointerDown,
27936
+ style: canvasScrollBodyStyle
27937
+ }
27938
+ ),
27939
+ /* @__PURE__ */ jsx3(
27940
+ "canvas",
27941
+ {
27942
+ ref: topBodyCanvasRef,
27943
+ onClick: handleCanvasBodyClick,
27944
+ onDoubleClick: handleCanvasBodyDoubleClick,
27945
+ onPointerDown: handleCanvasBodyPointerDown,
27946
+ style: canvasTopBodyStyle
27947
+ }
27948
+ ),
27949
+ /* @__PURE__ */ jsx3(
27950
+ "canvas",
27951
+ {
27952
+ ref: leftBodyCanvasRef,
27953
+ onClick: handleCanvasBodyClick,
27954
+ onDoubleClick: handleCanvasBodyDoubleClick,
27955
+ onPointerDown: handleCanvasBodyPointerDown,
27956
+ style: canvasLeftBodyStyle
27957
+ }
27958
+ ),
27959
+ /* @__PURE__ */ jsx3(
27960
+ "canvas",
27961
+ {
27962
+ ref: cornerBodyCanvasRef,
27963
+ onClick: handleCanvasBodyClick,
27964
+ onDoubleClick: handleCanvasBodyDoubleClick,
27965
+ onPointerDown: handleCanvasBodyPointerDown,
27966
+ style: canvasCornerBodyStyle
27967
+ }
27968
+ ),
27969
+ hasCanvasDomDrawingOverlays ? /* @__PURE__ */ jsxs3(Fragment4, { children: [
27970
+ /* @__PURE__ */ jsx3("div", { style: canvasScrollOverlayPaneStyle, children: /* @__PURE__ */ jsx3(
27971
+ "div",
27972
+ {
27973
+ ref: canvasScrollOverlayContentRef,
27974
+ style: {
27975
+ height: sheetContentHeight,
27976
+ left: 0,
27977
+ pointerEvents: "none",
27978
+ position: "absolute",
27979
+ top: 0,
27980
+ transform: `translate(${-drawingViewport.left - frozenPaneRight}px, ${-drawingViewport.top - frozenPaneBottom}px)`,
27981
+ transformOrigin: "0 0",
27982
+ width: totalWidth
27983
+ },
27984
+ children: paneDrawingNodes.scroll
27985
+ }
27986
+ ) }),
27987
+ /* @__PURE__ */ jsx3("div", { style: canvasTopOverlayPaneStyle, children: /* @__PURE__ */ jsx3(
27988
+ "div",
27989
+ {
27990
+ ref: canvasTopOverlayContentRef,
27991
+ style: {
27992
+ height: sheetContentHeight,
27993
+ left: 0,
27994
+ pointerEvents: "none",
27995
+ position: "absolute",
27996
+ top: 0,
27997
+ transform: `translate(${-drawingViewport.left - frozenPaneRight}px, ${-displayHeaderHeight}px)`,
27998
+ transformOrigin: "0 0",
27999
+ width: totalWidth
28000
+ },
28001
+ children: paneDrawingNodes.top
28002
+ }
28003
+ ) }),
28004
+ /* @__PURE__ */ jsx3("div", { style: canvasLeftOverlayPaneStyle, children: /* @__PURE__ */ jsx3(
28005
+ "div",
28006
+ {
28007
+ ref: canvasLeftOverlayContentRef,
28008
+ style: {
28009
+ height: sheetContentHeight,
28010
+ left: 0,
28011
+ pointerEvents: "none",
28012
+ position: "absolute",
28013
+ top: 0,
28014
+ transform: `translate(${-displayRowHeaderWidth}px, ${-drawingViewport.top - frozenPaneBottom}px)`,
28015
+ transformOrigin: "0 0",
28016
+ width: totalWidth
28017
+ },
28018
+ children: paneDrawingNodes.left
28019
+ }
28020
+ ) }),
28021
+ /* @__PURE__ */ jsx3("div", { style: canvasCornerOverlayPaneStyle, children: /* @__PURE__ */ jsx3(
27979
28022
  "div",
27980
28023
  {
28024
+ ref: canvasCornerOverlayContentRef,
27981
28025
  style: {
27982
- height: activeCellAdornmentRect.height,
27983
- left: activeCellAdornmentRect.left,
28026
+ height: sheetContentHeight,
28027
+ left: 0,
27984
28028
  pointerEvents: "none",
27985
28029
  position: "absolute",
27986
- top: activeCellAdornmentRect.top,
27987
- width: activeCellAdornmentRect.width,
27988
- zIndex: 27
28030
+ top: 0,
28031
+ transform: `translate(${-displayRowHeaderWidth}px, ${-displayHeaderHeight}px)`,
28032
+ transformOrigin: "0 0",
28033
+ width: totalWidth
27989
28034
  },
27990
- children: /* @__PURE__ */ jsx3("div", { style: { height: "100%", pointerEvents: "auto", position: "relative", width: "100%" }, children: activeCellAdornment })
28035
+ children: paneDrawingNodes.corner
27991
28036
  }
27992
- ) : null
27993
- ] }) : /* @__PURE__ */ jsxs3(
27994
- "table",
28037
+ ) })
28038
+ ] }) : null
28039
+ ] }),
28040
+ /* @__PURE__ */ jsxs3("div", { style: canvasHeaderViewportLayerStyle, children: [
28041
+ /* @__PURE__ */ jsx3(
28042
+ "canvas",
27995
28043
  {
27996
- ref: tableRef,
27997
- style: {
27998
- borderCollapse: "collapse",
27999
- color: "#000000",
28000
- flex: "0 0 auto",
28001
- tableLayout: "fixed",
28002
- width: totalWidth
28003
- },
28004
- children: [
28005
- /* @__PURE__ */ jsxs3("colgroup", { children: [
28006
- /* @__PURE__ */ jsx3("col", { style: { width: displayRowHeaderWidth } }),
28007
- leadingColumnSpacerWidth > 0 ? /* @__PURE__ */ jsx3("col", { style: { width: leadingColumnSpacerWidth } }) : null,
28008
- renderedCols.map((column) => /* @__PURE__ */ jsx3(
28009
- "col",
28010
- {
28011
- ref: (element) => {
28012
- if (element) {
28013
- colElementRefs.current.set(column.actualCol, element);
28014
- } else {
28015
- colElementRefs.current.delete(column.actualCol);
28016
- }
28017
- },
28018
- style: { width: column.size }
28019
- },
28020
- column.key
28021
- )),
28022
- trailingColumnSpacerWidth > 0 ? /* @__PURE__ */ jsx3("col", { style: { width: trailingColumnSpacerWidth } }) : null
28023
- ] }),
28024
- /* @__PURE__ */ jsx3("thead", { style: { position: "sticky", top: 0, zIndex: canvasHeaderOverlayZIndex }, children: /* @__PURE__ */ jsxs3("tr", { children: [
28025
- /* @__PURE__ */ jsx3(
28026
- "th",
28027
- {
28028
- style: {
28029
- ...headerCellStyle,
28030
- backgroundColor: palette.headerSurface,
28031
- left: 0,
28032
- width: displayRowHeaderWidth,
28033
- zIndex: cornerHeaderOverlayZIndex
28034
- }
28035
- }
28036
- ),
28037
- leadingColumnSpacerWidth > 0 ? /* @__PURE__ */ jsx3("th", { "aria-hidden": "true", style: { ...headerCellStyle, padding: 0, width: leadingColumnSpacerWidth } }) : null,
28038
- renderedCols.map((column) => /* @__PURE__ */ jsx3(
28039
- "th",
28040
- {
28041
- "data-xlsx-col-header": column.actualCol,
28042
- ref: (element) => setColHeaderRef(column.actualCol, element),
28043
- onPointerDown: (event) => handleColumnPointerDown(event, column.actualCol),
28044
- style: {
28045
- ...headerCellStyle,
28046
- left: stickyLeftByCol.get(column.actualCol),
28047
- zIndex: stickyLeftByCol.has(column.actualCol) ? stickyHeaderOverlayZIndex : headerCellStyle.zIndex
28048
- },
28049
- children: /* @__PURE__ */ jsxs3("div", { style: { position: "relative" }, children: [
28050
- /* @__PURE__ */ jsx3(
28051
- "span",
28052
- {
28053
- style: {
28054
- display: "inline-block",
28055
- transform: headerLabelLiveScale !== 1 ? `scale(${1 / headerLabelLiveScale})` : void 0,
28056
- transformOrigin: "center center"
28057
- },
28058
- children: columnLabel2(column.actualCol)
28059
- }
28060
- ),
28061
- /* @__PURE__ */ jsx3(
28062
- "div",
28063
- {
28064
- onPointerDown: (event) => {
28065
- if (!canResizeHeaders) {
28066
- return;
28067
- }
28068
- event.preventDefault();
28069
- event.stopPropagation();
28070
- startColumnResize(
28071
- event.pointerId,
28072
- column.actualCol,
28073
- column.size,
28074
- event.clientX
28075
- );
28076
- },
28077
- style: columnResizeHandleStyle
28078
- }
28079
- )
28080
- ] })
28081
- },
28082
- column.key
28083
- )),
28084
- trailingColumnSpacerWidth > 0 ? /* @__PURE__ */ jsx3("th", { "aria-hidden": "true", style: { ...headerCellStyle, padding: 0, width: trailingColumnSpacerWidth } }) : null
28085
- ] }) }),
28086
- /* @__PURE__ */ jsxs3("tbody", { children: [
28087
- virtualRows.map((virtualRow, index) => {
28088
- const actualRow = visibleRows[virtualRow.index];
28089
- if (actualRow === void 0) {
28090
- return null;
28091
- }
28092
- const previousEnd = index === 0 ? 0 : virtualRows[index - 1]?.end ?? 0;
28093
- const gapHeight = Math.max(0, virtualRow.start - previousEnd);
28094
- return /* @__PURE__ */ jsxs3(React4.Fragment, { children: [
28095
- gapHeight > 0 ? /* @__PURE__ */ jsx3("tr", { "aria-hidden": "true", style: { height: gapHeight }, children: /* @__PURE__ */ jsx3("td", { colSpan: rowColSpan }) }) : null,
28096
- /* @__PURE__ */ jsx3(
28097
- MemoGridRow,
28098
- {
28099
- actualRow,
28100
- editingCell,
28101
- editingValue,
28102
- frozenRowHeaderZIndex: frozenRowHeaderOverlayZIndex,
28103
- getCellData,
28104
- leadingSpacerWidth: leadingColumnSpacerWidth,
28105
- onCellClick: handleCellClick,
28106
- onCellDoubleClick: handleCellDoubleClick,
28107
- onCellPointerDown: handleCellPointerDown,
28108
- onEditingCancel: cancelEditing,
28109
- onEditingCommit: commitEditing,
28110
- onEditingValueChange: setEditingValue,
28111
- headerLabelLiveScale,
28112
- onRowHeaderRef: setRowHeaderRef,
28113
- onRowPointerDown: handleRowPointerDown,
28114
- onRowResizePointerDown: handleRowResizePointerDown,
28115
- palette,
28116
- readOnly,
28117
- renderCellAdornment,
28118
- rowHeight: virtualRow.size,
28119
- rowHeaderZIndex: rowHeaderOverlayZIndex,
28120
- rowHeaderWidth: displayRowHeaderWidth,
28121
- stickyLeftByCol,
28122
- stickyTop: stickyTopByRow.get(actualRow),
28123
- trailingSpacerWidth: trailingColumnSpacerWidth,
28124
- visibleCols: renderedCols,
28125
- zoomFactor
28126
- },
28127
- virtualRow.key
28128
- )
28129
- ] }, `row-fragment-${virtualRow.key}`);
28130
- }),
28131
- virtualRows.length > 0 && totalHeight - (virtualRows[virtualRows.length - 1]?.end ?? totalHeight) > 0 ? /* @__PURE__ */ jsx3(
28132
- "tr",
28133
- {
28134
- style: {
28135
- height: totalHeight - (virtualRows[virtualRows.length - 1]?.end ?? totalHeight)
28136
- },
28137
- children: /* @__PURE__ */ jsx3("td", { colSpan: rowColSpan })
28138
- }
28139
- ) : null
28140
- ] })
28141
- ]
28044
+ ref: topFrozenHeaderCanvasRef,
28045
+ onPointerLeave: handleCanvasHeaderPointerLeave,
28046
+ onPointerMove: handleCanvasColumnHeaderPointerMove,
28047
+ onPointerDown: handleCanvasColumnHeaderPointerDown,
28048
+ style: canvasTopFrozenHeaderStyle
28142
28049
  }
28143
28050
  ),
28144
28051
  /* @__PURE__ */ jsx3(
28145
- "div",
28052
+ "canvas",
28146
28053
  {
28147
- ref: selectionOverlayRef,
28148
- style: {
28149
- backgroundColor: selectionFill,
28150
- boxSizing: "border-box",
28151
- boxShadow: `inset 0 0 0 ${selectionBorderWidth}px ${selectionStroke}`,
28152
- contain: "layout paint",
28153
- height: resolvedSelectionOverlay?.height ?? 0,
28154
- left: resolvedSelectionOverlay?.left ?? 0,
28155
- opacity: resolvedSelectionOverlay ? 1 : 0,
28156
- pointerEvents: "none",
28157
- position: "absolute",
28158
- top: resolvedSelectionOverlay?.top ?? 0,
28159
- transition: canvasSelectionTransition,
28160
- visibility: resolvedSelectionOverlay ? "visible" : "hidden",
28161
- willChange: shouldAnimateCanvasSelection ? "left, top, width, height" : void 0,
28162
- width: resolvedSelectionOverlay?.width ?? 0,
28163
- zIndex: 24
28164
- }
28054
+ ref: topScrollHeaderCanvasRef,
28055
+ onPointerLeave: handleCanvasHeaderPointerLeave,
28056
+ onPointerMove: handleCanvasColumnHeaderPointerMove,
28057
+ onPointerDown: handleCanvasColumnHeaderPointerDown,
28058
+ style: canvasTopScrollHeaderStyle
28165
28059
  }
28166
28060
  ),
28167
28061
  /* @__PURE__ */ jsx3(
28168
- "div",
28062
+ "canvas",
28169
28063
  {
28170
- ref: activeValidationOverlayRef,
28171
- "aria-hidden": "true",
28172
- style: {
28173
- alignItems: "center",
28174
- color: palette.mutedText,
28175
- display: "inline-flex",
28176
- fontSize: 10 * zoomFactor,
28177
- fontWeight: 700,
28178
- height: 16 * zoomFactor,
28179
- justifyContent: "center",
28180
- opacity: 0,
28181
- pointerEvents: "none",
28182
- position: "absolute",
28183
- transform: "translateY(-50%)",
28184
- visibility: "hidden",
28185
- width: 12 * zoomFactor,
28186
- zIndex: 26
28187
- },
28188
- children: "\u25BE"
28064
+ ref: leftFrozenHeaderCanvasRef,
28065
+ onPointerLeave: handleCanvasHeaderPointerLeave,
28066
+ onPointerMove: handleCanvasRowHeaderPointerMove,
28067
+ onPointerDown: handleCanvasRowHeaderPointerDown,
28068
+ style: canvasLeftFrozenHeaderStyle
28189
28069
  }
28190
28070
  ),
28191
28071
  /* @__PURE__ */ jsx3(
28192
- "div",
28072
+ "canvas",
28193
28073
  {
28194
- ref: fillHandleRef,
28195
- onPointerDown: (event) => {
28196
- if (readOnly || event.button !== 0 || !normalizedSelection || !resolvedSelectionOverlay) {
28197
- return;
28198
- }
28199
- event.preventDefault();
28200
- event.stopPropagation();
28201
- startFillDrag(event.pointerId, normalizedSelection);
28202
- },
28203
- style: {
28204
- backgroundColor: selectionStroke,
28205
- border: `${Math.max(1, zoomFactor)}px solid ${palette.surface}`,
28206
- contain: "layout paint",
28207
- cursor: "crosshair",
28208
- display: !readOnly && resolvedSelectionOverlay ? "block" : "none",
28209
- height: 8 * zoomFactor,
28210
- left: resolvedSelectionOverlay ? resolvedSelectionOverlay.left + resolvedSelectionOverlay.width - 4 * zoomFactor : 0,
28211
- pointerEvents: "auto",
28212
- position: "absolute",
28213
- top: resolvedSelectionOverlay ? resolvedSelectionOverlay.top + resolvedSelectionOverlay.height - 4 * zoomFactor : 0,
28214
- transition: shouldAnimateCanvasSelection ? "left 120ms cubic-bezier(0.22, 1, 0.36, 1), top 120ms cubic-bezier(0.22, 1, 0.36, 1)" : "none",
28215
- willChange: shouldAnimateCanvasSelection ? "left, top" : void 0,
28216
- width: 8 * zoomFactor,
28217
- zIndex: 25
28218
- }
28074
+ ref: leftScrollHeaderCanvasRef,
28075
+ onPointerLeave: handleCanvasHeaderPointerLeave,
28076
+ onPointerMove: handleCanvasRowHeaderPointerMove,
28077
+ onPointerDown: handleCanvasRowHeaderPointerDown,
28078
+ style: canvasLeftScrollHeaderStyle
28219
28079
  }
28220
28080
  ),
28221
- resizeGuide ? /* @__PURE__ */ jsx3(
28081
+ /* @__PURE__ */ jsx3("canvas", { ref: cornerHeaderCanvasRef, style: canvasCornerHeaderStyle })
28082
+ ] }),
28083
+ editingCell && editingOverlayRect ? (() => {
28084
+ const editingCellStyle = getCellData(editingCell.row, editingCell.col).style;
28085
+ const editingBackground = typeof editingCellStyle.backgroundColor === "string" ? editingCellStyle.backgroundColor : resolveSheetSurface(activeSheet, palette);
28086
+ const editingColor = typeof editingCellStyle.color === "string" ? editingCellStyle.color : resolveReadableTextColor(null, editingBackground, palette);
28087
+ return /* @__PURE__ */ jsx3(
28222
28088
  "div",
28223
28089
  {
28224
- "aria-hidden": "true",
28225
28090
  style: {
28226
- backgroundColor: selectionStroke,
28227
- borderRadius: Math.max(999, 3 * zoomFactor),
28228
- boxShadow: `0 0 0 ${Math.max(1, zoomFactor)}px ${palette.surface}`,
28229
- height: resizeGuide.type === "column" ? Math.max(12, 14 * zoomFactor) : Math.max(3, 2 * zoomFactor),
28230
- left: resizeGuide.type === "column" ? resizeGuide.position - Math.max(2, 1.5 * zoomFactor) : Math.max(3, 4 * zoomFactor),
28231
- pointerEvents: "none",
28091
+ left: editingOverlayRect.left,
28232
28092
  position: "absolute",
28233
- top: resizeGuide.type === "column" ? Math.max(2 * zoomFactor, displayHeaderHeight - Math.max(14, 16 * zoomFactor)) : resizeGuide.position - Math.max(2, 1.5 * zoomFactor),
28234
- width: resizeGuide.type === "column" ? Math.max(3, 2 * zoomFactor) : Math.max(12, 14 * zoomFactor),
28235
- zIndex: 52
28236
- }
28237
- }
28238
- ) : null,
28239
- !renderTableHeaderMenu && openTableMenuState ? /* @__PURE__ */ jsx3(
28240
- "div",
28241
- {
28242
- ref: tableMenuRef,
28243
- style: {
28244
- color: palette.text,
28245
- left: Math.max(displayRowHeaderWidth + 4 * zoomFactor, openTableMenuState.left),
28246
- position: "absolute",
28247
- top: openTableMenuState.top,
28248
- zIndex: 50
28093
+ top: editingOverlayRect.top,
28094
+ width: editingOverlayRect.width,
28095
+ height: editingOverlayRect.height,
28096
+ zIndex: 28
28249
28097
  },
28250
28098
  children: /* @__PURE__ */ jsx3(
28251
- DefaultTableHeaderMenu,
28099
+ "input",
28252
28100
  {
28253
- cell: { col: openTableMenuState.column.index + openTableMenuState.table.start.col, row: openTableMenuState.table.start.row },
28254
- column: openTableMenuState.column,
28255
- direction: sortState && sortState.tableName === openTableMenuState.table.name && sortState.columnIndex === openTableMenuState.column.index ? sortState.direction : null,
28256
- sortAscending: () => {
28257
- sortTable(openTableMenuState.table.name, openTableMenuState.column.index, "ascending");
28258
- setOpenTableMenu(null);
28101
+ ref: editingInputRef,
28102
+ autoFocus: true,
28103
+ onBlur: commitEditing,
28104
+ onChange: (event) => setEditingValue(event.target.value),
28105
+ onKeyDown: (event) => {
28106
+ event.stopPropagation();
28107
+ if (event.key === "Enter") {
28108
+ event.preventDefault();
28109
+ commitEditing();
28110
+ return;
28111
+ }
28112
+ if (event.key === "Escape") {
28113
+ event.preventDefault();
28114
+ cancelEditing();
28115
+ }
28259
28116
  },
28260
- sortDescending: () => {
28261
- sortTable(openTableMenuState.table.name, openTableMenuState.column.index, "descending");
28262
- setOpenTableMenu(null);
28117
+ style: {
28118
+ backgroundColor: editingBackground,
28119
+ border: 0,
28120
+ boxShadow: `inset 0 0 0 ${selectionBorderWidth}px ${selectionStroke}`,
28121
+ boxSizing: "border-box",
28122
+ color: editingColor,
28123
+ display: "block",
28124
+ font: resolveCanvasFont(editingCellStyle, 12 * zoomFactor),
28125
+ height: "100%",
28126
+ margin: 0,
28127
+ minHeight: 0,
28128
+ outline: "none",
28129
+ overflow: "hidden",
28130
+ padding: scaleCssLengthExpression(DEFAULT_CELL_PADDING, zoomFactor),
28131
+ width: "100%"
28263
28132
  },
28264
- table: openTableMenuState.table,
28265
- triggerIcon: "\u25BE",
28266
- triggerProps: { type: "button" }
28133
+ value: editingValue
28267
28134
  }
28268
28135
  )
28269
28136
  }
28270
- ) : null
28271
- ]
28272
- }
28273
- )
28137
+ );
28138
+ })() : null,
28139
+ activeCellAdornment && activeCellAdornmentRect ? /* @__PURE__ */ jsx3(
28140
+ "div",
28141
+ {
28142
+ style: {
28143
+ height: activeCellAdornmentRect.height,
28144
+ left: activeCellAdornmentRect.left,
28145
+ pointerEvents: "none",
28146
+ position: "absolute",
28147
+ top: activeCellAdornmentRect.top,
28148
+ width: activeCellAdornmentRect.width,
28149
+ zIndex: 27
28150
+ },
28151
+ children: /* @__PURE__ */ jsx3("div", { style: { height: "100%", pointerEvents: "auto", position: "relative", width: "100%" }, children: activeCellAdornment })
28152
+ }
28153
+ ) : null
28154
+ ] }) : /* @__PURE__ */ jsxs3(
28155
+ "table",
28156
+ {
28157
+ ref: tableRef,
28158
+ style: {
28159
+ borderCollapse: "collapse",
28160
+ color: "#000000",
28161
+ flex: "0 0 auto",
28162
+ tableLayout: "fixed",
28163
+ width: totalWidth
28164
+ },
28165
+ children: [
28166
+ /* @__PURE__ */ jsxs3("colgroup", { children: [
28167
+ /* @__PURE__ */ jsx3("col", { style: { width: displayRowHeaderWidth } }),
28168
+ leadingColumnSpacerWidth > 0 ? /* @__PURE__ */ jsx3("col", { style: { width: leadingColumnSpacerWidth } }) : null,
28169
+ renderedCols.map((column) => /* @__PURE__ */ jsx3(
28170
+ "col",
28171
+ {
28172
+ ref: (element) => {
28173
+ if (element) {
28174
+ colElementRefs.current.set(column.actualCol, element);
28175
+ } else {
28176
+ colElementRefs.current.delete(column.actualCol);
28177
+ }
28178
+ },
28179
+ style: { width: column.size }
28180
+ },
28181
+ column.key
28182
+ )),
28183
+ trailingColumnSpacerWidth > 0 ? /* @__PURE__ */ jsx3("col", { style: { width: trailingColumnSpacerWidth } }) : null
28184
+ ] }),
28185
+ /* @__PURE__ */ jsx3("thead", { style: { position: "sticky", top: 0, zIndex: canvasHeaderOverlayZIndex }, children: /* @__PURE__ */ jsxs3("tr", { children: [
28186
+ /* @__PURE__ */ jsx3(
28187
+ "th",
28188
+ {
28189
+ style: {
28190
+ ...headerCellStyle,
28191
+ backgroundColor: palette.headerSurface,
28192
+ left: 0,
28193
+ width: displayRowHeaderWidth,
28194
+ zIndex: cornerHeaderOverlayZIndex
28195
+ }
28196
+ }
28197
+ ),
28198
+ leadingColumnSpacerWidth > 0 ? /* @__PURE__ */ jsx3("th", { "aria-hidden": "true", style: { ...headerCellStyle, padding: 0, width: leadingColumnSpacerWidth } }) : null,
28199
+ renderedCols.map((column) => /* @__PURE__ */ jsx3(
28200
+ "th",
28201
+ {
28202
+ "data-xlsx-col-header": column.actualCol,
28203
+ ref: (element) => setColHeaderRef(column.actualCol, element),
28204
+ onPointerDown: (event) => handleColumnPointerDown(event, column.actualCol),
28205
+ style: {
28206
+ ...headerCellStyle,
28207
+ left: stickyLeftByCol.get(column.actualCol),
28208
+ zIndex: stickyLeftByCol.has(column.actualCol) ? stickyHeaderOverlayZIndex : headerCellStyle.zIndex
28209
+ },
28210
+ children: /* @__PURE__ */ jsxs3("div", { style: { position: "relative" }, children: [
28211
+ /* @__PURE__ */ jsx3(
28212
+ "span",
28213
+ {
28214
+ style: {
28215
+ display: "inline-block",
28216
+ transform: headerLabelLiveScale !== 1 ? `scale(${1 / headerLabelLiveScale})` : void 0,
28217
+ transformOrigin: "center center"
28218
+ },
28219
+ children: columnLabel2(column.actualCol)
28220
+ }
28221
+ ),
28222
+ /* @__PURE__ */ jsx3(
28223
+ "div",
28224
+ {
28225
+ onPointerDown: (event) => {
28226
+ if (!canResizeHeaders) {
28227
+ return;
28228
+ }
28229
+ event.preventDefault();
28230
+ event.stopPropagation();
28231
+ startColumnResize(
28232
+ event.pointerId,
28233
+ column.actualCol,
28234
+ column.size,
28235
+ event.clientX
28236
+ );
28237
+ },
28238
+ style: columnResizeHandleStyle
28239
+ }
28240
+ )
28241
+ ] })
28242
+ },
28243
+ column.key
28244
+ )),
28245
+ trailingColumnSpacerWidth > 0 ? /* @__PURE__ */ jsx3("th", { "aria-hidden": "true", style: { ...headerCellStyle, padding: 0, width: trailingColumnSpacerWidth } }) : null
28246
+ ] }) }),
28247
+ /* @__PURE__ */ jsxs3("tbody", { children: [
28248
+ virtualRows.map((virtualRow, index) => {
28249
+ const actualRow = visibleRows[virtualRow.index];
28250
+ if (actualRow === void 0) {
28251
+ return null;
28252
+ }
28253
+ const previousEnd = index === 0 ? 0 : virtualRows[index - 1]?.end ?? 0;
28254
+ const gapHeight = Math.max(0, virtualRow.start - previousEnd);
28255
+ return /* @__PURE__ */ jsxs3(React4.Fragment, { children: [
28256
+ gapHeight > 0 ? /* @__PURE__ */ jsx3("tr", { "aria-hidden": "true", style: { height: gapHeight }, children: /* @__PURE__ */ jsx3("td", { colSpan: rowColSpan }) }) : null,
28257
+ /* @__PURE__ */ jsx3(
28258
+ MemoGridRow,
28259
+ {
28260
+ actualRow,
28261
+ editingCell,
28262
+ editingValue,
28263
+ frozenRowHeaderZIndex: frozenRowHeaderOverlayZIndex,
28264
+ getCellData,
28265
+ leadingSpacerWidth: leadingColumnSpacerWidth,
28266
+ onCellClick: handleCellClick,
28267
+ onCellDoubleClick: handleCellDoubleClick,
28268
+ onCellPointerDown: handleCellPointerDown,
28269
+ onEditingCancel: cancelEditing,
28270
+ onEditingCommit: commitEditing,
28271
+ onEditingValueChange: setEditingValue,
28272
+ headerLabelLiveScale,
28273
+ onRowHeaderRef: setRowHeaderRef,
28274
+ onRowPointerDown: handleRowPointerDown,
28275
+ onRowResizePointerDown: handleRowResizePointerDown,
28276
+ palette,
28277
+ readOnly,
28278
+ renderCellAdornment,
28279
+ rowHeight: virtualRow.size,
28280
+ rowHeaderZIndex: rowHeaderOverlayZIndex,
28281
+ rowHeaderWidth: displayRowHeaderWidth,
28282
+ stickyLeftByCol,
28283
+ stickyTop: stickyTopByRow.get(actualRow),
28284
+ trailingSpacerWidth: trailingColumnSpacerWidth,
28285
+ visibleCols: renderedCols,
28286
+ zoomFactor
28287
+ },
28288
+ virtualRow.key
28289
+ )
28290
+ ] }, `row-fragment-${virtualRow.key}`);
28291
+ }),
28292
+ virtualRows.length > 0 && totalHeight - (virtualRows[virtualRows.length - 1]?.end ?? totalHeight) > 0 ? /* @__PURE__ */ jsx3(
28293
+ "tr",
28294
+ {
28295
+ style: {
28296
+ height: totalHeight - (virtualRows[virtualRows.length - 1]?.end ?? totalHeight)
28297
+ },
28298
+ children: /* @__PURE__ */ jsx3("td", { colSpan: rowColSpan })
28299
+ }
28300
+ ) : null
28301
+ ] })
28302
+ ]
28303
+ }
28304
+ ),
28305
+ /* @__PURE__ */ jsx3(
28306
+ "div",
28307
+ {
28308
+ ref: selectionOverlayRef,
28309
+ style: {
28310
+ backgroundColor: selectionFill,
28311
+ boxSizing: "border-box",
28312
+ boxShadow: `inset 0 0 0 ${selectionBorderWidth}px ${selectionStroke}`,
28313
+ contain: "layout paint",
28314
+ height: resolvedSelectionOverlay?.height ?? 0,
28315
+ left: resolvedSelectionOverlay?.left ?? 0,
28316
+ opacity: resolvedSelectionOverlay ? 1 : 0,
28317
+ pointerEvents: "none",
28318
+ position: "absolute",
28319
+ top: resolvedSelectionOverlay?.top ?? 0,
28320
+ transition: canvasSelectionTransition,
28321
+ visibility: resolvedSelectionOverlay ? "visible" : "hidden",
28322
+ willChange: shouldAnimateCanvasSelection ? "left, top, width, height" : void 0,
28323
+ width: resolvedSelectionOverlay?.width ?? 0,
28324
+ zIndex: 24
28325
+ }
28326
+ }
28327
+ ),
28328
+ /* @__PURE__ */ jsx3(
28329
+ "div",
28330
+ {
28331
+ ref: activeValidationOverlayRef,
28332
+ "aria-hidden": "true",
28333
+ style: {
28334
+ alignItems: "center",
28335
+ color: palette.mutedText,
28336
+ display: "inline-flex",
28337
+ fontSize: 10 * zoomFactor,
28338
+ fontWeight: 700,
28339
+ height: 16 * zoomFactor,
28340
+ justifyContent: "center",
28341
+ opacity: 0,
28342
+ pointerEvents: "none",
28343
+ position: "absolute",
28344
+ transform: "translateY(-50%)",
28345
+ visibility: "hidden",
28346
+ width: 12 * zoomFactor,
28347
+ zIndex: 26
28348
+ },
28349
+ children: "\u25BE"
28350
+ }
28351
+ ),
28352
+ /* @__PURE__ */ jsx3(
28353
+ "div",
28354
+ {
28355
+ ref: fillHandleRef,
28356
+ onPointerDown: (event) => {
28357
+ if (readOnly || event.button !== 0 || !normalizedSelection || !resolvedSelectionOverlay) {
28358
+ return;
28359
+ }
28360
+ event.preventDefault();
28361
+ event.stopPropagation();
28362
+ startFillDrag(event.pointerId, normalizedSelection);
28363
+ },
28364
+ style: {
28365
+ backgroundColor: selectionStroke,
28366
+ border: `${Math.max(1, zoomFactor)}px solid ${palette.surface}`,
28367
+ contain: "layout paint",
28368
+ cursor: "crosshair",
28369
+ display: !readOnly && resolvedSelectionOverlay ? "block" : "none",
28370
+ height: 8 * zoomFactor,
28371
+ left: resolvedSelectionOverlay ? resolvedSelectionOverlay.left + resolvedSelectionOverlay.width - 4 * zoomFactor : 0,
28372
+ pointerEvents: "auto",
28373
+ position: "absolute",
28374
+ top: resolvedSelectionOverlay ? resolvedSelectionOverlay.top + resolvedSelectionOverlay.height - 4 * zoomFactor : 0,
28375
+ transition: shouldAnimateCanvasSelection ? "left 120ms cubic-bezier(0.22, 1, 0.36, 1), top 120ms cubic-bezier(0.22, 1, 0.36, 1)" : "none",
28376
+ willChange: shouldAnimateCanvasSelection ? "left, top" : void 0,
28377
+ width: 8 * zoomFactor,
28378
+ zIndex: 25
28379
+ }
28380
+ }
28381
+ ),
28382
+ resizeGuide ? /* @__PURE__ */ jsx3(
28383
+ "div",
28384
+ {
28385
+ "aria-hidden": "true",
28386
+ style: {
28387
+ backgroundColor: selectionStroke,
28388
+ borderRadius: Math.max(999, 3 * zoomFactor),
28389
+ boxShadow: `0 0 0 ${Math.max(1, zoomFactor)}px ${palette.surface}`,
28390
+ height: resizeGuide.type === "column" ? Math.max(12, 14 * zoomFactor) : Math.max(3, 2 * zoomFactor),
28391
+ left: resizeGuide.type === "column" ? resizeGuide.position - Math.max(2, 1.5 * zoomFactor) : Math.max(3, 4 * zoomFactor),
28392
+ pointerEvents: "none",
28393
+ position: "absolute",
28394
+ top: resizeGuide.type === "column" ? Math.max(2 * zoomFactor, displayHeaderHeight - Math.max(14, 16 * zoomFactor)) : resizeGuide.position - Math.max(2, 1.5 * zoomFactor),
28395
+ width: resizeGuide.type === "column" ? Math.max(3, 2 * zoomFactor) : Math.max(12, 14 * zoomFactor),
28396
+ zIndex: 52
28397
+ }
28398
+ }
28399
+ ) : null,
28400
+ !renderTableHeaderMenu && openTableMenuState ? /* @__PURE__ */ jsx3(
28401
+ "div",
28402
+ {
28403
+ ref: tableMenuRef,
28404
+ style: {
28405
+ color: palette.text,
28406
+ left: Math.max(displayRowHeaderWidth + 4 * zoomFactor, openTableMenuState.left),
28407
+ position: "absolute",
28408
+ top: openTableMenuState.top,
28409
+ zIndex: 50
28410
+ },
28411
+ children: /* @__PURE__ */ jsx3(
28412
+ DefaultTableHeaderMenu,
28413
+ {
28414
+ cell: { col: openTableMenuState.column.index + openTableMenuState.table.start.col, row: openTableMenuState.table.start.row },
28415
+ column: openTableMenuState.column,
28416
+ direction: sortState && sortState.tableName === openTableMenuState.table.name && sortState.columnIndex === openTableMenuState.column.index ? sortState.direction : null,
28417
+ sortAscending: () => {
28418
+ sortTable(openTableMenuState.table.name, openTableMenuState.column.index, "ascending");
28419
+ setOpenTableMenu(null);
28420
+ },
28421
+ sortDescending: () => {
28422
+ sortTable(openTableMenuState.table.name, openTableMenuState.column.index, "descending");
28423
+ setOpenTableMenu(null);
28424
+ },
28425
+ table: openTableMenuState.table,
28426
+ triggerIcon: "\u25BE",
28427
+ triggerProps: { type: "button" }
28428
+ }
28429
+ )
28430
+ }
28431
+ ) : null
28432
+ ]
28274
28433
  }
28275
28434
  )
28276
- },
28277
- activeTabIndex
28278
- ) });
28435
+ }
28436
+ );
28437
+ return /* @__PURE__ */ jsx3("div", { style: { backgroundColor: palette.canvas, display: "flex", flex: 1, minHeight: 0, minWidth: 0 }, children: renderScroller ? renderScroller({ children: scrollerContent, viewportProps: scrollerViewportProps }) : /* @__PURE__ */ jsx3("div", { ...scrollerViewportProps, children: scrollerContent }) });
28279
28438
  }
28280
28439
  function XlsxViewerInner({
28281
28440
  allowResizeInReadOnly = false,
@@ -28294,6 +28453,7 @@ function XlsxViewerInner({
28294
28453
  renderChartLoading,
28295
28454
  renderImage,
28296
28455
  renderImageSelection,
28456
+ renderScroller,
28297
28457
  renderTableHeaderMenu,
28298
28458
  rounded = true,
28299
28459
  selectionColor,
@@ -28355,6 +28515,7 @@ function XlsxViewerInner({
28355
28515
  renderChartLoading,
28356
28516
  renderImage,
28357
28517
  renderImageSelection,
28518
+ renderScroller,
28358
28519
  renderTableHeaderMenu,
28359
28520
  selectionColor,
28360
28521
  selectionFillColor,