@extend-ai/react-xlsx 0.16.6 → 0.17.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/README.md +56 -0
- package/dist/index.cjs +438 -99
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +35 -1
- package/dist/index.d.ts +35 -1
- package/dist/index.js +437 -99
- package/dist/index.js.map +1 -1
- package/dist/xlsx-worker.js +45 -20
- package/dist/xlsx-worker.js.map +1 -1
- package/package.json +2 -2
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,
|
|
@@ -3631,7 +3632,7 @@ function resolveWorkbookColor(color, themePalette) {
|
|
|
3631
3632
|
if (directHex) {
|
|
3632
3633
|
return normalizeHexColor2(directHex);
|
|
3633
3634
|
}
|
|
3634
|
-
const themeValue = color.theme;
|
|
3635
|
+
const themeValue = color.theme ?? color.themeIndex;
|
|
3635
3636
|
const numericTheme = typeof themeValue === "number" ? themeValue : typeof themeValue === "string" && themeValue.trim().length > 0 ? Number(themeValue) : Number.NaN;
|
|
3636
3637
|
const themeColor = Number.isFinite(numericTheme) ? themePalette?.colorsByIndex[numericTheme] ?? null : null;
|
|
3637
3638
|
if (!themeColor) {
|
|
@@ -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);
|
|
@@ -4257,6 +4260,12 @@ function parseSpreadsheetFont(node) {
|
|
|
4257
4260
|
return void 0;
|
|
4258
4261
|
}
|
|
4259
4262
|
const font = {};
|
|
4263
|
+
for (const [tag, property] of [["b", "bold"], ["i", "italic"], ["strike", "strikethrough"]]) {
|
|
4264
|
+
const flag = getFirstChild(node, tag);
|
|
4265
|
+
if (flag) {
|
|
4266
|
+
font[property] = hasEnabledSpreadsheetFlag(flag);
|
|
4267
|
+
}
|
|
4268
|
+
}
|
|
4260
4269
|
const size = getFirstChild(node, "sz")?.getAttribute("val");
|
|
4261
4270
|
const name = getFirstChild(node, "name")?.getAttribute("val");
|
|
4262
4271
|
const family = getFirstChild(node, "family")?.getAttribute("val");
|
|
@@ -4264,15 +4273,6 @@ function parseSpreadsheetFont(node) {
|
|
|
4264
4273
|
const charset = getFirstChild(node, "charset")?.getAttribute("val");
|
|
4265
4274
|
const verticalAlign = getFirstChild(node, "vertAlign")?.getAttribute("val");
|
|
4266
4275
|
const color = parseSpreadsheetColor(getFirstChild(node, "color"));
|
|
4267
|
-
if (hasEnabledSpreadsheetFlag(getFirstChild(node, "b"))) {
|
|
4268
|
-
font.bold = true;
|
|
4269
|
-
}
|
|
4270
|
-
if (hasEnabledSpreadsheetFlag(getFirstChild(node, "i"))) {
|
|
4271
|
-
font.italic = true;
|
|
4272
|
-
}
|
|
4273
|
-
if (hasEnabledSpreadsheetFlag(getFirstChild(node, "strike"))) {
|
|
4274
|
-
font.strikethrough = true;
|
|
4275
|
-
}
|
|
4276
4276
|
if (getFirstChild(node, "u")) {
|
|
4277
4277
|
font.underline = getFirstChild(node, "u")?.getAttribute("val") ?? "single";
|
|
4278
4278
|
}
|
|
@@ -4521,7 +4521,14 @@ function parseWorkbookStyles(archive) {
|
|
|
4521
4521
|
const styleById = {};
|
|
4522
4522
|
const tableStyleByName = {};
|
|
4523
4523
|
getChildElements(cellXfsNode, "xf").forEach((xfNode, index) => {
|
|
4524
|
-
|
|
4524
|
+
const style = parseResolvedXfStyle(xfNode, fonts, fills, borders, checkboxComplementIndices);
|
|
4525
|
+
const overrides = {};
|
|
4526
|
+
for (const component of ["font", "fill", "border"]) {
|
|
4527
|
+
if (Number(xfNode.getAttribute(`${component}Id`) ?? 0) > 0 && xfNode.getAttribute(`apply${component[0].toUpperCase()}${component.slice(1)}`) !== "0") {
|
|
4528
|
+
Object.assign(overrides, { [component]: style[component] });
|
|
4529
|
+
}
|
|
4530
|
+
}
|
|
4531
|
+
styleById[index] = { ...style, tableStyleOverrides: overrides };
|
|
4525
4532
|
});
|
|
4526
4533
|
getChildElements(cellStylesNode ?? document2.documentElement, "cellStyle").forEach((cellStyleNode) => {
|
|
4527
4534
|
const name = cellStyleNode.getAttribute("name");
|
|
@@ -4865,6 +4872,7 @@ function parseSheetState(archive, path, options) {
|
|
|
4865
4872
|
const rowHeightOverridesPx = {};
|
|
4866
4873
|
const colWidthOverridesPx = {};
|
|
4867
4874
|
const rowStyleIds = {};
|
|
4875
|
+
const cellStyleIds = {};
|
|
4868
4876
|
const colStyleIds = {};
|
|
4869
4877
|
let minContentCol = Number.POSITIVE_INFINITY;
|
|
4870
4878
|
let minContentRow = Number.POSITIVE_INFINITY;
|
|
@@ -4914,6 +4922,10 @@ function parseSheetState(archive, path, options) {
|
|
|
4914
4922
|
}
|
|
4915
4923
|
getChildElements(rowNode, "c").forEach((cellNode) => {
|
|
4916
4924
|
const cellRef = cellNode.getAttribute("r");
|
|
4925
|
+
const cellStyleId = Number(cellNode.getAttribute("s") ?? Number.NaN);
|
|
4926
|
+
if (cellRef && Number.isFinite(cellStyleId)) {
|
|
4927
|
+
cellStyleIds[cellRef] = cellStyleId;
|
|
4928
|
+
}
|
|
4917
4929
|
if (isMeaningfulCellNode(cellNode)) {
|
|
4918
4930
|
trackContentCell(cellRef);
|
|
4919
4931
|
}
|
|
@@ -4952,6 +4964,7 @@ function parseSheetState(archive, path, options) {
|
|
|
4952
4964
|
return {
|
|
4953
4965
|
autoFilterRanges,
|
|
4954
4966
|
cachedFormulaValues,
|
|
4967
|
+
cellStyleIds,
|
|
4955
4968
|
columnWidthCharacterWidthPx,
|
|
4956
4969
|
colWidthOverridesPx,
|
|
4957
4970
|
colStyleIds,
|
|
@@ -6723,6 +6736,102 @@ function tryRecalculate(workbook) {
|
|
|
6723
6736
|
}
|
|
6724
6737
|
}
|
|
6725
6738
|
|
|
6739
|
+
// src/range-reference.ts
|
|
6740
|
+
var XLSX_MAX_ROWS = 1048576;
|
|
6741
|
+
var XLSX_MAX_COLUMNS = 16384;
|
|
6742
|
+
function parseColumn(value) {
|
|
6743
|
+
let column = 0;
|
|
6744
|
+
for (const character of value.toUpperCase()) {
|
|
6745
|
+
column = column * 26 + character.charCodeAt(0) - 64;
|
|
6746
|
+
}
|
|
6747
|
+
return column > 0 && column <= XLSX_MAX_COLUMNS ? column - 1 : null;
|
|
6748
|
+
}
|
|
6749
|
+
function parseRow(value) {
|
|
6750
|
+
const row = Number(value);
|
|
6751
|
+
return row > 0 && row <= XLSX_MAX_ROWS ? row - 1 : null;
|
|
6752
|
+
}
|
|
6753
|
+
function parseCell(value) {
|
|
6754
|
+
const match = /^\$?([a-z]{1,3})\$?([1-9]\d{0,6})$/i.exec(value);
|
|
6755
|
+
if (!match) {
|
|
6756
|
+
return null;
|
|
6757
|
+
}
|
|
6758
|
+
const col = parseColumn(match[1]);
|
|
6759
|
+
const row = parseRow(match[2]);
|
|
6760
|
+
return col === null || row === null ? null : { col, row };
|
|
6761
|
+
}
|
|
6762
|
+
function parseXlsxRange(reference) {
|
|
6763
|
+
if (typeof reference !== "string") {
|
|
6764
|
+
return null;
|
|
6765
|
+
}
|
|
6766
|
+
let address = reference.trim().replace(/^=\s*/, "");
|
|
6767
|
+
let sheetName = null;
|
|
6768
|
+
if (address.startsWith("'")) {
|
|
6769
|
+
const match = /^'((?:[^']|'')+)'!(.+)$/.exec(address);
|
|
6770
|
+
if (!match) {
|
|
6771
|
+
return null;
|
|
6772
|
+
}
|
|
6773
|
+
sheetName = match[1].replace(/''/g, "'");
|
|
6774
|
+
address = match[2];
|
|
6775
|
+
} else if (address.includes("!")) {
|
|
6776
|
+
const match = /^([^\s'!\[\]:*?/\\+,;(){}=<>"&^%\-]+)!(.+)$/.exec(address);
|
|
6777
|
+
if (!match) {
|
|
6778
|
+
return null;
|
|
6779
|
+
}
|
|
6780
|
+
sheetName = match[1];
|
|
6781
|
+
address = match[2];
|
|
6782
|
+
}
|
|
6783
|
+
if (sheetName !== null && (sheetName.length > 31 || /[\[\]:*?/\\\u0000-\u001f]/.test(sheetName) || sheetName.startsWith("'") || sheetName.endsWith("'"))) {
|
|
6784
|
+
return null;
|
|
6785
|
+
}
|
|
6786
|
+
const parts = address.split(":");
|
|
6787
|
+
if (parts.length > 2) {
|
|
6788
|
+
return null;
|
|
6789
|
+
}
|
|
6790
|
+
const start = parseCell(parts[0]);
|
|
6791
|
+
const end = parseCell(parts[1] ?? parts[0]);
|
|
6792
|
+
if (start && end) {
|
|
6793
|
+
return {
|
|
6794
|
+
kind: "cells",
|
|
6795
|
+
range: {
|
|
6796
|
+
start: { col: Math.min(start.col, end.col), row: Math.min(start.row, end.row) },
|
|
6797
|
+
end: { col: Math.max(start.col, end.col), row: Math.max(start.row, end.row) }
|
|
6798
|
+
},
|
|
6799
|
+
sheetName
|
|
6800
|
+
};
|
|
6801
|
+
}
|
|
6802
|
+
const columns = /^\$?([a-z]{1,3}):\$?([a-z]{1,3})$/i.exec(address);
|
|
6803
|
+
if (columns) {
|
|
6804
|
+
const first = parseColumn(columns[1]);
|
|
6805
|
+
const last = parseColumn(columns[2]);
|
|
6806
|
+
if (first !== null && last !== null) {
|
|
6807
|
+
return {
|
|
6808
|
+
kind: "columns",
|
|
6809
|
+
range: {
|
|
6810
|
+
start: { col: Math.min(first, last), row: 0 },
|
|
6811
|
+
end: { col: Math.max(first, last), row: XLSX_MAX_ROWS - 1 }
|
|
6812
|
+
},
|
|
6813
|
+
sheetName
|
|
6814
|
+
};
|
|
6815
|
+
}
|
|
6816
|
+
}
|
|
6817
|
+
const rows = /^\$?([1-9]\d{0,6}):\$?([1-9]\d{0,6})$/.exec(address);
|
|
6818
|
+
if (rows) {
|
|
6819
|
+
const first = parseRow(rows[1]);
|
|
6820
|
+
const last = parseRow(rows[2]);
|
|
6821
|
+
if (first !== null && last !== null) {
|
|
6822
|
+
return {
|
|
6823
|
+
kind: "rows",
|
|
6824
|
+
range: {
|
|
6825
|
+
start: { col: 0, row: Math.min(first, last) },
|
|
6826
|
+
end: { col: XLSX_MAX_COLUMNS - 1, row: Math.max(first, last) }
|
|
6827
|
+
},
|
|
6828
|
+
sheetName
|
|
6829
|
+
};
|
|
6830
|
+
}
|
|
6831
|
+
}
|
|
6832
|
+
return null;
|
|
6833
|
+
}
|
|
6834
|
+
|
|
6726
6835
|
// src/wasm.ts
|
|
6727
6836
|
var wasmModulePromise = null;
|
|
6728
6837
|
var hasConfiguredWasmSource = false;
|
|
@@ -7345,6 +7454,7 @@ function buildSheetList(workbook, sheetStatesByWorkbookSheetIndex, themePalette,
|
|
|
7345
7454
|
hasVerticalMerges: mergeMetadata.hasVerticalMerges,
|
|
7346
7455
|
maxHorizontalMergeEndCol: mergeMetadata.maxHorizontalMergeEndCol,
|
|
7347
7456
|
maxVerticalMergeEndRow: mergeMetadata.maxVerticalMergeEndRow,
|
|
7457
|
+
mergedRanges: mergeMetadata.mergedRanges,
|
|
7348
7458
|
hiddenCols: [],
|
|
7349
7459
|
hiddenRows: [],
|
|
7350
7460
|
minUsedCol: -1,
|
|
@@ -7358,6 +7468,7 @@ function buildSheetList(workbook, sheetStatesByWorkbookSheetIndex, themePalette,
|
|
|
7358
7468
|
colCount: 0,
|
|
7359
7469
|
rowHeightOverridesPx: sheetState?.rowHeightOverridesPx ?? {},
|
|
7360
7470
|
rowStyleIds: sheetState?.rowStyleIds ?? {},
|
|
7471
|
+
cellStyleIds: sheetState?.cellStyleIds ?? {},
|
|
7361
7472
|
styleById: styleById ?? {},
|
|
7362
7473
|
sparklines: sheetState?.sparklines ?? [],
|
|
7363
7474
|
tableStyleByName: tableStyleByName ?? {},
|
|
@@ -7432,6 +7543,7 @@ function buildSheetList(workbook, sheetStatesByWorkbookSheetIndex, themePalette,
|
|
|
7432
7543
|
hasVerticalMerges: mergeMetadata.hasVerticalMerges,
|
|
7433
7544
|
maxHorizontalMergeEndCol: mergeMetadata.maxHorizontalMergeEndCol,
|
|
7434
7545
|
maxVerticalMergeEndRow: mergeMetadata.maxVerticalMergeEndRow,
|
|
7546
|
+
mergedRanges: mergeMetadata.mergedRanges,
|
|
7435
7547
|
hiddenCols: resolveWorksheetHiddenCols(worksheet, maxCol),
|
|
7436
7548
|
hiddenRows: resolveWorksheetHiddenRows(worksheet, maxRow),
|
|
7437
7549
|
minUsedCol: minCol,
|
|
@@ -7443,6 +7555,7 @@ function buildSheetList(workbook, sheetStatesByWorkbookSheetIndex, themePalette,
|
|
|
7443
7555
|
namedCellStyleByName: namedCellStyleByName ?? {},
|
|
7444
7556
|
rowHeightOverridesPx: sheetState?.rowHeightOverridesPx ?? {},
|
|
7445
7557
|
rowStyleIds: sheetState?.rowStyleIds ?? {},
|
|
7558
|
+
cellStyleIds: sheetState?.cellStyleIds ?? {},
|
|
7446
7559
|
showGridLines: sheetState?.showGridLines ?? true,
|
|
7447
7560
|
styleById: styleById ?? {},
|
|
7448
7561
|
sparklines: sheetState?.sparklines ?? [],
|
|
@@ -8433,6 +8546,7 @@ function useXlsxViewerController(options) {
|
|
|
8433
8546
|
const [zoomScaleOverridesByTabId, setZoomScaleOverridesByTabId] = React.useState({});
|
|
8434
8547
|
const [activeCell, setActiveCell] = React.useState(null);
|
|
8435
8548
|
const [selection, setSelection] = React.useState(null);
|
|
8549
|
+
const [highlightedRanges, setHighlightedRanges] = React.useState([]);
|
|
8436
8550
|
const [selectedChartId, setSelectedChartId] = React.useState(null);
|
|
8437
8551
|
const [selectedChartElement, setSelectedChartElement] = React.useState(null);
|
|
8438
8552
|
const [selectedImageId, setSelectedImageId] = React.useState(null);
|
|
@@ -8718,6 +8832,7 @@ function useXlsxViewerController(options) {
|
|
|
8718
8832
|
setActiveTabIndexState(0);
|
|
8719
8833
|
setActiveCell(null);
|
|
8720
8834
|
setSelection(null);
|
|
8835
|
+
setHighlightedRanges([]);
|
|
8721
8836
|
setSelectedChartId(null);
|
|
8722
8837
|
setSelectedChartElement(null);
|
|
8723
8838
|
setSelectedImageId(null);
|
|
@@ -8747,6 +8862,7 @@ function useXlsxViewerController(options) {
|
|
|
8747
8862
|
setActiveTabIndexState(0);
|
|
8748
8863
|
setActiveCell(null);
|
|
8749
8864
|
setSelection(null);
|
|
8865
|
+
setHighlightedRanges([]);
|
|
8750
8866
|
setSelectedChartId(null);
|
|
8751
8867
|
setSelectedChartElement(null);
|
|
8752
8868
|
setSelectedImageId(null);
|
|
@@ -8938,6 +9054,41 @@ function useXlsxViewerController(options) {
|
|
|
8938
9054
|
return index;
|
|
8939
9055
|
});
|
|
8940
9056
|
}, [tabs]);
|
|
9057
|
+
const highlightRanges = React.useCallback((references, options2 = {}) => {
|
|
9058
|
+
const inputs = typeof references === "string" ? [references] : references;
|
|
9059
|
+
if (!Array.isArray(inputs) || isLoading || error) {
|
|
9060
|
+
return false;
|
|
9061
|
+
}
|
|
9062
|
+
const nextHighlights = [];
|
|
9063
|
+
let firstSheetIndex = activeSheetIndex;
|
|
9064
|
+
for (const reference of inputs) {
|
|
9065
|
+
const parsed = parseXlsxRange(reference);
|
|
9066
|
+
if (!parsed) {
|
|
9067
|
+
return false;
|
|
9068
|
+
}
|
|
9069
|
+
const requestedSheetName = parsed.sheetName?.toLowerCase();
|
|
9070
|
+
const sheetIndex = requestedSheetName === void 0 ? options2.sheetIndex ?? activeSheetIndex : sheets.findIndex((sheet2) => sheet2.name.toLowerCase() === requestedSheetName);
|
|
9071
|
+
const sheet = Number.isInteger(sheetIndex) ? sheets[sheetIndex] : void 0;
|
|
9072
|
+
if (!sheet) {
|
|
9073
|
+
return false;
|
|
9074
|
+
}
|
|
9075
|
+
if (nextHighlights.length === 0) {
|
|
9076
|
+
firstSheetIndex = sheetIndex;
|
|
9077
|
+
}
|
|
9078
|
+
nextHighlights.push({
|
|
9079
|
+
...parsed,
|
|
9080
|
+
autoScroll: nextHighlights.length === 0 && (options2.autoScroll ?? true),
|
|
9081
|
+
sheetName: sheet.name,
|
|
9082
|
+
workbookSheetIndex: sheet.workbookSheetIndex
|
|
9083
|
+
});
|
|
9084
|
+
}
|
|
9085
|
+
setHighlightedRanges(nextHighlights);
|
|
9086
|
+
if (nextHighlights[0]?.autoScroll) {
|
|
9087
|
+
setActiveSheetIndex(firstSheetIndex);
|
|
9088
|
+
}
|
|
9089
|
+
return true;
|
|
9090
|
+
}, [activeSheetIndex, error, isLoading, setActiveSheetIndex, sheets]);
|
|
9091
|
+
const clearHighlightedRanges = React.useCallback(() => setHighlightedRanges([]), []);
|
|
8941
9092
|
const setZoomScale = React.useCallback((nextZoomScale) => {
|
|
8942
9093
|
const normalizedZoomScale = clampZoomScale(nextZoomScale);
|
|
8943
9094
|
setZoomScaleOverridesByTabId((current) => {
|
|
@@ -9868,7 +10019,7 @@ function useXlsxViewerController(options) {
|
|
|
9868
10019
|
return;
|
|
9869
10020
|
}
|
|
9870
10021
|
const dataStartRow = targetTable.start.row + Math.max(targetTable.headerRowCount, 1);
|
|
9871
|
-
const totalsRowOffset = targetTable.
|
|
10022
|
+
const totalsRowOffset = targetTable.totalsRowCount;
|
|
9872
10023
|
const dataEndRow = targetTable.end.row - totalsRowOffset;
|
|
9873
10024
|
const startCol = targetTable.start.col;
|
|
9874
10025
|
const endCol = targetTable.end.col;
|
|
@@ -10996,6 +11147,9 @@ function useXlsxViewerController(options) {
|
|
|
10996
11147
|
clearSelectedCells,
|
|
10997
11148
|
clearSelectedImage,
|
|
10998
11149
|
clearSelection,
|
|
11150
|
+
clearHighlightedRanges,
|
|
11151
|
+
highlightRanges,
|
|
11152
|
+
highlightedRanges,
|
|
10999
11153
|
continueDeferredLoad,
|
|
11000
11154
|
copySelectionToClipboard,
|
|
11001
11155
|
defaultZoomScale,
|
|
@@ -11116,6 +11270,9 @@ function useXlsxViewerController(options) {
|
|
|
11116
11270
|
clearSelectedCells,
|
|
11117
11271
|
clearSelectedImage,
|
|
11118
11272
|
continueDeferredLoad,
|
|
11273
|
+
clearHighlightedRanges,
|
|
11274
|
+
highlightRanges,
|
|
11275
|
+
highlightedRanges,
|
|
11119
11276
|
copySelectionToClipboard,
|
|
11120
11277
|
defaultZoomScale,
|
|
11121
11278
|
deferredLoadFileSize,
|
|
@@ -11799,6 +11956,62 @@ function growScrollDisplayLimit(current, growth, maximum, readOnly) {
|
|
|
11799
11956
|
return readOnly ? Math.max(current, Math.min(maximum, nextLimit)) : nextLimit;
|
|
11800
11957
|
}
|
|
11801
11958
|
|
|
11959
|
+
// src/range-highlight.ts
|
|
11960
|
+
function expandHighlightedRange(range, mergedRanges) {
|
|
11961
|
+
const expanded = { start: { ...range.start }, end: { ...range.end } };
|
|
11962
|
+
let changed;
|
|
11963
|
+
do {
|
|
11964
|
+
changed = false;
|
|
11965
|
+
for (const merged of mergedRanges) {
|
|
11966
|
+
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) {
|
|
11967
|
+
continue;
|
|
11968
|
+
}
|
|
11969
|
+
const startRow = Math.min(expanded.start.row, merged.start.row);
|
|
11970
|
+
const startCol = Math.min(expanded.start.col, merged.start.col);
|
|
11971
|
+
const endRow = Math.max(expanded.end.row, merged.end.row);
|
|
11972
|
+
const endCol = Math.max(expanded.end.col, merged.end.col);
|
|
11973
|
+
if (startRow !== expanded.start.row || startCol !== expanded.start.col || endRow !== expanded.end.row || endCol !== expanded.end.col) {
|
|
11974
|
+
expanded.start = { row: startRow, col: startCol };
|
|
11975
|
+
expanded.end = { row: endRow, col: endCol };
|
|
11976
|
+
changed = true;
|
|
11977
|
+
}
|
|
11978
|
+
}
|
|
11979
|
+
} while (changed);
|
|
11980
|
+
return expanded;
|
|
11981
|
+
}
|
|
11982
|
+
function lowerBound(indices, value) {
|
|
11983
|
+
let low = 0;
|
|
11984
|
+
let high = indices.length;
|
|
11985
|
+
while (low < high) {
|
|
11986
|
+
const middle = low + high >>> 1;
|
|
11987
|
+
if (indices[middle] < value) {
|
|
11988
|
+
low = middle + 1;
|
|
11989
|
+
} else {
|
|
11990
|
+
high = middle;
|
|
11991
|
+
}
|
|
11992
|
+
}
|
|
11993
|
+
return low;
|
|
11994
|
+
}
|
|
11995
|
+
function getHighlightAxisExtent(indices, prefixSums, start, end) {
|
|
11996
|
+
const first = lowerBound(indices, start);
|
|
11997
|
+
const afterLast = lowerBound(indices, end + 1);
|
|
11998
|
+
if (first >= afterLast) {
|
|
11999
|
+
return null;
|
|
12000
|
+
}
|
|
12001
|
+
return { start: prefixSums[first] ?? 0, end: prefixSums[afterLast] ?? 0 };
|
|
12002
|
+
}
|
|
12003
|
+
function getHighlightScrollOffset(start, end, frozenExtent, viewportExtent, currentOffset) {
|
|
12004
|
+
if (end <= frozenExtent || viewportExtent <= frozenExtent) {
|
|
12005
|
+
return currentOffset;
|
|
12006
|
+
}
|
|
12007
|
+
const scrollableStart = Math.max(start, frozenExtent);
|
|
12008
|
+
const availableExtent = viewportExtent - frozenExtent;
|
|
12009
|
+
if (scrollableStart < currentOffset + frozenExtent || end - scrollableStart > availableExtent) {
|
|
12010
|
+
return Math.max(0, scrollableStart - frozenExtent);
|
|
12011
|
+
}
|
|
12012
|
+
return end > currentOffset + viewportExtent ? end - viewportExtent : currentOffset;
|
|
12013
|
+
}
|
|
12014
|
+
|
|
11802
12015
|
// src/chart-renderer.tsx
|
|
11803
12016
|
var import_d3_hierarchy = require("d3-hierarchy");
|
|
11804
12017
|
var import_d3_geo = require("d3-geo");
|
|
@@ -18607,6 +18820,17 @@ function resolveViewerPalette(isDark = false, headerBackgroundColor, headerTextC
|
|
|
18607
18820
|
|
|
18608
18821
|
// src/XlsxViewer.tsx
|
|
18609
18822
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
18823
|
+
var RANGE_HIGHLIGHT_STYLES = `
|
|
18824
|
+
:where(.react-xlsx-range-highlight) {
|
|
18825
|
+
background: var(--xlsx-highlight-fill, rgb(59 130 246 / 8%));
|
|
18826
|
+
border: var(--xlsx-highlight-border, var(--xlsx-highlight-default-border-width, 1px) solid #3b82f6);
|
|
18827
|
+
border-radius: var(--xlsx-highlight-radius, 2px);
|
|
18828
|
+
}
|
|
18829
|
+
:where(.react-xlsx-range-highlight[data-dark="true"]) {
|
|
18830
|
+
background: var(--xlsx-highlight-fill, rgb(147 197 253 / 12%));
|
|
18831
|
+
border: var(--xlsx-highlight-border, var(--xlsx-highlight-default-border-width, 1px) solid #93c5fd);
|
|
18832
|
+
}
|
|
18833
|
+
`;
|
|
18610
18834
|
var DEFAULT_ROW_HEIGHT2 = 24;
|
|
18611
18835
|
var DEFAULT_COL_WIDTH2 = 80;
|
|
18612
18836
|
var HEADER_HEIGHT = 24;
|
|
@@ -18959,7 +19183,8 @@ function applyCanvasBorderDash(context, style, width) {
|
|
|
18959
19183
|
context.setLineDash([]);
|
|
18960
19184
|
}
|
|
18961
19185
|
function strokeCanvasBorderSide(context, side, rect, border) {
|
|
18962
|
-
const
|
|
19186
|
+
const strokeWidth = border.style === "double" ? border.width / 3 : border.width;
|
|
19187
|
+
const halfWidth = strokeWidth / 2;
|
|
18963
19188
|
const left = rect.left;
|
|
18964
19189
|
const right = rect.left + rect.width;
|
|
18965
19190
|
const top = rect.top;
|
|
@@ -18985,8 +19210,8 @@ function strokeCanvasBorderSide(context, side, rect, border) {
|
|
|
18985
19210
|
context.stroke();
|
|
18986
19211
|
};
|
|
18987
19212
|
if (border.style === "double") {
|
|
18988
|
-
const inset =
|
|
18989
|
-
context.lineWidth =
|
|
19213
|
+
const inset = border.width - strokeWidth;
|
|
19214
|
+
context.lineWidth = strokeWidth;
|
|
18990
19215
|
context.setLineDash([]);
|
|
18991
19216
|
strokeLine(0);
|
|
18992
19217
|
strokeLine(inset);
|
|
@@ -21899,6 +22124,43 @@ function mergeResolvedCellStyle(base, overlay, options) {
|
|
|
21899
22124
|
}
|
|
21900
22125
|
return nextStyle;
|
|
21901
22126
|
}
|
|
22127
|
+
function resolveCellTableOverrides(rawStyle, sheet, row, col) {
|
|
22128
|
+
const styleId = sheet?.cellStyleIds?.[cellAddressToA12({ row, col })] ?? sheet?.rowStyleIds[row] ?? sheet?.colStyleIds[col];
|
|
22129
|
+
const declared = styleId === void 0 ? void 0 : sheet?.styleById[styleId]?.tableStyleOverrides;
|
|
22130
|
+
const overrides = {};
|
|
22131
|
+
const font = asRecord(rawStyle?.font);
|
|
22132
|
+
if (font) {
|
|
22133
|
+
const explicitFont = {};
|
|
22134
|
+
const fontDefaults = {
|
|
22135
|
+
name: "Calibri",
|
|
22136
|
+
size: 11,
|
|
22137
|
+
bold: false,
|
|
22138
|
+
italic: false,
|
|
22139
|
+
underline: "none",
|
|
22140
|
+
strikethrough: false,
|
|
22141
|
+
verticalAlign: "baseline"
|
|
22142
|
+
};
|
|
22143
|
+
for (const [key, value] of Object.entries(font)) {
|
|
22144
|
+
const isExplicit = declared ? Object.hasOwn(declared.font ?? {}, key) : key === "color" ? asRecord(value)?.colorType !== "auto" : value !== fontDefaults[key];
|
|
22145
|
+
if (isExplicit) {
|
|
22146
|
+
explicitFont[key] = value;
|
|
22147
|
+
}
|
|
22148
|
+
}
|
|
22149
|
+
overrides.font = explicitFont;
|
|
22150
|
+
}
|
|
22151
|
+
const fill = asRecord(rawStyle?.fill);
|
|
22152
|
+
if (fill && fill.fillType !== "none") {
|
|
22153
|
+
overrides.fill = fill;
|
|
22154
|
+
}
|
|
22155
|
+
const border = asRecord(rawStyle?.border);
|
|
22156
|
+
if (border) {
|
|
22157
|
+
overrides.border = Object.fromEntries(Object.entries(border).filter(([, edge]) => {
|
|
22158
|
+
const style = asRecord(edge)?.style;
|
|
22159
|
+
return typeof style === "string" && style !== "none";
|
|
22160
|
+
}));
|
|
22161
|
+
}
|
|
22162
|
+
return overrides;
|
|
22163
|
+
}
|
|
21902
22164
|
function resolveBorderEdgePriority(edge) {
|
|
21903
22165
|
const style = typeof edge?.style === "string" ? edge.style : "none";
|
|
21904
22166
|
const stylePriority = {
|
|
@@ -22027,7 +22289,7 @@ function resolveTableCellStyle(table, row, col, activeSheet) {
|
|
|
22027
22289
|
return null;
|
|
22028
22290
|
}
|
|
22029
22291
|
const headerRowCount = Math.max(table.headerRowCount, 1);
|
|
22030
|
-
const totalsRowCount = table.
|
|
22292
|
+
const totalsRowCount = table.totalsRowCount;
|
|
22031
22293
|
const headerEndRow = table.start.row + headerRowCount - 1;
|
|
22032
22294
|
const totalsStartRow = table.end.row - totalsRowCount + 1;
|
|
22033
22295
|
const bodyStartRow = headerEndRow + 1;
|
|
@@ -24098,6 +24360,7 @@ function XlsxGrid({
|
|
|
24098
24360
|
errorState,
|
|
24099
24361
|
fileTooLargeState,
|
|
24100
24362
|
getCellStyle,
|
|
24363
|
+
highlightClassName,
|
|
24101
24364
|
loadingComponent,
|
|
24102
24365
|
loadingState,
|
|
24103
24366
|
onFormControlAction,
|
|
@@ -24142,6 +24405,7 @@ function XlsxGrid({
|
|
|
24142
24405
|
getClipboardData,
|
|
24143
24406
|
getCellDisplayValue: getControllerCellDisplayValue,
|
|
24144
24407
|
getFormControlItems,
|
|
24408
|
+
highlightedRanges,
|
|
24145
24409
|
images,
|
|
24146
24410
|
shapes,
|
|
24147
24411
|
isLoadDeferred,
|
|
@@ -24188,6 +24452,7 @@ function XlsxGrid({
|
|
|
24188
24452
|
), [formControls, getFormControlItems]);
|
|
24189
24453
|
const canResizeHeaders = !readOnly || allowResizeInReadOnly;
|
|
24190
24454
|
const scrollRef = React4.useRef(null);
|
|
24455
|
+
const scrolledHighlightRef = React4.useRef(null);
|
|
24191
24456
|
const wrapperRef = React4.useRef(null);
|
|
24192
24457
|
const tableRef = React4.useRef(null);
|
|
24193
24458
|
const gridKeyboardActiveRef = React4.useRef(false);
|
|
@@ -24376,6 +24641,10 @@ function XlsxGrid({
|
|
|
24376
24641
|
const resolveMergeAnchorCell = React4.useCallback((cell) => {
|
|
24377
24642
|
return mergedSecondaryAnchorMap.get(`${cell.row}:${cell.col}`) ?? cell;
|
|
24378
24643
|
}, [mergedSecondaryAnchorMap]);
|
|
24644
|
+
const highlightedCellRanges = React4.useMemo(
|
|
24645
|
+
() => highlightedRanges.flatMap((highlight, index) => activeSheet?.workbookSheetIndex === highlight.workbookSheetIndex ? [{ highlight, index, range: expandHighlightedRange(highlight.range, activeSheet?.mergedRanges ?? mergedRegions) }] : []),
|
|
24646
|
+
[activeSheet?.mergedRanges, activeSheet?.workbookSheetIndex, highlightedRanges, mergedRegions]
|
|
24647
|
+
);
|
|
24379
24648
|
const normalizedSelection = React4.useMemo(() => selection ? normalizeRange2(selection) : null, [selection]);
|
|
24380
24649
|
const zoomFactor = React4.useMemo(() => Math.max(0.1, zoomScale / 100), [zoomScale]);
|
|
24381
24650
|
const previousZoomFactorRef = React4.useRef(zoomFactor);
|
|
@@ -24415,7 +24684,7 @@ function XlsxGrid({
|
|
|
24415
24684
|
frozenPaneRight: liveFrozenPaneRight
|
|
24416
24685
|
} = canvasLayoutMetricsRef.current;
|
|
24417
24686
|
const currentLiveGestureZoom = liveGestureZoomRef.current;
|
|
24418
|
-
const isLiveZooming2 = currentLiveGestureZoom !== null && zoomScale === currentLiveGestureZoom.baseZoomScale;
|
|
24687
|
+
const isLiveZooming2 = experimentalCanvas && currentLiveGestureZoom !== null && zoomScale === currentLiveGestureZoom.baseZoomScale;
|
|
24419
24688
|
const liveZoomScale2 = isLiveZooming2 ? Math.max(0.1, currentLiveGestureZoom.targetZoomScale / currentLiveGestureZoom.baseZoomScale) : 1;
|
|
24420
24689
|
const scrollDeltaX = paintedViewport.left - nextLiveViewport.left;
|
|
24421
24690
|
const scrollDeltaY = paintedViewport.top - nextLiveViewport.top;
|
|
@@ -25386,7 +25655,7 @@ function XlsxGrid({
|
|
|
25386
25655
|
}, [shouldUseDomVirtualizer, syncDrawingViewport, zoomFactor]);
|
|
25387
25656
|
React4.useLayoutEffect(() => {
|
|
25388
25657
|
syncDrawingViewport(scrollRef.current, { immediate: true });
|
|
25389
|
-
}, [activeSheet, activeTabIndex, displayColLimit, displayRowLimit, syncDrawingViewport, zoomFactor]);
|
|
25658
|
+
}, [activeSheet, activeTabIndex, displayColLimit, displayRowLimit, highlightedCellRanges, syncDrawingViewport, zoomFactor]);
|
|
25390
25659
|
React4.useLayoutEffect(() => {
|
|
25391
25660
|
const scroller = scrollRef.current;
|
|
25392
25661
|
if (!scroller) {
|
|
@@ -26344,7 +26613,10 @@ function XlsxGrid({
|
|
|
26344
26613
|
});
|
|
26345
26614
|
const targetTable = getTableAtCell(effectiveTables, targetRow, targetCol);
|
|
26346
26615
|
const targetTableStyle = resolveTableCellStyle(targetTable, targetRow, targetCol, activeSheet);
|
|
26347
|
-
const resolvedStyle = mergeResolvedCellStyle(
|
|
26616
|
+
const resolvedStyle = targetTableStyle ? mergeResolvedCellStyle(
|
|
26617
|
+
mergeResolvedCellStyle(targetRawStyle, targetTableStyle),
|
|
26618
|
+
resolveCellTableOverrides(targetRawStyle, activeSheet, targetRow, targetCol)
|
|
26619
|
+
) : targetRawStyle;
|
|
26348
26620
|
cellBaseRawStyleCacheRef.current.set(targetCacheKey, resolvedStyle);
|
|
26349
26621
|
return resolvedStyle;
|
|
26350
26622
|
};
|
|
@@ -26530,11 +26802,11 @@ function XlsxGrid({
|
|
|
26530
26802
|
if (textWidth > availableTextWidth) {
|
|
26531
26803
|
const baseFontSizePx = resolveCanvasFontSizePx(nextData.style, 12 * zoomFactor);
|
|
26532
26804
|
const minimumFontSizePx = Math.max(6 * zoomFactor, baseFontSizePx * 0.4);
|
|
26533
|
-
let
|
|
26805
|
+
let lowerBound2 = minimumFontSizePx;
|
|
26534
26806
|
let upperBound = baseFontSizePx;
|
|
26535
26807
|
let bestFontSizePx = minimumFontSizePx;
|
|
26536
|
-
while (upperBound -
|
|
26537
|
-
const candidateFontSizePx = (
|
|
26808
|
+
while (upperBound - lowerBound2 > 0.25) {
|
|
26809
|
+
const candidateFontSizePx = (lowerBound2 + upperBound) / 2;
|
|
26538
26810
|
const candidateStyle = {
|
|
26539
26811
|
...nextData.style,
|
|
26540
26812
|
font: void 0,
|
|
@@ -26543,7 +26815,7 @@ function XlsxGrid({
|
|
|
26543
26815
|
const candidateWidth = measureTextWidth(nextData.value, candidateStyle);
|
|
26544
26816
|
if (candidateWidth <= availableTextWidth) {
|
|
26545
26817
|
bestFontSizePx = candidateFontSizePx;
|
|
26546
|
-
|
|
26818
|
+
lowerBound2 = candidateFontSizePx;
|
|
26547
26819
|
} else {
|
|
26548
26820
|
upperBound = candidateFontSizePx;
|
|
26549
26821
|
}
|
|
@@ -26594,6 +26866,51 @@ function XlsxGrid({
|
|
|
26594
26866
|
};
|
|
26595
26867
|
}, [colIndexByActual, colPrefixSums, displayHeaderHeight, displayRowHeaderWidth, displayedSelection, rowIndexByActual, rowPrefixSums]);
|
|
26596
26868
|
const resolvedSelectionOverlay = selectionOverlay;
|
|
26869
|
+
const rangeHighlightRects = React4.useMemo(() => highlightedCellRanges.map(({ highlight, index, range }) => {
|
|
26870
|
+
const rows = getHighlightAxisExtent(visibleRows, rowPrefixSums, range.start.row, range.end.row);
|
|
26871
|
+
const cols = getHighlightAxisExtent(visibleCols, colPrefixSums, range.start.col, range.end.col);
|
|
26872
|
+
return {
|
|
26873
|
+
highlight,
|
|
26874
|
+
index,
|
|
26875
|
+
range,
|
|
26876
|
+
rect: rows && cols ? {
|
|
26877
|
+
height: rows.end - rows.start,
|
|
26878
|
+
left: displayRowHeaderWidth + cols.start,
|
|
26879
|
+
top: displayHeaderHeight + rows.start,
|
|
26880
|
+
width: cols.end - cols.start
|
|
26881
|
+
} : null
|
|
26882
|
+
};
|
|
26883
|
+
}), [colPrefixSums, displayHeaderHeight, displayRowHeaderWidth, highlightedCellRanges, rowPrefixSums, visibleCols, visibleRows]);
|
|
26884
|
+
React4.useEffect(() => {
|
|
26885
|
+
let requiredRows = 0;
|
|
26886
|
+
let requiredCols = 0;
|
|
26887
|
+
for (const { highlight, range } of highlightedCellRanges) {
|
|
26888
|
+
if (highlight.kind !== "columns") {
|
|
26889
|
+
requiredRows = Math.max(requiredRows, Math.min(XLSX_MAX_ROWS, range.end.row + OPEN_GRID_ROW_PADDING + 1));
|
|
26890
|
+
}
|
|
26891
|
+
if (highlight.kind !== "rows") {
|
|
26892
|
+
requiredCols = Math.max(requiredCols, Math.min(XLSX_MAX_COLUMNS, range.end.col + OPEN_GRID_COL_PADDING + 1));
|
|
26893
|
+
}
|
|
26894
|
+
}
|
|
26895
|
+
setDisplayRowLimit((current) => Math.max(current, requiredRows));
|
|
26896
|
+
setDisplayColLimit((current) => Math.max(current, requiredCols));
|
|
26897
|
+
}, [activeSheet?.maxUsedCol, activeSheet?.maxUsedRow, highlightedCellRanges, activeSheetIndex, isWorkerBacked]);
|
|
26898
|
+
React4.useEffect(() => {
|
|
26899
|
+
const scroller = scrollRef.current;
|
|
26900
|
+
const target = rangeHighlightRects.find(({ highlight: highlight2 }) => highlight2.autoScroll);
|
|
26901
|
+
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) {
|
|
26902
|
+
return;
|
|
26903
|
+
}
|
|
26904
|
+
const { highlight, rect } = target;
|
|
26905
|
+
if (highlight.kind !== "columns") {
|
|
26906
|
+
scroller.scrollTop = getHighlightScrollOffset(rect.top, rect.top + rect.height, frozenPaneBottom, scroller.clientHeight, scroller.scrollTop);
|
|
26907
|
+
}
|
|
26908
|
+
if (highlight.kind !== "rows") {
|
|
26909
|
+
scroller.scrollLeft = getHighlightScrollOffset(rect.left, rect.left + rect.width, frozenPaneRight, scroller.clientWidth, scroller.scrollLeft);
|
|
26910
|
+
}
|
|
26911
|
+
scrolledHighlightRef.current = highlight;
|
|
26912
|
+
syncDrawingViewport(scroller, { immediate: true });
|
|
26913
|
+
}, [displayColLimit, displayRowLimit, drawingViewport.height, drawingViewport.width, frozenPaneBottom, frozenPaneRight, isLoading, rangeHighlightRects, syncDrawingViewport]);
|
|
26597
26914
|
const { fill: selectionFill, header: selectionHeaderSurface, stroke: selectionStroke } = React4.useMemo(() => resolveSelectionColors({
|
|
26598
26915
|
palette,
|
|
26599
26916
|
selectionColor,
|
|
@@ -28670,6 +28987,14 @@ function XlsxGrid({
|
|
|
28670
28987
|
hasPendingGridlinePath = false;
|
|
28671
28988
|
};
|
|
28672
28989
|
const drawnMergedAnchorKeys = /* @__PURE__ */ new Set();
|
|
28990
|
+
const deferredDoubleBorders = [];
|
|
28991
|
+
const drawCellBorder = (side, rect, border) => {
|
|
28992
|
+
if (border.style === "double") {
|
|
28993
|
+
deferredDoubleBorders.push({ side, rect, border });
|
|
28994
|
+
} else {
|
|
28995
|
+
strokeCanvasBorderSide(paneContext, side, rect, border);
|
|
28996
|
+
}
|
|
28997
|
+
};
|
|
28673
28998
|
for (const rowItem of paneAxisItems.rows) {
|
|
28674
28999
|
for (const colItem of paneAxisItems.cols) {
|
|
28675
29000
|
const cell = { row: rowItem.actualRow, col: colItem.actualCol };
|
|
@@ -28816,16 +29141,24 @@ function XlsxGrid({
|
|
|
28816
29141
|
flushPendingGridlines();
|
|
28817
29142
|
}
|
|
28818
29143
|
if (topBorder && drawRowIndex === 0) {
|
|
28819
|
-
|
|
29144
|
+
drawCellBorder("top", localRect, topBorder);
|
|
28820
29145
|
}
|
|
28821
29146
|
if (resolvedRightBorder) {
|
|
28822
|
-
|
|
29147
|
+
if (resolvedRightBorder.style === "double" && resolvedRightBorder === rightNeighborLeftBorder) {
|
|
29148
|
+
drawCellBorder("left", { ...localRect, left: localRect.left + localRect.width }, resolvedRightBorder);
|
|
29149
|
+
} else {
|
|
29150
|
+
drawCellBorder("right", localRect, resolvedRightBorder);
|
|
29151
|
+
}
|
|
28823
29152
|
}
|
|
28824
29153
|
if (resolvedBottomBorder) {
|
|
28825
|
-
|
|
29154
|
+
if (resolvedBottomBorder.style === "double" && resolvedBottomBorder === bottomNeighborTopBorder) {
|
|
29155
|
+
drawCellBorder("top", { ...localRect, top: localRect.top + localRect.height }, resolvedBottomBorder);
|
|
29156
|
+
} else {
|
|
29157
|
+
drawCellBorder("bottom", localRect, resolvedBottomBorder);
|
|
29158
|
+
}
|
|
28826
29159
|
}
|
|
28827
29160
|
if (leftBorder && drawColIndex === 0) {
|
|
28828
|
-
|
|
29161
|
+
drawCellBorder("left", localRect, leftBorder);
|
|
28829
29162
|
}
|
|
28830
29163
|
if (cellData.chartHighlight) {
|
|
28831
29164
|
const highlightBorder = {
|
|
@@ -29098,6 +29431,9 @@ function XlsxGrid({
|
|
|
29098
29431
|
}
|
|
29099
29432
|
}
|
|
29100
29433
|
flushPendingGridlines();
|
|
29434
|
+
for (const { side, rect, border } of deferredDoubleBorders) {
|
|
29435
|
+
strokeCanvasBorderSide(paneContext, side, rect, border);
|
|
29436
|
+
}
|
|
29101
29437
|
}
|
|
29102
29438
|
for (const pane of cellPaneOrder) {
|
|
29103
29439
|
const paneContext = bodyContexts[pane];
|
|
@@ -29609,6 +29945,7 @@ function XlsxGrid({
|
|
|
29609
29945
|
backgroundColor: palette.headerSurface,
|
|
29610
29946
|
borderBottom: "none",
|
|
29611
29947
|
borderRight: "none",
|
|
29948
|
+
boxSizing: "border-box",
|
|
29612
29949
|
boxShadow: gutterSeparatorShadow,
|
|
29613
29950
|
color: palette.headerText,
|
|
29614
29951
|
fontSize: "11px",
|
|
@@ -31300,6 +31637,51 @@ function XlsxGrid({
|
|
|
31300
31637
|
width: "100%"
|
|
31301
31638
|
}
|
|
31302
31639
|
};
|
|
31640
|
+
const rangeHighlightNodes = rangeHighlightRects.flatMap(({ index, rect }) => rect ? [
|
|
31641
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
31642
|
+
"div",
|
|
31643
|
+
{
|
|
31644
|
+
"aria-hidden": "true",
|
|
31645
|
+
className: classNames("react-xlsx-range-highlight", highlightClassName),
|
|
31646
|
+
"data-dark": paletteIsDark(palette) ? "true" : void 0,
|
|
31647
|
+
"data-xlsx-range-highlight": index,
|
|
31648
|
+
style: {
|
|
31649
|
+
...rect,
|
|
31650
|
+
["--xlsx-highlight-default-border-width"]: `${selectionBorderWidth}px`,
|
|
31651
|
+
boxSizing: "border-box",
|
|
31652
|
+
pointerEvents: "none",
|
|
31653
|
+
position: "absolute",
|
|
31654
|
+
zIndex: maxDrawingOverlayZIndex + 1
|
|
31655
|
+
}
|
|
31656
|
+
},
|
|
31657
|
+
index
|
|
31658
|
+
)
|
|
31659
|
+
] : []);
|
|
31660
|
+
const drawingOverlayPanes = experimentalCanvas && hasCanvasDomDrawingOverlays || rangeHighlightNodes.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { ...canvasBodyViewportLayerStyle, zIndex: experimentalCanvas ? 23 : 34 }, children: [
|
|
31661
|
+
{ pane: "scroll", style: canvasScrollOverlayPaneStyle, ref: canvasScrollOverlayContentRef, left: -drawingViewport.left - frozenPaneRight, top: -drawingViewport.top - frozenPaneBottom },
|
|
31662
|
+
{ pane: "top", style: canvasTopOverlayPaneStyle, ref: canvasTopOverlayContentRef, left: -drawingViewport.left - frozenPaneRight, top: -displayHeaderHeight },
|
|
31663
|
+
{ pane: "left", style: canvasLeftOverlayPaneStyle, ref: canvasLeftOverlayContentRef, left: -displayRowHeaderWidth, top: -drawingViewport.top - frozenPaneBottom },
|
|
31664
|
+
{ pane: "corner", style: canvasCornerOverlayPaneStyle, ref: canvasCornerOverlayContentRef, left: -displayRowHeaderWidth, top: -displayHeaderHeight }
|
|
31665
|
+
].map(({ pane, style, ref, left, top }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
31666
|
+
"div",
|
|
31667
|
+
{
|
|
31668
|
+
ref,
|
|
31669
|
+
style: {
|
|
31670
|
+
height: sheetContentHeight,
|
|
31671
|
+
left: 0,
|
|
31672
|
+
pointerEvents: "none",
|
|
31673
|
+
position: "absolute",
|
|
31674
|
+
top: 0,
|
|
31675
|
+
transform: `translate(${left}px, ${top}px)`,
|
|
31676
|
+
transformOrigin: "0 0",
|
|
31677
|
+
width: totalWidth
|
|
31678
|
+
},
|
|
31679
|
+
children: [
|
|
31680
|
+
experimentalCanvas ? paneDrawingNodes[pane] : null,
|
|
31681
|
+
rangeHighlightNodes
|
|
31682
|
+
]
|
|
31683
|
+
}
|
|
31684
|
+
) }, pane)) }) : null;
|
|
31303
31685
|
const scrollerContent = /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
31304
31686
|
"div",
|
|
31305
31687
|
{
|
|
@@ -31333,6 +31715,7 @@ function XlsxGrid({
|
|
|
31333
31715
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: cornerOverlayStyle, children: paneDrawingNodes.corner }),
|
|
31334
31716
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: scrollOverlayStyle, children: paneDrawingNodes.scroll })
|
|
31335
31717
|
] }) : null,
|
|
31718
|
+
drawingOverlayPanes,
|
|
31336
31719
|
experimentalCanvas ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
31337
31720
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: canvasBodyViewportLayerStyle, children: [
|
|
31338
31721
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
@@ -31374,77 +31757,7 @@ function XlsxGrid({
|
|
|
31374
31757
|
onPointerDown: handleCanvasBodyPointerDown,
|
|
31375
31758
|
style: canvasCornerBodyStyle
|
|
31376
31759
|
}
|
|
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
|
|
31760
|
+
)
|
|
31448
31761
|
] }),
|
|
31449
31762
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: canvasHeaderViewportLayerStyle, children: [
|
|
31450
31763
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
@@ -31890,6 +32203,7 @@ function XlsxGrid({
|
|
|
31890
32203
|
}
|
|
31891
32204
|
function XlsxViewerInner({
|
|
31892
32205
|
allowResizeInReadOnly = false,
|
|
32206
|
+
autoScrollToHighlightedRanges = true,
|
|
31893
32207
|
className,
|
|
31894
32208
|
controller,
|
|
31895
32209
|
emptyState,
|
|
@@ -31902,6 +32216,8 @@ function XlsxViewerInner({
|
|
|
31902
32216
|
headerBackgroundColor,
|
|
31903
32217
|
headerTextColor,
|
|
31904
32218
|
height,
|
|
32219
|
+
highlightClassName,
|
|
32220
|
+
highlightedRanges,
|
|
31905
32221
|
isDark = false,
|
|
31906
32222
|
loadingComponent,
|
|
31907
32223
|
loadingState,
|
|
@@ -31924,6 +32240,26 @@ function XlsxViewerInner({
|
|
|
31924
32240
|
}) {
|
|
31925
32241
|
const palette = useViewerPalette(isDark, headerBackgroundColor, headerTextColor);
|
|
31926
32242
|
const { displayFileName, error } = controller;
|
|
32243
|
+
const appliedHighlightRef = React4.useRef(null);
|
|
32244
|
+
const { clearHighlightedRanges, file, highlightRanges, isLoading, sheets, src } = controller;
|
|
32245
|
+
React4.useEffect(() => {
|
|
32246
|
+
if (isLoading || highlightedRanges === void 0) {
|
|
32247
|
+
appliedHighlightRef.current = null;
|
|
32248
|
+
return;
|
|
32249
|
+
}
|
|
32250
|
+
if (highlightedRanges !== null && sheets.length === 0) {
|
|
32251
|
+
return;
|
|
32252
|
+
}
|
|
32253
|
+
const referenceKey = JSON.stringify(typeof highlightedRanges === "string" ? [highlightedRanges] : highlightedRanges ?? []);
|
|
32254
|
+
const previous = appliedHighlightRef.current;
|
|
32255
|
+
if (previous && previous.referenceKey === referenceKey && previous.autoScroll === autoScrollToHighlightedRanges && previous.file === file && previous.src === src && previous.clear === clearHighlightedRanges) {
|
|
32256
|
+
return;
|
|
32257
|
+
}
|
|
32258
|
+
appliedHighlightRef.current = { autoScroll: autoScrollToHighlightedRanges, clear: clearHighlightedRanges, file, referenceKey, src };
|
|
32259
|
+
if (highlightedRanges === null || !highlightRanges(highlightedRanges, { autoScroll: autoScrollToHighlightedRanges })) {
|
|
32260
|
+
clearHighlightedRanges();
|
|
32261
|
+
}
|
|
32262
|
+
}, [autoScrollToHighlightedRanges, clearHighlightedRanges, file, highlightRanges, highlightedRanges, isLoading, sheets.length, src]);
|
|
31927
32263
|
const customFileTooLarge = error instanceof XlsxFileSizeLimitExceededError ? renderCustomFileTooLarge(
|
|
31928
32264
|
fileTooLargeState,
|
|
31929
32265
|
{
|
|
@@ -31956,6 +32292,7 @@ function XlsxViewerInner({
|
|
|
31956
32292
|
width: "100%"
|
|
31957
32293
|
},
|
|
31958
32294
|
children: [
|
|
32295
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("style", { children: RANGE_HIGHLIGHT_STYLES }),
|
|
31959
32296
|
resolveToolbar(toolbar, showDefaultToolbar, controller, palette),
|
|
31960
32297
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { display: "flex", flex: 1, minHeight: 0, minWidth: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
31961
32298
|
XlsxGrid,
|
|
@@ -31969,6 +32306,7 @@ function XlsxViewerInner({
|
|
|
31969
32306
|
experimentalCanvas,
|
|
31970
32307
|
fileTooLargeState,
|
|
31971
32308
|
getCellStyle,
|
|
32309
|
+
highlightClassName,
|
|
31972
32310
|
loadingComponent,
|
|
31973
32311
|
loadingState,
|
|
31974
32312
|
onFormControlAction,
|
|
@@ -33126,6 +33464,7 @@ function DefaultXlsxToolbar() {
|
|
|
33126
33464
|
XlsxViewer,
|
|
33127
33465
|
XlsxViewerProvider,
|
|
33128
33466
|
initWasm,
|
|
33467
|
+
parseXlsxRange,
|
|
33129
33468
|
setWasmSource,
|
|
33130
33469
|
useXlsxViewer,
|
|
33131
33470
|
useXlsxViewerCharts,
|