@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.cjs
CHANGED
|
@@ -35,6 +35,7 @@ __export(index_exports, {
|
|
|
35
35
|
XlsxViewer: () => XlsxViewer,
|
|
36
36
|
XlsxViewerProvider: () => XlsxViewerProvider,
|
|
37
37
|
initWasm: () => initWasm,
|
|
38
|
+
parseXlsxRange: () => parseXlsxRange,
|
|
38
39
|
setWasmSource: () => setWasmSource,
|
|
39
40
|
useXlsxViewer: () => useXlsxViewer,
|
|
40
41
|
useXlsxViewerCharts: () => useXlsxViewerCharts,
|
|
@@ -3789,7 +3790,8 @@ function resolveWorksheetMergeMetadata(worksheet) {
|
|
|
3789
3790
|
hasHorizontalMerges: false,
|
|
3790
3791
|
hasVerticalMerges: false,
|
|
3791
3792
|
maxHorizontalMergeEndCol: -1,
|
|
3792
|
-
maxVerticalMergeEndRow: -1
|
|
3793
|
+
maxVerticalMergeEndRow: -1,
|
|
3794
|
+
mergedRanges: []
|
|
3793
3795
|
};
|
|
3794
3796
|
const mergedRegions = Array.isArray(worksheet.mergedRegions) ? worksheet.mergedRegions : [];
|
|
3795
3797
|
for (const rawRegion of mergedRegions) {
|
|
@@ -3820,6 +3822,7 @@ function resolveWorksheetMergeMetadata(worksheet) {
|
|
|
3820
3822
|
if (!range) {
|
|
3821
3823
|
continue;
|
|
3822
3824
|
}
|
|
3825
|
+
mergeMetadata.mergedRanges.push(range);
|
|
3823
3826
|
if (range.end.col > range.start.col) {
|
|
3824
3827
|
mergeMetadata.hasHorizontalMerges = true;
|
|
3825
3828
|
mergeMetadata.maxHorizontalMergeEndCol = Math.max(mergeMetadata.maxHorizontalMergeEndCol, range.end.col);
|
|
@@ -6723,6 +6726,102 @@ function tryRecalculate(workbook) {
|
|
|
6723
6726
|
}
|
|
6724
6727
|
}
|
|
6725
6728
|
|
|
6729
|
+
// src/range-reference.ts
|
|
6730
|
+
var XLSX_MAX_ROWS = 1048576;
|
|
6731
|
+
var XLSX_MAX_COLUMNS = 16384;
|
|
6732
|
+
function parseColumn(value) {
|
|
6733
|
+
let column = 0;
|
|
6734
|
+
for (const character of value.toUpperCase()) {
|
|
6735
|
+
column = column * 26 + character.charCodeAt(0) - 64;
|
|
6736
|
+
}
|
|
6737
|
+
return column > 0 && column <= XLSX_MAX_COLUMNS ? column - 1 : null;
|
|
6738
|
+
}
|
|
6739
|
+
function parseRow(value) {
|
|
6740
|
+
const row = Number(value);
|
|
6741
|
+
return row > 0 && row <= XLSX_MAX_ROWS ? row - 1 : null;
|
|
6742
|
+
}
|
|
6743
|
+
function parseCell(value) {
|
|
6744
|
+
const match = /^\$?([a-z]{1,3})\$?([1-9]\d{0,6})$/i.exec(value);
|
|
6745
|
+
if (!match) {
|
|
6746
|
+
return null;
|
|
6747
|
+
}
|
|
6748
|
+
const col = parseColumn(match[1]);
|
|
6749
|
+
const row = parseRow(match[2]);
|
|
6750
|
+
return col === null || row === null ? null : { col, row };
|
|
6751
|
+
}
|
|
6752
|
+
function parseXlsxRange(reference) {
|
|
6753
|
+
if (typeof reference !== "string") {
|
|
6754
|
+
return null;
|
|
6755
|
+
}
|
|
6756
|
+
let address = reference.trim().replace(/^=\s*/, "");
|
|
6757
|
+
let sheetName = null;
|
|
6758
|
+
if (address.startsWith("'")) {
|
|
6759
|
+
const match = /^'((?:[^']|'')+)'!(.+)$/.exec(address);
|
|
6760
|
+
if (!match) {
|
|
6761
|
+
return null;
|
|
6762
|
+
}
|
|
6763
|
+
sheetName = match[1].replace(/''/g, "'");
|
|
6764
|
+
address = match[2];
|
|
6765
|
+
} else if (address.includes("!")) {
|
|
6766
|
+
const match = /^([^\s'!\[\]:*?/\\+,;(){}=<>"&^%\-]+)!(.+)$/.exec(address);
|
|
6767
|
+
if (!match) {
|
|
6768
|
+
return null;
|
|
6769
|
+
}
|
|
6770
|
+
sheetName = match[1];
|
|
6771
|
+
address = match[2];
|
|
6772
|
+
}
|
|
6773
|
+
if (sheetName !== null && (sheetName.length > 31 || /[\[\]:*?/\\\u0000-\u001f]/.test(sheetName) || sheetName.startsWith("'") || sheetName.endsWith("'"))) {
|
|
6774
|
+
return null;
|
|
6775
|
+
}
|
|
6776
|
+
const parts = address.split(":");
|
|
6777
|
+
if (parts.length > 2) {
|
|
6778
|
+
return null;
|
|
6779
|
+
}
|
|
6780
|
+
const start = parseCell(parts[0]);
|
|
6781
|
+
const end = parseCell(parts[1] ?? parts[0]);
|
|
6782
|
+
if (start && end) {
|
|
6783
|
+
return {
|
|
6784
|
+
kind: "cells",
|
|
6785
|
+
range: {
|
|
6786
|
+
start: { col: Math.min(start.col, end.col), row: Math.min(start.row, end.row) },
|
|
6787
|
+
end: { col: Math.max(start.col, end.col), row: Math.max(start.row, end.row) }
|
|
6788
|
+
},
|
|
6789
|
+
sheetName
|
|
6790
|
+
};
|
|
6791
|
+
}
|
|
6792
|
+
const columns = /^\$?([a-z]{1,3}):\$?([a-z]{1,3})$/i.exec(address);
|
|
6793
|
+
if (columns) {
|
|
6794
|
+
const first = parseColumn(columns[1]);
|
|
6795
|
+
const last = parseColumn(columns[2]);
|
|
6796
|
+
if (first !== null && last !== null) {
|
|
6797
|
+
return {
|
|
6798
|
+
kind: "columns",
|
|
6799
|
+
range: {
|
|
6800
|
+
start: { col: Math.min(first, last), row: 0 },
|
|
6801
|
+
end: { col: Math.max(first, last), row: XLSX_MAX_ROWS - 1 }
|
|
6802
|
+
},
|
|
6803
|
+
sheetName
|
|
6804
|
+
};
|
|
6805
|
+
}
|
|
6806
|
+
}
|
|
6807
|
+
const rows = /^\$?([1-9]\d{0,6}):\$?([1-9]\d{0,6})$/.exec(address);
|
|
6808
|
+
if (rows) {
|
|
6809
|
+
const first = parseRow(rows[1]);
|
|
6810
|
+
const last = parseRow(rows[2]);
|
|
6811
|
+
if (first !== null && last !== null) {
|
|
6812
|
+
return {
|
|
6813
|
+
kind: "rows",
|
|
6814
|
+
range: {
|
|
6815
|
+
start: { col: 0, row: Math.min(first, last) },
|
|
6816
|
+
end: { col: XLSX_MAX_COLUMNS - 1, row: Math.max(first, last) }
|
|
6817
|
+
},
|
|
6818
|
+
sheetName
|
|
6819
|
+
};
|
|
6820
|
+
}
|
|
6821
|
+
}
|
|
6822
|
+
return null;
|
|
6823
|
+
}
|
|
6824
|
+
|
|
6726
6825
|
// src/wasm.ts
|
|
6727
6826
|
var wasmModulePromise = null;
|
|
6728
6827
|
var hasConfiguredWasmSource = false;
|
|
@@ -7345,6 +7444,7 @@ function buildSheetList(workbook, sheetStatesByWorkbookSheetIndex, themePalette,
|
|
|
7345
7444
|
hasVerticalMerges: mergeMetadata.hasVerticalMerges,
|
|
7346
7445
|
maxHorizontalMergeEndCol: mergeMetadata.maxHorizontalMergeEndCol,
|
|
7347
7446
|
maxVerticalMergeEndRow: mergeMetadata.maxVerticalMergeEndRow,
|
|
7447
|
+
mergedRanges: mergeMetadata.mergedRanges,
|
|
7348
7448
|
hiddenCols: [],
|
|
7349
7449
|
hiddenRows: [],
|
|
7350
7450
|
minUsedCol: -1,
|
|
@@ -7432,6 +7532,7 @@ function buildSheetList(workbook, sheetStatesByWorkbookSheetIndex, themePalette,
|
|
|
7432
7532
|
hasVerticalMerges: mergeMetadata.hasVerticalMerges,
|
|
7433
7533
|
maxHorizontalMergeEndCol: mergeMetadata.maxHorizontalMergeEndCol,
|
|
7434
7534
|
maxVerticalMergeEndRow: mergeMetadata.maxVerticalMergeEndRow,
|
|
7535
|
+
mergedRanges: mergeMetadata.mergedRanges,
|
|
7435
7536
|
hiddenCols: resolveWorksheetHiddenCols(worksheet, maxCol),
|
|
7436
7537
|
hiddenRows: resolveWorksheetHiddenRows(worksheet, maxRow),
|
|
7437
7538
|
minUsedCol: minCol,
|
|
@@ -8433,6 +8534,7 @@ function useXlsxViewerController(options) {
|
|
|
8433
8534
|
const [zoomScaleOverridesByTabId, setZoomScaleOverridesByTabId] = React.useState({});
|
|
8434
8535
|
const [activeCell, setActiveCell] = React.useState(null);
|
|
8435
8536
|
const [selection, setSelection] = React.useState(null);
|
|
8537
|
+
const [highlightedRanges, setHighlightedRanges] = React.useState([]);
|
|
8436
8538
|
const [selectedChartId, setSelectedChartId] = React.useState(null);
|
|
8437
8539
|
const [selectedChartElement, setSelectedChartElement] = React.useState(null);
|
|
8438
8540
|
const [selectedImageId, setSelectedImageId] = React.useState(null);
|
|
@@ -8718,6 +8820,7 @@ function useXlsxViewerController(options) {
|
|
|
8718
8820
|
setActiveTabIndexState(0);
|
|
8719
8821
|
setActiveCell(null);
|
|
8720
8822
|
setSelection(null);
|
|
8823
|
+
setHighlightedRanges([]);
|
|
8721
8824
|
setSelectedChartId(null);
|
|
8722
8825
|
setSelectedChartElement(null);
|
|
8723
8826
|
setSelectedImageId(null);
|
|
@@ -8747,6 +8850,7 @@ function useXlsxViewerController(options) {
|
|
|
8747
8850
|
setActiveTabIndexState(0);
|
|
8748
8851
|
setActiveCell(null);
|
|
8749
8852
|
setSelection(null);
|
|
8853
|
+
setHighlightedRanges([]);
|
|
8750
8854
|
setSelectedChartId(null);
|
|
8751
8855
|
setSelectedChartElement(null);
|
|
8752
8856
|
setSelectedImageId(null);
|
|
@@ -8938,6 +9042,41 @@ function useXlsxViewerController(options) {
|
|
|
8938
9042
|
return index;
|
|
8939
9043
|
});
|
|
8940
9044
|
}, [tabs]);
|
|
9045
|
+
const highlightRanges = React.useCallback((references, options2 = {}) => {
|
|
9046
|
+
const inputs = typeof references === "string" ? [references] : references;
|
|
9047
|
+
if (!Array.isArray(inputs) || isLoading || error) {
|
|
9048
|
+
return false;
|
|
9049
|
+
}
|
|
9050
|
+
const nextHighlights = [];
|
|
9051
|
+
let firstSheetIndex = activeSheetIndex;
|
|
9052
|
+
for (const reference of inputs) {
|
|
9053
|
+
const parsed = parseXlsxRange(reference);
|
|
9054
|
+
if (!parsed) {
|
|
9055
|
+
return false;
|
|
9056
|
+
}
|
|
9057
|
+
const requestedSheetName = parsed.sheetName?.toLowerCase();
|
|
9058
|
+
const sheetIndex = requestedSheetName === void 0 ? options2.sheetIndex ?? activeSheetIndex : sheets.findIndex((sheet2) => sheet2.name.toLowerCase() === requestedSheetName);
|
|
9059
|
+
const sheet = Number.isInteger(sheetIndex) ? sheets[sheetIndex] : void 0;
|
|
9060
|
+
if (!sheet) {
|
|
9061
|
+
return false;
|
|
9062
|
+
}
|
|
9063
|
+
if (nextHighlights.length === 0) {
|
|
9064
|
+
firstSheetIndex = sheetIndex;
|
|
9065
|
+
}
|
|
9066
|
+
nextHighlights.push({
|
|
9067
|
+
...parsed,
|
|
9068
|
+
autoScroll: nextHighlights.length === 0 && (options2.autoScroll ?? true),
|
|
9069
|
+
sheetName: sheet.name,
|
|
9070
|
+
workbookSheetIndex: sheet.workbookSheetIndex
|
|
9071
|
+
});
|
|
9072
|
+
}
|
|
9073
|
+
setHighlightedRanges(nextHighlights);
|
|
9074
|
+
if (nextHighlights[0]?.autoScroll) {
|
|
9075
|
+
setActiveSheetIndex(firstSheetIndex);
|
|
9076
|
+
}
|
|
9077
|
+
return true;
|
|
9078
|
+
}, [activeSheetIndex, error, isLoading, setActiveSheetIndex, sheets]);
|
|
9079
|
+
const clearHighlightedRanges = React.useCallback(() => setHighlightedRanges([]), []);
|
|
8941
9080
|
const setZoomScale = React.useCallback((nextZoomScale) => {
|
|
8942
9081
|
const normalizedZoomScale = clampZoomScale(nextZoomScale);
|
|
8943
9082
|
setZoomScaleOverridesByTabId((current) => {
|
|
@@ -10996,6 +11135,9 @@ function useXlsxViewerController(options) {
|
|
|
10996
11135
|
clearSelectedCells,
|
|
10997
11136
|
clearSelectedImage,
|
|
10998
11137
|
clearSelection,
|
|
11138
|
+
clearHighlightedRanges,
|
|
11139
|
+
highlightRanges,
|
|
11140
|
+
highlightedRanges,
|
|
10999
11141
|
continueDeferredLoad,
|
|
11000
11142
|
copySelectionToClipboard,
|
|
11001
11143
|
defaultZoomScale,
|
|
@@ -11116,6 +11258,9 @@ function useXlsxViewerController(options) {
|
|
|
11116
11258
|
clearSelectedCells,
|
|
11117
11259
|
clearSelectedImage,
|
|
11118
11260
|
continueDeferredLoad,
|
|
11261
|
+
clearHighlightedRanges,
|
|
11262
|
+
highlightRanges,
|
|
11263
|
+
highlightedRanges,
|
|
11119
11264
|
copySelectionToClipboard,
|
|
11120
11265
|
defaultZoomScale,
|
|
11121
11266
|
deferredLoadFileSize,
|
|
@@ -11799,6 +11944,62 @@ function growScrollDisplayLimit(current, growth, maximum, readOnly) {
|
|
|
11799
11944
|
return readOnly ? Math.max(current, Math.min(maximum, nextLimit)) : nextLimit;
|
|
11800
11945
|
}
|
|
11801
11946
|
|
|
11947
|
+
// src/range-highlight.ts
|
|
11948
|
+
function expandHighlightedRange(range, mergedRanges) {
|
|
11949
|
+
const expanded = { start: { ...range.start }, end: { ...range.end } };
|
|
11950
|
+
let changed;
|
|
11951
|
+
do {
|
|
11952
|
+
changed = false;
|
|
11953
|
+
for (const merged of mergedRanges) {
|
|
11954
|
+
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) {
|
|
11955
|
+
continue;
|
|
11956
|
+
}
|
|
11957
|
+
const startRow = Math.min(expanded.start.row, merged.start.row);
|
|
11958
|
+
const startCol = Math.min(expanded.start.col, merged.start.col);
|
|
11959
|
+
const endRow = Math.max(expanded.end.row, merged.end.row);
|
|
11960
|
+
const endCol = Math.max(expanded.end.col, merged.end.col);
|
|
11961
|
+
if (startRow !== expanded.start.row || startCol !== expanded.start.col || endRow !== expanded.end.row || endCol !== expanded.end.col) {
|
|
11962
|
+
expanded.start = { row: startRow, col: startCol };
|
|
11963
|
+
expanded.end = { row: endRow, col: endCol };
|
|
11964
|
+
changed = true;
|
|
11965
|
+
}
|
|
11966
|
+
}
|
|
11967
|
+
} while (changed);
|
|
11968
|
+
return expanded;
|
|
11969
|
+
}
|
|
11970
|
+
function lowerBound(indices, value) {
|
|
11971
|
+
let low = 0;
|
|
11972
|
+
let high = indices.length;
|
|
11973
|
+
while (low < high) {
|
|
11974
|
+
const middle = low + high >>> 1;
|
|
11975
|
+
if (indices[middle] < value) {
|
|
11976
|
+
low = middle + 1;
|
|
11977
|
+
} else {
|
|
11978
|
+
high = middle;
|
|
11979
|
+
}
|
|
11980
|
+
}
|
|
11981
|
+
return low;
|
|
11982
|
+
}
|
|
11983
|
+
function getHighlightAxisExtent(indices, prefixSums, start, end) {
|
|
11984
|
+
const first = lowerBound(indices, start);
|
|
11985
|
+
const afterLast = lowerBound(indices, end + 1);
|
|
11986
|
+
if (first >= afterLast) {
|
|
11987
|
+
return null;
|
|
11988
|
+
}
|
|
11989
|
+
return { start: prefixSums[first] ?? 0, end: prefixSums[afterLast] ?? 0 };
|
|
11990
|
+
}
|
|
11991
|
+
function getHighlightScrollOffset(start, end, frozenExtent, viewportExtent, currentOffset) {
|
|
11992
|
+
if (end <= frozenExtent || viewportExtent <= frozenExtent) {
|
|
11993
|
+
return currentOffset;
|
|
11994
|
+
}
|
|
11995
|
+
const scrollableStart = Math.max(start, frozenExtent);
|
|
11996
|
+
const availableExtent = viewportExtent - frozenExtent;
|
|
11997
|
+
if (scrollableStart < currentOffset + frozenExtent || end - scrollableStart > availableExtent) {
|
|
11998
|
+
return Math.max(0, scrollableStart - frozenExtent);
|
|
11999
|
+
}
|
|
12000
|
+
return end > currentOffset + viewportExtent ? end - viewportExtent : currentOffset;
|
|
12001
|
+
}
|
|
12002
|
+
|
|
11802
12003
|
// src/chart-renderer.tsx
|
|
11803
12004
|
var import_d3_hierarchy = require("d3-hierarchy");
|
|
11804
12005
|
var import_d3_geo = require("d3-geo");
|
|
@@ -18607,6 +18808,17 @@ function resolveViewerPalette(isDark = false, headerBackgroundColor, headerTextC
|
|
|
18607
18808
|
|
|
18608
18809
|
// src/XlsxViewer.tsx
|
|
18609
18810
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
18811
|
+
var RANGE_HIGHLIGHT_STYLES = `
|
|
18812
|
+
:where(.react-xlsx-range-highlight) {
|
|
18813
|
+
background: var(--xlsx-highlight-fill, rgb(59 130 246 / 8%));
|
|
18814
|
+
border: var(--xlsx-highlight-border, var(--xlsx-highlight-default-border-width, 1px) solid #3b82f6);
|
|
18815
|
+
border-radius: var(--xlsx-highlight-radius, 2px);
|
|
18816
|
+
}
|
|
18817
|
+
:where(.react-xlsx-range-highlight[data-dark="true"]) {
|
|
18818
|
+
background: var(--xlsx-highlight-fill, rgb(147 197 253 / 12%));
|
|
18819
|
+
border: var(--xlsx-highlight-border, var(--xlsx-highlight-default-border-width, 1px) solid #93c5fd);
|
|
18820
|
+
}
|
|
18821
|
+
`;
|
|
18610
18822
|
var DEFAULT_ROW_HEIGHT2 = 24;
|
|
18611
18823
|
var DEFAULT_COL_WIDTH2 = 80;
|
|
18612
18824
|
var HEADER_HEIGHT = 24;
|
|
@@ -24098,6 +24310,7 @@ function XlsxGrid({
|
|
|
24098
24310
|
errorState,
|
|
24099
24311
|
fileTooLargeState,
|
|
24100
24312
|
getCellStyle,
|
|
24313
|
+
highlightClassName,
|
|
24101
24314
|
loadingComponent,
|
|
24102
24315
|
loadingState,
|
|
24103
24316
|
onFormControlAction,
|
|
@@ -24142,6 +24355,7 @@ function XlsxGrid({
|
|
|
24142
24355
|
getClipboardData,
|
|
24143
24356
|
getCellDisplayValue: getControllerCellDisplayValue,
|
|
24144
24357
|
getFormControlItems,
|
|
24358
|
+
highlightedRanges,
|
|
24145
24359
|
images,
|
|
24146
24360
|
shapes,
|
|
24147
24361
|
isLoadDeferred,
|
|
@@ -24188,6 +24402,7 @@ function XlsxGrid({
|
|
|
24188
24402
|
), [formControls, getFormControlItems]);
|
|
24189
24403
|
const canResizeHeaders = !readOnly || allowResizeInReadOnly;
|
|
24190
24404
|
const scrollRef = React4.useRef(null);
|
|
24405
|
+
const scrolledHighlightRef = React4.useRef(null);
|
|
24191
24406
|
const wrapperRef = React4.useRef(null);
|
|
24192
24407
|
const tableRef = React4.useRef(null);
|
|
24193
24408
|
const gridKeyboardActiveRef = React4.useRef(false);
|
|
@@ -24376,6 +24591,10 @@ function XlsxGrid({
|
|
|
24376
24591
|
const resolveMergeAnchorCell = React4.useCallback((cell) => {
|
|
24377
24592
|
return mergedSecondaryAnchorMap.get(`${cell.row}:${cell.col}`) ?? cell;
|
|
24378
24593
|
}, [mergedSecondaryAnchorMap]);
|
|
24594
|
+
const highlightedCellRanges = React4.useMemo(
|
|
24595
|
+
() => highlightedRanges.flatMap((highlight, index) => activeSheet?.workbookSheetIndex === highlight.workbookSheetIndex ? [{ highlight, index, range: expandHighlightedRange(highlight.range, activeSheet?.mergedRanges ?? mergedRegions) }] : []),
|
|
24596
|
+
[activeSheet?.mergedRanges, activeSheet?.workbookSheetIndex, highlightedRanges, mergedRegions]
|
|
24597
|
+
);
|
|
24379
24598
|
const normalizedSelection = React4.useMemo(() => selection ? normalizeRange2(selection) : null, [selection]);
|
|
24380
24599
|
const zoomFactor = React4.useMemo(() => Math.max(0.1, zoomScale / 100), [zoomScale]);
|
|
24381
24600
|
const previousZoomFactorRef = React4.useRef(zoomFactor);
|
|
@@ -24415,7 +24634,7 @@ function XlsxGrid({
|
|
|
24415
24634
|
frozenPaneRight: liveFrozenPaneRight
|
|
24416
24635
|
} = canvasLayoutMetricsRef.current;
|
|
24417
24636
|
const currentLiveGestureZoom = liveGestureZoomRef.current;
|
|
24418
|
-
const isLiveZooming2 = currentLiveGestureZoom !== null && zoomScale === currentLiveGestureZoom.baseZoomScale;
|
|
24637
|
+
const isLiveZooming2 = experimentalCanvas && currentLiveGestureZoom !== null && zoomScale === currentLiveGestureZoom.baseZoomScale;
|
|
24419
24638
|
const liveZoomScale2 = isLiveZooming2 ? Math.max(0.1, currentLiveGestureZoom.targetZoomScale / currentLiveGestureZoom.baseZoomScale) : 1;
|
|
24420
24639
|
const scrollDeltaX = paintedViewport.left - nextLiveViewport.left;
|
|
24421
24640
|
const scrollDeltaY = paintedViewport.top - nextLiveViewport.top;
|
|
@@ -25386,7 +25605,7 @@ function XlsxGrid({
|
|
|
25386
25605
|
}, [shouldUseDomVirtualizer, syncDrawingViewport, zoomFactor]);
|
|
25387
25606
|
React4.useLayoutEffect(() => {
|
|
25388
25607
|
syncDrawingViewport(scrollRef.current, { immediate: true });
|
|
25389
|
-
}, [activeSheet, activeTabIndex, displayColLimit, displayRowLimit, syncDrawingViewport, zoomFactor]);
|
|
25608
|
+
}, [activeSheet, activeTabIndex, displayColLimit, displayRowLimit, highlightedCellRanges, syncDrawingViewport, zoomFactor]);
|
|
25390
25609
|
React4.useLayoutEffect(() => {
|
|
25391
25610
|
const scroller = scrollRef.current;
|
|
25392
25611
|
if (!scroller) {
|
|
@@ -26530,11 +26749,11 @@ function XlsxGrid({
|
|
|
26530
26749
|
if (textWidth > availableTextWidth) {
|
|
26531
26750
|
const baseFontSizePx = resolveCanvasFontSizePx(nextData.style, 12 * zoomFactor);
|
|
26532
26751
|
const minimumFontSizePx = Math.max(6 * zoomFactor, baseFontSizePx * 0.4);
|
|
26533
|
-
let
|
|
26752
|
+
let lowerBound2 = minimumFontSizePx;
|
|
26534
26753
|
let upperBound = baseFontSizePx;
|
|
26535
26754
|
let bestFontSizePx = minimumFontSizePx;
|
|
26536
|
-
while (upperBound -
|
|
26537
|
-
const candidateFontSizePx = (
|
|
26755
|
+
while (upperBound - lowerBound2 > 0.25) {
|
|
26756
|
+
const candidateFontSizePx = (lowerBound2 + upperBound) / 2;
|
|
26538
26757
|
const candidateStyle = {
|
|
26539
26758
|
...nextData.style,
|
|
26540
26759
|
font: void 0,
|
|
@@ -26543,7 +26762,7 @@ function XlsxGrid({
|
|
|
26543
26762
|
const candidateWidth = measureTextWidth(nextData.value, candidateStyle);
|
|
26544
26763
|
if (candidateWidth <= availableTextWidth) {
|
|
26545
26764
|
bestFontSizePx = candidateFontSizePx;
|
|
26546
|
-
|
|
26765
|
+
lowerBound2 = candidateFontSizePx;
|
|
26547
26766
|
} else {
|
|
26548
26767
|
upperBound = candidateFontSizePx;
|
|
26549
26768
|
}
|
|
@@ -26594,6 +26813,51 @@ function XlsxGrid({
|
|
|
26594
26813
|
};
|
|
26595
26814
|
}, [colIndexByActual, colPrefixSums, displayHeaderHeight, displayRowHeaderWidth, displayedSelection, rowIndexByActual, rowPrefixSums]);
|
|
26596
26815
|
const resolvedSelectionOverlay = selectionOverlay;
|
|
26816
|
+
const rangeHighlightRects = React4.useMemo(() => highlightedCellRanges.map(({ highlight, index, range }) => {
|
|
26817
|
+
const rows = getHighlightAxisExtent(visibleRows, rowPrefixSums, range.start.row, range.end.row);
|
|
26818
|
+
const cols = getHighlightAxisExtent(visibleCols, colPrefixSums, range.start.col, range.end.col);
|
|
26819
|
+
return {
|
|
26820
|
+
highlight,
|
|
26821
|
+
index,
|
|
26822
|
+
range,
|
|
26823
|
+
rect: rows && cols ? {
|
|
26824
|
+
height: rows.end - rows.start,
|
|
26825
|
+
left: displayRowHeaderWidth + cols.start,
|
|
26826
|
+
top: displayHeaderHeight + rows.start,
|
|
26827
|
+
width: cols.end - cols.start
|
|
26828
|
+
} : null
|
|
26829
|
+
};
|
|
26830
|
+
}), [colPrefixSums, displayHeaderHeight, displayRowHeaderWidth, highlightedCellRanges, rowPrefixSums, visibleCols, visibleRows]);
|
|
26831
|
+
React4.useEffect(() => {
|
|
26832
|
+
let requiredRows = 0;
|
|
26833
|
+
let requiredCols = 0;
|
|
26834
|
+
for (const { highlight, range } of highlightedCellRanges) {
|
|
26835
|
+
if (highlight.kind !== "columns") {
|
|
26836
|
+
requiredRows = Math.max(requiredRows, Math.min(XLSX_MAX_ROWS, range.end.row + OPEN_GRID_ROW_PADDING + 1));
|
|
26837
|
+
}
|
|
26838
|
+
if (highlight.kind !== "rows") {
|
|
26839
|
+
requiredCols = Math.max(requiredCols, Math.min(XLSX_MAX_COLUMNS, range.end.col + OPEN_GRID_COL_PADDING + 1));
|
|
26840
|
+
}
|
|
26841
|
+
}
|
|
26842
|
+
setDisplayRowLimit((current) => Math.max(current, requiredRows));
|
|
26843
|
+
setDisplayColLimit((current) => Math.max(current, requiredCols));
|
|
26844
|
+
}, [activeSheet?.maxUsedCol, activeSheet?.maxUsedRow, highlightedCellRanges, activeSheetIndex, isWorkerBacked]);
|
|
26845
|
+
React4.useEffect(() => {
|
|
26846
|
+
const scroller = scrollRef.current;
|
|
26847
|
+
const target = rangeHighlightRects.find(({ highlight: highlight2 }) => highlight2.autoScroll);
|
|
26848
|
+
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) {
|
|
26849
|
+
return;
|
|
26850
|
+
}
|
|
26851
|
+
const { highlight, rect } = target;
|
|
26852
|
+
if (highlight.kind !== "columns") {
|
|
26853
|
+
scroller.scrollTop = getHighlightScrollOffset(rect.top, rect.top + rect.height, frozenPaneBottom, scroller.clientHeight, scroller.scrollTop);
|
|
26854
|
+
}
|
|
26855
|
+
if (highlight.kind !== "rows") {
|
|
26856
|
+
scroller.scrollLeft = getHighlightScrollOffset(rect.left, rect.left + rect.width, frozenPaneRight, scroller.clientWidth, scroller.scrollLeft);
|
|
26857
|
+
}
|
|
26858
|
+
scrolledHighlightRef.current = highlight;
|
|
26859
|
+
syncDrawingViewport(scroller, { immediate: true });
|
|
26860
|
+
}, [displayColLimit, displayRowLimit, drawingViewport.height, drawingViewport.width, frozenPaneBottom, frozenPaneRight, isLoading, rangeHighlightRects, syncDrawingViewport]);
|
|
26597
26861
|
const { fill: selectionFill, header: selectionHeaderSurface, stroke: selectionStroke } = React4.useMemo(() => resolveSelectionColors({
|
|
26598
26862
|
palette,
|
|
26599
26863
|
selectionColor,
|
|
@@ -29609,6 +29873,7 @@ function XlsxGrid({
|
|
|
29609
29873
|
backgroundColor: palette.headerSurface,
|
|
29610
29874
|
borderBottom: "none",
|
|
29611
29875
|
borderRight: "none",
|
|
29876
|
+
boxSizing: "border-box",
|
|
29612
29877
|
boxShadow: gutterSeparatorShadow,
|
|
29613
29878
|
color: palette.headerText,
|
|
29614
29879
|
fontSize: "11px",
|
|
@@ -31300,6 +31565,51 @@ function XlsxGrid({
|
|
|
31300
31565
|
width: "100%"
|
|
31301
31566
|
}
|
|
31302
31567
|
};
|
|
31568
|
+
const rangeHighlightNodes = rangeHighlightRects.flatMap(({ index, rect }) => rect ? [
|
|
31569
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
31570
|
+
"div",
|
|
31571
|
+
{
|
|
31572
|
+
"aria-hidden": "true",
|
|
31573
|
+
className: classNames("react-xlsx-range-highlight", highlightClassName),
|
|
31574
|
+
"data-dark": paletteIsDark(palette) ? "true" : void 0,
|
|
31575
|
+
"data-xlsx-range-highlight": index,
|
|
31576
|
+
style: {
|
|
31577
|
+
...rect,
|
|
31578
|
+
["--xlsx-highlight-default-border-width"]: `${selectionBorderWidth}px`,
|
|
31579
|
+
boxSizing: "border-box",
|
|
31580
|
+
pointerEvents: "none",
|
|
31581
|
+
position: "absolute",
|
|
31582
|
+
zIndex: maxDrawingOverlayZIndex + 1
|
|
31583
|
+
}
|
|
31584
|
+
},
|
|
31585
|
+
index
|
|
31586
|
+
)
|
|
31587
|
+
] : []);
|
|
31588
|
+
const drawingOverlayPanes = experimentalCanvas && hasCanvasDomDrawingOverlays || rangeHighlightNodes.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { ...canvasBodyViewportLayerStyle, zIndex: experimentalCanvas ? 23 : 34 }, children: [
|
|
31589
|
+
{ pane: "scroll", style: canvasScrollOverlayPaneStyle, ref: canvasScrollOverlayContentRef, left: -drawingViewport.left - frozenPaneRight, top: -drawingViewport.top - frozenPaneBottom },
|
|
31590
|
+
{ pane: "top", style: canvasTopOverlayPaneStyle, ref: canvasTopOverlayContentRef, left: -drawingViewport.left - frozenPaneRight, top: -displayHeaderHeight },
|
|
31591
|
+
{ pane: "left", style: canvasLeftOverlayPaneStyle, ref: canvasLeftOverlayContentRef, left: -displayRowHeaderWidth, top: -drawingViewport.top - frozenPaneBottom },
|
|
31592
|
+
{ pane: "corner", style: canvasCornerOverlayPaneStyle, ref: canvasCornerOverlayContentRef, left: -displayRowHeaderWidth, top: -displayHeaderHeight }
|
|
31593
|
+
].map(({ pane, style, ref, left, top }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
31594
|
+
"div",
|
|
31595
|
+
{
|
|
31596
|
+
ref,
|
|
31597
|
+
style: {
|
|
31598
|
+
height: sheetContentHeight,
|
|
31599
|
+
left: 0,
|
|
31600
|
+
pointerEvents: "none",
|
|
31601
|
+
position: "absolute",
|
|
31602
|
+
top: 0,
|
|
31603
|
+
transform: `translate(${left}px, ${top}px)`,
|
|
31604
|
+
transformOrigin: "0 0",
|
|
31605
|
+
width: totalWidth
|
|
31606
|
+
},
|
|
31607
|
+
children: [
|
|
31608
|
+
experimentalCanvas ? paneDrawingNodes[pane] : null,
|
|
31609
|
+
rangeHighlightNodes
|
|
31610
|
+
]
|
|
31611
|
+
}
|
|
31612
|
+
) }, pane)) }) : null;
|
|
31303
31613
|
const scrollerContent = /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
31304
31614
|
"div",
|
|
31305
31615
|
{
|
|
@@ -31333,6 +31643,7 @@ function XlsxGrid({
|
|
|
31333
31643
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: cornerOverlayStyle, children: paneDrawingNodes.corner }),
|
|
31334
31644
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: scrollOverlayStyle, children: paneDrawingNodes.scroll })
|
|
31335
31645
|
] }) : null,
|
|
31646
|
+
drawingOverlayPanes,
|
|
31336
31647
|
experimentalCanvas ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
31337
31648
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: canvasBodyViewportLayerStyle, children: [
|
|
31338
31649
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
@@ -31374,77 +31685,7 @@ function XlsxGrid({
|
|
|
31374
31685
|
onPointerDown: handleCanvasBodyPointerDown,
|
|
31375
31686
|
style: canvasCornerBodyStyle
|
|
31376
31687
|
}
|
|
31377
|
-
)
|
|
31378
|
-
hasCanvasDomDrawingOverlays ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
31379
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: canvasScrollOverlayPaneStyle, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
31380
|
-
"div",
|
|
31381
|
-
{
|
|
31382
|
-
ref: canvasScrollOverlayContentRef,
|
|
31383
|
-
style: {
|
|
31384
|
-
height: sheetContentHeight,
|
|
31385
|
-
left: 0,
|
|
31386
|
-
pointerEvents: "none",
|
|
31387
|
-
position: "absolute",
|
|
31388
|
-
top: 0,
|
|
31389
|
-
transform: `translate(${-drawingViewport.left - frozenPaneRight}px, ${-drawingViewport.top - frozenPaneBottom}px)`,
|
|
31390
|
-
transformOrigin: "0 0",
|
|
31391
|
-
width: totalWidth
|
|
31392
|
-
},
|
|
31393
|
-
children: paneDrawingNodes.scroll
|
|
31394
|
-
}
|
|
31395
|
-
) }),
|
|
31396
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: canvasTopOverlayPaneStyle, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
31397
|
-
"div",
|
|
31398
|
-
{
|
|
31399
|
-
ref: canvasTopOverlayContentRef,
|
|
31400
|
-
style: {
|
|
31401
|
-
height: sheetContentHeight,
|
|
31402
|
-
left: 0,
|
|
31403
|
-
pointerEvents: "none",
|
|
31404
|
-
position: "absolute",
|
|
31405
|
-
top: 0,
|
|
31406
|
-
transform: `translate(${-drawingViewport.left - frozenPaneRight}px, ${-displayHeaderHeight}px)`,
|
|
31407
|
-
transformOrigin: "0 0",
|
|
31408
|
-
width: totalWidth
|
|
31409
|
-
},
|
|
31410
|
-
children: paneDrawingNodes.top
|
|
31411
|
-
}
|
|
31412
|
-
) }),
|
|
31413
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: canvasLeftOverlayPaneStyle, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
31414
|
-
"div",
|
|
31415
|
-
{
|
|
31416
|
-
ref: canvasLeftOverlayContentRef,
|
|
31417
|
-
style: {
|
|
31418
|
-
height: sheetContentHeight,
|
|
31419
|
-
left: 0,
|
|
31420
|
-
pointerEvents: "none",
|
|
31421
|
-
position: "absolute",
|
|
31422
|
-
top: 0,
|
|
31423
|
-
transform: `translate(${-displayRowHeaderWidth}px, ${-drawingViewport.top - frozenPaneBottom}px)`,
|
|
31424
|
-
transformOrigin: "0 0",
|
|
31425
|
-
width: totalWidth
|
|
31426
|
-
},
|
|
31427
|
-
children: paneDrawingNodes.left
|
|
31428
|
-
}
|
|
31429
|
-
) }),
|
|
31430
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: canvasCornerOverlayPaneStyle, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
31431
|
-
"div",
|
|
31432
|
-
{
|
|
31433
|
-
ref: canvasCornerOverlayContentRef,
|
|
31434
|
-
style: {
|
|
31435
|
-
height: sheetContentHeight,
|
|
31436
|
-
left: 0,
|
|
31437
|
-
pointerEvents: "none",
|
|
31438
|
-
position: "absolute",
|
|
31439
|
-
top: 0,
|
|
31440
|
-
transform: `translate(${-displayRowHeaderWidth}px, ${-displayHeaderHeight}px)`,
|
|
31441
|
-
transformOrigin: "0 0",
|
|
31442
|
-
width: totalWidth
|
|
31443
|
-
},
|
|
31444
|
-
children: paneDrawingNodes.corner
|
|
31445
|
-
}
|
|
31446
|
-
) })
|
|
31447
|
-
] }) : null
|
|
31688
|
+
)
|
|
31448
31689
|
] }),
|
|
31449
31690
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: canvasHeaderViewportLayerStyle, children: [
|
|
31450
31691
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
@@ -31890,6 +32131,7 @@ function XlsxGrid({
|
|
|
31890
32131
|
}
|
|
31891
32132
|
function XlsxViewerInner({
|
|
31892
32133
|
allowResizeInReadOnly = false,
|
|
32134
|
+
autoScrollToHighlightedRanges = true,
|
|
31893
32135
|
className,
|
|
31894
32136
|
controller,
|
|
31895
32137
|
emptyState,
|
|
@@ -31902,6 +32144,8 @@ function XlsxViewerInner({
|
|
|
31902
32144
|
headerBackgroundColor,
|
|
31903
32145
|
headerTextColor,
|
|
31904
32146
|
height,
|
|
32147
|
+
highlightClassName,
|
|
32148
|
+
highlightedRanges,
|
|
31905
32149
|
isDark = false,
|
|
31906
32150
|
loadingComponent,
|
|
31907
32151
|
loadingState,
|
|
@@ -31924,6 +32168,26 @@ function XlsxViewerInner({
|
|
|
31924
32168
|
}) {
|
|
31925
32169
|
const palette = useViewerPalette(isDark, headerBackgroundColor, headerTextColor);
|
|
31926
32170
|
const { displayFileName, error } = controller;
|
|
32171
|
+
const appliedHighlightRef = React4.useRef(null);
|
|
32172
|
+
const { clearHighlightedRanges, file, highlightRanges, isLoading, sheets, src } = controller;
|
|
32173
|
+
React4.useEffect(() => {
|
|
32174
|
+
if (isLoading || highlightedRanges === void 0) {
|
|
32175
|
+
appliedHighlightRef.current = null;
|
|
32176
|
+
return;
|
|
32177
|
+
}
|
|
32178
|
+
if (highlightedRanges !== null && sheets.length === 0) {
|
|
32179
|
+
return;
|
|
32180
|
+
}
|
|
32181
|
+
const referenceKey = JSON.stringify(typeof highlightedRanges === "string" ? [highlightedRanges] : highlightedRanges ?? []);
|
|
32182
|
+
const previous = appliedHighlightRef.current;
|
|
32183
|
+
if (previous && previous.referenceKey === referenceKey && previous.autoScroll === autoScrollToHighlightedRanges && previous.file === file && previous.src === src && previous.clear === clearHighlightedRanges) {
|
|
32184
|
+
return;
|
|
32185
|
+
}
|
|
32186
|
+
appliedHighlightRef.current = { autoScroll: autoScrollToHighlightedRanges, clear: clearHighlightedRanges, file, referenceKey, src };
|
|
32187
|
+
if (highlightedRanges === null || !highlightRanges(highlightedRanges, { autoScroll: autoScrollToHighlightedRanges })) {
|
|
32188
|
+
clearHighlightedRanges();
|
|
32189
|
+
}
|
|
32190
|
+
}, [autoScrollToHighlightedRanges, clearHighlightedRanges, file, highlightRanges, highlightedRanges, isLoading, sheets.length, src]);
|
|
31927
32191
|
const customFileTooLarge = error instanceof XlsxFileSizeLimitExceededError ? renderCustomFileTooLarge(
|
|
31928
32192
|
fileTooLargeState,
|
|
31929
32193
|
{
|
|
@@ -31956,6 +32220,7 @@ function XlsxViewerInner({
|
|
|
31956
32220
|
width: "100%"
|
|
31957
32221
|
},
|
|
31958
32222
|
children: [
|
|
32223
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("style", { children: RANGE_HIGHLIGHT_STYLES }),
|
|
31959
32224
|
resolveToolbar(toolbar, showDefaultToolbar, controller, palette),
|
|
31960
32225
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { display: "flex", flex: 1, minHeight: 0, minWidth: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
31961
32226
|
XlsxGrid,
|
|
@@ -31969,6 +32234,7 @@ function XlsxViewerInner({
|
|
|
31969
32234
|
experimentalCanvas,
|
|
31970
32235
|
fileTooLargeState,
|
|
31971
32236
|
getCellStyle,
|
|
32237
|
+
highlightClassName,
|
|
31972
32238
|
loadingComponent,
|
|
31973
32239
|
loadingState,
|
|
31974
32240
|
onFormControlAction,
|
|
@@ -33126,6 +33392,7 @@ function DefaultXlsxToolbar() {
|
|
|
33126
33392
|
XlsxViewer,
|
|
33127
33393
|
XlsxViewerProvider,
|
|
33128
33394
|
initWasm,
|
|
33395
|
+
parseXlsxRange,
|
|
33129
33396
|
setWasmSource,
|
|
33130
33397
|
useXlsxViewer,
|
|
33131
33398
|
useXlsxViewerCharts,
|