@extend-ai/react-xlsx 0.16.6 → 0.17.0
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/README.md +56 -0
- package/dist/index.cjs +345 -78
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -1
- package/dist/index.d.ts +33 -1
- package/dist/index.js +344 -78
- package/dist/index.js.map +1 -1
- package/dist/xlsx-worker.js +5 -1
- package/dist/xlsx-worker.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3739,7 +3739,8 @@ function resolveWorksheetMergeMetadata(worksheet) {
|
|
|
3739
3739
|
hasHorizontalMerges: false,
|
|
3740
3740
|
hasVerticalMerges: false,
|
|
3741
3741
|
maxHorizontalMergeEndCol: -1,
|
|
3742
|
-
maxVerticalMergeEndRow: -1
|
|
3742
|
+
maxVerticalMergeEndRow: -1,
|
|
3743
|
+
mergedRanges: []
|
|
3743
3744
|
};
|
|
3744
3745
|
const mergedRegions = Array.isArray(worksheet.mergedRegions) ? worksheet.mergedRegions : [];
|
|
3745
3746
|
for (const rawRegion of mergedRegions) {
|
|
@@ -3770,6 +3771,7 @@ function resolveWorksheetMergeMetadata(worksheet) {
|
|
|
3770
3771
|
if (!range) {
|
|
3771
3772
|
continue;
|
|
3772
3773
|
}
|
|
3774
|
+
mergeMetadata.mergedRanges.push(range);
|
|
3773
3775
|
if (range.end.col > range.start.col) {
|
|
3774
3776
|
mergeMetadata.hasHorizontalMerges = true;
|
|
3775
3777
|
mergeMetadata.maxHorizontalMergeEndCol = Math.max(mergeMetadata.maxHorizontalMergeEndCol, range.end.col);
|
|
@@ -6673,6 +6675,102 @@ function tryRecalculate(workbook) {
|
|
|
6673
6675
|
}
|
|
6674
6676
|
}
|
|
6675
6677
|
|
|
6678
|
+
// src/range-reference.ts
|
|
6679
|
+
var XLSX_MAX_ROWS = 1048576;
|
|
6680
|
+
var XLSX_MAX_COLUMNS = 16384;
|
|
6681
|
+
function parseColumn(value) {
|
|
6682
|
+
let column = 0;
|
|
6683
|
+
for (const character of value.toUpperCase()) {
|
|
6684
|
+
column = column * 26 + character.charCodeAt(0) - 64;
|
|
6685
|
+
}
|
|
6686
|
+
return column > 0 && column <= XLSX_MAX_COLUMNS ? column - 1 : null;
|
|
6687
|
+
}
|
|
6688
|
+
function parseRow(value) {
|
|
6689
|
+
const row = Number(value);
|
|
6690
|
+
return row > 0 && row <= XLSX_MAX_ROWS ? row - 1 : null;
|
|
6691
|
+
}
|
|
6692
|
+
function parseCell(value) {
|
|
6693
|
+
const match = /^\$?([a-z]{1,3})\$?([1-9]\d{0,6})$/i.exec(value);
|
|
6694
|
+
if (!match) {
|
|
6695
|
+
return null;
|
|
6696
|
+
}
|
|
6697
|
+
const col = parseColumn(match[1]);
|
|
6698
|
+
const row = parseRow(match[2]);
|
|
6699
|
+
return col === null || row === null ? null : { col, row };
|
|
6700
|
+
}
|
|
6701
|
+
function parseXlsxRange(reference) {
|
|
6702
|
+
if (typeof reference !== "string") {
|
|
6703
|
+
return null;
|
|
6704
|
+
}
|
|
6705
|
+
let address = reference.trim().replace(/^=\s*/, "");
|
|
6706
|
+
let sheetName = null;
|
|
6707
|
+
if (address.startsWith("'")) {
|
|
6708
|
+
const match = /^'((?:[^']|'')+)'!(.+)$/.exec(address);
|
|
6709
|
+
if (!match) {
|
|
6710
|
+
return null;
|
|
6711
|
+
}
|
|
6712
|
+
sheetName = match[1].replace(/''/g, "'");
|
|
6713
|
+
address = match[2];
|
|
6714
|
+
} else if (address.includes("!")) {
|
|
6715
|
+
const match = /^([^\s'!\[\]:*?/\\+,;(){}=<>"&^%\-]+)!(.+)$/.exec(address);
|
|
6716
|
+
if (!match) {
|
|
6717
|
+
return null;
|
|
6718
|
+
}
|
|
6719
|
+
sheetName = match[1];
|
|
6720
|
+
address = match[2];
|
|
6721
|
+
}
|
|
6722
|
+
if (sheetName !== null && (sheetName.length > 31 || /[\[\]:*?/\\\u0000-\u001f]/.test(sheetName) || sheetName.startsWith("'") || sheetName.endsWith("'"))) {
|
|
6723
|
+
return null;
|
|
6724
|
+
}
|
|
6725
|
+
const parts = address.split(":");
|
|
6726
|
+
if (parts.length > 2) {
|
|
6727
|
+
return null;
|
|
6728
|
+
}
|
|
6729
|
+
const start = parseCell(parts[0]);
|
|
6730
|
+
const end = parseCell(parts[1] ?? parts[0]);
|
|
6731
|
+
if (start && end) {
|
|
6732
|
+
return {
|
|
6733
|
+
kind: "cells",
|
|
6734
|
+
range: {
|
|
6735
|
+
start: { col: Math.min(start.col, end.col), row: Math.min(start.row, end.row) },
|
|
6736
|
+
end: { col: Math.max(start.col, end.col), row: Math.max(start.row, end.row) }
|
|
6737
|
+
},
|
|
6738
|
+
sheetName
|
|
6739
|
+
};
|
|
6740
|
+
}
|
|
6741
|
+
const columns = /^\$?([a-z]{1,3}):\$?([a-z]{1,3})$/i.exec(address);
|
|
6742
|
+
if (columns) {
|
|
6743
|
+
const first = parseColumn(columns[1]);
|
|
6744
|
+
const last = parseColumn(columns[2]);
|
|
6745
|
+
if (first !== null && last !== null) {
|
|
6746
|
+
return {
|
|
6747
|
+
kind: "columns",
|
|
6748
|
+
range: {
|
|
6749
|
+
start: { col: Math.min(first, last), row: 0 },
|
|
6750
|
+
end: { col: Math.max(first, last), row: XLSX_MAX_ROWS - 1 }
|
|
6751
|
+
},
|
|
6752
|
+
sheetName
|
|
6753
|
+
};
|
|
6754
|
+
}
|
|
6755
|
+
}
|
|
6756
|
+
const rows = /^\$?([1-9]\d{0,6}):\$?([1-9]\d{0,6})$/.exec(address);
|
|
6757
|
+
if (rows) {
|
|
6758
|
+
const first = parseRow(rows[1]);
|
|
6759
|
+
const last = parseRow(rows[2]);
|
|
6760
|
+
if (first !== null && last !== null) {
|
|
6761
|
+
return {
|
|
6762
|
+
kind: "rows",
|
|
6763
|
+
range: {
|
|
6764
|
+
start: { col: 0, row: Math.min(first, last) },
|
|
6765
|
+
end: { col: XLSX_MAX_COLUMNS - 1, row: Math.max(first, last) }
|
|
6766
|
+
},
|
|
6767
|
+
sheetName
|
|
6768
|
+
};
|
|
6769
|
+
}
|
|
6770
|
+
}
|
|
6771
|
+
return null;
|
|
6772
|
+
}
|
|
6773
|
+
|
|
6676
6774
|
// src/wasm.ts
|
|
6677
6775
|
var wasmModulePromise = null;
|
|
6678
6776
|
var hasConfiguredWasmSource = false;
|
|
@@ -7294,6 +7392,7 @@ function buildSheetList(workbook, sheetStatesByWorkbookSheetIndex, themePalette,
|
|
|
7294
7392
|
hasVerticalMerges: mergeMetadata.hasVerticalMerges,
|
|
7295
7393
|
maxHorizontalMergeEndCol: mergeMetadata.maxHorizontalMergeEndCol,
|
|
7296
7394
|
maxVerticalMergeEndRow: mergeMetadata.maxVerticalMergeEndRow,
|
|
7395
|
+
mergedRanges: mergeMetadata.mergedRanges,
|
|
7297
7396
|
hiddenCols: [],
|
|
7298
7397
|
hiddenRows: [],
|
|
7299
7398
|
minUsedCol: -1,
|
|
@@ -7381,6 +7480,7 @@ function buildSheetList(workbook, sheetStatesByWorkbookSheetIndex, themePalette,
|
|
|
7381
7480
|
hasVerticalMerges: mergeMetadata.hasVerticalMerges,
|
|
7382
7481
|
maxHorizontalMergeEndCol: mergeMetadata.maxHorizontalMergeEndCol,
|
|
7383
7482
|
maxVerticalMergeEndRow: mergeMetadata.maxVerticalMergeEndRow,
|
|
7483
|
+
mergedRanges: mergeMetadata.mergedRanges,
|
|
7384
7484
|
hiddenCols: resolveWorksheetHiddenCols(worksheet, maxCol),
|
|
7385
7485
|
hiddenRows: resolveWorksheetHiddenRows(worksheet, maxRow),
|
|
7386
7486
|
minUsedCol: minCol,
|
|
@@ -8382,6 +8482,7 @@ function useXlsxViewerController(options) {
|
|
|
8382
8482
|
const [zoomScaleOverridesByTabId, setZoomScaleOverridesByTabId] = React.useState({});
|
|
8383
8483
|
const [activeCell, setActiveCell] = React.useState(null);
|
|
8384
8484
|
const [selection, setSelection] = React.useState(null);
|
|
8485
|
+
const [highlightedRanges, setHighlightedRanges] = React.useState([]);
|
|
8385
8486
|
const [selectedChartId, setSelectedChartId] = React.useState(null);
|
|
8386
8487
|
const [selectedChartElement, setSelectedChartElement] = React.useState(null);
|
|
8387
8488
|
const [selectedImageId, setSelectedImageId] = React.useState(null);
|
|
@@ -8667,6 +8768,7 @@ function useXlsxViewerController(options) {
|
|
|
8667
8768
|
setActiveTabIndexState(0);
|
|
8668
8769
|
setActiveCell(null);
|
|
8669
8770
|
setSelection(null);
|
|
8771
|
+
setHighlightedRanges([]);
|
|
8670
8772
|
setSelectedChartId(null);
|
|
8671
8773
|
setSelectedChartElement(null);
|
|
8672
8774
|
setSelectedImageId(null);
|
|
@@ -8696,6 +8798,7 @@ function useXlsxViewerController(options) {
|
|
|
8696
8798
|
setActiveTabIndexState(0);
|
|
8697
8799
|
setActiveCell(null);
|
|
8698
8800
|
setSelection(null);
|
|
8801
|
+
setHighlightedRanges([]);
|
|
8699
8802
|
setSelectedChartId(null);
|
|
8700
8803
|
setSelectedChartElement(null);
|
|
8701
8804
|
setSelectedImageId(null);
|
|
@@ -8887,6 +8990,41 @@ function useXlsxViewerController(options) {
|
|
|
8887
8990
|
return index;
|
|
8888
8991
|
});
|
|
8889
8992
|
}, [tabs]);
|
|
8993
|
+
const highlightRanges = React.useCallback((references, options2 = {}) => {
|
|
8994
|
+
const inputs = typeof references === "string" ? [references] : references;
|
|
8995
|
+
if (!Array.isArray(inputs) || isLoading || error) {
|
|
8996
|
+
return false;
|
|
8997
|
+
}
|
|
8998
|
+
const nextHighlights = [];
|
|
8999
|
+
let firstSheetIndex = activeSheetIndex;
|
|
9000
|
+
for (const reference of inputs) {
|
|
9001
|
+
const parsed = parseXlsxRange(reference);
|
|
9002
|
+
if (!parsed) {
|
|
9003
|
+
return false;
|
|
9004
|
+
}
|
|
9005
|
+
const requestedSheetName = parsed.sheetName?.toLowerCase();
|
|
9006
|
+
const sheetIndex = requestedSheetName === void 0 ? options2.sheetIndex ?? activeSheetIndex : sheets.findIndex((sheet2) => sheet2.name.toLowerCase() === requestedSheetName);
|
|
9007
|
+
const sheet = Number.isInteger(sheetIndex) ? sheets[sheetIndex] : void 0;
|
|
9008
|
+
if (!sheet) {
|
|
9009
|
+
return false;
|
|
9010
|
+
}
|
|
9011
|
+
if (nextHighlights.length === 0) {
|
|
9012
|
+
firstSheetIndex = sheetIndex;
|
|
9013
|
+
}
|
|
9014
|
+
nextHighlights.push({
|
|
9015
|
+
...parsed,
|
|
9016
|
+
autoScroll: nextHighlights.length === 0 && (options2.autoScroll ?? true),
|
|
9017
|
+
sheetName: sheet.name,
|
|
9018
|
+
workbookSheetIndex: sheet.workbookSheetIndex
|
|
9019
|
+
});
|
|
9020
|
+
}
|
|
9021
|
+
setHighlightedRanges(nextHighlights);
|
|
9022
|
+
if (nextHighlights[0]?.autoScroll) {
|
|
9023
|
+
setActiveSheetIndex(firstSheetIndex);
|
|
9024
|
+
}
|
|
9025
|
+
return true;
|
|
9026
|
+
}, [activeSheetIndex, error, isLoading, setActiveSheetIndex, sheets]);
|
|
9027
|
+
const clearHighlightedRanges = React.useCallback(() => setHighlightedRanges([]), []);
|
|
8890
9028
|
const setZoomScale = React.useCallback((nextZoomScale) => {
|
|
8891
9029
|
const normalizedZoomScale = clampZoomScale(nextZoomScale);
|
|
8892
9030
|
setZoomScaleOverridesByTabId((current) => {
|
|
@@ -10945,6 +11083,9 @@ function useXlsxViewerController(options) {
|
|
|
10945
11083
|
clearSelectedCells,
|
|
10946
11084
|
clearSelectedImage,
|
|
10947
11085
|
clearSelection,
|
|
11086
|
+
clearHighlightedRanges,
|
|
11087
|
+
highlightRanges,
|
|
11088
|
+
highlightedRanges,
|
|
10948
11089
|
continueDeferredLoad,
|
|
10949
11090
|
copySelectionToClipboard,
|
|
10950
11091
|
defaultZoomScale,
|
|
@@ -11065,6 +11206,9 @@ function useXlsxViewerController(options) {
|
|
|
11065
11206
|
clearSelectedCells,
|
|
11066
11207
|
clearSelectedImage,
|
|
11067
11208
|
continueDeferredLoad,
|
|
11209
|
+
clearHighlightedRanges,
|
|
11210
|
+
highlightRanges,
|
|
11211
|
+
highlightedRanges,
|
|
11068
11212
|
copySelectionToClipboard,
|
|
11069
11213
|
defaultZoomScale,
|
|
11070
11214
|
deferredLoadFileSize,
|
|
@@ -11750,6 +11894,62 @@ function growScrollDisplayLimit(current, growth, maximum, readOnly) {
|
|
|
11750
11894
|
return readOnly ? Math.max(current, Math.min(maximum, nextLimit)) : nextLimit;
|
|
11751
11895
|
}
|
|
11752
11896
|
|
|
11897
|
+
// src/range-highlight.ts
|
|
11898
|
+
function expandHighlightedRange(range, mergedRanges) {
|
|
11899
|
+
const expanded = { start: { ...range.start }, end: { ...range.end } };
|
|
11900
|
+
let changed;
|
|
11901
|
+
do {
|
|
11902
|
+
changed = false;
|
|
11903
|
+
for (const merged of mergedRanges) {
|
|
11904
|
+
if (merged.end.row < expanded.start.row || merged.start.row > expanded.end.row || merged.end.col < expanded.start.col || merged.start.col > expanded.end.col) {
|
|
11905
|
+
continue;
|
|
11906
|
+
}
|
|
11907
|
+
const startRow = Math.min(expanded.start.row, merged.start.row);
|
|
11908
|
+
const startCol = Math.min(expanded.start.col, merged.start.col);
|
|
11909
|
+
const endRow = Math.max(expanded.end.row, merged.end.row);
|
|
11910
|
+
const endCol = Math.max(expanded.end.col, merged.end.col);
|
|
11911
|
+
if (startRow !== expanded.start.row || startCol !== expanded.start.col || endRow !== expanded.end.row || endCol !== expanded.end.col) {
|
|
11912
|
+
expanded.start = { row: startRow, col: startCol };
|
|
11913
|
+
expanded.end = { row: endRow, col: endCol };
|
|
11914
|
+
changed = true;
|
|
11915
|
+
}
|
|
11916
|
+
}
|
|
11917
|
+
} while (changed);
|
|
11918
|
+
return expanded;
|
|
11919
|
+
}
|
|
11920
|
+
function lowerBound(indices, value) {
|
|
11921
|
+
let low = 0;
|
|
11922
|
+
let high = indices.length;
|
|
11923
|
+
while (low < high) {
|
|
11924
|
+
const middle = low + high >>> 1;
|
|
11925
|
+
if (indices[middle] < value) {
|
|
11926
|
+
low = middle + 1;
|
|
11927
|
+
} else {
|
|
11928
|
+
high = middle;
|
|
11929
|
+
}
|
|
11930
|
+
}
|
|
11931
|
+
return low;
|
|
11932
|
+
}
|
|
11933
|
+
function getHighlightAxisExtent(indices, prefixSums, start, end) {
|
|
11934
|
+
const first = lowerBound(indices, start);
|
|
11935
|
+
const afterLast = lowerBound(indices, end + 1);
|
|
11936
|
+
if (first >= afterLast) {
|
|
11937
|
+
return null;
|
|
11938
|
+
}
|
|
11939
|
+
return { start: prefixSums[first] ?? 0, end: prefixSums[afterLast] ?? 0 };
|
|
11940
|
+
}
|
|
11941
|
+
function getHighlightScrollOffset(start, end, frozenExtent, viewportExtent, currentOffset) {
|
|
11942
|
+
if (end <= frozenExtent || viewportExtent <= frozenExtent) {
|
|
11943
|
+
return currentOffset;
|
|
11944
|
+
}
|
|
11945
|
+
const scrollableStart = Math.max(start, frozenExtent);
|
|
11946
|
+
const availableExtent = viewportExtent - frozenExtent;
|
|
11947
|
+
if (scrollableStart < currentOffset + frozenExtent || end - scrollableStart > availableExtent) {
|
|
11948
|
+
return Math.max(0, scrollableStart - frozenExtent);
|
|
11949
|
+
}
|
|
11950
|
+
return end > currentOffset + viewportExtent ? end - viewportExtent : currentOffset;
|
|
11951
|
+
}
|
|
11952
|
+
|
|
11753
11953
|
// src/chart-renderer.tsx
|
|
11754
11954
|
import { hierarchy as d3Hierarchy, partition as d3Partition, treemap as d3Treemap, treemapBinary, treemapDice } from "d3-hierarchy";
|
|
11755
11955
|
import { geoIdentity, geoMercator, geoNaturalEarth1, geoPath } from "d3-geo";
|
|
@@ -18573,6 +18773,17 @@ function resolveViewerPalette(isDark = false, headerBackgroundColor, headerTextC
|
|
|
18573
18773
|
|
|
18574
18774
|
// src/XlsxViewer.tsx
|
|
18575
18775
|
import { Fragment as Fragment4, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
18776
|
+
var RANGE_HIGHLIGHT_STYLES = `
|
|
18777
|
+
:where(.react-xlsx-range-highlight) {
|
|
18778
|
+
background: var(--xlsx-highlight-fill, rgb(59 130 246 / 8%));
|
|
18779
|
+
border: var(--xlsx-highlight-border, var(--xlsx-highlight-default-border-width, 1px) solid #3b82f6);
|
|
18780
|
+
border-radius: var(--xlsx-highlight-radius, 2px);
|
|
18781
|
+
}
|
|
18782
|
+
:where(.react-xlsx-range-highlight[data-dark="true"]) {
|
|
18783
|
+
background: var(--xlsx-highlight-fill, rgb(147 197 253 / 12%));
|
|
18784
|
+
border: var(--xlsx-highlight-border, var(--xlsx-highlight-default-border-width, 1px) solid #93c5fd);
|
|
18785
|
+
}
|
|
18786
|
+
`;
|
|
18576
18787
|
var DEFAULT_ROW_HEIGHT2 = 24;
|
|
18577
18788
|
var DEFAULT_COL_WIDTH2 = 80;
|
|
18578
18789
|
var HEADER_HEIGHT = 24;
|
|
@@ -24064,6 +24275,7 @@ function XlsxGrid({
|
|
|
24064
24275
|
errorState,
|
|
24065
24276
|
fileTooLargeState,
|
|
24066
24277
|
getCellStyle,
|
|
24278
|
+
highlightClassName,
|
|
24067
24279
|
loadingComponent,
|
|
24068
24280
|
loadingState,
|
|
24069
24281
|
onFormControlAction,
|
|
@@ -24108,6 +24320,7 @@ function XlsxGrid({
|
|
|
24108
24320
|
getClipboardData,
|
|
24109
24321
|
getCellDisplayValue: getControllerCellDisplayValue,
|
|
24110
24322
|
getFormControlItems,
|
|
24323
|
+
highlightedRanges,
|
|
24111
24324
|
images,
|
|
24112
24325
|
shapes,
|
|
24113
24326
|
isLoadDeferred,
|
|
@@ -24154,6 +24367,7 @@ function XlsxGrid({
|
|
|
24154
24367
|
), [formControls, getFormControlItems]);
|
|
24155
24368
|
const canResizeHeaders = !readOnly || allowResizeInReadOnly;
|
|
24156
24369
|
const scrollRef = React4.useRef(null);
|
|
24370
|
+
const scrolledHighlightRef = React4.useRef(null);
|
|
24157
24371
|
const wrapperRef = React4.useRef(null);
|
|
24158
24372
|
const tableRef = React4.useRef(null);
|
|
24159
24373
|
const gridKeyboardActiveRef = React4.useRef(false);
|
|
@@ -24342,6 +24556,10 @@ function XlsxGrid({
|
|
|
24342
24556
|
const resolveMergeAnchorCell = React4.useCallback((cell) => {
|
|
24343
24557
|
return mergedSecondaryAnchorMap.get(`${cell.row}:${cell.col}`) ?? cell;
|
|
24344
24558
|
}, [mergedSecondaryAnchorMap]);
|
|
24559
|
+
const highlightedCellRanges = React4.useMemo(
|
|
24560
|
+
() => highlightedRanges.flatMap((highlight, index) => activeSheet?.workbookSheetIndex === highlight.workbookSheetIndex ? [{ highlight, index, range: expandHighlightedRange(highlight.range, activeSheet?.mergedRanges ?? mergedRegions) }] : []),
|
|
24561
|
+
[activeSheet?.mergedRanges, activeSheet?.workbookSheetIndex, highlightedRanges, mergedRegions]
|
|
24562
|
+
);
|
|
24345
24563
|
const normalizedSelection = React4.useMemo(() => selection ? normalizeRange2(selection) : null, [selection]);
|
|
24346
24564
|
const zoomFactor = React4.useMemo(() => Math.max(0.1, zoomScale / 100), [zoomScale]);
|
|
24347
24565
|
const previousZoomFactorRef = React4.useRef(zoomFactor);
|
|
@@ -24381,7 +24599,7 @@ function XlsxGrid({
|
|
|
24381
24599
|
frozenPaneRight: liveFrozenPaneRight
|
|
24382
24600
|
} = canvasLayoutMetricsRef.current;
|
|
24383
24601
|
const currentLiveGestureZoom = liveGestureZoomRef.current;
|
|
24384
|
-
const isLiveZooming2 = currentLiveGestureZoom !== null && zoomScale === currentLiveGestureZoom.baseZoomScale;
|
|
24602
|
+
const isLiveZooming2 = experimentalCanvas && currentLiveGestureZoom !== null && zoomScale === currentLiveGestureZoom.baseZoomScale;
|
|
24385
24603
|
const liveZoomScale2 = isLiveZooming2 ? Math.max(0.1, currentLiveGestureZoom.targetZoomScale / currentLiveGestureZoom.baseZoomScale) : 1;
|
|
24386
24604
|
const scrollDeltaX = paintedViewport.left - nextLiveViewport.left;
|
|
24387
24605
|
const scrollDeltaY = paintedViewport.top - nextLiveViewport.top;
|
|
@@ -25352,7 +25570,7 @@ function XlsxGrid({
|
|
|
25352
25570
|
}, [shouldUseDomVirtualizer, syncDrawingViewport, zoomFactor]);
|
|
25353
25571
|
React4.useLayoutEffect(() => {
|
|
25354
25572
|
syncDrawingViewport(scrollRef.current, { immediate: true });
|
|
25355
|
-
}, [activeSheet, activeTabIndex, displayColLimit, displayRowLimit, syncDrawingViewport, zoomFactor]);
|
|
25573
|
+
}, [activeSheet, activeTabIndex, displayColLimit, displayRowLimit, highlightedCellRanges, syncDrawingViewport, zoomFactor]);
|
|
25356
25574
|
React4.useLayoutEffect(() => {
|
|
25357
25575
|
const scroller = scrollRef.current;
|
|
25358
25576
|
if (!scroller) {
|
|
@@ -26496,11 +26714,11 @@ function XlsxGrid({
|
|
|
26496
26714
|
if (textWidth > availableTextWidth) {
|
|
26497
26715
|
const baseFontSizePx = resolveCanvasFontSizePx(nextData.style, 12 * zoomFactor);
|
|
26498
26716
|
const minimumFontSizePx = Math.max(6 * zoomFactor, baseFontSizePx * 0.4);
|
|
26499
|
-
let
|
|
26717
|
+
let lowerBound2 = minimumFontSizePx;
|
|
26500
26718
|
let upperBound = baseFontSizePx;
|
|
26501
26719
|
let bestFontSizePx = minimumFontSizePx;
|
|
26502
|
-
while (upperBound -
|
|
26503
|
-
const candidateFontSizePx = (
|
|
26720
|
+
while (upperBound - lowerBound2 > 0.25) {
|
|
26721
|
+
const candidateFontSizePx = (lowerBound2 + upperBound) / 2;
|
|
26504
26722
|
const candidateStyle = {
|
|
26505
26723
|
...nextData.style,
|
|
26506
26724
|
font: void 0,
|
|
@@ -26509,7 +26727,7 @@ function XlsxGrid({
|
|
|
26509
26727
|
const candidateWidth = measureTextWidth(nextData.value, candidateStyle);
|
|
26510
26728
|
if (candidateWidth <= availableTextWidth) {
|
|
26511
26729
|
bestFontSizePx = candidateFontSizePx;
|
|
26512
|
-
|
|
26730
|
+
lowerBound2 = candidateFontSizePx;
|
|
26513
26731
|
} else {
|
|
26514
26732
|
upperBound = candidateFontSizePx;
|
|
26515
26733
|
}
|
|
@@ -26560,6 +26778,51 @@ function XlsxGrid({
|
|
|
26560
26778
|
};
|
|
26561
26779
|
}, [colIndexByActual, colPrefixSums, displayHeaderHeight, displayRowHeaderWidth, displayedSelection, rowIndexByActual, rowPrefixSums]);
|
|
26562
26780
|
const resolvedSelectionOverlay = selectionOverlay;
|
|
26781
|
+
const rangeHighlightRects = React4.useMemo(() => highlightedCellRanges.map(({ highlight, index, range }) => {
|
|
26782
|
+
const rows = getHighlightAxisExtent(visibleRows, rowPrefixSums, range.start.row, range.end.row);
|
|
26783
|
+
const cols = getHighlightAxisExtent(visibleCols, colPrefixSums, range.start.col, range.end.col);
|
|
26784
|
+
return {
|
|
26785
|
+
highlight,
|
|
26786
|
+
index,
|
|
26787
|
+
range,
|
|
26788
|
+
rect: rows && cols ? {
|
|
26789
|
+
height: rows.end - rows.start,
|
|
26790
|
+
left: displayRowHeaderWidth + cols.start,
|
|
26791
|
+
top: displayHeaderHeight + rows.start,
|
|
26792
|
+
width: cols.end - cols.start
|
|
26793
|
+
} : null
|
|
26794
|
+
};
|
|
26795
|
+
}), [colPrefixSums, displayHeaderHeight, displayRowHeaderWidth, highlightedCellRanges, rowPrefixSums, visibleCols, visibleRows]);
|
|
26796
|
+
React4.useEffect(() => {
|
|
26797
|
+
let requiredRows = 0;
|
|
26798
|
+
let requiredCols = 0;
|
|
26799
|
+
for (const { highlight, range } of highlightedCellRanges) {
|
|
26800
|
+
if (highlight.kind !== "columns") {
|
|
26801
|
+
requiredRows = Math.max(requiredRows, Math.min(XLSX_MAX_ROWS, range.end.row + OPEN_GRID_ROW_PADDING + 1));
|
|
26802
|
+
}
|
|
26803
|
+
if (highlight.kind !== "rows") {
|
|
26804
|
+
requiredCols = Math.max(requiredCols, Math.min(XLSX_MAX_COLUMNS, range.end.col + OPEN_GRID_COL_PADDING + 1));
|
|
26805
|
+
}
|
|
26806
|
+
}
|
|
26807
|
+
setDisplayRowLimit((current) => Math.max(current, requiredRows));
|
|
26808
|
+
setDisplayColLimit((current) => Math.max(current, requiredCols));
|
|
26809
|
+
}, [activeSheet?.maxUsedCol, activeSheet?.maxUsedRow, highlightedCellRanges, activeSheetIndex, isWorkerBacked]);
|
|
26810
|
+
React4.useEffect(() => {
|
|
26811
|
+
const scroller = scrollRef.current;
|
|
26812
|
+
const target = rangeHighlightRects.find(({ highlight: highlight2 }) => highlight2.autoScroll);
|
|
26813
|
+
if (!scroller || !target?.rect || scrolledHighlightRef.current === target.highlight || isLoading || scroller.clientWidth === 0 || scroller.clientHeight === 0 || target.highlight.kind !== "columns" && displayRowLimit <= target.range.end.row || target.highlight.kind !== "rows" && displayColLimit <= target.range.end.col) {
|
|
26814
|
+
return;
|
|
26815
|
+
}
|
|
26816
|
+
const { highlight, rect } = target;
|
|
26817
|
+
if (highlight.kind !== "columns") {
|
|
26818
|
+
scroller.scrollTop = getHighlightScrollOffset(rect.top, rect.top + rect.height, frozenPaneBottom, scroller.clientHeight, scroller.scrollTop);
|
|
26819
|
+
}
|
|
26820
|
+
if (highlight.kind !== "rows") {
|
|
26821
|
+
scroller.scrollLeft = getHighlightScrollOffset(rect.left, rect.left + rect.width, frozenPaneRight, scroller.clientWidth, scroller.scrollLeft);
|
|
26822
|
+
}
|
|
26823
|
+
scrolledHighlightRef.current = highlight;
|
|
26824
|
+
syncDrawingViewport(scroller, { immediate: true });
|
|
26825
|
+
}, [displayColLimit, displayRowLimit, drawingViewport.height, drawingViewport.width, frozenPaneBottom, frozenPaneRight, isLoading, rangeHighlightRects, syncDrawingViewport]);
|
|
26563
26826
|
const { fill: selectionFill, header: selectionHeaderSurface, stroke: selectionStroke } = React4.useMemo(() => resolveSelectionColors({
|
|
26564
26827
|
palette,
|
|
26565
26828
|
selectionColor,
|
|
@@ -29575,6 +29838,7 @@ function XlsxGrid({
|
|
|
29575
29838
|
backgroundColor: palette.headerSurface,
|
|
29576
29839
|
borderBottom: "none",
|
|
29577
29840
|
borderRight: "none",
|
|
29841
|
+
boxSizing: "border-box",
|
|
29578
29842
|
boxShadow: gutterSeparatorShadow,
|
|
29579
29843
|
color: palette.headerText,
|
|
29580
29844
|
fontSize: "11px",
|
|
@@ -31266,6 +31530,51 @@ function XlsxGrid({
|
|
|
31266
31530
|
width: "100%"
|
|
31267
31531
|
}
|
|
31268
31532
|
};
|
|
31533
|
+
const rangeHighlightNodes = rangeHighlightRects.flatMap(({ index, rect }) => rect ? [
|
|
31534
|
+
/* @__PURE__ */ jsx3(
|
|
31535
|
+
"div",
|
|
31536
|
+
{
|
|
31537
|
+
"aria-hidden": "true",
|
|
31538
|
+
className: classNames("react-xlsx-range-highlight", highlightClassName),
|
|
31539
|
+
"data-dark": paletteIsDark(palette) ? "true" : void 0,
|
|
31540
|
+
"data-xlsx-range-highlight": index,
|
|
31541
|
+
style: {
|
|
31542
|
+
...rect,
|
|
31543
|
+
["--xlsx-highlight-default-border-width"]: `${selectionBorderWidth}px`,
|
|
31544
|
+
boxSizing: "border-box",
|
|
31545
|
+
pointerEvents: "none",
|
|
31546
|
+
position: "absolute",
|
|
31547
|
+
zIndex: maxDrawingOverlayZIndex + 1
|
|
31548
|
+
}
|
|
31549
|
+
},
|
|
31550
|
+
index
|
|
31551
|
+
)
|
|
31552
|
+
] : []);
|
|
31553
|
+
const drawingOverlayPanes = experimentalCanvas && hasCanvasDomDrawingOverlays || rangeHighlightNodes.length > 0 ? /* @__PURE__ */ jsx3("div", { style: { ...canvasBodyViewportLayerStyle, zIndex: experimentalCanvas ? 23 : 34 }, children: [
|
|
31554
|
+
{ pane: "scroll", style: canvasScrollOverlayPaneStyle, ref: canvasScrollOverlayContentRef, left: -drawingViewport.left - frozenPaneRight, top: -drawingViewport.top - frozenPaneBottom },
|
|
31555
|
+
{ pane: "top", style: canvasTopOverlayPaneStyle, ref: canvasTopOverlayContentRef, left: -drawingViewport.left - frozenPaneRight, top: -displayHeaderHeight },
|
|
31556
|
+
{ pane: "left", style: canvasLeftOverlayPaneStyle, ref: canvasLeftOverlayContentRef, left: -displayRowHeaderWidth, top: -drawingViewport.top - frozenPaneBottom },
|
|
31557
|
+
{ pane: "corner", style: canvasCornerOverlayPaneStyle, ref: canvasCornerOverlayContentRef, left: -displayRowHeaderWidth, top: -displayHeaderHeight }
|
|
31558
|
+
].map(({ pane, style, ref, left, top }) => /* @__PURE__ */ jsx3("div", { style, children: /* @__PURE__ */ jsxs3(
|
|
31559
|
+
"div",
|
|
31560
|
+
{
|
|
31561
|
+
ref,
|
|
31562
|
+
style: {
|
|
31563
|
+
height: sheetContentHeight,
|
|
31564
|
+
left: 0,
|
|
31565
|
+
pointerEvents: "none",
|
|
31566
|
+
position: "absolute",
|
|
31567
|
+
top: 0,
|
|
31568
|
+
transform: `translate(${left}px, ${top}px)`,
|
|
31569
|
+
transformOrigin: "0 0",
|
|
31570
|
+
width: totalWidth
|
|
31571
|
+
},
|
|
31572
|
+
children: [
|
|
31573
|
+
experimentalCanvas ? paneDrawingNodes[pane] : null,
|
|
31574
|
+
rangeHighlightNodes
|
|
31575
|
+
]
|
|
31576
|
+
}
|
|
31577
|
+
) }, pane)) }) : null;
|
|
31269
31578
|
const scrollerContent = /* @__PURE__ */ jsx3(
|
|
31270
31579
|
"div",
|
|
31271
31580
|
{
|
|
@@ -31299,6 +31608,7 @@ function XlsxGrid({
|
|
|
31299
31608
|
/* @__PURE__ */ jsx3("div", { style: cornerOverlayStyle, children: paneDrawingNodes.corner }),
|
|
31300
31609
|
/* @__PURE__ */ jsx3("div", { style: scrollOverlayStyle, children: paneDrawingNodes.scroll })
|
|
31301
31610
|
] }) : null,
|
|
31611
|
+
drawingOverlayPanes,
|
|
31302
31612
|
experimentalCanvas ? /* @__PURE__ */ jsxs3(Fragment4, { children: [
|
|
31303
31613
|
/* @__PURE__ */ jsxs3("div", { style: canvasBodyViewportLayerStyle, children: [
|
|
31304
31614
|
/* @__PURE__ */ jsx3(
|
|
@@ -31340,77 +31650,7 @@ function XlsxGrid({
|
|
|
31340
31650
|
onPointerDown: handleCanvasBodyPointerDown,
|
|
31341
31651
|
style: canvasCornerBodyStyle
|
|
31342
31652
|
}
|
|
31343
|
-
)
|
|
31344
|
-
hasCanvasDomDrawingOverlays ? /* @__PURE__ */ jsxs3(Fragment4, { children: [
|
|
31345
|
-
/* @__PURE__ */ jsx3("div", { style: canvasScrollOverlayPaneStyle, children: /* @__PURE__ */ jsx3(
|
|
31346
|
-
"div",
|
|
31347
|
-
{
|
|
31348
|
-
ref: canvasScrollOverlayContentRef,
|
|
31349
|
-
style: {
|
|
31350
|
-
height: sheetContentHeight,
|
|
31351
|
-
left: 0,
|
|
31352
|
-
pointerEvents: "none",
|
|
31353
|
-
position: "absolute",
|
|
31354
|
-
top: 0,
|
|
31355
|
-
transform: `translate(${-drawingViewport.left - frozenPaneRight}px, ${-drawingViewport.top - frozenPaneBottom}px)`,
|
|
31356
|
-
transformOrigin: "0 0",
|
|
31357
|
-
width: totalWidth
|
|
31358
|
-
},
|
|
31359
|
-
children: paneDrawingNodes.scroll
|
|
31360
|
-
}
|
|
31361
|
-
) }),
|
|
31362
|
-
/* @__PURE__ */ jsx3("div", { style: canvasTopOverlayPaneStyle, children: /* @__PURE__ */ jsx3(
|
|
31363
|
-
"div",
|
|
31364
|
-
{
|
|
31365
|
-
ref: canvasTopOverlayContentRef,
|
|
31366
|
-
style: {
|
|
31367
|
-
height: sheetContentHeight,
|
|
31368
|
-
left: 0,
|
|
31369
|
-
pointerEvents: "none",
|
|
31370
|
-
position: "absolute",
|
|
31371
|
-
top: 0,
|
|
31372
|
-
transform: `translate(${-drawingViewport.left - frozenPaneRight}px, ${-displayHeaderHeight}px)`,
|
|
31373
|
-
transformOrigin: "0 0",
|
|
31374
|
-
width: totalWidth
|
|
31375
|
-
},
|
|
31376
|
-
children: paneDrawingNodes.top
|
|
31377
|
-
}
|
|
31378
|
-
) }),
|
|
31379
|
-
/* @__PURE__ */ jsx3("div", { style: canvasLeftOverlayPaneStyle, children: /* @__PURE__ */ jsx3(
|
|
31380
|
-
"div",
|
|
31381
|
-
{
|
|
31382
|
-
ref: canvasLeftOverlayContentRef,
|
|
31383
|
-
style: {
|
|
31384
|
-
height: sheetContentHeight,
|
|
31385
|
-
left: 0,
|
|
31386
|
-
pointerEvents: "none",
|
|
31387
|
-
position: "absolute",
|
|
31388
|
-
top: 0,
|
|
31389
|
-
transform: `translate(${-displayRowHeaderWidth}px, ${-drawingViewport.top - frozenPaneBottom}px)`,
|
|
31390
|
-
transformOrigin: "0 0",
|
|
31391
|
-
width: totalWidth
|
|
31392
|
-
},
|
|
31393
|
-
children: paneDrawingNodes.left
|
|
31394
|
-
}
|
|
31395
|
-
) }),
|
|
31396
|
-
/* @__PURE__ */ jsx3("div", { style: canvasCornerOverlayPaneStyle, children: /* @__PURE__ */ jsx3(
|
|
31397
|
-
"div",
|
|
31398
|
-
{
|
|
31399
|
-
ref: canvasCornerOverlayContentRef,
|
|
31400
|
-
style: {
|
|
31401
|
-
height: sheetContentHeight,
|
|
31402
|
-
left: 0,
|
|
31403
|
-
pointerEvents: "none",
|
|
31404
|
-
position: "absolute",
|
|
31405
|
-
top: 0,
|
|
31406
|
-
transform: `translate(${-displayRowHeaderWidth}px, ${-displayHeaderHeight}px)`,
|
|
31407
|
-
transformOrigin: "0 0",
|
|
31408
|
-
width: totalWidth
|
|
31409
|
-
},
|
|
31410
|
-
children: paneDrawingNodes.corner
|
|
31411
|
-
}
|
|
31412
|
-
) })
|
|
31413
|
-
] }) : null
|
|
31653
|
+
)
|
|
31414
31654
|
] }),
|
|
31415
31655
|
/* @__PURE__ */ jsxs3("div", { style: canvasHeaderViewportLayerStyle, children: [
|
|
31416
31656
|
/* @__PURE__ */ jsx3(
|
|
@@ -31856,6 +32096,7 @@ function XlsxGrid({
|
|
|
31856
32096
|
}
|
|
31857
32097
|
function XlsxViewerInner({
|
|
31858
32098
|
allowResizeInReadOnly = false,
|
|
32099
|
+
autoScrollToHighlightedRanges = true,
|
|
31859
32100
|
className,
|
|
31860
32101
|
controller,
|
|
31861
32102
|
emptyState,
|
|
@@ -31868,6 +32109,8 @@ function XlsxViewerInner({
|
|
|
31868
32109
|
headerBackgroundColor,
|
|
31869
32110
|
headerTextColor,
|
|
31870
32111
|
height,
|
|
32112
|
+
highlightClassName,
|
|
32113
|
+
highlightedRanges,
|
|
31871
32114
|
isDark = false,
|
|
31872
32115
|
loadingComponent,
|
|
31873
32116
|
loadingState,
|
|
@@ -31890,6 +32133,26 @@ function XlsxViewerInner({
|
|
|
31890
32133
|
}) {
|
|
31891
32134
|
const palette = useViewerPalette(isDark, headerBackgroundColor, headerTextColor);
|
|
31892
32135
|
const { displayFileName, error } = controller;
|
|
32136
|
+
const appliedHighlightRef = React4.useRef(null);
|
|
32137
|
+
const { clearHighlightedRanges, file, highlightRanges, isLoading, sheets, src } = controller;
|
|
32138
|
+
React4.useEffect(() => {
|
|
32139
|
+
if (isLoading || highlightedRanges === void 0) {
|
|
32140
|
+
appliedHighlightRef.current = null;
|
|
32141
|
+
return;
|
|
32142
|
+
}
|
|
32143
|
+
if (highlightedRanges !== null && sheets.length === 0) {
|
|
32144
|
+
return;
|
|
32145
|
+
}
|
|
32146
|
+
const referenceKey = JSON.stringify(typeof highlightedRanges === "string" ? [highlightedRanges] : highlightedRanges ?? []);
|
|
32147
|
+
const previous = appliedHighlightRef.current;
|
|
32148
|
+
if (previous && previous.referenceKey === referenceKey && previous.autoScroll === autoScrollToHighlightedRanges && previous.file === file && previous.src === src && previous.clear === clearHighlightedRanges) {
|
|
32149
|
+
return;
|
|
32150
|
+
}
|
|
32151
|
+
appliedHighlightRef.current = { autoScroll: autoScrollToHighlightedRanges, clear: clearHighlightedRanges, file, referenceKey, src };
|
|
32152
|
+
if (highlightedRanges === null || !highlightRanges(highlightedRanges, { autoScroll: autoScrollToHighlightedRanges })) {
|
|
32153
|
+
clearHighlightedRanges();
|
|
32154
|
+
}
|
|
32155
|
+
}, [autoScrollToHighlightedRanges, clearHighlightedRanges, file, highlightRanges, highlightedRanges, isLoading, sheets.length, src]);
|
|
31893
32156
|
const customFileTooLarge = error instanceof XlsxFileSizeLimitExceededError ? renderCustomFileTooLarge(
|
|
31894
32157
|
fileTooLargeState,
|
|
31895
32158
|
{
|
|
@@ -31922,6 +32185,7 @@ function XlsxViewerInner({
|
|
|
31922
32185
|
width: "100%"
|
|
31923
32186
|
},
|
|
31924
32187
|
children: [
|
|
32188
|
+
/* @__PURE__ */ jsx3("style", { children: RANGE_HIGHLIGHT_STYLES }),
|
|
31925
32189
|
resolveToolbar(toolbar, showDefaultToolbar, controller, palette),
|
|
31926
32190
|
/* @__PURE__ */ jsx3("div", { style: { display: "flex", flex: 1, minHeight: 0, minWidth: 0 }, children: /* @__PURE__ */ jsx3(
|
|
31927
32191
|
XlsxGrid,
|
|
@@ -31935,6 +32199,7 @@ function XlsxViewerInner({
|
|
|
31935
32199
|
experimentalCanvas,
|
|
31936
32200
|
fileTooLargeState,
|
|
31937
32201
|
getCellStyle,
|
|
32202
|
+
highlightClassName,
|
|
31938
32203
|
loadingComponent,
|
|
31939
32204
|
loadingState,
|
|
31940
32205
|
onFormControlAction,
|
|
@@ -33091,6 +33356,7 @@ export {
|
|
|
33091
33356
|
XlsxViewer,
|
|
33092
33357
|
XlsxViewerProvider,
|
|
33093
33358
|
initWasm,
|
|
33359
|
+
parseXlsxRange,
|
|
33094
33360
|
setWasmSource,
|
|
33095
33361
|
useXlsxViewer,
|
|
33096
33362
|
useXlsxViewerCharts,
|