@extend-ai/react-xlsx 0.7.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1244 -173
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -2
- package/dist/index.d.ts +30 -2
- package/dist/index.js +1243 -173
- package/dist/index.js.map +1 -1
- package/dist/xlsx-worker.js +64 -10
- package/dist/xlsx-worker.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -41,6 +41,7 @@ __export(index_exports, {
|
|
|
41
41
|
useXlsxViewerImages: () => useXlsxViewerImages,
|
|
42
42
|
useXlsxViewerSelection: () => useXlsxViewerSelection,
|
|
43
43
|
useXlsxViewerTables: () => useXlsxViewerTables,
|
|
44
|
+
useXlsxViewerThumbnails: () => useXlsxViewerThumbnails,
|
|
44
45
|
useXlsxViewerZoom: () => useXlsxViewerZoom
|
|
45
46
|
});
|
|
46
47
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -4267,13 +4268,36 @@ function parseWorkbookTableMetadata(archive, workbookSheets) {
|
|
|
4267
4268
|
}
|
|
4268
4269
|
return [{
|
|
4269
4270
|
displayName: tableNode.getAttribute("displayName") ?? void 0,
|
|
4271
|
+
headerRowCount: parseWorkbookTableCount(tableNode.getAttribute("headerRowCount"), 1),
|
|
4270
4272
|
headerRowCellStyle: tableNode.getAttribute("headerRowCellStyle") ?? void 0,
|
|
4271
4273
|
name: tableNode.getAttribute("name") ?? void 0,
|
|
4272
|
-
reference: tableNode.getAttribute("ref") ?? void 0
|
|
4274
|
+
reference: tableNode.getAttribute("ref") ?? void 0,
|
|
4275
|
+
totalsRowCount: parseWorkbookTableCount(tableNode.getAttribute("totalsRowCount"), 0),
|
|
4276
|
+
totalsRowShown: parseWorkbookTableBoolean(tableNode.getAttribute("totalsRowShown"), false)
|
|
4273
4277
|
}];
|
|
4274
4278
|
});
|
|
4275
4279
|
});
|
|
4276
4280
|
}
|
|
4281
|
+
function parseWorkbookTableCount(value, fallback) {
|
|
4282
|
+
if (value === null) {
|
|
4283
|
+
return fallback;
|
|
4284
|
+
}
|
|
4285
|
+
const parsed = Number.parseInt(value, 10);
|
|
4286
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : fallback;
|
|
4287
|
+
}
|
|
4288
|
+
function parseWorkbookTableBoolean(value, fallback) {
|
|
4289
|
+
if (value === null) {
|
|
4290
|
+
return fallback;
|
|
4291
|
+
}
|
|
4292
|
+
const normalized = value.trim().toLowerCase();
|
|
4293
|
+
if (normalized === "0" || normalized === "false" || normalized === "") {
|
|
4294
|
+
return false;
|
|
4295
|
+
}
|
|
4296
|
+
if (normalized === "1" || normalized === "true") {
|
|
4297
|
+
return true;
|
|
4298
|
+
}
|
|
4299
|
+
return fallback;
|
|
4300
|
+
}
|
|
4277
4301
|
function parseSqrefRanges(sqref) {
|
|
4278
4302
|
if (!sqref) {
|
|
4279
4303
|
return [];
|
|
@@ -6880,17 +6904,18 @@ function rangeContainsCell(range, cell) {
|
|
|
6880
6904
|
function mapWorksheetTables(worksheet, metadataForSheet) {
|
|
6881
6905
|
const rawTables = worksheet?.tables ?? [];
|
|
6882
6906
|
return rawTables.flatMap((table, index) => {
|
|
6883
|
-
const reference = typeof table.reference === "string" ? table.reference : "";
|
|
6884
|
-
const parsedRange = parseA1RangeReference2(reference);
|
|
6885
|
-
if (!parsedRange) {
|
|
6886
|
-
return [];
|
|
6887
|
-
}
|
|
6888
6907
|
const rawColumns = Array.isArray(table.columns) ? table.columns : [];
|
|
6889
6908
|
const rawName = typeof table.name === "string" ? table.name : `Table${index + 1}`;
|
|
6890
6909
|
const rawDisplayName = typeof table.displayName === "string" ? table.displayName : typeof table.name === "string" ? table.name : `Table ${index + 1}`;
|
|
6891
6910
|
const metadata = metadataForSheet?.find(
|
|
6892
|
-
(entry) => entry.name && entry.name === rawName || entry.displayName && entry.displayName === rawDisplayName || entry.reference && entry.reference === reference
|
|
6911
|
+
(entry) => entry.name && entry.name === rawName || entry.displayName && entry.displayName === rawDisplayName || entry.reference && entry.reference === table.reference
|
|
6893
6912
|
);
|
|
6913
|
+
const rawReference = typeof table.reference === "string" ? table.reference : "";
|
|
6914
|
+
const reference = metadata?.reference ?? rawReference;
|
|
6915
|
+
const parsedRange = parseA1RangeReference2(reference);
|
|
6916
|
+
if (!parsedRange) {
|
|
6917
|
+
return [];
|
|
6918
|
+
}
|
|
6894
6919
|
return [{
|
|
6895
6920
|
columns: rawColumns.map((column, columnIndex) => ({
|
|
6896
6921
|
id: typeof column.id === "number" ? column.id ?? columnIndex + 1 : columnIndex + 1,
|
|
@@ -6899,17 +6924,47 @@ function mapWorksheetTables(worksheet, metadataForSheet) {
|
|
|
6899
6924
|
})),
|
|
6900
6925
|
displayName: rawDisplayName,
|
|
6901
6926
|
end: parsedRange.end,
|
|
6902
|
-
headerRowCount:
|
|
6927
|
+
headerRowCount: metadata?.headerRowCount ?? resolveWorkbookTableCount(table.headerRowCount, 1),
|
|
6903
6928
|
headerRowCellStyle: metadata?.headerRowCellStyle,
|
|
6904
6929
|
name: rawName,
|
|
6905
6930
|
reference,
|
|
6906
6931
|
start: parsedRange.start,
|
|
6907
6932
|
styleInfo: table.styleInfo,
|
|
6908
|
-
totalsRowCount:
|
|
6909
|
-
totalsRowShown:
|
|
6933
|
+
totalsRowCount: metadata?.totalsRowCount ?? resolveWorkbookTableCount(table.totalsRowCount, 0),
|
|
6934
|
+
totalsRowShown: metadata?.totalsRowShown ?? resolveWorkbookTableBoolean(table.totalsRowShown)
|
|
6910
6935
|
}];
|
|
6911
6936
|
});
|
|
6912
6937
|
}
|
|
6938
|
+
function resolveWorkbookTableCount(value, fallback) {
|
|
6939
|
+
if (typeof value === "number" && Number.isFinite(value) && value >= 0) {
|
|
6940
|
+
return value;
|
|
6941
|
+
}
|
|
6942
|
+
if (typeof value === "string") {
|
|
6943
|
+
const parsed = Number.parseInt(value, 10);
|
|
6944
|
+
if (Number.isFinite(parsed) && parsed >= 0) {
|
|
6945
|
+
return parsed;
|
|
6946
|
+
}
|
|
6947
|
+
}
|
|
6948
|
+
return fallback;
|
|
6949
|
+
}
|
|
6950
|
+
function resolveWorkbookTableBoolean(value) {
|
|
6951
|
+
if (typeof value === "boolean") {
|
|
6952
|
+
return value;
|
|
6953
|
+
}
|
|
6954
|
+
if (typeof value === "number") {
|
|
6955
|
+
return value !== 0;
|
|
6956
|
+
}
|
|
6957
|
+
if (typeof value === "string") {
|
|
6958
|
+
const normalized = value.trim().toLowerCase();
|
|
6959
|
+
if (normalized === "0" || normalized === "false" || normalized === "") {
|
|
6960
|
+
return false;
|
|
6961
|
+
}
|
|
6962
|
+
if (normalized === "1" || normalized === "true") {
|
|
6963
|
+
return true;
|
|
6964
|
+
}
|
|
6965
|
+
}
|
|
6966
|
+
return false;
|
|
6967
|
+
}
|
|
6913
6968
|
function fileStem(fileName) {
|
|
6914
6969
|
const normalized = fileName.trim();
|
|
6915
6970
|
const lastDot = normalized.lastIndexOf(".");
|
|
@@ -7040,7 +7095,17 @@ async function resolveWorkbookBuffer({ file, src }, signal) {
|
|
|
7040
7095
|
if (file) {
|
|
7041
7096
|
buffer = file;
|
|
7042
7097
|
} else if (src) {
|
|
7043
|
-
|
|
7098
|
+
let response;
|
|
7099
|
+
try {
|
|
7100
|
+
response = await fetch(src, { signal });
|
|
7101
|
+
} catch (error) {
|
|
7102
|
+
if (isAbortError(error)) {
|
|
7103
|
+
throw error;
|
|
7104
|
+
}
|
|
7105
|
+
throw new Error(
|
|
7106
|
+
"Failed to fetch workbook. The remote URL may be blocked by CORS, unavailable, or not directly downloadable from the browser."
|
|
7107
|
+
);
|
|
7108
|
+
}
|
|
7044
7109
|
if (!response.ok) {
|
|
7045
7110
|
throw new Error(`Failed to fetch workbook (status ${response.status})`);
|
|
7046
7111
|
}
|
|
@@ -7596,6 +7661,7 @@ function downloadUrl(src, fileName) {
|
|
|
7596
7661
|
}
|
|
7597
7662
|
function useXlsxViewerController(options) {
|
|
7598
7663
|
const {
|
|
7664
|
+
allowResizeInReadOnly = false,
|
|
7599
7665
|
deferLoadingAboveBytes = DEFAULT_DEFER_LOADING_ABOVE_BYTES,
|
|
7600
7666
|
file,
|
|
7601
7667
|
fileName,
|
|
@@ -7649,6 +7715,7 @@ function useXlsxViewerController(options) {
|
|
|
7649
7715
|
const displayFileName = React.useMemo(() => resolveDisplayFileName(src, fileName), [fileName, src]);
|
|
7650
7716
|
const shouldDeferLoading = deferLoadingAboveBytes > 0;
|
|
7651
7717
|
const readOnly = requestedReadOnly || forcedReadOnly;
|
|
7718
|
+
const canResizeReadOnly = requestedReadOnly && allowResizeInReadOnly && !forcedReadOnly;
|
|
7652
7719
|
const workerSupported = useWorker && typeof Worker !== "undefined";
|
|
7653
7720
|
const shouldUseWorker = workerSupported && forcedReadOnly;
|
|
7654
7721
|
const shouldForceReadOnlyForBuffer = React.useCallback((bufferByteLength) => !requestedReadOnly && readOnlyAboveBytes > 0 && bufferByteLength > readOnlyAboveBytes, [readOnlyAboveBytes, requestedReadOnly]);
|
|
@@ -8943,7 +9010,7 @@ function useXlsxViewerController(options) {
|
|
|
8943
9010
|
refreshWorkbookState(workbook);
|
|
8944
9011
|
}, [refreshWorkbookState, workbook]);
|
|
8945
9012
|
const resizeColumn = React.useCallback((col, widthPx) => {
|
|
8946
|
-
if (readOnly || !workbook || !activeSheet) {
|
|
9013
|
+
if (readOnly && !canResizeReadOnly || !workbook || !activeSheet) {
|
|
8947
9014
|
return;
|
|
8948
9015
|
}
|
|
8949
9016
|
recordHistoryBeforeMutation();
|
|
@@ -8953,9 +9020,9 @@ function useXlsxViewerController(options) {
|
|
|
8953
9020
|
pxToSheetColumnWidth(resolveContentSheetAxisPixels(widthPx, activeSheet.showGridLines))
|
|
8954
9021
|
);
|
|
8955
9022
|
refreshWorkbookState(workbook);
|
|
8956
|
-
}, [activeSheet, readOnly, recordHistoryBeforeMutation, refreshWorkbookState, workbook]);
|
|
9023
|
+
}, [activeSheet, canResizeReadOnly, readOnly, recordHistoryBeforeMutation, refreshWorkbookState, workbook]);
|
|
8957
9024
|
const resizeRow = React.useCallback((row, heightPx) => {
|
|
8958
|
-
if (readOnly || !workbook || !activeSheet) {
|
|
9025
|
+
if (readOnly && !canResizeReadOnly || !workbook || !activeSheet) {
|
|
8959
9026
|
return;
|
|
8960
9027
|
}
|
|
8961
9028
|
recordHistoryBeforeMutation();
|
|
@@ -8965,7 +9032,7 @@ function useXlsxViewerController(options) {
|
|
|
8965
9032
|
pxToSheetRowHeight(resolveContentSheetAxisPixels(heightPx, activeSheet.showGridLines))
|
|
8966
9033
|
);
|
|
8967
9034
|
refreshWorkbookState(workbook);
|
|
8968
|
-
}, [activeSheet, readOnly, recordHistoryBeforeMutation, refreshWorkbookState, workbook]);
|
|
9035
|
+
}, [activeSheet, canResizeReadOnly, readOnly, recordHistoryBeforeMutation, refreshWorkbookState, workbook]);
|
|
8969
9036
|
const resolveAnchoredObjectRect = React.useCallback((anchor, worksheet) => {
|
|
8970
9037
|
const resolveAxisSum = (index, getSize) => {
|
|
8971
9038
|
let total = 0;
|
|
@@ -16348,6 +16415,13 @@ var IMAGE_MIN_SIZE_PX = 16;
|
|
|
16348
16415
|
var IMAGE_HANDLE_SIZE_PX = 10;
|
|
16349
16416
|
var CANVAS_RESIZE_HIT_SLOP_PX = 8;
|
|
16350
16417
|
var CANVAS_VIEWPORT_OVERSCAN_PX = 240;
|
|
16418
|
+
var THUMBNAIL_DEFAULT_MAX_DIMENSION = 192;
|
|
16419
|
+
var THUMBNAIL_FALLBACK_ROWS = 12;
|
|
16420
|
+
var THUMBNAIL_FALLBACK_COLS = 8;
|
|
16421
|
+
var THUMBNAIL_MAX_ROWS = 200;
|
|
16422
|
+
var THUMBNAIL_MAX_COLS = 80;
|
|
16423
|
+
var THUMBNAIL_MAX_SOURCE_HEIGHT_PX = 900;
|
|
16424
|
+
var THUMBNAIL_MAX_SOURCE_WIDTH_PX = 1440;
|
|
16351
16425
|
var LIVE_ZOOM_COMMIT_IDLE_MS = 48;
|
|
16352
16426
|
var WHEEL_ZOOM_SENSITIVITY = 25e-5;
|
|
16353
16427
|
var WHEEL_LINE_DELTA_PX = 16;
|
|
@@ -18354,6 +18428,97 @@ function resolveImageHandleStyle(position, stroke, surface, scale = 1) {
|
|
|
18354
18428
|
function useViewerPalette(isDark = false) {
|
|
18355
18429
|
return isDark ? DARK_PALETTE : LIGHT_PALETTE;
|
|
18356
18430
|
}
|
|
18431
|
+
function normalizeThumbnailResolution(resolution) {
|
|
18432
|
+
if (typeof resolution === "number" && Number.isFinite(resolution) && resolution > 0) {
|
|
18433
|
+
return {
|
|
18434
|
+
maxHeight: resolution,
|
|
18435
|
+
maxWidth: resolution
|
|
18436
|
+
};
|
|
18437
|
+
}
|
|
18438
|
+
const resolvedObject = typeof resolution === "object" && resolution ? resolution : void 0;
|
|
18439
|
+
return {
|
|
18440
|
+
maxHeight: resolvedObject?.maxHeight && Number.isFinite(resolvedObject.maxHeight) && resolvedObject.maxHeight > 0 ? resolvedObject.maxHeight : THUMBNAIL_DEFAULT_MAX_DIMENSION,
|
|
18441
|
+
maxWidth: resolvedObject?.maxWidth && Number.isFinite(resolvedObject.maxWidth) && resolvedObject.maxWidth > 0 ? resolvedObject.maxWidth : THUMBNAIL_DEFAULT_MAX_DIMENSION
|
|
18442
|
+
};
|
|
18443
|
+
}
|
|
18444
|
+
function resolveThumbnailOutputSize(sourceWidth, sourceHeight, resolution) {
|
|
18445
|
+
const normalized = normalizeThumbnailResolution(resolution);
|
|
18446
|
+
const safeSourceWidth = Math.max(1, sourceWidth);
|
|
18447
|
+
const safeSourceHeight = Math.max(1, sourceHeight);
|
|
18448
|
+
const scale = Math.min(
|
|
18449
|
+
normalized.maxWidth / safeSourceWidth,
|
|
18450
|
+
normalized.maxHeight / safeSourceHeight,
|
|
18451
|
+
1
|
|
18452
|
+
);
|
|
18453
|
+
return {
|
|
18454
|
+
height: Math.max(1, Math.round(safeSourceHeight * scale)),
|
|
18455
|
+
maxHeight: normalized.maxHeight,
|
|
18456
|
+
maxWidth: normalized.maxWidth,
|
|
18457
|
+
scale,
|
|
18458
|
+
width: Math.max(1, Math.round(safeSourceWidth * scale))
|
|
18459
|
+
};
|
|
18460
|
+
}
|
|
18461
|
+
function resolveThumbnailAxisIndices({
|
|
18462
|
+
fallbackCount,
|
|
18463
|
+
getSizePx,
|
|
18464
|
+
maxCount,
|
|
18465
|
+
maxLogicalPixels,
|
|
18466
|
+
maxUsedIndex,
|
|
18467
|
+
minUsedIndex,
|
|
18468
|
+
precomputed
|
|
18469
|
+
}) {
|
|
18470
|
+
const sourceIndices = precomputed.length > 0 ? precomputed : Array.from({
|
|
18471
|
+
length: Math.max(fallbackCount, Math.max(0, maxUsedIndex + 1))
|
|
18472
|
+
}, (_, index) => index);
|
|
18473
|
+
const hasUsedRange = maxUsedIndex >= minUsedIndex && maxUsedIndex >= 0;
|
|
18474
|
+
const preferredStart = hasUsedRange ? Math.max(0, minUsedIndex) : 0;
|
|
18475
|
+
const preferredEnd = hasUsedRange ? maxUsedIndex : Math.max(0, preferredStart + fallbackCount - 1);
|
|
18476
|
+
const picked = [];
|
|
18477
|
+
let totalSize = 0;
|
|
18478
|
+
for (const actualIndex of sourceIndices) {
|
|
18479
|
+
if (actualIndex < preferredStart) {
|
|
18480
|
+
continue;
|
|
18481
|
+
}
|
|
18482
|
+
if (hasUsedRange && actualIndex > preferredEnd) {
|
|
18483
|
+
break;
|
|
18484
|
+
}
|
|
18485
|
+
const size = Math.max(1, getSizePx(actualIndex));
|
|
18486
|
+
picked.push(actualIndex);
|
|
18487
|
+
totalSize += size;
|
|
18488
|
+
if (picked.length >= maxCount || totalSize >= maxLogicalPixels) {
|
|
18489
|
+
break;
|
|
18490
|
+
}
|
|
18491
|
+
}
|
|
18492
|
+
if (picked.length > 0) {
|
|
18493
|
+
return picked;
|
|
18494
|
+
}
|
|
18495
|
+
for (const actualIndex of sourceIndices) {
|
|
18496
|
+
const size = Math.max(1, getSizePx(actualIndex));
|
|
18497
|
+
picked.push(actualIndex);
|
|
18498
|
+
totalSize += size;
|
|
18499
|
+
if (picked.length >= fallbackCount || picked.length >= maxCount || totalSize >= maxLogicalPixels) {
|
|
18500
|
+
break;
|
|
18501
|
+
}
|
|
18502
|
+
}
|
|
18503
|
+
return picked.length > 0 ? picked : [0];
|
|
18504
|
+
}
|
|
18505
|
+
function buildThumbnailAxisItems(actualIndices, getSizePx) {
|
|
18506
|
+
const items = [];
|
|
18507
|
+
let offset = 0;
|
|
18508
|
+
for (const actualIndex of actualIndices) {
|
|
18509
|
+
const size = Math.max(1, getSizePx(actualIndex));
|
|
18510
|
+
items.push({
|
|
18511
|
+
actualIndex,
|
|
18512
|
+
size,
|
|
18513
|
+
start: offset
|
|
18514
|
+
});
|
|
18515
|
+
offset += size;
|
|
18516
|
+
}
|
|
18517
|
+
return {
|
|
18518
|
+
items,
|
|
18519
|
+
totalSize: offset
|
|
18520
|
+
};
|
|
18521
|
+
}
|
|
18357
18522
|
function columnLabel2(col) {
|
|
18358
18523
|
let label = "";
|
|
18359
18524
|
let nextValue = col;
|
|
@@ -19260,7 +19425,6 @@ function getTableHeaderColumn(table, row, col) {
|
|
|
19260
19425
|
return table.columns[index] ?? null;
|
|
19261
19426
|
}
|
|
19262
19427
|
function DefaultTableHeaderMenu({
|
|
19263
|
-
close,
|
|
19264
19428
|
direction,
|
|
19265
19429
|
sortAscending,
|
|
19266
19430
|
sortDescending
|
|
@@ -19282,10 +19446,7 @@ function DefaultTableHeaderMenu({
|
|
|
19282
19446
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
19283
19447
|
"button",
|
|
19284
19448
|
{
|
|
19285
|
-
onClick:
|
|
19286
|
-
sortAscending();
|
|
19287
|
-
close();
|
|
19288
|
-
},
|
|
19449
|
+
onClick: sortAscending,
|
|
19289
19450
|
style: {
|
|
19290
19451
|
background: direction === "ascending" ? "var(--xlsx-menu-active)" : "transparent",
|
|
19291
19452
|
border: "none",
|
|
@@ -19303,10 +19464,7 @@ function DefaultTableHeaderMenu({
|
|
|
19303
19464
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
19304
19465
|
"button",
|
|
19305
19466
|
{
|
|
19306
|
-
onClick:
|
|
19307
|
-
sortDescending();
|
|
19308
|
-
close();
|
|
19309
|
-
},
|
|
19467
|
+
onClick: sortDescending,
|
|
19310
19468
|
style: {
|
|
19311
19469
|
background: direction === "descending" ? "var(--xlsx-menu-active)" : "transparent",
|
|
19312
19470
|
border: "none",
|
|
@@ -19325,6 +19483,25 @@ function DefaultTableHeaderMenu({
|
|
|
19325
19483
|
}
|
|
19326
19484
|
);
|
|
19327
19485
|
}
|
|
19486
|
+
function resolveTableHeaderTriggerStyle(palette, zoomFactor) {
|
|
19487
|
+
return {
|
|
19488
|
+
alignItems: "center",
|
|
19489
|
+
background: "transparent",
|
|
19490
|
+
border: "none",
|
|
19491
|
+
color: palette.mutedText,
|
|
19492
|
+
cursor: "pointer",
|
|
19493
|
+
display: "inline-flex",
|
|
19494
|
+
fontSize: 10 * zoomFactor,
|
|
19495
|
+
height: 16 * zoomFactor,
|
|
19496
|
+
justifyContent: "center",
|
|
19497
|
+
padding: 0,
|
|
19498
|
+
position: "absolute",
|
|
19499
|
+
right: 4 * zoomFactor,
|
|
19500
|
+
top: 3 * zoomFactor,
|
|
19501
|
+
width: 16 * zoomFactor,
|
|
19502
|
+
zIndex: 6
|
|
19503
|
+
};
|
|
19504
|
+
}
|
|
19328
19505
|
function SegmentedControl({
|
|
19329
19506
|
items,
|
|
19330
19507
|
onValueChange,
|
|
@@ -19833,6 +20010,109 @@ function resolveSelectionColors({
|
|
|
19833
20010
|
stroke
|
|
19834
20011
|
};
|
|
19835
20012
|
}
|
|
20013
|
+
function buildFullCanvasDirtyRect(width, height) {
|
|
20014
|
+
if (width <= 0 || height <= 0) {
|
|
20015
|
+
return [];
|
|
20016
|
+
}
|
|
20017
|
+
return [{
|
|
20018
|
+
height,
|
|
20019
|
+
left: 0,
|
|
20020
|
+
top: 0,
|
|
20021
|
+
width
|
|
20022
|
+
}];
|
|
20023
|
+
}
|
|
20024
|
+
function intersectsCanvasDirtyRects(left, top, width, height, dirtyRects) {
|
|
20025
|
+
if (dirtyRects.length === 0 || width <= 0 || height <= 0) {
|
|
20026
|
+
return false;
|
|
20027
|
+
}
|
|
20028
|
+
const right = left + width;
|
|
20029
|
+
const bottom = top + height;
|
|
20030
|
+
return dirtyRects.some((dirtyRect) => left < dirtyRect.left + dirtyRect.width && right > dirtyRect.left && top < dirtyRect.top + dirtyRect.height && bottom > dirtyRect.top);
|
|
20031
|
+
}
|
|
20032
|
+
function blitCanvasWithScrollDelta(canvas, context, bufferCanvas, dpr, width, height, deltaX, deltaY) {
|
|
20033
|
+
if (width <= 0 || height <= 0) {
|
|
20034
|
+
return [];
|
|
20035
|
+
}
|
|
20036
|
+
const clampedDeltaX = Math.max(-width, Math.min(width, deltaX));
|
|
20037
|
+
const clampedDeltaY = Math.max(-height, Math.min(height, deltaY));
|
|
20038
|
+
if (Math.abs(clampedDeltaX) < 0.01 && Math.abs(clampedDeltaY) < 0.01) {
|
|
20039
|
+
return [];
|
|
20040
|
+
}
|
|
20041
|
+
if (Math.abs(clampedDeltaX) >= width || Math.abs(clampedDeltaY) >= height) {
|
|
20042
|
+
return null;
|
|
20043
|
+
}
|
|
20044
|
+
const deviceWidth = Math.max(1, Math.round(width * dpr));
|
|
20045
|
+
const deviceHeight = Math.max(1, Math.round(height * dpr));
|
|
20046
|
+
if (bufferCanvas.width !== deviceWidth) {
|
|
20047
|
+
bufferCanvas.width = deviceWidth;
|
|
20048
|
+
}
|
|
20049
|
+
if (bufferCanvas.height !== deviceHeight) {
|
|
20050
|
+
bufferCanvas.height = deviceHeight;
|
|
20051
|
+
}
|
|
20052
|
+
const bufferContext = bufferCanvas.getContext("2d");
|
|
20053
|
+
if (!bufferContext) {
|
|
20054
|
+
return null;
|
|
20055
|
+
}
|
|
20056
|
+
bufferContext.setTransform(1, 0, 0, 1, 0, 0);
|
|
20057
|
+
bufferContext.clearRect(0, 0, deviceWidth, deviceHeight);
|
|
20058
|
+
bufferContext.drawImage(canvas, 0, 0);
|
|
20059
|
+
const deltaDeviceX = clampedDeltaX * dpr;
|
|
20060
|
+
const deltaDeviceY = clampedDeltaY * dpr;
|
|
20061
|
+
const overlapDeviceWidth = deviceWidth - Math.abs(deltaDeviceX);
|
|
20062
|
+
const overlapDeviceHeight = deviceHeight - Math.abs(deltaDeviceY);
|
|
20063
|
+
if (overlapDeviceWidth <= 0 || overlapDeviceHeight <= 0) {
|
|
20064
|
+
return null;
|
|
20065
|
+
}
|
|
20066
|
+
const sourceX = deltaDeviceX > 0 ? deltaDeviceX : 0;
|
|
20067
|
+
const sourceY = deltaDeviceY > 0 ? deltaDeviceY : 0;
|
|
20068
|
+
const destinationX = deltaDeviceX > 0 ? 0 : -deltaDeviceX;
|
|
20069
|
+
const destinationY = deltaDeviceY > 0 ? 0 : -deltaDeviceY;
|
|
20070
|
+
context.setTransform(1, 0, 0, 1, 0, 0);
|
|
20071
|
+
context.drawImage(
|
|
20072
|
+
bufferCanvas,
|
|
20073
|
+
sourceX,
|
|
20074
|
+
sourceY,
|
|
20075
|
+
overlapDeviceWidth,
|
|
20076
|
+
overlapDeviceHeight,
|
|
20077
|
+
destinationX,
|
|
20078
|
+
destinationY,
|
|
20079
|
+
overlapDeviceWidth,
|
|
20080
|
+
overlapDeviceHeight
|
|
20081
|
+
);
|
|
20082
|
+
context.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
20083
|
+
const dirtyRects = [];
|
|
20084
|
+
if (clampedDeltaX > 0) {
|
|
20085
|
+
dirtyRects.push({
|
|
20086
|
+
height,
|
|
20087
|
+
left: Math.max(0, width - clampedDeltaX),
|
|
20088
|
+
top: 0,
|
|
20089
|
+
width: Math.min(width, clampedDeltaX)
|
|
20090
|
+
});
|
|
20091
|
+
} else if (clampedDeltaX < 0) {
|
|
20092
|
+
dirtyRects.push({
|
|
20093
|
+
height,
|
|
20094
|
+
left: 0,
|
|
20095
|
+
top: 0,
|
|
20096
|
+
width: Math.min(width, -clampedDeltaX)
|
|
20097
|
+
});
|
|
20098
|
+
}
|
|
20099
|
+
if (clampedDeltaY > 0) {
|
|
20100
|
+
dirtyRects.push({
|
|
20101
|
+
height: Math.min(height, clampedDeltaY),
|
|
20102
|
+
left: 0,
|
|
20103
|
+
top: Math.max(0, height - clampedDeltaY),
|
|
20104
|
+
width
|
|
20105
|
+
});
|
|
20106
|
+
} else if (clampedDeltaY < 0) {
|
|
20107
|
+
dirtyRects.push({
|
|
20108
|
+
height: Math.min(height, -clampedDeltaY),
|
|
20109
|
+
left: 0,
|
|
20110
|
+
top: 0,
|
|
20111
|
+
width
|
|
20112
|
+
});
|
|
20113
|
+
}
|
|
20114
|
+
return dirtyRects;
|
|
20115
|
+
}
|
|
19836
20116
|
function buildConditionalFormatRuleKey(rule) {
|
|
19837
20117
|
return `${rule.kind}:${rule.priority}:${rule.ranges.map((range) => `${range.start.row}:${range.start.col}-${range.end.row}:${range.end.col}`).join("|")}`;
|
|
19838
20118
|
}
|
|
@@ -20692,8 +20972,20 @@ function XlsxGrid({
|
|
|
20692
20972
|
const topBodyCanvasRef = React4.useRef(null);
|
|
20693
20973
|
const leftBodyCanvasRef = React4.useRef(null);
|
|
20694
20974
|
const cornerBodyCanvasRef = React4.useRef(null);
|
|
20695
|
-
const
|
|
20696
|
-
|
|
20975
|
+
const bodyBlitBufferCanvasRef = React4.useRef({
|
|
20976
|
+
corner: null,
|
|
20977
|
+
left: null,
|
|
20978
|
+
scroll: null,
|
|
20979
|
+
top: null
|
|
20980
|
+
});
|
|
20981
|
+
const headerBlitBufferCanvasRef = React4.useRef({
|
|
20982
|
+
left: null,
|
|
20983
|
+
top: null
|
|
20984
|
+
});
|
|
20985
|
+
const topFrozenHeaderCanvasRef = React4.useRef(null);
|
|
20986
|
+
const topScrollHeaderCanvasRef = React4.useRef(null);
|
|
20987
|
+
const leftFrozenHeaderCanvasRef = React4.useRef(null);
|
|
20988
|
+
const leftScrollHeaderCanvasRef = React4.useRef(null);
|
|
20697
20989
|
const cornerHeaderCanvasRef = React4.useRef(null);
|
|
20698
20990
|
const selectionOverlayRef = React4.useRef(null);
|
|
20699
20991
|
const activeValidationOverlayRef = React4.useRef(null);
|
|
@@ -20897,16 +21189,31 @@ function XlsxGrid({
|
|
|
20897
21189
|
liveZoomTranslateX2,
|
|
20898
21190
|
liveZoomTranslateY2
|
|
20899
21191
|
);
|
|
20900
|
-
|
|
20901
|
-
|
|
20902
|
-
|
|
20903
|
-
|
|
20904
|
-
|
|
20905
|
-
|
|
20906
|
-
|
|
20907
|
-
|
|
20908
|
-
|
|
20909
|
-
|
|
21192
|
+
applyCanvasTransform(
|
|
21193
|
+
topScrollHeaderCanvasRef.current,
|
|
21194
|
+
scrollDeltaX + liveZoomTranslateX2,
|
|
21195
|
+
liveZoomTranslateY2
|
|
21196
|
+
);
|
|
21197
|
+
applyCanvasTransform(
|
|
21198
|
+
topFrozenHeaderCanvasRef.current,
|
|
21199
|
+
liveZoomTranslateX2,
|
|
21200
|
+
liveZoomTranslateY2
|
|
21201
|
+
);
|
|
21202
|
+
applyCanvasTransform(
|
|
21203
|
+
leftScrollHeaderCanvasRef.current,
|
|
21204
|
+
liveZoomTranslateX2,
|
|
21205
|
+
scrollDeltaY + liveZoomTranslateY2
|
|
21206
|
+
);
|
|
21207
|
+
applyCanvasTransform(
|
|
21208
|
+
leftFrozenHeaderCanvasRef.current,
|
|
21209
|
+
liveZoomTranslateX2,
|
|
21210
|
+
liveZoomTranslateY2
|
|
21211
|
+
);
|
|
21212
|
+
applyCanvasTransform(
|
|
21213
|
+
cornerHeaderCanvasRef.current,
|
|
21214
|
+
liveZoomTranslateX2,
|
|
21215
|
+
liveZoomTranslateY2
|
|
21216
|
+
);
|
|
20910
21217
|
}, [zoomScale]);
|
|
20911
21218
|
const updateLiveGestureZoomState = React4.useCallback((nextState) => {
|
|
20912
21219
|
const resolvedState = typeof nextState === "function" ? nextState(liveGestureZoomRef.current) : nextState;
|
|
@@ -21037,6 +21344,22 @@ function XlsxGrid({
|
|
|
21037
21344
|
scrollRef.current.style.cursor = "";
|
|
21038
21345
|
}
|
|
21039
21346
|
}, []);
|
|
21347
|
+
const getBodyBlitBufferCanvas = React4.useCallback((pane) => {
|
|
21348
|
+
let bufferCanvas = bodyBlitBufferCanvasRef.current[pane];
|
|
21349
|
+
if (!bufferCanvas && typeof document !== "undefined") {
|
|
21350
|
+
bufferCanvas = document.createElement("canvas");
|
|
21351
|
+
bodyBlitBufferCanvasRef.current[pane] = bufferCanvas;
|
|
21352
|
+
}
|
|
21353
|
+
return bufferCanvas;
|
|
21354
|
+
}, []);
|
|
21355
|
+
const getHeaderBlitBufferCanvas = React4.useCallback((axis) => {
|
|
21356
|
+
let bufferCanvas = headerBlitBufferCanvasRef.current[axis];
|
|
21357
|
+
if (!bufferCanvas && typeof document !== "undefined") {
|
|
21358
|
+
bufferCanvas = document.createElement("canvas");
|
|
21359
|
+
headerBlitBufferCanvasRef.current[axis] = bufferCanvas;
|
|
21360
|
+
}
|
|
21361
|
+
return bufferCanvas;
|
|
21362
|
+
}, []);
|
|
21040
21363
|
const visibleRows = React4.useMemo(() => {
|
|
21041
21364
|
return buildVisibleAxisIndices(
|
|
21042
21365
|
activeSheet?.visibleRows ?? [],
|
|
@@ -21751,14 +22074,14 @@ function XlsxGrid({
|
|
|
21751
22074
|
const handleScrollerScroll = React4.useCallback((event) => {
|
|
21752
22075
|
const currentScroller = event.currentTarget;
|
|
21753
22076
|
cachedScrollerRectRef.current = null;
|
|
21754
|
-
syncDrawingViewport(currentScroller, { immediate:
|
|
22077
|
+
syncDrawingViewport(currentScroller, { immediate: true });
|
|
21755
22078
|
if (currentScroller.scrollHeight - (currentScroller.scrollTop + currentScroller.clientHeight) < OPEN_GRID_VERTICAL_EDGE_PX) {
|
|
21756
22079
|
setDisplayRowLimit((current) => current + OPEN_GRID_ROW_GROWTH);
|
|
21757
22080
|
}
|
|
21758
22081
|
if (currentScroller.scrollWidth - (currentScroller.scrollLeft + currentScroller.clientWidth) < OPEN_GRID_HORIZONTAL_EDGE_PX) {
|
|
21759
22082
|
setDisplayColLimit((current) => current + OPEN_GRID_COL_GROWTH);
|
|
21760
22083
|
}
|
|
21761
|
-
}, [
|
|
22084
|
+
}, [syncDrawingViewport]);
|
|
21762
22085
|
React4.useEffect(() => {
|
|
21763
22086
|
const scroller = scrollRef.current;
|
|
21764
22087
|
if (!scroller || !enableGestureZoom) {
|
|
@@ -23539,6 +23862,30 @@ function XlsxGrid({
|
|
|
23539
23862
|
return null;
|
|
23540
23863
|
}
|
|
23541
23864
|
const direction = sortState && sortState.tableName === table.name && sortState.columnIndex === tableColumn.index ? sortState.direction : null;
|
|
23865
|
+
const triggerIcon = direction === "ascending" ? "\u25B2" : direction === "descending" ? "\u25BC" : "\u25BE";
|
|
23866
|
+
if (renderTableHeaderMenu) {
|
|
23867
|
+
return renderTableHeaderMenu({
|
|
23868
|
+
cell,
|
|
23869
|
+
column: tableColumn,
|
|
23870
|
+
direction,
|
|
23871
|
+
sortAscending: () => sortTable(table.name, tableColumn.index, "ascending"),
|
|
23872
|
+
sortDescending: () => sortTable(table.name, tableColumn.index, "descending"),
|
|
23873
|
+
table,
|
|
23874
|
+
triggerIcon,
|
|
23875
|
+
triggerProps: {
|
|
23876
|
+
"aria-haspopup": "menu",
|
|
23877
|
+
"aria-label": `Open menu for ${tableColumn.name}`,
|
|
23878
|
+
onClick: (event) => {
|
|
23879
|
+
event.stopPropagation();
|
|
23880
|
+
},
|
|
23881
|
+
onPointerDown: (event) => {
|
|
23882
|
+
event.stopPropagation();
|
|
23883
|
+
},
|
|
23884
|
+
style: resolveTableHeaderTriggerStyle(palette, zoomFactor),
|
|
23885
|
+
type: "button"
|
|
23886
|
+
}
|
|
23887
|
+
});
|
|
23888
|
+
}
|
|
23542
23889
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
23543
23890
|
"button",
|
|
23544
23891
|
{
|
|
@@ -23554,27 +23901,13 @@ function XlsxGrid({
|
|
|
23554
23901
|
);
|
|
23555
23902
|
},
|
|
23556
23903
|
style: {
|
|
23557
|
-
|
|
23558
|
-
background: "transparent",
|
|
23559
|
-
border: "none",
|
|
23560
|
-
color: palette.mutedText,
|
|
23561
|
-
cursor: "pointer",
|
|
23562
|
-
display: "inline-flex",
|
|
23563
|
-
fontSize: 10 * zoomFactor,
|
|
23564
|
-
height: 16 * zoomFactor,
|
|
23565
|
-
justifyContent: "center",
|
|
23566
|
-
padding: 0,
|
|
23567
|
-
position: "absolute",
|
|
23568
|
-
right: 4 * zoomFactor,
|
|
23569
|
-
top: 3 * zoomFactor,
|
|
23570
|
-
width: 16 * zoomFactor,
|
|
23571
|
-
zIndex: 6
|
|
23904
|
+
...resolveTableHeaderTriggerStyle(palette, zoomFactor)
|
|
23572
23905
|
},
|
|
23573
23906
|
type: "button",
|
|
23574
|
-
children:
|
|
23907
|
+
children: triggerIcon
|
|
23575
23908
|
}
|
|
23576
23909
|
);
|
|
23577
|
-
}, [effectiveTables, palette
|
|
23910
|
+
}, [effectiveTables, palette, renderTableHeaderMenu, sortState, sortTable, zoomFactor]);
|
|
23578
23911
|
const resolveCanvasColumnHeaderRect = React4.useCallback((actualCol) => {
|
|
23579
23912
|
const colIndex = colIndexByActual.get(actualCol);
|
|
23580
23913
|
if (colIndex === void 0) {
|
|
@@ -23613,6 +23946,54 @@ function XlsxGrid({
|
|
|
23613
23946
|
rowPrefixSums,
|
|
23614
23947
|
stickyTopByRow
|
|
23615
23948
|
]);
|
|
23949
|
+
const canvasColumnHeaderCells = React4.useMemo(
|
|
23950
|
+
() => canvasVisibleColItems.flatMap((column) => {
|
|
23951
|
+
const rect = resolveCanvasColumnHeaderRect(column.actualCol);
|
|
23952
|
+
if (!rect) {
|
|
23953
|
+
return [];
|
|
23954
|
+
}
|
|
23955
|
+
const isFrozen = stickyLeftByCol.has(column.actualCol);
|
|
23956
|
+
return [{
|
|
23957
|
+
actualCol: column.actualCol,
|
|
23958
|
+
height: displayHeaderHeight,
|
|
23959
|
+
isFrozen,
|
|
23960
|
+
left: rect.left,
|
|
23961
|
+
localLeft: rect.left - (isFrozen ? displayRowHeaderWidth : frozenPaneRight),
|
|
23962
|
+
width: rect.width
|
|
23963
|
+
}];
|
|
23964
|
+
}),
|
|
23965
|
+
[
|
|
23966
|
+
canvasVisibleColItems,
|
|
23967
|
+
displayHeaderHeight,
|
|
23968
|
+
displayRowHeaderWidth,
|
|
23969
|
+
frozenPaneRight,
|
|
23970
|
+
resolveCanvasColumnHeaderRect,
|
|
23971
|
+
stickyLeftByCol
|
|
23972
|
+
]
|
|
23973
|
+
);
|
|
23974
|
+
const canvasRowHeaderCells = React4.useMemo(
|
|
23975
|
+
() => canvasVisibleRowItems.flatMap((row) => {
|
|
23976
|
+
const rect = resolveCanvasRowHeaderRect(row.actualRow);
|
|
23977
|
+
if (!rect) {
|
|
23978
|
+
return [];
|
|
23979
|
+
}
|
|
23980
|
+
const isFrozen = stickyTopByRow.has(row.actualRow);
|
|
23981
|
+
return [{
|
|
23982
|
+
actualRow: row.actualRow,
|
|
23983
|
+
height: rect.height,
|
|
23984
|
+
isFrozen,
|
|
23985
|
+
localTop: rect.top - (isFrozen ? displayHeaderHeight : frozenPaneBottom),
|
|
23986
|
+
top: rect.top
|
|
23987
|
+
}];
|
|
23988
|
+
}),
|
|
23989
|
+
[
|
|
23990
|
+
canvasVisibleRowItems,
|
|
23991
|
+
displayHeaderHeight,
|
|
23992
|
+
frozenPaneBottom,
|
|
23993
|
+
resolveCanvasRowHeaderRect,
|
|
23994
|
+
stickyTopByRow
|
|
23995
|
+
]
|
|
23996
|
+
);
|
|
23616
23997
|
const resolveCanvasColumnResizeTarget = React4.useCallback((clientX) => {
|
|
23617
23998
|
if (!canResizeHeaders) {
|
|
23618
23999
|
return null;
|
|
@@ -23622,17 +24003,26 @@ function XlsxGrid({
|
|
|
23622
24003
|
return null;
|
|
23623
24004
|
}
|
|
23624
24005
|
const localX = clientX - scrollerRect.left;
|
|
23625
|
-
for (const column of
|
|
23626
|
-
|
|
23627
|
-
|
|
23628
|
-
continue;
|
|
24006
|
+
for (const column of canvasColumnHeaderCells) {
|
|
24007
|
+
if (Math.abs(localX - (column.left + column.width)) <= CANVAS_RESIZE_HIT_SLOP_PX) {
|
|
24008
|
+
return { actualCol: column.actualCol, width: column.width };
|
|
23629
24009
|
}
|
|
23630
|
-
|
|
23631
|
-
|
|
24010
|
+
}
|
|
24011
|
+
return null;
|
|
24012
|
+
}, [canResizeHeaders, canvasColumnHeaderCells]);
|
|
24013
|
+
const resolveCanvasColumnHeaderTarget = React4.useCallback((clientX) => {
|
|
24014
|
+
const scrollerRect = scrollRef.current?.getBoundingClientRect();
|
|
24015
|
+
if (!scrollerRect) {
|
|
24016
|
+
return null;
|
|
24017
|
+
}
|
|
24018
|
+
const localX = clientX - scrollerRect.left;
|
|
24019
|
+
for (const column of canvasColumnHeaderCells) {
|
|
24020
|
+
if (localX >= column.left && localX <= column.left + column.width) {
|
|
24021
|
+
return column.actualCol;
|
|
23632
24022
|
}
|
|
23633
24023
|
}
|
|
23634
24024
|
return null;
|
|
23635
|
-
}, [
|
|
24025
|
+
}, [canvasColumnHeaderCells]);
|
|
23636
24026
|
const resolveCanvasRowResizeTarget = React4.useCallback((clientY) => {
|
|
23637
24027
|
if (!canResizeHeaders) {
|
|
23638
24028
|
return null;
|
|
@@ -23642,17 +24032,26 @@ function XlsxGrid({
|
|
|
23642
24032
|
return null;
|
|
23643
24033
|
}
|
|
23644
24034
|
const localY = clientY - scrollerRect.top;
|
|
23645
|
-
for (const row of
|
|
23646
|
-
|
|
23647
|
-
|
|
23648
|
-
continue;
|
|
24035
|
+
for (const row of canvasRowHeaderCells) {
|
|
24036
|
+
if (Math.abs(localY - (row.top + row.height)) <= CANVAS_RESIZE_HIT_SLOP_PX) {
|
|
24037
|
+
return { actualRow: row.actualRow, height: row.height };
|
|
23649
24038
|
}
|
|
23650
|
-
|
|
23651
|
-
|
|
24039
|
+
}
|
|
24040
|
+
return null;
|
|
24041
|
+
}, [canResizeHeaders, canvasRowHeaderCells]);
|
|
24042
|
+
const resolveCanvasRowHeaderTarget = React4.useCallback((clientY) => {
|
|
24043
|
+
const scrollerRect = scrollRef.current?.getBoundingClientRect();
|
|
24044
|
+
if (!scrollerRect) {
|
|
24045
|
+
return null;
|
|
24046
|
+
}
|
|
24047
|
+
const localY = clientY - scrollerRect.top;
|
|
24048
|
+
for (const row of canvasRowHeaderCells) {
|
|
24049
|
+
if (localY >= row.top && localY <= row.top + row.height) {
|
|
24050
|
+
return row.actualRow;
|
|
23652
24051
|
}
|
|
23653
24052
|
}
|
|
23654
24053
|
return null;
|
|
23655
|
-
}, [
|
|
24054
|
+
}, [canvasRowHeaderCells]);
|
|
23656
24055
|
const handleCanvasColumnHeaderPointerMove = React4.useCallback((event) => {
|
|
23657
24056
|
if (resizeStateRef.current?.type === "column") {
|
|
23658
24057
|
event.currentTarget.style.cursor = "col-resize";
|
|
@@ -23755,17 +24154,17 @@ function XlsxGrid({
|
|
|
23755
24154
|
startColumnResize(event.pointerId, resizeTarget.actualCol, resizeTarget.width, event.clientX);
|
|
23756
24155
|
return;
|
|
23757
24156
|
}
|
|
23758
|
-
const
|
|
23759
|
-
if (
|
|
24157
|
+
const actualCol = resolveCanvasColumnHeaderTarget(event.clientX);
|
|
24158
|
+
if (actualCol === null) {
|
|
23760
24159
|
return;
|
|
23761
24160
|
}
|
|
23762
24161
|
event.preventDefault();
|
|
23763
24162
|
focusGrid();
|
|
23764
24163
|
const currentSelection = selectionRef.current;
|
|
23765
|
-
const anchorCol = event.shiftKey && currentSelection ? currentSelection.start.col :
|
|
24164
|
+
const anchorCol = event.shiftKey && currentSelection ? currentSelection.start.col : actualCol;
|
|
23766
24165
|
const initialRange = normalizeRange2({
|
|
23767
24166
|
start: { row: firstVisibleRow, col: anchorCol },
|
|
23768
|
-
end: { row: lastVisibleRow, col:
|
|
24167
|
+
end: { row: lastVisibleRow, col: actualCol }
|
|
23769
24168
|
});
|
|
23770
24169
|
const anchorColIndex = colIndexByActual.get(anchorCol);
|
|
23771
24170
|
if (anchorColIndex === void 0) {
|
|
@@ -23775,7 +24174,7 @@ function XlsxGrid({
|
|
|
23775
24174
|
event.pointerId,
|
|
23776
24175
|
{ row: firstVisibleRow, col: anchorCol },
|
|
23777
24176
|
"column",
|
|
23778
|
-
{ row: firstVisibleRow, col:
|
|
24177
|
+
{ row: firstVisibleRow, col: actualCol },
|
|
23779
24178
|
{
|
|
23780
24179
|
contentScaleX: 1,
|
|
23781
24180
|
contentScaleY: 1,
|
|
@@ -23796,9 +24195,8 @@ function XlsxGrid({
|
|
|
23796
24195
|
firstVisibleRow,
|
|
23797
24196
|
focusGrid,
|
|
23798
24197
|
lastVisibleRow,
|
|
23799
|
-
|
|
24198
|
+
resolveCanvasColumnHeaderTarget,
|
|
23800
24199
|
resolveCanvasColumnResizeTarget,
|
|
23801
|
-
resolvePointerCellFromClient,
|
|
23802
24200
|
rowPrefixSums,
|
|
23803
24201
|
startCellSelection
|
|
23804
24202
|
]);
|
|
@@ -23813,17 +24211,17 @@ function XlsxGrid({
|
|
|
23813
24211
|
startRowResize(event.pointerId, resizeTarget.actualRow, resizeTarget.height, event.clientY);
|
|
23814
24212
|
return;
|
|
23815
24213
|
}
|
|
23816
|
-
const
|
|
23817
|
-
if (
|
|
24214
|
+
const actualRow = resolveCanvasRowHeaderTarget(event.clientY);
|
|
24215
|
+
if (actualRow === null) {
|
|
23818
24216
|
return;
|
|
23819
24217
|
}
|
|
23820
24218
|
event.preventDefault();
|
|
23821
24219
|
focusGrid();
|
|
23822
24220
|
const currentSelection = selectionRef.current;
|
|
23823
|
-
const anchorRow = event.shiftKey && currentSelection ? currentSelection.start.row :
|
|
24221
|
+
const anchorRow = event.shiftKey && currentSelection ? currentSelection.start.row : actualRow;
|
|
23824
24222
|
const initialRange = normalizeRange2({
|
|
23825
24223
|
start: { row: anchorRow, col: firstVisibleCol },
|
|
23826
|
-
end: { row:
|
|
24224
|
+
end: { row: actualRow, col: lastVisibleCol }
|
|
23827
24225
|
});
|
|
23828
24226
|
const anchorRowIndex = rowIndexByActual.get(anchorRow);
|
|
23829
24227
|
if (anchorRowIndex === void 0) {
|
|
@@ -23833,7 +24231,7 @@ function XlsxGrid({
|
|
|
23833
24231
|
event.pointerId,
|
|
23834
24232
|
{ row: anchorRow, col: firstVisibleCol },
|
|
23835
24233
|
"row",
|
|
23836
|
-
{ row:
|
|
24234
|
+
{ row: actualRow, col: firstVisibleCol },
|
|
23837
24235
|
{
|
|
23838
24236
|
contentScaleX: 1,
|
|
23839
24237
|
contentScaleY: 1,
|
|
@@ -23853,8 +24251,8 @@ function XlsxGrid({
|
|
|
23853
24251
|
firstVisibleCol,
|
|
23854
24252
|
focusGrid,
|
|
23855
24253
|
lastVisibleCol,
|
|
24254
|
+
resolveCanvasRowHeaderTarget,
|
|
23856
24255
|
resolveCanvasRowResizeTarget,
|
|
23857
|
-
resolvePointerCellFromClient,
|
|
23858
24256
|
rowIndexByActual,
|
|
23859
24257
|
rowPrefixSums,
|
|
23860
24258
|
startCellSelection
|
|
@@ -23864,7 +24262,7 @@ function XlsxGrid({
|
|
|
23864
24262
|
return;
|
|
23865
24263
|
}
|
|
23866
24264
|
const dpr = typeof window === "undefined" ? 1 : Math.max(1, window.devicePixelRatio || 1);
|
|
23867
|
-
function configureCanvas(canvas, width, height) {
|
|
24265
|
+
function configureCanvas(canvas, width, height, options) {
|
|
23868
24266
|
if (!canvas) {
|
|
23869
24267
|
return null;
|
|
23870
24268
|
}
|
|
@@ -23887,7 +24285,9 @@ function XlsxGrid({
|
|
|
23887
24285
|
return null;
|
|
23888
24286
|
}
|
|
23889
24287
|
context.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
23890
|
-
|
|
24288
|
+
if (options?.clear !== false) {
|
|
24289
|
+
context.clearRect(0, 0, width, height);
|
|
24290
|
+
}
|
|
23891
24291
|
return context;
|
|
23892
24292
|
}
|
|
23893
24293
|
const bodyWidth = Math.max(0, drawingViewport.width);
|
|
@@ -23919,12 +24319,24 @@ function XlsxGrid({
|
|
|
23919
24319
|
rangeSignature,
|
|
23920
24320
|
rowHeaderWidth,
|
|
23921
24321
|
rowSignature: nextBodyCanvasSignature.rowSignature,
|
|
24322
|
+
viewportLeft: drawingViewport.left,
|
|
24323
|
+
viewportTop: drawingViewport.top,
|
|
23922
24324
|
zoomFactor
|
|
23923
24325
|
};
|
|
23924
24326
|
const previousBodyCanvasSignature = paintedBodyCanvasSignatureRef.current;
|
|
23925
24327
|
const previousHeaderCanvasSignature = paintedHeaderCanvasSignatureRef.current;
|
|
24328
|
+
const previousPaintedViewport = paintedDrawingViewportRef.current;
|
|
23926
24329
|
const shouldRepaintBody = !(previousBodyCanvasSignature && previousBodyCanvasSignature.activeSheet === nextBodyCanvasSignature.activeSheet && previousBodyCanvasSignature.bodyHeight === nextBodyCanvasSignature.bodyHeight && previousBodyCanvasSignature.bodyWidth === nextBodyCanvasSignature.bodyWidth && previousBodyCanvasSignature.colSignature === nextBodyCanvasSignature.colSignature && previousBodyCanvasSignature.getCellData === nextBodyCanvasSignature.getCellData && previousBodyCanvasSignature.headerHeight === nextBodyCanvasSignature.headerHeight && previousBodyCanvasSignature.palette === nextBodyCanvasSignature.palette && previousBodyCanvasSignature.rowHeaderWidth === nextBodyCanvasSignature.rowHeaderWidth && previousBodyCanvasSignature.rowSignature === nextBodyCanvasSignature.rowSignature && previousBodyCanvasSignature.zoomFactor === nextBodyCanvasSignature.zoomFactor);
|
|
23927
|
-
const shouldRepaintHeaders = !(previousHeaderCanvasSignature && previousHeaderCanvasSignature.activeSheet === nextHeaderCanvasSignature.activeSheet && previousHeaderCanvasSignature.bodyHeight === nextHeaderCanvasSignature.bodyHeight && previousHeaderCanvasSignature.bodyWidth === nextHeaderCanvasSignature.bodyWidth && previousHeaderCanvasSignature.colSignature === nextHeaderCanvasSignature.colSignature && previousHeaderCanvasSignature.headerHeight === nextHeaderCanvasSignature.headerHeight && previousHeaderCanvasSignature.palette === nextHeaderCanvasSignature.palette && previousHeaderCanvasSignature.rangeSignature === nextHeaderCanvasSignature.rangeSignature && previousHeaderCanvasSignature.rowHeaderWidth === nextHeaderCanvasSignature.rowHeaderWidth && previousHeaderCanvasSignature.rowSignature === nextHeaderCanvasSignature.rowSignature && previousHeaderCanvasSignature.zoomFactor === nextHeaderCanvasSignature.zoomFactor);
|
|
24330
|
+
const shouldRepaintHeaders = !(previousHeaderCanvasSignature && previousHeaderCanvasSignature.activeSheet === nextHeaderCanvasSignature.activeSheet && previousHeaderCanvasSignature.bodyHeight === nextHeaderCanvasSignature.bodyHeight && previousHeaderCanvasSignature.bodyWidth === nextHeaderCanvasSignature.bodyWidth && previousHeaderCanvasSignature.colSignature === nextHeaderCanvasSignature.colSignature && previousHeaderCanvasSignature.headerHeight === nextHeaderCanvasSignature.headerHeight && previousHeaderCanvasSignature.palette === nextHeaderCanvasSignature.palette && previousHeaderCanvasSignature.rangeSignature === nextHeaderCanvasSignature.rangeSignature && previousHeaderCanvasSignature.rowHeaderWidth === nextHeaderCanvasSignature.rowHeaderWidth && previousHeaderCanvasSignature.rowSignature === nextHeaderCanvasSignature.rowSignature && previousHeaderCanvasSignature.viewportLeft === nextHeaderCanvasSignature.viewportLeft && previousHeaderCanvasSignature.viewportTop === nextHeaderCanvasSignature.viewportTop && previousHeaderCanvasSignature.zoomFactor === nextHeaderCanvasSignature.zoomFactor);
|
|
24331
|
+
const canBlitBody = Boolean(
|
|
24332
|
+
shouldRepaintBody && previousBodyCanvasSignature && previousBodyCanvasSignature.activeSheet === nextBodyCanvasSignature.activeSheet && previousBodyCanvasSignature.bodyHeight === nextBodyCanvasSignature.bodyHeight && previousBodyCanvasSignature.bodyWidth === nextBodyCanvasSignature.bodyWidth && previousBodyCanvasSignature.getCellData === nextBodyCanvasSignature.getCellData && previousBodyCanvasSignature.headerHeight === nextBodyCanvasSignature.headerHeight && previousBodyCanvasSignature.palette === nextBodyCanvasSignature.palette && previousBodyCanvasSignature.rowHeaderWidth === nextBodyCanvasSignature.rowHeaderWidth && previousBodyCanvasSignature.zoomFactor === nextBodyCanvasSignature.zoomFactor
|
|
24333
|
+
);
|
|
24334
|
+
const canBlitTopHeader = Boolean(
|
|
24335
|
+
shouldRepaintHeaders && previousHeaderCanvasSignature && previousHeaderCanvasSignature.activeSheet === nextHeaderCanvasSignature.activeSheet && previousHeaderCanvasSignature.bodyHeight === nextHeaderCanvasSignature.bodyHeight && previousHeaderCanvasSignature.bodyWidth === nextHeaderCanvasSignature.bodyWidth && previousHeaderCanvasSignature.headerHeight === nextHeaderCanvasSignature.headerHeight && previousHeaderCanvasSignature.palette === nextHeaderCanvasSignature.palette && previousHeaderCanvasSignature.rangeSignature === nextHeaderCanvasSignature.rangeSignature && previousHeaderCanvasSignature.rowHeaderWidth === nextHeaderCanvasSignature.rowHeaderWidth && previousHeaderCanvasSignature.zoomFactor === nextHeaderCanvasSignature.zoomFactor
|
|
24336
|
+
);
|
|
24337
|
+
const canBlitLeftHeader = Boolean(
|
|
24338
|
+
shouldRepaintHeaders && previousHeaderCanvasSignature && previousHeaderCanvasSignature.activeSheet === nextHeaderCanvasSignature.activeSheet && previousHeaderCanvasSignature.bodyHeight === nextHeaderCanvasSignature.bodyHeight && previousHeaderCanvasSignature.bodyWidth === nextHeaderCanvasSignature.bodyWidth && previousHeaderCanvasSignature.headerHeight === nextHeaderCanvasSignature.headerHeight && previousHeaderCanvasSignature.palette === nextHeaderCanvasSignature.palette && previousHeaderCanvasSignature.rangeSignature === nextHeaderCanvasSignature.rangeSignature && previousHeaderCanvasSignature.rowHeaderWidth === nextHeaderCanvasSignature.rowHeaderWidth && previousHeaderCanvasSignature.zoomFactor === nextHeaderCanvasSignature.zoomFactor
|
|
24339
|
+
);
|
|
23928
24340
|
if (!shouldRepaintBody && !shouldRepaintHeaders) {
|
|
23929
24341
|
return;
|
|
23930
24342
|
}
|
|
@@ -23936,6 +24348,10 @@ function XlsxGrid({
|
|
|
23936
24348
|
const leftBodyCanvasHeight2 = scrollBodyCanvasHeight2;
|
|
23937
24349
|
const cornerBodyCanvasWidth2 = leftBodyCanvasWidth2;
|
|
23938
24350
|
const cornerBodyCanvasHeight2 = topBodyCanvasHeight2;
|
|
24351
|
+
const topFrozenHeaderCanvasWidth2 = leftBodyCanvasWidth2;
|
|
24352
|
+
const topScrollHeaderCanvasWidth2 = scrollBodyCanvasWidth2;
|
|
24353
|
+
const leftFrozenHeaderCanvasHeight2 = topBodyCanvasHeight2;
|
|
24354
|
+
const leftScrollHeaderCanvasHeight2 = scrollBodyCanvasHeight2;
|
|
23939
24355
|
const paneBounds = {
|
|
23940
24356
|
corner: {
|
|
23941
24357
|
height: cornerBodyCanvasHeight2,
|
|
@@ -23963,29 +24379,50 @@ function XlsxGrid({
|
|
|
23963
24379
|
}
|
|
23964
24380
|
};
|
|
23965
24381
|
const bodyContexts = shouldRepaintBody ? {
|
|
23966
|
-
corner: configureCanvas(cornerBodyCanvasRef.current, cornerBodyCanvasWidth2, cornerBodyCanvasHeight2),
|
|
23967
|
-
left: configureCanvas(leftBodyCanvasRef.current, leftBodyCanvasWidth2, leftBodyCanvasHeight2),
|
|
23968
|
-
scroll: configureCanvas(scrollBodyCanvasRef.current, scrollBodyCanvasWidth2, scrollBodyCanvasHeight2),
|
|
23969
|
-
top: configureCanvas(topBodyCanvasRef.current, topBodyCanvasWidth2, topBodyCanvasHeight2)
|
|
24382
|
+
corner: configureCanvas(cornerBodyCanvasRef.current, cornerBodyCanvasWidth2, cornerBodyCanvasHeight2, { clear: !canBlitBody }),
|
|
24383
|
+
left: configureCanvas(leftBodyCanvasRef.current, leftBodyCanvasWidth2, leftBodyCanvasHeight2, { clear: !canBlitBody }),
|
|
24384
|
+
scroll: configureCanvas(scrollBodyCanvasRef.current, scrollBodyCanvasWidth2, scrollBodyCanvasHeight2, { clear: !canBlitBody }),
|
|
24385
|
+
top: configureCanvas(topBodyCanvasRef.current, topBodyCanvasWidth2, topBodyCanvasHeight2, { clear: !canBlitBody })
|
|
23970
24386
|
} : {
|
|
23971
24387
|
corner: null,
|
|
23972
24388
|
left: null,
|
|
23973
24389
|
scroll: null,
|
|
23974
24390
|
top: null
|
|
23975
24391
|
};
|
|
23976
|
-
const
|
|
23977
|
-
|
|
24392
|
+
const topHeaderContexts = shouldRepaintHeaders ? {
|
|
24393
|
+
frozen: configureCanvas(topFrozenHeaderCanvasRef.current, topFrozenHeaderCanvasWidth2, headerHeight),
|
|
24394
|
+
scroll: configureCanvas(topScrollHeaderCanvasRef.current, topScrollHeaderCanvasWidth2, headerHeight, { clear: !canBlitTopHeader })
|
|
24395
|
+
} : {
|
|
24396
|
+
frozen: null,
|
|
24397
|
+
scroll: null
|
|
24398
|
+
};
|
|
24399
|
+
const leftHeaderContexts = shouldRepaintHeaders ? {
|
|
24400
|
+
frozen: configureCanvas(leftFrozenHeaderCanvasRef.current, rowHeaderWidth, leftFrozenHeaderCanvasHeight2),
|
|
24401
|
+
scroll: configureCanvas(leftScrollHeaderCanvasRef.current, rowHeaderWidth, leftScrollHeaderCanvasHeight2, { clear: !canBlitLeftHeader })
|
|
24402
|
+
} : {
|
|
24403
|
+
frozen: null,
|
|
24404
|
+
scroll: null
|
|
24405
|
+
};
|
|
23978
24406
|
const cornerContext = shouldRepaintHeaders ? configureCanvas(cornerHeaderCanvasRef.current, rowHeaderWidth, headerHeight) : null;
|
|
23979
|
-
if (shouldRepaintBody && (!bodyContexts.scroll || !bodyContexts.top || !bodyContexts.left || !bodyContexts.corner) || shouldRepaintHeaders && (!
|
|
24407
|
+
if (shouldRepaintBody && (!bodyContexts.scroll || !bodyContexts.top || !bodyContexts.left || !bodyContexts.corner) || shouldRepaintHeaders && (!cornerContext || topFrozenHeaderCanvasWidth2 > 0 && !topHeaderContexts.frozen || topScrollHeaderCanvasWidth2 > 0 && !topHeaderContexts.scroll || leftFrozenHeaderCanvasHeight2 > 0 && !leftHeaderContexts.frozen || leftScrollHeaderCanvasHeight2 > 0 && !leftHeaderContexts.scroll)) {
|
|
23980
24408
|
return;
|
|
23981
24409
|
}
|
|
23982
24410
|
const showGridLines = activeSheet?.showGridLines ?? true;
|
|
24411
|
+
const sheetSurface = resolveSheetSurface(activeSheet, palette);
|
|
23983
24412
|
const deferredSpillTextsByPane = {
|
|
23984
24413
|
corner: [],
|
|
23985
24414
|
left: [],
|
|
23986
24415
|
scroll: [],
|
|
23987
24416
|
top: []
|
|
23988
24417
|
};
|
|
24418
|
+
const bodyDirtyRectsByPane = {
|
|
24419
|
+
corner: [],
|
|
24420
|
+
left: [],
|
|
24421
|
+
scroll: [],
|
|
24422
|
+
top: []
|
|
24423
|
+
};
|
|
24424
|
+
let topScrollHeaderDirtyRects = buildFullCanvasDirtyRect(topScrollHeaderCanvasWidth2, headerHeight);
|
|
24425
|
+
let leftScrollHeaderDirtyRects = buildFullCanvasDirtyRect(rowHeaderWidth, leftScrollHeaderCanvasHeight2);
|
|
23989
24426
|
const cellPaneOrder = ["scroll", "top", "left", "corner"];
|
|
23990
24427
|
if (shouldRepaintBody) {
|
|
23991
24428
|
for (const pane of Object.keys(bodyContexts)) {
|
|
@@ -23994,14 +24431,44 @@ function XlsxGrid({
|
|
|
23994
24431
|
if (!context || bounds.width <= 0 || bounds.height <= 0) {
|
|
23995
24432
|
continue;
|
|
23996
24433
|
}
|
|
23997
|
-
|
|
23998
|
-
|
|
24434
|
+
let dirtyRects = buildFullCanvasDirtyRect(bounds.width, bounds.height);
|
|
24435
|
+
if (canBlitBody) {
|
|
24436
|
+
const bufferCanvas = getBodyBlitBufferCanvas(pane);
|
|
24437
|
+
const deltaX = pane === "scroll" || pane === "top" ? drawingViewport.left - previousPaintedViewport.left : 0;
|
|
24438
|
+
const deltaY = pane === "scroll" || pane === "left" ? drawingViewport.top - previousPaintedViewport.top : 0;
|
|
24439
|
+
if (bufferCanvas) {
|
|
24440
|
+
const blittedDirtyRects = blitCanvasWithScrollDelta(
|
|
24441
|
+
pane === "corner" ? cornerBodyCanvasRef.current : pane === "left" ? leftBodyCanvasRef.current : pane === "top" ? topBodyCanvasRef.current : scrollBodyCanvasRef.current,
|
|
24442
|
+
context,
|
|
24443
|
+
bufferCanvas,
|
|
24444
|
+
dpr,
|
|
24445
|
+
bounds.width,
|
|
24446
|
+
bounds.height,
|
|
24447
|
+
deltaX,
|
|
24448
|
+
deltaY
|
|
24449
|
+
);
|
|
24450
|
+
if (blittedDirtyRects) {
|
|
24451
|
+
dirtyRects = blittedDirtyRects;
|
|
24452
|
+
}
|
|
24453
|
+
}
|
|
24454
|
+
} else {
|
|
24455
|
+
context.clearRect(0, 0, bounds.width, bounds.height);
|
|
24456
|
+
}
|
|
24457
|
+
bodyDirtyRectsByPane[pane] = dirtyRects;
|
|
24458
|
+
if (dirtyRects.length === 0) {
|
|
24459
|
+
continue;
|
|
24460
|
+
}
|
|
24461
|
+
context.fillStyle = sheetSurface;
|
|
24462
|
+
for (const dirtyRect of dirtyRects) {
|
|
24463
|
+
context.fillRect(dirtyRect.left, dirtyRect.top, dirtyRect.width, dirtyRect.height);
|
|
24464
|
+
}
|
|
23999
24465
|
}
|
|
24000
24466
|
for (const pane of cellPaneOrder) {
|
|
24001
24467
|
const paneContext = bodyContexts[pane];
|
|
24002
24468
|
const paneBoundsForCell = paneBounds[pane];
|
|
24469
|
+
const paneDirtyRects = bodyDirtyRectsByPane[pane];
|
|
24003
24470
|
const paneAxisItems = canvasPaneAxisItems[pane];
|
|
24004
|
-
if (!paneContext || paneBoundsForCell.width <= 0 || paneBoundsForCell.height <= 0 || paneAxisItems.rows.length === 0 || paneAxisItems.cols.length === 0) {
|
|
24471
|
+
if (!paneContext || paneDirtyRects.length === 0 || paneBoundsForCell.width <= 0 || paneBoundsForCell.height <= 0 || paneAxisItems.rows.length === 0 || paneAxisItems.cols.length === 0) {
|
|
24005
24472
|
continue;
|
|
24006
24473
|
}
|
|
24007
24474
|
const drawnMergedAnchorKeys = /* @__PURE__ */ new Set();
|
|
@@ -24041,11 +24508,14 @@ function XlsxGrid({
|
|
|
24041
24508
|
if (localRect.left + drawableWidth < 0 || localRect.top + localRect.height < 0 || localRect.left > paneBoundsForCell.width || localRect.top > paneBoundsForCell.height) {
|
|
24042
24509
|
continue;
|
|
24043
24510
|
}
|
|
24511
|
+
if (!intersectsCanvasDirtyRects(localRect.left, localRect.top, drawableWidth, localRect.height, paneDirtyRects)) {
|
|
24512
|
+
continue;
|
|
24513
|
+
}
|
|
24044
24514
|
const cellStyle = cellData.style;
|
|
24045
24515
|
const canvasCellStyle = cellData.canvas ?? buildCanvasCellStyleCache(cellStyle);
|
|
24046
|
-
const fillColor = cellData.conditionalColorScale?.color ?? (typeof cellStyle.backgroundColor === "string" ? cellStyle.backgroundColor :
|
|
24516
|
+
const fillColor = cellData.conditionalColorScale?.color ?? (typeof cellStyle.backgroundColor === "string" ? cellStyle.backgroundColor : sheetSurface);
|
|
24047
24517
|
const gradientFill = !cellData.conditionalColorScale && typeof cellStyle.backgroundImage === "string" ? resolveCanvasGradientFill(paneContext, localRect, cellStyle.backgroundImage) : null;
|
|
24048
|
-
const hasExplicitCellFill = cellData.conditionalColorScale !== null || gradientFill !== null || typeof cellStyle.backgroundColor === "string" && cellStyle.backgroundColor !==
|
|
24518
|
+
const hasExplicitCellFill = cellData.conditionalColorScale !== null || gradientFill !== null || typeof cellStyle.backgroundColor === "string" && cellStyle.backgroundColor !== sheetSurface;
|
|
24049
24519
|
paneContext.fillStyle = gradientFill ?? fillColor;
|
|
24050
24520
|
paneContext.fillRect(localRect.left, localRect.top, localRect.width, localRect.height);
|
|
24051
24521
|
if (cellData.chartHighlight) {
|
|
@@ -24399,55 +24869,139 @@ function XlsxGrid({
|
|
|
24399
24869
|
}
|
|
24400
24870
|
}
|
|
24401
24871
|
}
|
|
24402
|
-
if (shouldRepaintHeaders &&
|
|
24403
|
-
|
|
24404
|
-
|
|
24405
|
-
|
|
24406
|
-
|
|
24407
|
-
|
|
24408
|
-
const
|
|
24409
|
-
if (
|
|
24872
|
+
if (shouldRepaintHeaders && cornerContext) {
|
|
24873
|
+
const topFrozenHeaderContext = topHeaderContexts.frozen;
|
|
24874
|
+
const topScrollHeaderContext = topHeaderContexts.scroll;
|
|
24875
|
+
const leftFrozenHeaderContext = leftHeaderContexts.frozen;
|
|
24876
|
+
const leftScrollHeaderContext = leftHeaderContexts.scroll;
|
|
24877
|
+
if (canBlitTopHeader) {
|
|
24878
|
+
const bufferCanvas = getHeaderBlitBufferCanvas("top");
|
|
24879
|
+
if (bufferCanvas && topScrollHeaderContext && topScrollHeaderCanvasRef.current) {
|
|
24880
|
+
const blittedDirtyRects = blitCanvasWithScrollDelta(
|
|
24881
|
+
topScrollHeaderCanvasRef.current,
|
|
24882
|
+
topScrollHeaderContext,
|
|
24883
|
+
bufferCanvas,
|
|
24884
|
+
dpr,
|
|
24885
|
+
topScrollHeaderCanvasWidth2,
|
|
24886
|
+
headerHeight,
|
|
24887
|
+
drawingViewport.left - previousPaintedViewport.left,
|
|
24888
|
+
0
|
|
24889
|
+
);
|
|
24890
|
+
if (blittedDirtyRects) {
|
|
24891
|
+
topScrollHeaderDirtyRects = blittedDirtyRects;
|
|
24892
|
+
}
|
|
24893
|
+
}
|
|
24894
|
+
}
|
|
24895
|
+
if (canBlitLeftHeader) {
|
|
24896
|
+
const bufferCanvas = getHeaderBlitBufferCanvas("left");
|
|
24897
|
+
if (bufferCanvas && leftScrollHeaderContext && leftScrollHeaderCanvasRef.current) {
|
|
24898
|
+
const blittedDirtyRects = blitCanvasWithScrollDelta(
|
|
24899
|
+
leftScrollHeaderCanvasRef.current,
|
|
24900
|
+
leftScrollHeaderContext,
|
|
24901
|
+
bufferCanvas,
|
|
24902
|
+
dpr,
|
|
24903
|
+
rowHeaderWidth,
|
|
24904
|
+
leftScrollHeaderCanvasHeight2,
|
|
24905
|
+
0,
|
|
24906
|
+
drawingViewport.top - previousPaintedViewport.top
|
|
24907
|
+
);
|
|
24908
|
+
if (blittedDirtyRects) {
|
|
24909
|
+
leftScrollHeaderDirtyRects = blittedDirtyRects;
|
|
24910
|
+
}
|
|
24911
|
+
}
|
|
24912
|
+
}
|
|
24913
|
+
if (topFrozenHeaderContext && topFrozenHeaderCanvasWidth2 > 0) {
|
|
24914
|
+
topFrozenHeaderContext.fillStyle = palette.headerSurface;
|
|
24915
|
+
topFrozenHeaderContext.fillRect(0, 0, topFrozenHeaderCanvasWidth2, headerHeight);
|
|
24916
|
+
}
|
|
24917
|
+
if (topScrollHeaderContext && topScrollHeaderCanvasWidth2 > 0) {
|
|
24918
|
+
topScrollHeaderContext.fillStyle = palette.headerSurface;
|
|
24919
|
+
for (const dirtyRect of topScrollHeaderDirtyRects) {
|
|
24920
|
+
topScrollHeaderContext.fillRect(dirtyRect.left, dirtyRect.top, dirtyRect.width, dirtyRect.height);
|
|
24921
|
+
}
|
|
24922
|
+
}
|
|
24923
|
+
if (topFrozenHeaderContext) {
|
|
24924
|
+
topFrozenHeaderContext.strokeStyle = palette.border;
|
|
24925
|
+
topFrozenHeaderContext.lineWidth = 1;
|
|
24926
|
+
}
|
|
24927
|
+
if (topScrollHeaderContext) {
|
|
24928
|
+
topScrollHeaderContext.strokeStyle = palette.border;
|
|
24929
|
+
topScrollHeaderContext.lineWidth = 1;
|
|
24930
|
+
}
|
|
24931
|
+
for (const column of canvasColumnHeaderCells) {
|
|
24932
|
+
const paneContext = column.isFrozen ? topFrozenHeaderContext : topScrollHeaderContext;
|
|
24933
|
+
if (!paneContext) {
|
|
24934
|
+
continue;
|
|
24935
|
+
}
|
|
24936
|
+
if (column.localLeft + column.width < 0 || column.localLeft > (column.isFrozen ? topFrozenHeaderCanvasWidth2 : topScrollHeaderCanvasWidth2)) {
|
|
24937
|
+
continue;
|
|
24938
|
+
}
|
|
24939
|
+
if (!column.isFrozen && !intersectsCanvasDirtyRects(column.localLeft, 0, column.width, column.height, topScrollHeaderDirtyRects)) {
|
|
24940
|
+
continue;
|
|
24941
|
+
}
|
|
24942
|
+
const selected = normalizedVisibleRange && column.actualCol >= normalizedVisibleRange.start.col && column.actualCol <= normalizedVisibleRange.end.col;
|
|
24943
|
+
paneContext.fillStyle = selected ? selectionHeaderSurface : palette.headerSurface;
|
|
24944
|
+
paneContext.fillRect(column.localLeft, 0, column.width, column.height);
|
|
24945
|
+
paneContext.strokeStyle = palette.border;
|
|
24946
|
+
paneContext.beginPath();
|
|
24947
|
+
paneContext.moveTo(column.localLeft + column.width - 0.5, 0);
|
|
24948
|
+
paneContext.lineTo(column.localLeft + column.width - 0.5, column.height);
|
|
24949
|
+
paneContext.moveTo(column.localLeft, column.height - 0.5);
|
|
24950
|
+
paneContext.lineTo(column.localLeft + column.width, column.height - 0.5);
|
|
24951
|
+
paneContext.stroke();
|
|
24952
|
+
paneContext.font = `600 ${11 * zoomFactor}px ui-sans-serif, system-ui, sans-serif`;
|
|
24953
|
+
paneContext.fillStyle = palette.mutedText;
|
|
24954
|
+
paneContext.textAlign = "center";
|
|
24955
|
+
paneContext.textBaseline = "middle";
|
|
24956
|
+
paneContext.fillText(
|
|
24957
|
+
columnLabel2(column.actualCol),
|
|
24958
|
+
column.localLeft + column.width / 2,
|
|
24959
|
+
column.height / 2
|
|
24960
|
+
);
|
|
24961
|
+
}
|
|
24962
|
+
if (leftFrozenHeaderContext && leftFrozenHeaderCanvasHeight2 > 0) {
|
|
24963
|
+
leftFrozenHeaderContext.fillStyle = palette.rowHeaderSurface;
|
|
24964
|
+
leftFrozenHeaderContext.fillRect(0, 0, rowHeaderWidth, leftFrozenHeaderCanvasHeight2);
|
|
24965
|
+
}
|
|
24966
|
+
if (leftScrollHeaderContext && leftScrollHeaderCanvasHeight2 > 0) {
|
|
24967
|
+
leftScrollHeaderContext.fillStyle = palette.rowHeaderSurface;
|
|
24968
|
+
for (const dirtyRect of leftScrollHeaderDirtyRects) {
|
|
24969
|
+
leftScrollHeaderContext.fillRect(dirtyRect.left, dirtyRect.top, dirtyRect.width, dirtyRect.height);
|
|
24970
|
+
}
|
|
24971
|
+
}
|
|
24972
|
+
if (leftFrozenHeaderContext) {
|
|
24973
|
+
leftFrozenHeaderContext.strokeStyle = palette.border;
|
|
24974
|
+
leftFrozenHeaderContext.lineWidth = 1;
|
|
24975
|
+
}
|
|
24976
|
+
if (leftScrollHeaderContext) {
|
|
24977
|
+
leftScrollHeaderContext.strokeStyle = palette.border;
|
|
24978
|
+
leftScrollHeaderContext.lineWidth = 1;
|
|
24979
|
+
}
|
|
24980
|
+
for (const row of canvasRowHeaderCells) {
|
|
24981
|
+
const paneContext = row.isFrozen ? leftFrozenHeaderContext : leftScrollHeaderContext;
|
|
24982
|
+
if (!paneContext) {
|
|
24983
|
+
continue;
|
|
24984
|
+
}
|
|
24985
|
+
if (row.localTop + row.height < 0 || row.localTop > (row.isFrozen ? leftFrozenHeaderCanvasHeight2 : leftScrollHeaderCanvasHeight2)) {
|
|
24410
24986
|
continue;
|
|
24411
24987
|
}
|
|
24412
|
-
|
|
24413
|
-
topHeaderContext.fillStyle = selected ? selectionHeaderSurface : palette.headerSurface;
|
|
24414
|
-
topHeaderContext.fillRect(rect.left, 0, rect.width, headerHeight);
|
|
24415
|
-
topHeaderContext.strokeStyle = palette.border;
|
|
24416
|
-
topHeaderContext.beginPath();
|
|
24417
|
-
topHeaderContext.moveTo(rect.left + rect.width - 0.5, 0);
|
|
24418
|
-
topHeaderContext.lineTo(rect.left + rect.width - 0.5, headerHeight);
|
|
24419
|
-
topHeaderContext.moveTo(rect.left, headerHeight - 0.5);
|
|
24420
|
-
topHeaderContext.lineTo(rect.left + rect.width, headerHeight - 0.5);
|
|
24421
|
-
topHeaderContext.stroke();
|
|
24422
|
-
topHeaderContext.font = `600 ${11 * zoomFactor}px ui-sans-serif, system-ui, sans-serif`;
|
|
24423
|
-
topHeaderContext.fillStyle = palette.mutedText;
|
|
24424
|
-
topHeaderContext.textAlign = "center";
|
|
24425
|
-
topHeaderContext.textBaseline = "middle";
|
|
24426
|
-
topHeaderContext.fillText(columnLabel2(colItem.actualCol), rect.left + rect.width / 2, headerHeight / 2);
|
|
24427
|
-
}
|
|
24428
|
-
leftHeaderContext.fillStyle = palette.rowHeaderSurface;
|
|
24429
|
-
leftHeaderContext.fillRect(0, 0, rowHeaderWidth, bodyHeight);
|
|
24430
|
-
leftHeaderContext.strokeStyle = palette.border;
|
|
24431
|
-
leftHeaderContext.lineWidth = 1;
|
|
24432
|
-
for (const rowItem of canvasVisibleRowItems) {
|
|
24433
|
-
const rect = resolveCanvasRowHeaderRect(rowItem.actualRow);
|
|
24434
|
-
if (!rect || rect.top + rect.height < displayHeaderHeight || rect.top > bodyHeight) {
|
|
24988
|
+
if (!row.isFrozen && !intersectsCanvasDirtyRects(0, row.localTop, rowHeaderWidth, row.height, leftScrollHeaderDirtyRects)) {
|
|
24435
24989
|
continue;
|
|
24436
24990
|
}
|
|
24437
|
-
const selected = normalizedVisibleRange &&
|
|
24438
|
-
|
|
24439
|
-
|
|
24440
|
-
|
|
24441
|
-
|
|
24442
|
-
|
|
24443
|
-
|
|
24444
|
-
|
|
24445
|
-
|
|
24446
|
-
|
|
24447
|
-
|
|
24448
|
-
|
|
24449
|
-
|
|
24450
|
-
|
|
24991
|
+
const selected = normalizedVisibleRange && row.actualRow >= normalizedVisibleRange.start.row && row.actualRow <= normalizedVisibleRange.end.row;
|
|
24992
|
+
paneContext.fillStyle = selected ? selectionHeaderSurface : palette.rowHeaderSurface;
|
|
24993
|
+
paneContext.fillRect(0, row.localTop, rowHeaderWidth, row.height);
|
|
24994
|
+
paneContext.beginPath();
|
|
24995
|
+
paneContext.moveTo(0, row.localTop + row.height - 0.5);
|
|
24996
|
+
paneContext.lineTo(rowHeaderWidth, row.localTop + row.height - 0.5);
|
|
24997
|
+
paneContext.moveTo(rowHeaderWidth - 0.5, row.localTop);
|
|
24998
|
+
paneContext.lineTo(rowHeaderWidth - 0.5, row.localTop + row.height);
|
|
24999
|
+
paneContext.stroke();
|
|
25000
|
+
paneContext.font = `600 ${11 * zoomFactor}px ui-sans-serif, system-ui, sans-serif`;
|
|
25001
|
+
paneContext.fillStyle = palette.mutedText;
|
|
25002
|
+
paneContext.textAlign = "center";
|
|
25003
|
+
paneContext.textBaseline = "middle";
|
|
25004
|
+
paneContext.fillText(`${row.actualRow + 1}`, rowHeaderWidth / 2, row.localTop + row.height / 2);
|
|
24451
25005
|
}
|
|
24452
25006
|
cornerContext.fillStyle = palette.rowHeaderSurface;
|
|
24453
25007
|
cornerContext.fillRect(0, 0, rowHeaderWidth, headerHeight);
|
|
@@ -24471,7 +25025,9 @@ function XlsxGrid({
|
|
|
24471
25025
|
}, [
|
|
24472
25026
|
activeSheet,
|
|
24473
25027
|
applyCanvasViewportCompensation,
|
|
25028
|
+
canvasColumnHeaderCells,
|
|
24474
25029
|
canvasPaneAxisItems,
|
|
25030
|
+
canvasRowHeaderCells,
|
|
24475
25031
|
canvasVisibleColItems,
|
|
24476
25032
|
canvasVisibleRowItems,
|
|
24477
25033
|
colIndexByActual,
|
|
@@ -24486,11 +25042,13 @@ function XlsxGrid({
|
|
|
24486
25042
|
drawingViewport.height,
|
|
24487
25043
|
drawingViewport.width,
|
|
24488
25044
|
experimentalCanvas,
|
|
25045
|
+
frozenPaneBottom,
|
|
25046
|
+
frozenPaneRight,
|
|
24489
25047
|
getCellData,
|
|
25048
|
+
getBodyBlitBufferCanvas,
|
|
25049
|
+
getHeaderBlitBufferCanvas,
|
|
24490
25050
|
palette,
|
|
24491
25051
|
resolveCellDisplayRect,
|
|
24492
|
-
resolveCanvasColumnHeaderRect,
|
|
24493
|
-
resolveCanvasRowHeaderRect,
|
|
24494
25052
|
resolveMergeAnchorCell,
|
|
24495
25053
|
resizeGuide,
|
|
24496
25054
|
rowIndexByActual,
|
|
@@ -24784,6 +25342,10 @@ function XlsxGrid({
|
|
|
24784
25342
|
const leftBodyCanvasHeight = scrollBodyCanvasHeight;
|
|
24785
25343
|
const cornerBodyCanvasWidth = leftBodyCanvasWidth;
|
|
24786
25344
|
const cornerBodyCanvasHeight = topBodyCanvasHeight;
|
|
25345
|
+
const topFrozenHeaderCanvasWidth = leftBodyCanvasWidth;
|
|
25346
|
+
const topScrollHeaderCanvasWidth = scrollBodyCanvasWidth;
|
|
25347
|
+
const leftFrozenHeaderCanvasHeight = topBodyCanvasHeight;
|
|
25348
|
+
const leftScrollHeaderCanvasHeight = scrollBodyCanvasHeight;
|
|
24787
25349
|
const canvasBodyBaseStyle = {
|
|
24788
25350
|
cursor: "cell",
|
|
24789
25351
|
pointerEvents: "auto",
|
|
@@ -24819,22 +25381,38 @@ function XlsxGrid({
|
|
|
24819
25381
|
top: displayHeaderHeight,
|
|
24820
25382
|
zIndex: 31
|
|
24821
25383
|
};
|
|
24822
|
-
const
|
|
25384
|
+
const canvasHeaderBaseStyle = {
|
|
24823
25385
|
cursor: "default",
|
|
24824
|
-
display: drawingViewport.width > 0 && drawingViewport.height > 0 ? "block" : "none",
|
|
24825
|
-
left: 0,
|
|
24826
25386
|
pointerEvents: "auto",
|
|
24827
25387
|
position: "absolute",
|
|
25388
|
+
transformOrigin: "0 0"
|
|
25389
|
+
};
|
|
25390
|
+
const canvasTopFrozenHeaderStyle = {
|
|
25391
|
+
...canvasHeaderBaseStyle,
|
|
25392
|
+
display: topFrozenHeaderCanvasWidth > 0 && drawingViewport.height > 0 ? "block" : "none",
|
|
25393
|
+
left: displayRowHeaderWidth,
|
|
25394
|
+
top: 0,
|
|
25395
|
+
zIndex: canvasHeaderOverlayZIndex + 1
|
|
25396
|
+
};
|
|
25397
|
+
const canvasTopScrollHeaderStyle = {
|
|
25398
|
+
...canvasHeaderBaseStyle,
|
|
25399
|
+
display: topScrollHeaderCanvasWidth > 0 && drawingViewport.height > 0 ? "block" : "none",
|
|
25400
|
+
left: frozenPaneRight,
|
|
24828
25401
|
top: 0,
|
|
24829
25402
|
zIndex: canvasHeaderOverlayZIndex
|
|
24830
25403
|
};
|
|
24831
|
-
const
|
|
24832
|
-
|
|
24833
|
-
display:
|
|
25404
|
+
const canvasLeftFrozenHeaderStyle = {
|
|
25405
|
+
...canvasHeaderBaseStyle,
|
|
25406
|
+
display: leftFrozenHeaderCanvasHeight > 0 && drawingViewport.width > 0 ? "block" : "none",
|
|
24834
25407
|
left: 0,
|
|
24835
|
-
|
|
24836
|
-
|
|
24837
|
-
|
|
25408
|
+
top: displayHeaderHeight,
|
|
25409
|
+
zIndex: canvasHeaderOverlayZIndex + 1
|
|
25410
|
+
};
|
|
25411
|
+
const canvasLeftScrollHeaderStyle = {
|
|
25412
|
+
...canvasHeaderBaseStyle,
|
|
25413
|
+
display: leftScrollHeaderCanvasHeight > 0 && drawingViewport.width > 0 ? "block" : "none",
|
|
25414
|
+
left: 0,
|
|
25415
|
+
top: frozenPaneBottom,
|
|
24838
25416
|
zIndex: canvasHeaderOverlayZIndex
|
|
24839
25417
|
};
|
|
24840
25418
|
const canvasCornerHeaderStyle = {
|
|
@@ -24843,6 +25421,7 @@ function XlsxGrid({
|
|
|
24843
25421
|
pointerEvents: "none",
|
|
24844
25422
|
position: "absolute",
|
|
24845
25423
|
top: 0,
|
|
25424
|
+
transformOrigin: "0 0",
|
|
24846
25425
|
zIndex: canvasHeaderOverlayZIndex + 1
|
|
24847
25426
|
};
|
|
24848
25427
|
const editingOverlayRect = experimentalCanvas && editingCell ? resolveCellDisplayRect(editingCell) : null;
|
|
@@ -25989,7 +26568,7 @@ function XlsxGrid({
|
|
|
25989
26568
|
pointerEvents: "none",
|
|
25990
26569
|
position: "absolute",
|
|
25991
26570
|
top: 0,
|
|
25992
|
-
transform: `translate(${-drawingViewport.left}px, ${-drawingViewport.top}px)`,
|
|
26571
|
+
transform: `translate(${-drawingViewport.left - frozenPaneRight}px, ${-drawingViewport.top - frozenPaneBottom}px)`,
|
|
25993
26572
|
width: totalWidth
|
|
25994
26573
|
},
|
|
25995
26574
|
children: paneDrawingNodes.scroll
|
|
@@ -26004,7 +26583,7 @@ function XlsxGrid({
|
|
|
26004
26583
|
pointerEvents: "none",
|
|
26005
26584
|
position: "absolute",
|
|
26006
26585
|
top: 0,
|
|
26007
|
-
transform: `translate(${-drawingViewport.left}px, ${-displayHeaderHeight}px)`,
|
|
26586
|
+
transform: `translate(${-drawingViewport.left - frozenPaneRight}px, ${-displayHeaderHeight}px)`,
|
|
26008
26587
|
width: totalWidth
|
|
26009
26588
|
},
|
|
26010
26589
|
children: paneDrawingNodes.top
|
|
@@ -26019,7 +26598,7 @@ function XlsxGrid({
|
|
|
26019
26598
|
pointerEvents: "none",
|
|
26020
26599
|
position: "absolute",
|
|
26021
26600
|
top: 0,
|
|
26022
|
-
transform: `translate(${-displayRowHeaderWidth}px, ${-drawingViewport.top}px)`,
|
|
26601
|
+
transform: `translate(${-displayRowHeaderWidth}px, ${-drawingViewport.top - frozenPaneBottom}px)`,
|
|
26023
26602
|
width: totalWidth
|
|
26024
26603
|
},
|
|
26025
26604
|
children: paneDrawingNodes.left
|
|
@@ -26046,21 +26625,41 @@ function XlsxGrid({
|
|
|
26046
26625
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
26047
26626
|
"canvas",
|
|
26048
26627
|
{
|
|
26049
|
-
ref:
|
|
26628
|
+
ref: topFrozenHeaderCanvasRef,
|
|
26629
|
+
onPointerLeave: handleCanvasHeaderPointerLeave,
|
|
26630
|
+
onPointerMove: handleCanvasColumnHeaderPointerMove,
|
|
26631
|
+
onPointerDown: handleCanvasColumnHeaderPointerDown,
|
|
26632
|
+
style: canvasTopFrozenHeaderStyle
|
|
26633
|
+
}
|
|
26634
|
+
),
|
|
26635
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
26636
|
+
"canvas",
|
|
26637
|
+
{
|
|
26638
|
+
ref: topScrollHeaderCanvasRef,
|
|
26050
26639
|
onPointerLeave: handleCanvasHeaderPointerLeave,
|
|
26051
26640
|
onPointerMove: handleCanvasColumnHeaderPointerMove,
|
|
26052
26641
|
onPointerDown: handleCanvasColumnHeaderPointerDown,
|
|
26053
|
-
style:
|
|
26642
|
+
style: canvasTopScrollHeaderStyle
|
|
26054
26643
|
}
|
|
26055
26644
|
),
|
|
26056
26645
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
26057
26646
|
"canvas",
|
|
26058
26647
|
{
|
|
26059
|
-
ref:
|
|
26648
|
+
ref: leftFrozenHeaderCanvasRef,
|
|
26060
26649
|
onPointerLeave: handleCanvasHeaderPointerLeave,
|
|
26061
26650
|
onPointerMove: handleCanvasRowHeaderPointerMove,
|
|
26062
26651
|
onPointerDown: handleCanvasRowHeaderPointerDown,
|
|
26063
|
-
style:
|
|
26652
|
+
style: canvasLeftFrozenHeaderStyle
|
|
26653
|
+
}
|
|
26654
|
+
),
|
|
26655
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
26656
|
+
"canvas",
|
|
26657
|
+
{
|
|
26658
|
+
ref: leftScrollHeaderCanvasRef,
|
|
26659
|
+
onPointerLeave: handleCanvasHeaderPointerLeave,
|
|
26660
|
+
onPointerMove: handleCanvasRowHeaderPointerMove,
|
|
26661
|
+
onPointerDown: handleCanvasRowHeaderPointerDown,
|
|
26662
|
+
style: canvasLeftScrollHeaderStyle
|
|
26064
26663
|
}
|
|
26065
26664
|
),
|
|
26066
26665
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("canvas", { ref: cornerHeaderCanvasRef, style: canvasCornerHeaderStyle })
|
|
@@ -26370,7 +26969,7 @@ function XlsxGrid({
|
|
|
26370
26969
|
}
|
|
26371
26970
|
}
|
|
26372
26971
|
) : null,
|
|
26373
|
-
openTableMenuState ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
26972
|
+
!renderTableHeaderMenu && openTableMenuState ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
26374
26973
|
"div",
|
|
26375
26974
|
{
|
|
26376
26975
|
ref: tableMenuRef,
|
|
@@ -26381,22 +26980,23 @@ function XlsxGrid({
|
|
|
26381
26980
|
top: openTableMenuState.top,
|
|
26382
26981
|
zIndex: 50
|
|
26383
26982
|
},
|
|
26384
|
-
children:
|
|
26385
|
-
close: () => setOpenTableMenu(null),
|
|
26386
|
-
column: openTableMenuState.column,
|
|
26387
|
-
direction: sortState && sortState.tableName === openTableMenuState.table.name && sortState.columnIndex === openTableMenuState.column.index ? sortState.direction : null,
|
|
26388
|
-
sortAscending: () => sortTable(openTableMenuState.table.name, openTableMenuState.column.index, "ascending"),
|
|
26389
|
-
sortDescending: () => sortTable(openTableMenuState.table.name, openTableMenuState.column.index, "descending"),
|
|
26390
|
-
table: openTableMenuState.table
|
|
26391
|
-
}) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
26983
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
26392
26984
|
DefaultTableHeaderMenu,
|
|
26393
26985
|
{
|
|
26394
|
-
|
|
26986
|
+
cell: { col: openTableMenuState.column.index + openTableMenuState.table.start.col, row: openTableMenuState.table.start.row },
|
|
26395
26987
|
column: openTableMenuState.column,
|
|
26396
26988
|
direction: sortState && sortState.tableName === openTableMenuState.table.name && sortState.columnIndex === openTableMenuState.column.index ? sortState.direction : null,
|
|
26397
|
-
sortAscending: () =>
|
|
26398
|
-
|
|
26399
|
-
|
|
26989
|
+
sortAscending: () => {
|
|
26990
|
+
sortTable(openTableMenuState.table.name, openTableMenuState.column.index, "ascending");
|
|
26991
|
+
setOpenTableMenu(null);
|
|
26992
|
+
},
|
|
26993
|
+
sortDescending: () => {
|
|
26994
|
+
sortTable(openTableMenuState.table.name, openTableMenuState.column.index, "descending");
|
|
26995
|
+
setOpenTableMenu(null);
|
|
26996
|
+
},
|
|
26997
|
+
table: openTableMenuState.table,
|
|
26998
|
+
triggerIcon: "\u25BE",
|
|
26999
|
+
triggerProps: { type: "button" }
|
|
26400
27000
|
}
|
|
26401
27001
|
)
|
|
26402
27002
|
}
|
|
@@ -26827,6 +27427,476 @@ function useXlsxViewerCharts() {
|
|
|
26827
27427
|
]
|
|
26828
27428
|
);
|
|
26829
27429
|
}
|
|
27430
|
+
function useXlsxViewerThumbnails(options = {}) {
|
|
27431
|
+
const { workbook, sheets } = useXlsxViewer();
|
|
27432
|
+
const { isDark } = React4.useContext(ViewerAppearanceContext);
|
|
27433
|
+
const palette = useViewerPalette(isDark);
|
|
27434
|
+
const includeHeaders = options.includeHeaders ?? true;
|
|
27435
|
+
const resolution = options.resolution;
|
|
27436
|
+
const thumbnails = React4.useMemo(() => {
|
|
27437
|
+
return sheets.map((sheet, sheetIndex) => {
|
|
27438
|
+
const worksheet = workbook?.getSheet(sheet.workbookSheetIndex) ?? null;
|
|
27439
|
+
const showGridLines = sheet.showGridLines ?? true;
|
|
27440
|
+
const hiddenRowSet = new Set(sheet.hiddenRows ?? []);
|
|
27441
|
+
const hiddenColSet = new Set(sheet.hiddenCols ?? []);
|
|
27442
|
+
const visibleRows = buildVisibleAxisIndices(
|
|
27443
|
+
sheet.visibleRows ?? [],
|
|
27444
|
+
Math.max(THUMBNAIL_FALLBACK_ROWS, (sheet.maxUsedRow ?? -1) + THUMBNAIL_FALLBACK_ROWS + 1),
|
|
27445
|
+
sheet.maxUsedRow ?? -1,
|
|
27446
|
+
hiddenRowSet
|
|
27447
|
+
);
|
|
27448
|
+
const visibleCols = buildVisibleAxisIndices(
|
|
27449
|
+
sheet.visibleCols ?? [],
|
|
27450
|
+
Math.max(THUMBNAIL_FALLBACK_COLS, (sheet.maxUsedCol ?? -1) + THUMBNAIL_FALLBACK_COLS + 1),
|
|
27451
|
+
sheet.maxUsedCol ?? -1,
|
|
27452
|
+
hiddenColSet
|
|
27453
|
+
);
|
|
27454
|
+
const resolveColumnWidthPx = (actualCol) => {
|
|
27455
|
+
if (worksheet && !worksheet.isColumnHidden(actualCol)) {
|
|
27456
|
+
const width = worksheet.getColumnWidth(actualCol);
|
|
27457
|
+
if (width !== void 0 && width !== null) {
|
|
27458
|
+
return Math.max(
|
|
27459
|
+
resolveRenderedSheetAxisPixels(resolveSheetColumnWidthPixels(width, sheet.columnWidthCharacterWidthPx), showGridLines),
|
|
27460
|
+
DEFAULT_COL_WIDTH2 / 2
|
|
27461
|
+
);
|
|
27462
|
+
}
|
|
27463
|
+
}
|
|
27464
|
+
return Math.max(
|
|
27465
|
+
resolveRenderedSheetAxisPixels(
|
|
27466
|
+
sheet.colWidthOverridesPx[actualCol] ?? sheet.defaultColWidthPx ?? DEFAULT_COL_WIDTH2,
|
|
27467
|
+
showGridLines
|
|
27468
|
+
),
|
|
27469
|
+
DEFAULT_COL_WIDTH2 / 2
|
|
27470
|
+
);
|
|
27471
|
+
};
|
|
27472
|
+
const resolveRowHeightPx = (actualRow) => {
|
|
27473
|
+
if (worksheet && !worksheet.isRowHidden(actualRow)) {
|
|
27474
|
+
const height = worksheet.getRowHeight(actualRow);
|
|
27475
|
+
if (height !== void 0 && height !== null) {
|
|
27476
|
+
return Math.max(
|
|
27477
|
+
resolveRenderedSheetAxisPixels(resolveSheetRowHeightPixels(height), showGridLines),
|
|
27478
|
+
DEFAULT_ROW_HEIGHT2 / 1.5
|
|
27479
|
+
);
|
|
27480
|
+
}
|
|
27481
|
+
}
|
|
27482
|
+
return Math.max(
|
|
27483
|
+
resolveRenderedSheetAxisPixels(
|
|
27484
|
+
sheet.rowHeightOverridesPx[actualRow] ?? sheet.defaultRowHeightPx ?? DEFAULT_ROW_HEIGHT2,
|
|
27485
|
+
showGridLines
|
|
27486
|
+
),
|
|
27487
|
+
DEFAULT_ROW_HEIGHT2 / 1.5
|
|
27488
|
+
);
|
|
27489
|
+
};
|
|
27490
|
+
const previewRows = resolveThumbnailAxisIndices({
|
|
27491
|
+
fallbackCount: THUMBNAIL_FALLBACK_ROWS,
|
|
27492
|
+
getSizePx: resolveRowHeightPx,
|
|
27493
|
+
maxCount: THUMBNAIL_MAX_ROWS,
|
|
27494
|
+
maxLogicalPixels: THUMBNAIL_MAX_SOURCE_HEIGHT_PX,
|
|
27495
|
+
maxUsedIndex: sheet.maxUsedRow ?? -1,
|
|
27496
|
+
minUsedIndex: Math.max(0, sheet.minUsedRow ?? 0),
|
|
27497
|
+
precomputed: visibleRows
|
|
27498
|
+
});
|
|
27499
|
+
const previewCols = resolveThumbnailAxisIndices({
|
|
27500
|
+
fallbackCount: THUMBNAIL_FALLBACK_COLS,
|
|
27501
|
+
getSizePx: resolveColumnWidthPx,
|
|
27502
|
+
maxCount: THUMBNAIL_MAX_COLS,
|
|
27503
|
+
maxLogicalPixels: THUMBNAIL_MAX_SOURCE_WIDTH_PX,
|
|
27504
|
+
maxUsedIndex: sheet.maxUsedCol ?? -1,
|
|
27505
|
+
minUsedIndex: Math.max(0, sheet.minUsedCol ?? 0),
|
|
27506
|
+
precomputed: visibleCols
|
|
27507
|
+
});
|
|
27508
|
+
const rowAxis = buildThumbnailAxisItems(previewRows, resolveRowHeightPx);
|
|
27509
|
+
const colAxis = buildThumbnailAxisItems(previewCols, resolveColumnWidthPx);
|
|
27510
|
+
const rowItemByActual = new Map(rowAxis.items.map((item) => [item.actualIndex, item]));
|
|
27511
|
+
const colItemByActual = new Map(colAxis.items.map((item) => [item.actualIndex, item]));
|
|
27512
|
+
const headerHeight = includeHeaders ? HEADER_HEIGHT : 0;
|
|
27513
|
+
const rowHeaderWidth = includeHeaders ? ROW_HEADER_WIDTH : 0;
|
|
27514
|
+
const sourceWidth = rowHeaderWidth + colAxis.totalSize;
|
|
27515
|
+
const sourceHeight = headerHeight + rowAxis.totalSize;
|
|
27516
|
+
const outputSize = resolveThumbnailOutputSize(sourceWidth, sourceHeight, resolution);
|
|
27517
|
+
const sourceRange = {
|
|
27518
|
+
start: {
|
|
27519
|
+
col: previewCols[0] ?? 0,
|
|
27520
|
+
row: previewRows[0] ?? 0
|
|
27521
|
+
},
|
|
27522
|
+
end: {
|
|
27523
|
+
col: previewCols[previewCols.length - 1] ?? 0,
|
|
27524
|
+
row: previewRows[previewRows.length - 1] ?? 0
|
|
27525
|
+
}
|
|
27526
|
+
};
|
|
27527
|
+
const sparklineByCell = new Map(
|
|
27528
|
+
(sheet.sparklines ?? []).map((sparkline) => [`${sparkline.target.row}:${sparkline.target.col}`, sparkline])
|
|
27529
|
+
);
|
|
27530
|
+
const paint = (canvas) => {
|
|
27531
|
+
if (!canvas) {
|
|
27532
|
+
return false;
|
|
27533
|
+
}
|
|
27534
|
+
const context = canvas.getContext("2d");
|
|
27535
|
+
if (!context) {
|
|
27536
|
+
return false;
|
|
27537
|
+
}
|
|
27538
|
+
const dpr = typeof window === "undefined" ? 1 : Math.max(1, window.devicePixelRatio || 1);
|
|
27539
|
+
const outputWidth = outputSize.width;
|
|
27540
|
+
const outputHeight = outputSize.height;
|
|
27541
|
+
const scale = outputSize.scale;
|
|
27542
|
+
const deviceWidth = Math.max(1, Math.round(outputWidth * dpr));
|
|
27543
|
+
const deviceHeight = Math.max(1, Math.round(outputHeight * dpr));
|
|
27544
|
+
if (canvas.width !== deviceWidth) {
|
|
27545
|
+
canvas.width = deviceWidth;
|
|
27546
|
+
}
|
|
27547
|
+
if (canvas.height !== deviceHeight) {
|
|
27548
|
+
canvas.height = deviceHeight;
|
|
27549
|
+
}
|
|
27550
|
+
if (canvas.style.width !== `${outputWidth}px`) {
|
|
27551
|
+
canvas.style.width = `${outputWidth}px`;
|
|
27552
|
+
}
|
|
27553
|
+
if (canvas.style.height !== `${outputHeight}px`) {
|
|
27554
|
+
canvas.style.height = `${outputHeight}px`;
|
|
27555
|
+
}
|
|
27556
|
+
context.setTransform(dpr * scale, 0, 0, dpr * scale, 0, 0);
|
|
27557
|
+
context.clearRect(0, 0, Math.max(1, sourceWidth), Math.max(1, sourceHeight));
|
|
27558
|
+
context.fillStyle = palette.canvas;
|
|
27559
|
+
context.fillRect(0, 0, Math.max(1, sourceWidth), Math.max(1, sourceHeight));
|
|
27560
|
+
context.fillStyle = resolveSheetSurface(sheet, palette);
|
|
27561
|
+
context.fillRect(rowHeaderWidth, headerHeight, Math.max(1, colAxis.totalSize), Math.max(1, rowAxis.totalSize));
|
|
27562
|
+
if (includeHeaders) {
|
|
27563
|
+
context.fillStyle = palette.headerSurface;
|
|
27564
|
+
context.fillRect(rowHeaderWidth, 0, Math.max(1, colAxis.totalSize), headerHeight);
|
|
27565
|
+
context.fillStyle = palette.rowHeaderSurface;
|
|
27566
|
+
context.fillRect(0, headerHeight, rowHeaderWidth, Math.max(1, rowAxis.totalSize));
|
|
27567
|
+
context.fillRect(0, 0, rowHeaderWidth, headerHeight);
|
|
27568
|
+
}
|
|
27569
|
+
if (!worksheet) {
|
|
27570
|
+
return true;
|
|
27571
|
+
}
|
|
27572
|
+
const conditionalFormatMetricsCache = /* @__PURE__ */ new Map();
|
|
27573
|
+
const cellRenderCache = /* @__PURE__ */ new Map();
|
|
27574
|
+
const getCellData = (row, col) => {
|
|
27575
|
+
const cacheKey = `${row}:${col}`;
|
|
27576
|
+
const cached = cellRenderCache.get(cacheKey);
|
|
27577
|
+
if (cached) {
|
|
27578
|
+
return cached;
|
|
27579
|
+
}
|
|
27580
|
+
if (worksheet.isMergedSecondary(row, col)) {
|
|
27581
|
+
const mergedSecondaryData = {
|
|
27582
|
+
isMergedSecondary: true,
|
|
27583
|
+
style: {},
|
|
27584
|
+
value: ""
|
|
27585
|
+
};
|
|
27586
|
+
cellRenderCache.set(cacheKey, mergedSecondaryData);
|
|
27587
|
+
return mergedSecondaryData;
|
|
27588
|
+
}
|
|
27589
|
+
const merge = worksheet.getMergeSpan(row, col);
|
|
27590
|
+
const inheritedStyle = resolveInheritedCellStyle2(sheet, row, col);
|
|
27591
|
+
const worksheetStyle = worksheet.getCellStyleAt(row, col) ?? null;
|
|
27592
|
+
const mergedStyle = mergeResolvedCellStyle(inheritedStyle, worksheetStyle, { replaceXfSubtrees: true });
|
|
27593
|
+
const alignment = mergedStyle?.alignment;
|
|
27594
|
+
const sparkline = sparklineByCell.get(cacheKey) ?? null;
|
|
27595
|
+
const sparklineValues = sparkline ? sparkline.range.start.row === sparkline.range.end.row ? Array.from(
|
|
27596
|
+
{ length: Math.abs(sparkline.range.end.col - sparkline.range.start.col) + 1 },
|
|
27597
|
+
(_, index) => getCellNumericValue(
|
|
27598
|
+
worksheet,
|
|
27599
|
+
sparkline.range.start.row,
|
|
27600
|
+
Math.min(sparkline.range.start.col, sparkline.range.end.col) + index
|
|
27601
|
+
)
|
|
27602
|
+
) : Array.from(
|
|
27603
|
+
{ length: Math.abs(sparkline.range.end.row - sparkline.range.start.row) + 1 },
|
|
27604
|
+
(_, index) => getCellNumericValue(
|
|
27605
|
+
worksheet,
|
|
27606
|
+
Math.min(sparkline.range.start.row, sparkline.range.end.row) + index,
|
|
27607
|
+
sparkline.range.start.col
|
|
27608
|
+
)
|
|
27609
|
+
) : null;
|
|
27610
|
+
const checkboxState = mergedStyle?.cellControl ? getCellBooleanValue(worksheet, row, col) : null;
|
|
27611
|
+
const nextData = {
|
|
27612
|
+
canvas: void 0,
|
|
27613
|
+
checkboxState,
|
|
27614
|
+
colSpan: merge?.colSpan,
|
|
27615
|
+
conditionalColorScale: resolveConditionalColorScaleForCell(
|
|
27616
|
+
row,
|
|
27617
|
+
col,
|
|
27618
|
+
worksheet,
|
|
27619
|
+
sheet,
|
|
27620
|
+
conditionalFormatMetricsCache
|
|
27621
|
+
),
|
|
27622
|
+
conditionalDataBar: resolveConditionalDataBarForCell(
|
|
27623
|
+
row,
|
|
27624
|
+
col,
|
|
27625
|
+
worksheet,
|
|
27626
|
+
sheet,
|
|
27627
|
+
conditionalFormatMetricsCache
|
|
27628
|
+
),
|
|
27629
|
+
conditionalIcon: resolveConditionalIconForCell(
|
|
27630
|
+
row,
|
|
27631
|
+
col,
|
|
27632
|
+
worksheet,
|
|
27633
|
+
sheet,
|
|
27634
|
+
conditionalFormatMetricsCache
|
|
27635
|
+
),
|
|
27636
|
+
isMergedSecondary: false,
|
|
27637
|
+
rowSpan: merge?.rowSpan,
|
|
27638
|
+
sparkline: sparkline && sparklineValues ? { config: sparkline, values: sparklineValues } : null,
|
|
27639
|
+
style: buildCellStyle(mergedStyle, palette, sheet.themePalette, {
|
|
27640
|
+
showGridLines
|
|
27641
|
+
}),
|
|
27642
|
+
textRotationDeg: resolveSpreadsheetTextRotation(alignment?.textRotation),
|
|
27643
|
+
value: sparkline ? "" : checkboxState !== null ? "" : getCellDisplayValue(worksheet, row, col, sheet)
|
|
27644
|
+
};
|
|
27645
|
+
nextData.canvas = buildCanvasCellStyleCache(nextData.style);
|
|
27646
|
+
cellRenderCache.set(cacheKey, nextData);
|
|
27647
|
+
return nextData;
|
|
27648
|
+
};
|
|
27649
|
+
for (const rowItem of rowAxis.items) {
|
|
27650
|
+
for (const colItem of colAxis.items) {
|
|
27651
|
+
const cellData = getCellData(rowItem.actualIndex, colItem.actualIndex);
|
|
27652
|
+
if (cellData.isMergedSecondary) {
|
|
27653
|
+
continue;
|
|
27654
|
+
}
|
|
27655
|
+
const colSpan = Math.max(1, cellData.colSpan ?? 1);
|
|
27656
|
+
const rowSpan = Math.max(1, cellData.rowSpan ?? 1);
|
|
27657
|
+
let width = colItem.size;
|
|
27658
|
+
let height = rowItem.size;
|
|
27659
|
+
for (let colOffset = 1; colOffset < colSpan; colOffset += 1) {
|
|
27660
|
+
const nextCol = colItemByActual.get(colItem.actualIndex + colOffset);
|
|
27661
|
+
if (!nextCol) {
|
|
27662
|
+
break;
|
|
27663
|
+
}
|
|
27664
|
+
width += nextCol.size;
|
|
27665
|
+
}
|
|
27666
|
+
for (let rowOffset = 1; rowOffset < rowSpan; rowOffset += 1) {
|
|
27667
|
+
const nextRow = rowItemByActual.get(rowItem.actualIndex + rowOffset);
|
|
27668
|
+
if (!nextRow) {
|
|
27669
|
+
break;
|
|
27670
|
+
}
|
|
27671
|
+
height += nextRow.size;
|
|
27672
|
+
}
|
|
27673
|
+
const rect = {
|
|
27674
|
+
height,
|
|
27675
|
+
left: rowHeaderWidth + colItem.start,
|
|
27676
|
+
top: headerHeight + rowItem.start,
|
|
27677
|
+
width
|
|
27678
|
+
};
|
|
27679
|
+
const canvasCellStyle = cellData.canvas ?? buildCanvasCellStyleCache(cellData.style);
|
|
27680
|
+
const gradientFill = typeof cellData.style.backgroundImage === "string" ? resolveCanvasGradientFill(context, rect, cellData.style.backgroundImage) : null;
|
|
27681
|
+
const fillColor = cellData.conditionalColorScale?.color ?? (typeof cellData.style.backgroundColor === "string" ? cellData.style.backgroundColor : resolveSheetSurface(sheet, palette));
|
|
27682
|
+
const hasExplicitCellFill = cellData.conditionalColorScale !== null || gradientFill !== null || typeof cellData.style.backgroundColor === "string" && cellData.style.backgroundColor !== resolveSheetSurface(sheet, palette);
|
|
27683
|
+
context.fillStyle = gradientFill ?? fillColor;
|
|
27684
|
+
context.fillRect(rect.left, rect.top, rect.width, rect.height);
|
|
27685
|
+
if (cellData.conditionalDataBar) {
|
|
27686
|
+
const barLeft = rect.left + 4;
|
|
27687
|
+
const barTop = rect.top + 4;
|
|
27688
|
+
const barWidth = Math.max(0, (rect.width - 8) * (cellData.conditionalDataBar.widthPercent / 100));
|
|
27689
|
+
const barHeight = Math.max(0, rect.height - 8);
|
|
27690
|
+
if (barWidth > 0 && barHeight > 0) {
|
|
27691
|
+
context.fillStyle = resolveCanvasDataBarFill(
|
|
27692
|
+
context,
|
|
27693
|
+
barLeft,
|
|
27694
|
+
barTop,
|
|
27695
|
+
barWidth,
|
|
27696
|
+
barHeight,
|
|
27697
|
+
cellData.conditionalDataBar
|
|
27698
|
+
);
|
|
27699
|
+
context.fillRect(barLeft, barTop, barWidth, barHeight);
|
|
27700
|
+
if (cellData.conditionalDataBar.border !== false && cellData.conditionalDataBar.borderColor) {
|
|
27701
|
+
context.strokeStyle = cellData.conditionalDataBar.borderColor;
|
|
27702
|
+
context.lineWidth = 1;
|
|
27703
|
+
context.strokeRect(barLeft + 0.5, barTop + 0.5, Math.max(0, barWidth - 1), Math.max(0, barHeight - 1));
|
|
27704
|
+
}
|
|
27705
|
+
}
|
|
27706
|
+
}
|
|
27707
|
+
if (showGridLines && !hasExplicitCellFill) {
|
|
27708
|
+
context.strokeStyle = palette.border;
|
|
27709
|
+
context.lineWidth = 1;
|
|
27710
|
+
context.beginPath();
|
|
27711
|
+
if (colItem.start === 0) {
|
|
27712
|
+
context.moveTo(rect.left + 0.5, rect.top);
|
|
27713
|
+
context.lineTo(rect.left + 0.5, rect.top + rect.height);
|
|
27714
|
+
}
|
|
27715
|
+
if (rowItem.start === 0) {
|
|
27716
|
+
context.moveTo(rect.left, rect.top + 0.5);
|
|
27717
|
+
context.lineTo(rect.left + rect.width, rect.top + 0.5);
|
|
27718
|
+
}
|
|
27719
|
+
context.moveTo(rect.left + rect.width - 0.5, rect.top);
|
|
27720
|
+
context.lineTo(rect.left + rect.width - 0.5, rect.top + rect.height);
|
|
27721
|
+
context.moveTo(rect.left, rect.top + rect.height - 0.5);
|
|
27722
|
+
context.lineTo(rect.left + rect.width, rect.top + rect.height - 0.5);
|
|
27723
|
+
context.stroke();
|
|
27724
|
+
}
|
|
27725
|
+
if (canvasCellStyle.topBorder) {
|
|
27726
|
+
strokeCanvasBorderSide(context, "top", rect, canvasCellStyle.topBorder);
|
|
27727
|
+
}
|
|
27728
|
+
if (canvasCellStyle.rightBorder) {
|
|
27729
|
+
strokeCanvasBorderSide(context, "right", rect, canvasCellStyle.rightBorder);
|
|
27730
|
+
}
|
|
27731
|
+
if (canvasCellStyle.bottomBorder) {
|
|
27732
|
+
strokeCanvasBorderSide(context, "bottom", rect, canvasCellStyle.bottomBorder);
|
|
27733
|
+
}
|
|
27734
|
+
if (canvasCellStyle.leftBorder) {
|
|
27735
|
+
strokeCanvasBorderSide(context, "left", rect, canvasCellStyle.leftBorder);
|
|
27736
|
+
}
|
|
27737
|
+
const padding = canvasCellStyle.padding;
|
|
27738
|
+
const contentLeft = rect.left + padding.left;
|
|
27739
|
+
const contentTop = rect.top + padding.top;
|
|
27740
|
+
const contentWidth = Math.max(0, rect.width - padding.left - padding.right);
|
|
27741
|
+
const contentHeight = Math.max(0, rect.height - padding.top - padding.bottom);
|
|
27742
|
+
const rawText = cellData.value ?? "";
|
|
27743
|
+
context.save();
|
|
27744
|
+
context.beginPath();
|
|
27745
|
+
context.rect(contentLeft, contentTop, contentWidth, contentHeight);
|
|
27746
|
+
context.clip();
|
|
27747
|
+
context.font = canvasCellStyle.baseFont;
|
|
27748
|
+
context.fillStyle = canvasCellStyle.textColor;
|
|
27749
|
+
context.textBaseline = "middle";
|
|
27750
|
+
if (cellData.checkboxState != null) {
|
|
27751
|
+
const boxSize = Math.min(14, contentWidth, contentHeight);
|
|
27752
|
+
const boxLeft = rect.left + (rect.width - boxSize) / 2;
|
|
27753
|
+
const boxTop = rect.top + (rect.height - boxSize) / 2;
|
|
27754
|
+
context.strokeStyle = paletteIsDark(palette) ? "#cbd5e1" : "#475569";
|
|
27755
|
+
context.lineWidth = 1.25;
|
|
27756
|
+
context.strokeRect(boxLeft, boxTop, boxSize, boxSize);
|
|
27757
|
+
if (cellData.checkboxState) {
|
|
27758
|
+
context.fillStyle = paletteIsDark(palette) ? "#60a5fa" : "#2563eb";
|
|
27759
|
+
context.fillRect(boxLeft + 1.5, boxTop + 1.5, Math.max(0, boxSize - 3), Math.max(0, boxSize - 3));
|
|
27760
|
+
}
|
|
27761
|
+
} else if (cellData.sparkline) {
|
|
27762
|
+
const sparkline = cellData.sparkline.config;
|
|
27763
|
+
const sparklineValues = cellData.sparkline.values;
|
|
27764
|
+
const points = sparklineValues.map((value, index) => ({ index, value })).filter((entry) => typeof entry.value === "number" && Number.isFinite(entry.value));
|
|
27765
|
+
if (points.length > 1) {
|
|
27766
|
+
const minValue = Math.min(...points.map((entry) => entry.value));
|
|
27767
|
+
const maxValue = Math.max(...points.map((entry) => entry.value));
|
|
27768
|
+
const sparkLeft = contentLeft + 1;
|
|
27769
|
+
const sparkTop = contentTop + 2;
|
|
27770
|
+
const sparkWidth = Math.max(1, contentWidth - 2);
|
|
27771
|
+
const sparkHeight = Math.max(1, contentHeight - 4);
|
|
27772
|
+
const xStep = points.length > 1 ? sparkWidth / (points.length - 1) : 0;
|
|
27773
|
+
context.strokeStyle = sparkline.color ?? "#2563eb";
|
|
27774
|
+
context.lineCap = "round";
|
|
27775
|
+
context.lineJoin = "round";
|
|
27776
|
+
context.lineWidth = 1.25;
|
|
27777
|
+
context.beginPath();
|
|
27778
|
+
points.forEach((entry, index) => {
|
|
27779
|
+
const x = sparkLeft + index * xStep;
|
|
27780
|
+
const y = sparkTop + sparkHeight - clampSparklineValue(entry.value, minValue, maxValue) * sparkHeight;
|
|
27781
|
+
if (index === 0) {
|
|
27782
|
+
context.moveTo(x, y);
|
|
27783
|
+
} else {
|
|
27784
|
+
context.lineTo(x, y);
|
|
27785
|
+
}
|
|
27786
|
+
});
|
|
27787
|
+
context.stroke();
|
|
27788
|
+
}
|
|
27789
|
+
} else if (rawText.length > 0) {
|
|
27790
|
+
const align = canvasCellStyle.textAlign;
|
|
27791
|
+
context.textAlign = align;
|
|
27792
|
+
const textX = align === "right" ? contentLeft + contentWidth : align === "center" ? contentLeft + contentWidth / 2 : contentLeft;
|
|
27793
|
+
const textY = contentTop + contentHeight / 2;
|
|
27794
|
+
const trailingInset = cellData.conditionalIcon ? 18 : 0;
|
|
27795
|
+
const maxTextWidth = Math.max(0, contentWidth - trailingInset);
|
|
27796
|
+
if (cellData.textRotationDeg) {
|
|
27797
|
+
const rotationOriginX = contentLeft + contentWidth / 2;
|
|
27798
|
+
context.save();
|
|
27799
|
+
context.translate(rotationOriginX, textY);
|
|
27800
|
+
context.rotate(cellData.textRotationDeg * Math.PI / 180);
|
|
27801
|
+
context.fillText(
|
|
27802
|
+
rawText,
|
|
27803
|
+
align === "right" ? contentWidth / 2 : align === "center" ? 0 : -(contentWidth / 2),
|
|
27804
|
+
0
|
|
27805
|
+
);
|
|
27806
|
+
context.restore();
|
|
27807
|
+
} else if (canvasCellStyle.usesWrappedText || rawText.includes("\n")) {
|
|
27808
|
+
const lines = wrapCanvasText(context, rawText, maxTextWidth);
|
|
27809
|
+
const lineHeight = resolveCanvasLineHeight(cellData.style, 12);
|
|
27810
|
+
const textBlockHeight = lines.length * lineHeight;
|
|
27811
|
+
let textBlockTop = contentTop;
|
|
27812
|
+
if (cellData.style.verticalAlign === "middle") {
|
|
27813
|
+
textBlockTop = contentTop + (contentHeight - textBlockHeight) / 2;
|
|
27814
|
+
} else if (cellData.style.verticalAlign !== "top") {
|
|
27815
|
+
textBlockTop = contentTop + contentHeight - textBlockHeight;
|
|
27816
|
+
}
|
|
27817
|
+
lines.forEach((line, lineIndex) => {
|
|
27818
|
+
context.fillText(line, textX, textBlockTop + lineIndex * lineHeight + lineHeight / 2);
|
|
27819
|
+
});
|
|
27820
|
+
} else {
|
|
27821
|
+
const text = canvasCellStyle.textOverflowEllipsis ? truncateCanvasText(context, rawText, maxTextWidth) : rawText;
|
|
27822
|
+
context.fillText(text, textX, textY);
|
|
27823
|
+
}
|
|
27824
|
+
}
|
|
27825
|
+
if (cellData.conditionalIcon) {
|
|
27826
|
+
const iconSize = 10;
|
|
27827
|
+
const iconX = rect.left + rect.width - (padding.right + iconSize + 4);
|
|
27828
|
+
const iconY = rect.top + rect.height / 2;
|
|
27829
|
+
drawCanvasConditionalIcon(context, cellData.conditionalIcon, iconX + iconSize / 2, iconY, iconSize);
|
|
27830
|
+
}
|
|
27831
|
+
context.restore();
|
|
27832
|
+
}
|
|
27833
|
+
}
|
|
27834
|
+
if (includeHeaders) {
|
|
27835
|
+
context.strokeStyle = palette.border;
|
|
27836
|
+
context.lineWidth = 1;
|
|
27837
|
+
context.font = "600 11px ui-sans-serif, system-ui, sans-serif";
|
|
27838
|
+
context.fillStyle = palette.mutedText;
|
|
27839
|
+
context.textBaseline = "middle";
|
|
27840
|
+
for (const colItem of colAxis.items) {
|
|
27841
|
+
const left = rowHeaderWidth + colItem.start;
|
|
27842
|
+
context.beginPath();
|
|
27843
|
+
context.moveTo(left + colItem.size - 0.5, 0);
|
|
27844
|
+
context.lineTo(left + colItem.size - 0.5, headerHeight);
|
|
27845
|
+
context.moveTo(left, headerHeight - 0.5);
|
|
27846
|
+
context.lineTo(left + colItem.size, headerHeight - 0.5);
|
|
27847
|
+
context.stroke();
|
|
27848
|
+
context.textAlign = "center";
|
|
27849
|
+
context.fillText(columnLabel2(colItem.actualIndex), left + colItem.size / 2, headerHeight / 2);
|
|
27850
|
+
}
|
|
27851
|
+
for (const rowItem of rowAxis.items) {
|
|
27852
|
+
const top = headerHeight + rowItem.start;
|
|
27853
|
+
context.beginPath();
|
|
27854
|
+
context.moveTo(0, top + rowItem.size - 0.5);
|
|
27855
|
+
context.lineTo(rowHeaderWidth, top + rowItem.size - 0.5);
|
|
27856
|
+
context.moveTo(rowHeaderWidth - 0.5, top);
|
|
27857
|
+
context.lineTo(rowHeaderWidth - 0.5, top + rowItem.size);
|
|
27858
|
+
context.stroke();
|
|
27859
|
+
context.textAlign = "center";
|
|
27860
|
+
context.fillText(`${rowItem.actualIndex + 1}`, rowHeaderWidth / 2, top + rowItem.size / 2);
|
|
27861
|
+
}
|
|
27862
|
+
context.beginPath();
|
|
27863
|
+
context.moveTo(rowHeaderWidth - 0.5, 0);
|
|
27864
|
+
context.lineTo(rowHeaderWidth - 0.5, headerHeight);
|
|
27865
|
+
context.moveTo(0, headerHeight - 0.5);
|
|
27866
|
+
context.lineTo(rowHeaderWidth, headerHeight - 0.5);
|
|
27867
|
+
context.stroke();
|
|
27868
|
+
}
|
|
27869
|
+
return true;
|
|
27870
|
+
};
|
|
27871
|
+
const plan = {
|
|
27872
|
+
aspectRatio: sourceWidth / Math.max(1, sourceHeight),
|
|
27873
|
+
contentHeight: rowAxis.totalSize,
|
|
27874
|
+
contentWidth: colAxis.totalSize,
|
|
27875
|
+
height: outputSize.height,
|
|
27876
|
+
paint,
|
|
27877
|
+
sourceRange,
|
|
27878
|
+
width: outputSize.width
|
|
27879
|
+
};
|
|
27880
|
+
return {
|
|
27881
|
+
...plan,
|
|
27882
|
+
sheet,
|
|
27883
|
+
sheetIndex,
|
|
27884
|
+
workbookSheetIndex: sheet.workbookSheetIndex
|
|
27885
|
+
};
|
|
27886
|
+
});
|
|
27887
|
+
}, [includeHeaders, palette, resolution, sheets, workbook]);
|
|
27888
|
+
const paintThumbnail = React4.useCallback(
|
|
27889
|
+
(sheetIndex, canvas) => thumbnails[sheetIndex]?.paint(canvas) ?? false,
|
|
27890
|
+
[thumbnails]
|
|
27891
|
+
);
|
|
27892
|
+
return React4.useMemo(
|
|
27893
|
+
() => ({
|
|
27894
|
+
paintThumbnail,
|
|
27895
|
+
thumbnails
|
|
27896
|
+
}),
|
|
27897
|
+
[paintThumbnail, thumbnails]
|
|
27898
|
+
);
|
|
27899
|
+
}
|
|
26830
27900
|
function XlsxViewer(props) {
|
|
26831
27901
|
const contextController = React4.useContext(ViewerContext);
|
|
26832
27902
|
if (props.controller) {
|
|
@@ -26856,6 +27926,7 @@ function DefaultXlsxToolbar() {
|
|
|
26856
27926
|
useXlsxViewerImages,
|
|
26857
27927
|
useXlsxViewerSelection,
|
|
26858
27928
|
useXlsxViewerTables,
|
|
27929
|
+
useXlsxViewerThumbnails,
|
|
26859
27930
|
useXlsxViewerZoom
|
|
26860
27931
|
});
|
|
26861
27932
|
//# sourceMappingURL=index.cjs.map
|