@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.js
CHANGED
|
@@ -4220,13 +4220,36 @@ function parseWorkbookTableMetadata(archive, workbookSheets) {
|
|
|
4220
4220
|
}
|
|
4221
4221
|
return [{
|
|
4222
4222
|
displayName: tableNode.getAttribute("displayName") ?? void 0,
|
|
4223
|
+
headerRowCount: parseWorkbookTableCount(tableNode.getAttribute("headerRowCount"), 1),
|
|
4223
4224
|
headerRowCellStyle: tableNode.getAttribute("headerRowCellStyle") ?? void 0,
|
|
4224
4225
|
name: tableNode.getAttribute("name") ?? void 0,
|
|
4225
|
-
reference: tableNode.getAttribute("ref") ?? void 0
|
|
4226
|
+
reference: tableNode.getAttribute("ref") ?? void 0,
|
|
4227
|
+
totalsRowCount: parseWorkbookTableCount(tableNode.getAttribute("totalsRowCount"), 0),
|
|
4228
|
+
totalsRowShown: parseWorkbookTableBoolean(tableNode.getAttribute("totalsRowShown"), false)
|
|
4226
4229
|
}];
|
|
4227
4230
|
});
|
|
4228
4231
|
});
|
|
4229
4232
|
}
|
|
4233
|
+
function parseWorkbookTableCount(value, fallback) {
|
|
4234
|
+
if (value === null) {
|
|
4235
|
+
return fallback;
|
|
4236
|
+
}
|
|
4237
|
+
const parsed = Number.parseInt(value, 10);
|
|
4238
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : fallback;
|
|
4239
|
+
}
|
|
4240
|
+
function parseWorkbookTableBoolean(value, fallback) {
|
|
4241
|
+
if (value === null) {
|
|
4242
|
+
return fallback;
|
|
4243
|
+
}
|
|
4244
|
+
const normalized = value.trim().toLowerCase();
|
|
4245
|
+
if (normalized === "0" || normalized === "false" || normalized === "") {
|
|
4246
|
+
return false;
|
|
4247
|
+
}
|
|
4248
|
+
if (normalized === "1" || normalized === "true") {
|
|
4249
|
+
return true;
|
|
4250
|
+
}
|
|
4251
|
+
return fallback;
|
|
4252
|
+
}
|
|
4230
4253
|
function parseSqrefRanges(sqref) {
|
|
4231
4254
|
if (!sqref) {
|
|
4232
4255
|
return [];
|
|
@@ -6832,17 +6855,18 @@ function rangeContainsCell(range, cell) {
|
|
|
6832
6855
|
function mapWorksheetTables(worksheet, metadataForSheet) {
|
|
6833
6856
|
const rawTables = worksheet?.tables ?? [];
|
|
6834
6857
|
return rawTables.flatMap((table, index) => {
|
|
6835
|
-
const reference = typeof table.reference === "string" ? table.reference : "";
|
|
6836
|
-
const parsedRange = parseA1RangeReference2(reference);
|
|
6837
|
-
if (!parsedRange) {
|
|
6838
|
-
return [];
|
|
6839
|
-
}
|
|
6840
6858
|
const rawColumns = Array.isArray(table.columns) ? table.columns : [];
|
|
6841
6859
|
const rawName = typeof table.name === "string" ? table.name : `Table${index + 1}`;
|
|
6842
6860
|
const rawDisplayName = typeof table.displayName === "string" ? table.displayName : typeof table.name === "string" ? table.name : `Table ${index + 1}`;
|
|
6843
6861
|
const metadata = metadataForSheet?.find(
|
|
6844
|
-
(entry) => entry.name && entry.name === rawName || entry.displayName && entry.displayName === rawDisplayName || entry.reference && entry.reference === reference
|
|
6862
|
+
(entry) => entry.name && entry.name === rawName || entry.displayName && entry.displayName === rawDisplayName || entry.reference && entry.reference === table.reference
|
|
6845
6863
|
);
|
|
6864
|
+
const rawReference = typeof table.reference === "string" ? table.reference : "";
|
|
6865
|
+
const reference = metadata?.reference ?? rawReference;
|
|
6866
|
+
const parsedRange = parseA1RangeReference2(reference);
|
|
6867
|
+
if (!parsedRange) {
|
|
6868
|
+
return [];
|
|
6869
|
+
}
|
|
6846
6870
|
return [{
|
|
6847
6871
|
columns: rawColumns.map((column, columnIndex) => ({
|
|
6848
6872
|
id: typeof column.id === "number" ? column.id ?? columnIndex + 1 : columnIndex + 1,
|
|
@@ -6851,17 +6875,47 @@ function mapWorksheetTables(worksheet, metadataForSheet) {
|
|
|
6851
6875
|
})),
|
|
6852
6876
|
displayName: rawDisplayName,
|
|
6853
6877
|
end: parsedRange.end,
|
|
6854
|
-
headerRowCount:
|
|
6878
|
+
headerRowCount: metadata?.headerRowCount ?? resolveWorkbookTableCount(table.headerRowCount, 1),
|
|
6855
6879
|
headerRowCellStyle: metadata?.headerRowCellStyle,
|
|
6856
6880
|
name: rawName,
|
|
6857
6881
|
reference,
|
|
6858
6882
|
start: parsedRange.start,
|
|
6859
6883
|
styleInfo: table.styleInfo,
|
|
6860
|
-
totalsRowCount:
|
|
6861
|
-
totalsRowShown:
|
|
6884
|
+
totalsRowCount: metadata?.totalsRowCount ?? resolveWorkbookTableCount(table.totalsRowCount, 0),
|
|
6885
|
+
totalsRowShown: metadata?.totalsRowShown ?? resolveWorkbookTableBoolean(table.totalsRowShown)
|
|
6862
6886
|
}];
|
|
6863
6887
|
});
|
|
6864
6888
|
}
|
|
6889
|
+
function resolveWorkbookTableCount(value, fallback) {
|
|
6890
|
+
if (typeof value === "number" && Number.isFinite(value) && value >= 0) {
|
|
6891
|
+
return value;
|
|
6892
|
+
}
|
|
6893
|
+
if (typeof value === "string") {
|
|
6894
|
+
const parsed = Number.parseInt(value, 10);
|
|
6895
|
+
if (Number.isFinite(parsed) && parsed >= 0) {
|
|
6896
|
+
return parsed;
|
|
6897
|
+
}
|
|
6898
|
+
}
|
|
6899
|
+
return fallback;
|
|
6900
|
+
}
|
|
6901
|
+
function resolveWorkbookTableBoolean(value) {
|
|
6902
|
+
if (typeof value === "boolean") {
|
|
6903
|
+
return value;
|
|
6904
|
+
}
|
|
6905
|
+
if (typeof value === "number") {
|
|
6906
|
+
return value !== 0;
|
|
6907
|
+
}
|
|
6908
|
+
if (typeof value === "string") {
|
|
6909
|
+
const normalized = value.trim().toLowerCase();
|
|
6910
|
+
if (normalized === "0" || normalized === "false" || normalized === "") {
|
|
6911
|
+
return false;
|
|
6912
|
+
}
|
|
6913
|
+
if (normalized === "1" || normalized === "true") {
|
|
6914
|
+
return true;
|
|
6915
|
+
}
|
|
6916
|
+
}
|
|
6917
|
+
return false;
|
|
6918
|
+
}
|
|
6865
6919
|
function fileStem(fileName) {
|
|
6866
6920
|
const normalized = fileName.trim();
|
|
6867
6921
|
const lastDot = normalized.lastIndexOf(".");
|
|
@@ -6992,7 +7046,17 @@ async function resolveWorkbookBuffer({ file, src }, signal) {
|
|
|
6992
7046
|
if (file) {
|
|
6993
7047
|
buffer = file;
|
|
6994
7048
|
} else if (src) {
|
|
6995
|
-
|
|
7049
|
+
let response;
|
|
7050
|
+
try {
|
|
7051
|
+
response = await fetch(src, { signal });
|
|
7052
|
+
} catch (error) {
|
|
7053
|
+
if (isAbortError(error)) {
|
|
7054
|
+
throw error;
|
|
7055
|
+
}
|
|
7056
|
+
throw new Error(
|
|
7057
|
+
"Failed to fetch workbook. The remote URL may be blocked by CORS, unavailable, or not directly downloadable from the browser."
|
|
7058
|
+
);
|
|
7059
|
+
}
|
|
6996
7060
|
if (!response.ok) {
|
|
6997
7061
|
throw new Error(`Failed to fetch workbook (status ${response.status})`);
|
|
6998
7062
|
}
|
|
@@ -7548,6 +7612,7 @@ function downloadUrl(src, fileName) {
|
|
|
7548
7612
|
}
|
|
7549
7613
|
function useXlsxViewerController(options) {
|
|
7550
7614
|
const {
|
|
7615
|
+
allowResizeInReadOnly = false,
|
|
7551
7616
|
deferLoadingAboveBytes = DEFAULT_DEFER_LOADING_ABOVE_BYTES,
|
|
7552
7617
|
file,
|
|
7553
7618
|
fileName,
|
|
@@ -7601,6 +7666,7 @@ function useXlsxViewerController(options) {
|
|
|
7601
7666
|
const displayFileName = React.useMemo(() => resolveDisplayFileName(src, fileName), [fileName, src]);
|
|
7602
7667
|
const shouldDeferLoading = deferLoadingAboveBytes > 0;
|
|
7603
7668
|
const readOnly = requestedReadOnly || forcedReadOnly;
|
|
7669
|
+
const canResizeReadOnly = requestedReadOnly && allowResizeInReadOnly && !forcedReadOnly;
|
|
7604
7670
|
const workerSupported = useWorker && typeof Worker !== "undefined";
|
|
7605
7671
|
const shouldUseWorker = workerSupported && forcedReadOnly;
|
|
7606
7672
|
const shouldForceReadOnlyForBuffer = React.useCallback((bufferByteLength) => !requestedReadOnly && readOnlyAboveBytes > 0 && bufferByteLength > readOnlyAboveBytes, [readOnlyAboveBytes, requestedReadOnly]);
|
|
@@ -8895,7 +8961,7 @@ function useXlsxViewerController(options) {
|
|
|
8895
8961
|
refreshWorkbookState(workbook);
|
|
8896
8962
|
}, [refreshWorkbookState, workbook]);
|
|
8897
8963
|
const resizeColumn = React.useCallback((col, widthPx) => {
|
|
8898
|
-
if (readOnly || !workbook || !activeSheet) {
|
|
8964
|
+
if (readOnly && !canResizeReadOnly || !workbook || !activeSheet) {
|
|
8899
8965
|
return;
|
|
8900
8966
|
}
|
|
8901
8967
|
recordHistoryBeforeMutation();
|
|
@@ -8905,9 +8971,9 @@ function useXlsxViewerController(options) {
|
|
|
8905
8971
|
pxToSheetColumnWidth(resolveContentSheetAxisPixels(widthPx, activeSheet.showGridLines))
|
|
8906
8972
|
);
|
|
8907
8973
|
refreshWorkbookState(workbook);
|
|
8908
|
-
}, [activeSheet, readOnly, recordHistoryBeforeMutation, refreshWorkbookState, workbook]);
|
|
8974
|
+
}, [activeSheet, canResizeReadOnly, readOnly, recordHistoryBeforeMutation, refreshWorkbookState, workbook]);
|
|
8909
8975
|
const resizeRow = React.useCallback((row, heightPx) => {
|
|
8910
|
-
if (readOnly || !workbook || !activeSheet) {
|
|
8976
|
+
if (readOnly && !canResizeReadOnly || !workbook || !activeSheet) {
|
|
8911
8977
|
return;
|
|
8912
8978
|
}
|
|
8913
8979
|
recordHistoryBeforeMutation();
|
|
@@ -8917,7 +8983,7 @@ function useXlsxViewerController(options) {
|
|
|
8917
8983
|
pxToSheetRowHeight(resolveContentSheetAxisPixels(heightPx, activeSheet.showGridLines))
|
|
8918
8984
|
);
|
|
8919
8985
|
refreshWorkbookState(workbook);
|
|
8920
|
-
}, [activeSheet, readOnly, recordHistoryBeforeMutation, refreshWorkbookState, workbook]);
|
|
8986
|
+
}, [activeSheet, canResizeReadOnly, readOnly, recordHistoryBeforeMutation, refreshWorkbookState, workbook]);
|
|
8921
8987
|
const resolveAnchoredObjectRect = React.useCallback((anchor, worksheet) => {
|
|
8922
8988
|
const resolveAxisSum = (index, getSize) => {
|
|
8923
8989
|
let total = 0;
|
|
@@ -16317,6 +16383,13 @@ var IMAGE_MIN_SIZE_PX = 16;
|
|
|
16317
16383
|
var IMAGE_HANDLE_SIZE_PX = 10;
|
|
16318
16384
|
var CANVAS_RESIZE_HIT_SLOP_PX = 8;
|
|
16319
16385
|
var CANVAS_VIEWPORT_OVERSCAN_PX = 240;
|
|
16386
|
+
var THUMBNAIL_DEFAULT_MAX_DIMENSION = 192;
|
|
16387
|
+
var THUMBNAIL_FALLBACK_ROWS = 12;
|
|
16388
|
+
var THUMBNAIL_FALLBACK_COLS = 8;
|
|
16389
|
+
var THUMBNAIL_MAX_ROWS = 200;
|
|
16390
|
+
var THUMBNAIL_MAX_COLS = 80;
|
|
16391
|
+
var THUMBNAIL_MAX_SOURCE_HEIGHT_PX = 900;
|
|
16392
|
+
var THUMBNAIL_MAX_SOURCE_WIDTH_PX = 1440;
|
|
16320
16393
|
var LIVE_ZOOM_COMMIT_IDLE_MS = 48;
|
|
16321
16394
|
var WHEEL_ZOOM_SENSITIVITY = 25e-5;
|
|
16322
16395
|
var WHEEL_LINE_DELTA_PX = 16;
|
|
@@ -18323,6 +18396,97 @@ function resolveImageHandleStyle(position, stroke, surface, scale = 1) {
|
|
|
18323
18396
|
function useViewerPalette(isDark = false) {
|
|
18324
18397
|
return isDark ? DARK_PALETTE : LIGHT_PALETTE;
|
|
18325
18398
|
}
|
|
18399
|
+
function normalizeThumbnailResolution(resolution) {
|
|
18400
|
+
if (typeof resolution === "number" && Number.isFinite(resolution) && resolution > 0) {
|
|
18401
|
+
return {
|
|
18402
|
+
maxHeight: resolution,
|
|
18403
|
+
maxWidth: resolution
|
|
18404
|
+
};
|
|
18405
|
+
}
|
|
18406
|
+
const resolvedObject = typeof resolution === "object" && resolution ? resolution : void 0;
|
|
18407
|
+
return {
|
|
18408
|
+
maxHeight: resolvedObject?.maxHeight && Number.isFinite(resolvedObject.maxHeight) && resolvedObject.maxHeight > 0 ? resolvedObject.maxHeight : THUMBNAIL_DEFAULT_MAX_DIMENSION,
|
|
18409
|
+
maxWidth: resolvedObject?.maxWidth && Number.isFinite(resolvedObject.maxWidth) && resolvedObject.maxWidth > 0 ? resolvedObject.maxWidth : THUMBNAIL_DEFAULT_MAX_DIMENSION
|
|
18410
|
+
};
|
|
18411
|
+
}
|
|
18412
|
+
function resolveThumbnailOutputSize(sourceWidth, sourceHeight, resolution) {
|
|
18413
|
+
const normalized = normalizeThumbnailResolution(resolution);
|
|
18414
|
+
const safeSourceWidth = Math.max(1, sourceWidth);
|
|
18415
|
+
const safeSourceHeight = Math.max(1, sourceHeight);
|
|
18416
|
+
const scale = Math.min(
|
|
18417
|
+
normalized.maxWidth / safeSourceWidth,
|
|
18418
|
+
normalized.maxHeight / safeSourceHeight,
|
|
18419
|
+
1
|
|
18420
|
+
);
|
|
18421
|
+
return {
|
|
18422
|
+
height: Math.max(1, Math.round(safeSourceHeight * scale)),
|
|
18423
|
+
maxHeight: normalized.maxHeight,
|
|
18424
|
+
maxWidth: normalized.maxWidth,
|
|
18425
|
+
scale,
|
|
18426
|
+
width: Math.max(1, Math.round(safeSourceWidth * scale))
|
|
18427
|
+
};
|
|
18428
|
+
}
|
|
18429
|
+
function resolveThumbnailAxisIndices({
|
|
18430
|
+
fallbackCount,
|
|
18431
|
+
getSizePx,
|
|
18432
|
+
maxCount,
|
|
18433
|
+
maxLogicalPixels,
|
|
18434
|
+
maxUsedIndex,
|
|
18435
|
+
minUsedIndex,
|
|
18436
|
+
precomputed
|
|
18437
|
+
}) {
|
|
18438
|
+
const sourceIndices = precomputed.length > 0 ? precomputed : Array.from({
|
|
18439
|
+
length: Math.max(fallbackCount, Math.max(0, maxUsedIndex + 1))
|
|
18440
|
+
}, (_, index) => index);
|
|
18441
|
+
const hasUsedRange = maxUsedIndex >= minUsedIndex && maxUsedIndex >= 0;
|
|
18442
|
+
const preferredStart = hasUsedRange ? Math.max(0, minUsedIndex) : 0;
|
|
18443
|
+
const preferredEnd = hasUsedRange ? maxUsedIndex : Math.max(0, preferredStart + fallbackCount - 1);
|
|
18444
|
+
const picked = [];
|
|
18445
|
+
let totalSize = 0;
|
|
18446
|
+
for (const actualIndex of sourceIndices) {
|
|
18447
|
+
if (actualIndex < preferredStart) {
|
|
18448
|
+
continue;
|
|
18449
|
+
}
|
|
18450
|
+
if (hasUsedRange && actualIndex > preferredEnd) {
|
|
18451
|
+
break;
|
|
18452
|
+
}
|
|
18453
|
+
const size = Math.max(1, getSizePx(actualIndex));
|
|
18454
|
+
picked.push(actualIndex);
|
|
18455
|
+
totalSize += size;
|
|
18456
|
+
if (picked.length >= maxCount || totalSize >= maxLogicalPixels) {
|
|
18457
|
+
break;
|
|
18458
|
+
}
|
|
18459
|
+
}
|
|
18460
|
+
if (picked.length > 0) {
|
|
18461
|
+
return picked;
|
|
18462
|
+
}
|
|
18463
|
+
for (const actualIndex of sourceIndices) {
|
|
18464
|
+
const size = Math.max(1, getSizePx(actualIndex));
|
|
18465
|
+
picked.push(actualIndex);
|
|
18466
|
+
totalSize += size;
|
|
18467
|
+
if (picked.length >= fallbackCount || picked.length >= maxCount || totalSize >= maxLogicalPixels) {
|
|
18468
|
+
break;
|
|
18469
|
+
}
|
|
18470
|
+
}
|
|
18471
|
+
return picked.length > 0 ? picked : [0];
|
|
18472
|
+
}
|
|
18473
|
+
function buildThumbnailAxisItems(actualIndices, getSizePx) {
|
|
18474
|
+
const items = [];
|
|
18475
|
+
let offset = 0;
|
|
18476
|
+
for (const actualIndex of actualIndices) {
|
|
18477
|
+
const size = Math.max(1, getSizePx(actualIndex));
|
|
18478
|
+
items.push({
|
|
18479
|
+
actualIndex,
|
|
18480
|
+
size,
|
|
18481
|
+
start: offset
|
|
18482
|
+
});
|
|
18483
|
+
offset += size;
|
|
18484
|
+
}
|
|
18485
|
+
return {
|
|
18486
|
+
items,
|
|
18487
|
+
totalSize: offset
|
|
18488
|
+
};
|
|
18489
|
+
}
|
|
18326
18490
|
function columnLabel2(col) {
|
|
18327
18491
|
let label = "";
|
|
18328
18492
|
let nextValue = col;
|
|
@@ -19229,7 +19393,6 @@ function getTableHeaderColumn(table, row, col) {
|
|
|
19229
19393
|
return table.columns[index] ?? null;
|
|
19230
19394
|
}
|
|
19231
19395
|
function DefaultTableHeaderMenu({
|
|
19232
|
-
close,
|
|
19233
19396
|
direction,
|
|
19234
19397
|
sortAscending,
|
|
19235
19398
|
sortDescending
|
|
@@ -19251,10 +19414,7 @@ function DefaultTableHeaderMenu({
|
|
|
19251
19414
|
/* @__PURE__ */ jsx3(
|
|
19252
19415
|
"button",
|
|
19253
19416
|
{
|
|
19254
|
-
onClick:
|
|
19255
|
-
sortAscending();
|
|
19256
|
-
close();
|
|
19257
|
-
},
|
|
19417
|
+
onClick: sortAscending,
|
|
19258
19418
|
style: {
|
|
19259
19419
|
background: direction === "ascending" ? "var(--xlsx-menu-active)" : "transparent",
|
|
19260
19420
|
border: "none",
|
|
@@ -19272,10 +19432,7 @@ function DefaultTableHeaderMenu({
|
|
|
19272
19432
|
/* @__PURE__ */ jsx3(
|
|
19273
19433
|
"button",
|
|
19274
19434
|
{
|
|
19275
|
-
onClick:
|
|
19276
|
-
sortDescending();
|
|
19277
|
-
close();
|
|
19278
|
-
},
|
|
19435
|
+
onClick: sortDescending,
|
|
19279
19436
|
style: {
|
|
19280
19437
|
background: direction === "descending" ? "var(--xlsx-menu-active)" : "transparent",
|
|
19281
19438
|
border: "none",
|
|
@@ -19294,6 +19451,25 @@ function DefaultTableHeaderMenu({
|
|
|
19294
19451
|
}
|
|
19295
19452
|
);
|
|
19296
19453
|
}
|
|
19454
|
+
function resolveTableHeaderTriggerStyle(palette, zoomFactor) {
|
|
19455
|
+
return {
|
|
19456
|
+
alignItems: "center",
|
|
19457
|
+
background: "transparent",
|
|
19458
|
+
border: "none",
|
|
19459
|
+
color: palette.mutedText,
|
|
19460
|
+
cursor: "pointer",
|
|
19461
|
+
display: "inline-flex",
|
|
19462
|
+
fontSize: 10 * zoomFactor,
|
|
19463
|
+
height: 16 * zoomFactor,
|
|
19464
|
+
justifyContent: "center",
|
|
19465
|
+
padding: 0,
|
|
19466
|
+
position: "absolute",
|
|
19467
|
+
right: 4 * zoomFactor,
|
|
19468
|
+
top: 3 * zoomFactor,
|
|
19469
|
+
width: 16 * zoomFactor,
|
|
19470
|
+
zIndex: 6
|
|
19471
|
+
};
|
|
19472
|
+
}
|
|
19297
19473
|
function SegmentedControl({
|
|
19298
19474
|
items,
|
|
19299
19475
|
onValueChange,
|
|
@@ -19802,6 +19978,109 @@ function resolveSelectionColors({
|
|
|
19802
19978
|
stroke
|
|
19803
19979
|
};
|
|
19804
19980
|
}
|
|
19981
|
+
function buildFullCanvasDirtyRect(width, height) {
|
|
19982
|
+
if (width <= 0 || height <= 0) {
|
|
19983
|
+
return [];
|
|
19984
|
+
}
|
|
19985
|
+
return [{
|
|
19986
|
+
height,
|
|
19987
|
+
left: 0,
|
|
19988
|
+
top: 0,
|
|
19989
|
+
width
|
|
19990
|
+
}];
|
|
19991
|
+
}
|
|
19992
|
+
function intersectsCanvasDirtyRects(left, top, width, height, dirtyRects) {
|
|
19993
|
+
if (dirtyRects.length === 0 || width <= 0 || height <= 0) {
|
|
19994
|
+
return false;
|
|
19995
|
+
}
|
|
19996
|
+
const right = left + width;
|
|
19997
|
+
const bottom = top + height;
|
|
19998
|
+
return dirtyRects.some((dirtyRect) => left < dirtyRect.left + dirtyRect.width && right > dirtyRect.left && top < dirtyRect.top + dirtyRect.height && bottom > dirtyRect.top);
|
|
19999
|
+
}
|
|
20000
|
+
function blitCanvasWithScrollDelta(canvas, context, bufferCanvas, dpr, width, height, deltaX, deltaY) {
|
|
20001
|
+
if (width <= 0 || height <= 0) {
|
|
20002
|
+
return [];
|
|
20003
|
+
}
|
|
20004
|
+
const clampedDeltaX = Math.max(-width, Math.min(width, deltaX));
|
|
20005
|
+
const clampedDeltaY = Math.max(-height, Math.min(height, deltaY));
|
|
20006
|
+
if (Math.abs(clampedDeltaX) < 0.01 && Math.abs(clampedDeltaY) < 0.01) {
|
|
20007
|
+
return [];
|
|
20008
|
+
}
|
|
20009
|
+
if (Math.abs(clampedDeltaX) >= width || Math.abs(clampedDeltaY) >= height) {
|
|
20010
|
+
return null;
|
|
20011
|
+
}
|
|
20012
|
+
const deviceWidth = Math.max(1, Math.round(width * dpr));
|
|
20013
|
+
const deviceHeight = Math.max(1, Math.round(height * dpr));
|
|
20014
|
+
if (bufferCanvas.width !== deviceWidth) {
|
|
20015
|
+
bufferCanvas.width = deviceWidth;
|
|
20016
|
+
}
|
|
20017
|
+
if (bufferCanvas.height !== deviceHeight) {
|
|
20018
|
+
bufferCanvas.height = deviceHeight;
|
|
20019
|
+
}
|
|
20020
|
+
const bufferContext = bufferCanvas.getContext("2d");
|
|
20021
|
+
if (!bufferContext) {
|
|
20022
|
+
return null;
|
|
20023
|
+
}
|
|
20024
|
+
bufferContext.setTransform(1, 0, 0, 1, 0, 0);
|
|
20025
|
+
bufferContext.clearRect(0, 0, deviceWidth, deviceHeight);
|
|
20026
|
+
bufferContext.drawImage(canvas, 0, 0);
|
|
20027
|
+
const deltaDeviceX = clampedDeltaX * dpr;
|
|
20028
|
+
const deltaDeviceY = clampedDeltaY * dpr;
|
|
20029
|
+
const overlapDeviceWidth = deviceWidth - Math.abs(deltaDeviceX);
|
|
20030
|
+
const overlapDeviceHeight = deviceHeight - Math.abs(deltaDeviceY);
|
|
20031
|
+
if (overlapDeviceWidth <= 0 || overlapDeviceHeight <= 0) {
|
|
20032
|
+
return null;
|
|
20033
|
+
}
|
|
20034
|
+
const sourceX = deltaDeviceX > 0 ? deltaDeviceX : 0;
|
|
20035
|
+
const sourceY = deltaDeviceY > 0 ? deltaDeviceY : 0;
|
|
20036
|
+
const destinationX = deltaDeviceX > 0 ? 0 : -deltaDeviceX;
|
|
20037
|
+
const destinationY = deltaDeviceY > 0 ? 0 : -deltaDeviceY;
|
|
20038
|
+
context.setTransform(1, 0, 0, 1, 0, 0);
|
|
20039
|
+
context.drawImage(
|
|
20040
|
+
bufferCanvas,
|
|
20041
|
+
sourceX,
|
|
20042
|
+
sourceY,
|
|
20043
|
+
overlapDeviceWidth,
|
|
20044
|
+
overlapDeviceHeight,
|
|
20045
|
+
destinationX,
|
|
20046
|
+
destinationY,
|
|
20047
|
+
overlapDeviceWidth,
|
|
20048
|
+
overlapDeviceHeight
|
|
20049
|
+
);
|
|
20050
|
+
context.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
20051
|
+
const dirtyRects = [];
|
|
20052
|
+
if (clampedDeltaX > 0) {
|
|
20053
|
+
dirtyRects.push({
|
|
20054
|
+
height,
|
|
20055
|
+
left: Math.max(0, width - clampedDeltaX),
|
|
20056
|
+
top: 0,
|
|
20057
|
+
width: Math.min(width, clampedDeltaX)
|
|
20058
|
+
});
|
|
20059
|
+
} else if (clampedDeltaX < 0) {
|
|
20060
|
+
dirtyRects.push({
|
|
20061
|
+
height,
|
|
20062
|
+
left: 0,
|
|
20063
|
+
top: 0,
|
|
20064
|
+
width: Math.min(width, -clampedDeltaX)
|
|
20065
|
+
});
|
|
20066
|
+
}
|
|
20067
|
+
if (clampedDeltaY > 0) {
|
|
20068
|
+
dirtyRects.push({
|
|
20069
|
+
height: Math.min(height, clampedDeltaY),
|
|
20070
|
+
left: 0,
|
|
20071
|
+
top: Math.max(0, height - clampedDeltaY),
|
|
20072
|
+
width
|
|
20073
|
+
});
|
|
20074
|
+
} else if (clampedDeltaY < 0) {
|
|
20075
|
+
dirtyRects.push({
|
|
20076
|
+
height: Math.min(height, -clampedDeltaY),
|
|
20077
|
+
left: 0,
|
|
20078
|
+
top: 0,
|
|
20079
|
+
width
|
|
20080
|
+
});
|
|
20081
|
+
}
|
|
20082
|
+
return dirtyRects;
|
|
20083
|
+
}
|
|
19805
20084
|
function buildConditionalFormatRuleKey(rule) {
|
|
19806
20085
|
return `${rule.kind}:${rule.priority}:${rule.ranges.map((range) => `${range.start.row}:${range.start.col}-${range.end.row}:${range.end.col}`).join("|")}`;
|
|
19807
20086
|
}
|
|
@@ -20661,8 +20940,20 @@ function XlsxGrid({
|
|
|
20661
20940
|
const topBodyCanvasRef = React4.useRef(null);
|
|
20662
20941
|
const leftBodyCanvasRef = React4.useRef(null);
|
|
20663
20942
|
const cornerBodyCanvasRef = React4.useRef(null);
|
|
20664
|
-
const
|
|
20665
|
-
|
|
20943
|
+
const bodyBlitBufferCanvasRef = React4.useRef({
|
|
20944
|
+
corner: null,
|
|
20945
|
+
left: null,
|
|
20946
|
+
scroll: null,
|
|
20947
|
+
top: null
|
|
20948
|
+
});
|
|
20949
|
+
const headerBlitBufferCanvasRef = React4.useRef({
|
|
20950
|
+
left: null,
|
|
20951
|
+
top: null
|
|
20952
|
+
});
|
|
20953
|
+
const topFrozenHeaderCanvasRef = React4.useRef(null);
|
|
20954
|
+
const topScrollHeaderCanvasRef = React4.useRef(null);
|
|
20955
|
+
const leftFrozenHeaderCanvasRef = React4.useRef(null);
|
|
20956
|
+
const leftScrollHeaderCanvasRef = React4.useRef(null);
|
|
20666
20957
|
const cornerHeaderCanvasRef = React4.useRef(null);
|
|
20667
20958
|
const selectionOverlayRef = React4.useRef(null);
|
|
20668
20959
|
const activeValidationOverlayRef = React4.useRef(null);
|
|
@@ -20866,16 +21157,31 @@ function XlsxGrid({
|
|
|
20866
21157
|
liveZoomTranslateX2,
|
|
20867
21158
|
liveZoomTranslateY2
|
|
20868
21159
|
);
|
|
20869
|
-
|
|
20870
|
-
|
|
20871
|
-
|
|
20872
|
-
|
|
20873
|
-
|
|
20874
|
-
|
|
20875
|
-
|
|
20876
|
-
|
|
20877
|
-
|
|
20878
|
-
|
|
21160
|
+
applyCanvasTransform(
|
|
21161
|
+
topScrollHeaderCanvasRef.current,
|
|
21162
|
+
scrollDeltaX + liveZoomTranslateX2,
|
|
21163
|
+
liveZoomTranslateY2
|
|
21164
|
+
);
|
|
21165
|
+
applyCanvasTransform(
|
|
21166
|
+
topFrozenHeaderCanvasRef.current,
|
|
21167
|
+
liveZoomTranslateX2,
|
|
21168
|
+
liveZoomTranslateY2
|
|
21169
|
+
);
|
|
21170
|
+
applyCanvasTransform(
|
|
21171
|
+
leftScrollHeaderCanvasRef.current,
|
|
21172
|
+
liveZoomTranslateX2,
|
|
21173
|
+
scrollDeltaY + liveZoomTranslateY2
|
|
21174
|
+
);
|
|
21175
|
+
applyCanvasTransform(
|
|
21176
|
+
leftFrozenHeaderCanvasRef.current,
|
|
21177
|
+
liveZoomTranslateX2,
|
|
21178
|
+
liveZoomTranslateY2
|
|
21179
|
+
);
|
|
21180
|
+
applyCanvasTransform(
|
|
21181
|
+
cornerHeaderCanvasRef.current,
|
|
21182
|
+
liveZoomTranslateX2,
|
|
21183
|
+
liveZoomTranslateY2
|
|
21184
|
+
);
|
|
20879
21185
|
}, [zoomScale]);
|
|
20880
21186
|
const updateLiveGestureZoomState = React4.useCallback((nextState) => {
|
|
20881
21187
|
const resolvedState = typeof nextState === "function" ? nextState(liveGestureZoomRef.current) : nextState;
|
|
@@ -21006,6 +21312,22 @@ function XlsxGrid({
|
|
|
21006
21312
|
scrollRef.current.style.cursor = "";
|
|
21007
21313
|
}
|
|
21008
21314
|
}, []);
|
|
21315
|
+
const getBodyBlitBufferCanvas = React4.useCallback((pane) => {
|
|
21316
|
+
let bufferCanvas = bodyBlitBufferCanvasRef.current[pane];
|
|
21317
|
+
if (!bufferCanvas && typeof document !== "undefined") {
|
|
21318
|
+
bufferCanvas = document.createElement("canvas");
|
|
21319
|
+
bodyBlitBufferCanvasRef.current[pane] = bufferCanvas;
|
|
21320
|
+
}
|
|
21321
|
+
return bufferCanvas;
|
|
21322
|
+
}, []);
|
|
21323
|
+
const getHeaderBlitBufferCanvas = React4.useCallback((axis) => {
|
|
21324
|
+
let bufferCanvas = headerBlitBufferCanvasRef.current[axis];
|
|
21325
|
+
if (!bufferCanvas && typeof document !== "undefined") {
|
|
21326
|
+
bufferCanvas = document.createElement("canvas");
|
|
21327
|
+
headerBlitBufferCanvasRef.current[axis] = bufferCanvas;
|
|
21328
|
+
}
|
|
21329
|
+
return bufferCanvas;
|
|
21330
|
+
}, []);
|
|
21009
21331
|
const visibleRows = React4.useMemo(() => {
|
|
21010
21332
|
return buildVisibleAxisIndices(
|
|
21011
21333
|
activeSheet?.visibleRows ?? [],
|
|
@@ -21720,14 +22042,14 @@ function XlsxGrid({
|
|
|
21720
22042
|
const handleScrollerScroll = React4.useCallback((event) => {
|
|
21721
22043
|
const currentScroller = event.currentTarget;
|
|
21722
22044
|
cachedScrollerRectRef.current = null;
|
|
21723
|
-
syncDrawingViewport(currentScroller, { immediate:
|
|
22045
|
+
syncDrawingViewport(currentScroller, { immediate: true });
|
|
21724
22046
|
if (currentScroller.scrollHeight - (currentScroller.scrollTop + currentScroller.clientHeight) < OPEN_GRID_VERTICAL_EDGE_PX) {
|
|
21725
22047
|
setDisplayRowLimit((current) => current + OPEN_GRID_ROW_GROWTH);
|
|
21726
22048
|
}
|
|
21727
22049
|
if (currentScroller.scrollWidth - (currentScroller.scrollLeft + currentScroller.clientWidth) < OPEN_GRID_HORIZONTAL_EDGE_PX) {
|
|
21728
22050
|
setDisplayColLimit((current) => current + OPEN_GRID_COL_GROWTH);
|
|
21729
22051
|
}
|
|
21730
|
-
}, [
|
|
22052
|
+
}, [syncDrawingViewport]);
|
|
21731
22053
|
React4.useEffect(() => {
|
|
21732
22054
|
const scroller = scrollRef.current;
|
|
21733
22055
|
if (!scroller || !enableGestureZoom) {
|
|
@@ -23508,6 +23830,30 @@ function XlsxGrid({
|
|
|
23508
23830
|
return null;
|
|
23509
23831
|
}
|
|
23510
23832
|
const direction = sortState && sortState.tableName === table.name && sortState.columnIndex === tableColumn.index ? sortState.direction : null;
|
|
23833
|
+
const triggerIcon = direction === "ascending" ? "\u25B2" : direction === "descending" ? "\u25BC" : "\u25BE";
|
|
23834
|
+
if (renderTableHeaderMenu) {
|
|
23835
|
+
return renderTableHeaderMenu({
|
|
23836
|
+
cell,
|
|
23837
|
+
column: tableColumn,
|
|
23838
|
+
direction,
|
|
23839
|
+
sortAscending: () => sortTable(table.name, tableColumn.index, "ascending"),
|
|
23840
|
+
sortDescending: () => sortTable(table.name, tableColumn.index, "descending"),
|
|
23841
|
+
table,
|
|
23842
|
+
triggerIcon,
|
|
23843
|
+
triggerProps: {
|
|
23844
|
+
"aria-haspopup": "menu",
|
|
23845
|
+
"aria-label": `Open menu for ${tableColumn.name}`,
|
|
23846
|
+
onClick: (event) => {
|
|
23847
|
+
event.stopPropagation();
|
|
23848
|
+
},
|
|
23849
|
+
onPointerDown: (event) => {
|
|
23850
|
+
event.stopPropagation();
|
|
23851
|
+
},
|
|
23852
|
+
style: resolveTableHeaderTriggerStyle(palette, zoomFactor),
|
|
23853
|
+
type: "button"
|
|
23854
|
+
}
|
|
23855
|
+
});
|
|
23856
|
+
}
|
|
23511
23857
|
return /* @__PURE__ */ jsx3(
|
|
23512
23858
|
"button",
|
|
23513
23859
|
{
|
|
@@ -23523,27 +23869,13 @@ function XlsxGrid({
|
|
|
23523
23869
|
);
|
|
23524
23870
|
},
|
|
23525
23871
|
style: {
|
|
23526
|
-
|
|
23527
|
-
background: "transparent",
|
|
23528
|
-
border: "none",
|
|
23529
|
-
color: palette.mutedText,
|
|
23530
|
-
cursor: "pointer",
|
|
23531
|
-
display: "inline-flex",
|
|
23532
|
-
fontSize: 10 * zoomFactor,
|
|
23533
|
-
height: 16 * zoomFactor,
|
|
23534
|
-
justifyContent: "center",
|
|
23535
|
-
padding: 0,
|
|
23536
|
-
position: "absolute",
|
|
23537
|
-
right: 4 * zoomFactor,
|
|
23538
|
-
top: 3 * zoomFactor,
|
|
23539
|
-
width: 16 * zoomFactor,
|
|
23540
|
-
zIndex: 6
|
|
23872
|
+
...resolveTableHeaderTriggerStyle(palette, zoomFactor)
|
|
23541
23873
|
},
|
|
23542
23874
|
type: "button",
|
|
23543
|
-
children:
|
|
23875
|
+
children: triggerIcon
|
|
23544
23876
|
}
|
|
23545
23877
|
);
|
|
23546
|
-
}, [effectiveTables, palette
|
|
23878
|
+
}, [effectiveTables, palette, renderTableHeaderMenu, sortState, sortTable, zoomFactor]);
|
|
23547
23879
|
const resolveCanvasColumnHeaderRect = React4.useCallback((actualCol) => {
|
|
23548
23880
|
const colIndex = colIndexByActual.get(actualCol);
|
|
23549
23881
|
if (colIndex === void 0) {
|
|
@@ -23582,6 +23914,54 @@ function XlsxGrid({
|
|
|
23582
23914
|
rowPrefixSums,
|
|
23583
23915
|
stickyTopByRow
|
|
23584
23916
|
]);
|
|
23917
|
+
const canvasColumnHeaderCells = React4.useMemo(
|
|
23918
|
+
() => canvasVisibleColItems.flatMap((column) => {
|
|
23919
|
+
const rect = resolveCanvasColumnHeaderRect(column.actualCol);
|
|
23920
|
+
if (!rect) {
|
|
23921
|
+
return [];
|
|
23922
|
+
}
|
|
23923
|
+
const isFrozen = stickyLeftByCol.has(column.actualCol);
|
|
23924
|
+
return [{
|
|
23925
|
+
actualCol: column.actualCol,
|
|
23926
|
+
height: displayHeaderHeight,
|
|
23927
|
+
isFrozen,
|
|
23928
|
+
left: rect.left,
|
|
23929
|
+
localLeft: rect.left - (isFrozen ? displayRowHeaderWidth : frozenPaneRight),
|
|
23930
|
+
width: rect.width
|
|
23931
|
+
}];
|
|
23932
|
+
}),
|
|
23933
|
+
[
|
|
23934
|
+
canvasVisibleColItems,
|
|
23935
|
+
displayHeaderHeight,
|
|
23936
|
+
displayRowHeaderWidth,
|
|
23937
|
+
frozenPaneRight,
|
|
23938
|
+
resolveCanvasColumnHeaderRect,
|
|
23939
|
+
stickyLeftByCol
|
|
23940
|
+
]
|
|
23941
|
+
);
|
|
23942
|
+
const canvasRowHeaderCells = React4.useMemo(
|
|
23943
|
+
() => canvasVisibleRowItems.flatMap((row) => {
|
|
23944
|
+
const rect = resolveCanvasRowHeaderRect(row.actualRow);
|
|
23945
|
+
if (!rect) {
|
|
23946
|
+
return [];
|
|
23947
|
+
}
|
|
23948
|
+
const isFrozen = stickyTopByRow.has(row.actualRow);
|
|
23949
|
+
return [{
|
|
23950
|
+
actualRow: row.actualRow,
|
|
23951
|
+
height: rect.height,
|
|
23952
|
+
isFrozen,
|
|
23953
|
+
localTop: rect.top - (isFrozen ? displayHeaderHeight : frozenPaneBottom),
|
|
23954
|
+
top: rect.top
|
|
23955
|
+
}];
|
|
23956
|
+
}),
|
|
23957
|
+
[
|
|
23958
|
+
canvasVisibleRowItems,
|
|
23959
|
+
displayHeaderHeight,
|
|
23960
|
+
frozenPaneBottom,
|
|
23961
|
+
resolveCanvasRowHeaderRect,
|
|
23962
|
+
stickyTopByRow
|
|
23963
|
+
]
|
|
23964
|
+
);
|
|
23585
23965
|
const resolveCanvasColumnResizeTarget = React4.useCallback((clientX) => {
|
|
23586
23966
|
if (!canResizeHeaders) {
|
|
23587
23967
|
return null;
|
|
@@ -23591,17 +23971,26 @@ function XlsxGrid({
|
|
|
23591
23971
|
return null;
|
|
23592
23972
|
}
|
|
23593
23973
|
const localX = clientX - scrollerRect.left;
|
|
23594
|
-
for (const column of
|
|
23595
|
-
|
|
23596
|
-
|
|
23597
|
-
continue;
|
|
23974
|
+
for (const column of canvasColumnHeaderCells) {
|
|
23975
|
+
if (Math.abs(localX - (column.left + column.width)) <= CANVAS_RESIZE_HIT_SLOP_PX) {
|
|
23976
|
+
return { actualCol: column.actualCol, width: column.width };
|
|
23598
23977
|
}
|
|
23599
|
-
|
|
23600
|
-
|
|
23978
|
+
}
|
|
23979
|
+
return null;
|
|
23980
|
+
}, [canResizeHeaders, canvasColumnHeaderCells]);
|
|
23981
|
+
const resolveCanvasColumnHeaderTarget = React4.useCallback((clientX) => {
|
|
23982
|
+
const scrollerRect = scrollRef.current?.getBoundingClientRect();
|
|
23983
|
+
if (!scrollerRect) {
|
|
23984
|
+
return null;
|
|
23985
|
+
}
|
|
23986
|
+
const localX = clientX - scrollerRect.left;
|
|
23987
|
+
for (const column of canvasColumnHeaderCells) {
|
|
23988
|
+
if (localX >= column.left && localX <= column.left + column.width) {
|
|
23989
|
+
return column.actualCol;
|
|
23601
23990
|
}
|
|
23602
23991
|
}
|
|
23603
23992
|
return null;
|
|
23604
|
-
}, [
|
|
23993
|
+
}, [canvasColumnHeaderCells]);
|
|
23605
23994
|
const resolveCanvasRowResizeTarget = React4.useCallback((clientY) => {
|
|
23606
23995
|
if (!canResizeHeaders) {
|
|
23607
23996
|
return null;
|
|
@@ -23611,17 +24000,26 @@ function XlsxGrid({
|
|
|
23611
24000
|
return null;
|
|
23612
24001
|
}
|
|
23613
24002
|
const localY = clientY - scrollerRect.top;
|
|
23614
|
-
for (const row of
|
|
23615
|
-
|
|
23616
|
-
|
|
23617
|
-
continue;
|
|
24003
|
+
for (const row of canvasRowHeaderCells) {
|
|
24004
|
+
if (Math.abs(localY - (row.top + row.height)) <= CANVAS_RESIZE_HIT_SLOP_PX) {
|
|
24005
|
+
return { actualRow: row.actualRow, height: row.height };
|
|
23618
24006
|
}
|
|
23619
|
-
|
|
23620
|
-
|
|
24007
|
+
}
|
|
24008
|
+
return null;
|
|
24009
|
+
}, [canResizeHeaders, canvasRowHeaderCells]);
|
|
24010
|
+
const resolveCanvasRowHeaderTarget = React4.useCallback((clientY) => {
|
|
24011
|
+
const scrollerRect = scrollRef.current?.getBoundingClientRect();
|
|
24012
|
+
if (!scrollerRect) {
|
|
24013
|
+
return null;
|
|
24014
|
+
}
|
|
24015
|
+
const localY = clientY - scrollerRect.top;
|
|
24016
|
+
for (const row of canvasRowHeaderCells) {
|
|
24017
|
+
if (localY >= row.top && localY <= row.top + row.height) {
|
|
24018
|
+
return row.actualRow;
|
|
23621
24019
|
}
|
|
23622
24020
|
}
|
|
23623
24021
|
return null;
|
|
23624
|
-
}, [
|
|
24022
|
+
}, [canvasRowHeaderCells]);
|
|
23625
24023
|
const handleCanvasColumnHeaderPointerMove = React4.useCallback((event) => {
|
|
23626
24024
|
if (resizeStateRef.current?.type === "column") {
|
|
23627
24025
|
event.currentTarget.style.cursor = "col-resize";
|
|
@@ -23724,17 +24122,17 @@ function XlsxGrid({
|
|
|
23724
24122
|
startColumnResize(event.pointerId, resizeTarget.actualCol, resizeTarget.width, event.clientX);
|
|
23725
24123
|
return;
|
|
23726
24124
|
}
|
|
23727
|
-
const
|
|
23728
|
-
if (
|
|
24125
|
+
const actualCol = resolveCanvasColumnHeaderTarget(event.clientX);
|
|
24126
|
+
if (actualCol === null) {
|
|
23729
24127
|
return;
|
|
23730
24128
|
}
|
|
23731
24129
|
event.preventDefault();
|
|
23732
24130
|
focusGrid();
|
|
23733
24131
|
const currentSelection = selectionRef.current;
|
|
23734
|
-
const anchorCol = event.shiftKey && currentSelection ? currentSelection.start.col :
|
|
24132
|
+
const anchorCol = event.shiftKey && currentSelection ? currentSelection.start.col : actualCol;
|
|
23735
24133
|
const initialRange = normalizeRange2({
|
|
23736
24134
|
start: { row: firstVisibleRow, col: anchorCol },
|
|
23737
|
-
end: { row: lastVisibleRow, col:
|
|
24135
|
+
end: { row: lastVisibleRow, col: actualCol }
|
|
23738
24136
|
});
|
|
23739
24137
|
const anchorColIndex = colIndexByActual.get(anchorCol);
|
|
23740
24138
|
if (anchorColIndex === void 0) {
|
|
@@ -23744,7 +24142,7 @@ function XlsxGrid({
|
|
|
23744
24142
|
event.pointerId,
|
|
23745
24143
|
{ row: firstVisibleRow, col: anchorCol },
|
|
23746
24144
|
"column",
|
|
23747
|
-
{ row: firstVisibleRow, col:
|
|
24145
|
+
{ row: firstVisibleRow, col: actualCol },
|
|
23748
24146
|
{
|
|
23749
24147
|
contentScaleX: 1,
|
|
23750
24148
|
contentScaleY: 1,
|
|
@@ -23765,9 +24163,8 @@ function XlsxGrid({
|
|
|
23765
24163
|
firstVisibleRow,
|
|
23766
24164
|
focusGrid,
|
|
23767
24165
|
lastVisibleRow,
|
|
23768
|
-
|
|
24166
|
+
resolveCanvasColumnHeaderTarget,
|
|
23769
24167
|
resolveCanvasColumnResizeTarget,
|
|
23770
|
-
resolvePointerCellFromClient,
|
|
23771
24168
|
rowPrefixSums,
|
|
23772
24169
|
startCellSelection
|
|
23773
24170
|
]);
|
|
@@ -23782,17 +24179,17 @@ function XlsxGrid({
|
|
|
23782
24179
|
startRowResize(event.pointerId, resizeTarget.actualRow, resizeTarget.height, event.clientY);
|
|
23783
24180
|
return;
|
|
23784
24181
|
}
|
|
23785
|
-
const
|
|
23786
|
-
if (
|
|
24182
|
+
const actualRow = resolveCanvasRowHeaderTarget(event.clientY);
|
|
24183
|
+
if (actualRow === null) {
|
|
23787
24184
|
return;
|
|
23788
24185
|
}
|
|
23789
24186
|
event.preventDefault();
|
|
23790
24187
|
focusGrid();
|
|
23791
24188
|
const currentSelection = selectionRef.current;
|
|
23792
|
-
const anchorRow = event.shiftKey && currentSelection ? currentSelection.start.row :
|
|
24189
|
+
const anchorRow = event.shiftKey && currentSelection ? currentSelection.start.row : actualRow;
|
|
23793
24190
|
const initialRange = normalizeRange2({
|
|
23794
24191
|
start: { row: anchorRow, col: firstVisibleCol },
|
|
23795
|
-
end: { row:
|
|
24192
|
+
end: { row: actualRow, col: lastVisibleCol }
|
|
23796
24193
|
});
|
|
23797
24194
|
const anchorRowIndex = rowIndexByActual.get(anchorRow);
|
|
23798
24195
|
if (anchorRowIndex === void 0) {
|
|
@@ -23802,7 +24199,7 @@ function XlsxGrid({
|
|
|
23802
24199
|
event.pointerId,
|
|
23803
24200
|
{ row: anchorRow, col: firstVisibleCol },
|
|
23804
24201
|
"row",
|
|
23805
|
-
{ row:
|
|
24202
|
+
{ row: actualRow, col: firstVisibleCol },
|
|
23806
24203
|
{
|
|
23807
24204
|
contentScaleX: 1,
|
|
23808
24205
|
contentScaleY: 1,
|
|
@@ -23822,8 +24219,8 @@ function XlsxGrid({
|
|
|
23822
24219
|
firstVisibleCol,
|
|
23823
24220
|
focusGrid,
|
|
23824
24221
|
lastVisibleCol,
|
|
24222
|
+
resolveCanvasRowHeaderTarget,
|
|
23825
24223
|
resolveCanvasRowResizeTarget,
|
|
23826
|
-
resolvePointerCellFromClient,
|
|
23827
24224
|
rowIndexByActual,
|
|
23828
24225
|
rowPrefixSums,
|
|
23829
24226
|
startCellSelection
|
|
@@ -23833,7 +24230,7 @@ function XlsxGrid({
|
|
|
23833
24230
|
return;
|
|
23834
24231
|
}
|
|
23835
24232
|
const dpr = typeof window === "undefined" ? 1 : Math.max(1, window.devicePixelRatio || 1);
|
|
23836
|
-
function configureCanvas(canvas, width, height) {
|
|
24233
|
+
function configureCanvas(canvas, width, height, options) {
|
|
23837
24234
|
if (!canvas) {
|
|
23838
24235
|
return null;
|
|
23839
24236
|
}
|
|
@@ -23856,7 +24253,9 @@ function XlsxGrid({
|
|
|
23856
24253
|
return null;
|
|
23857
24254
|
}
|
|
23858
24255
|
context.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
23859
|
-
|
|
24256
|
+
if (options?.clear !== false) {
|
|
24257
|
+
context.clearRect(0, 0, width, height);
|
|
24258
|
+
}
|
|
23860
24259
|
return context;
|
|
23861
24260
|
}
|
|
23862
24261
|
const bodyWidth = Math.max(0, drawingViewport.width);
|
|
@@ -23888,12 +24287,24 @@ function XlsxGrid({
|
|
|
23888
24287
|
rangeSignature,
|
|
23889
24288
|
rowHeaderWidth,
|
|
23890
24289
|
rowSignature: nextBodyCanvasSignature.rowSignature,
|
|
24290
|
+
viewportLeft: drawingViewport.left,
|
|
24291
|
+
viewportTop: drawingViewport.top,
|
|
23891
24292
|
zoomFactor
|
|
23892
24293
|
};
|
|
23893
24294
|
const previousBodyCanvasSignature = paintedBodyCanvasSignatureRef.current;
|
|
23894
24295
|
const previousHeaderCanvasSignature = paintedHeaderCanvasSignatureRef.current;
|
|
24296
|
+
const previousPaintedViewport = paintedDrawingViewportRef.current;
|
|
23895
24297
|
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);
|
|
23896
|
-
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);
|
|
24298
|
+
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);
|
|
24299
|
+
const canBlitBody = Boolean(
|
|
24300
|
+
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
|
|
24301
|
+
);
|
|
24302
|
+
const canBlitTopHeader = Boolean(
|
|
24303
|
+
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
|
|
24304
|
+
);
|
|
24305
|
+
const canBlitLeftHeader = Boolean(
|
|
24306
|
+
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
|
|
24307
|
+
);
|
|
23897
24308
|
if (!shouldRepaintBody && !shouldRepaintHeaders) {
|
|
23898
24309
|
return;
|
|
23899
24310
|
}
|
|
@@ -23905,6 +24316,10 @@ function XlsxGrid({
|
|
|
23905
24316
|
const leftBodyCanvasHeight2 = scrollBodyCanvasHeight2;
|
|
23906
24317
|
const cornerBodyCanvasWidth2 = leftBodyCanvasWidth2;
|
|
23907
24318
|
const cornerBodyCanvasHeight2 = topBodyCanvasHeight2;
|
|
24319
|
+
const topFrozenHeaderCanvasWidth2 = leftBodyCanvasWidth2;
|
|
24320
|
+
const topScrollHeaderCanvasWidth2 = scrollBodyCanvasWidth2;
|
|
24321
|
+
const leftFrozenHeaderCanvasHeight2 = topBodyCanvasHeight2;
|
|
24322
|
+
const leftScrollHeaderCanvasHeight2 = scrollBodyCanvasHeight2;
|
|
23908
24323
|
const paneBounds = {
|
|
23909
24324
|
corner: {
|
|
23910
24325
|
height: cornerBodyCanvasHeight2,
|
|
@@ -23932,29 +24347,50 @@ function XlsxGrid({
|
|
|
23932
24347
|
}
|
|
23933
24348
|
};
|
|
23934
24349
|
const bodyContexts = shouldRepaintBody ? {
|
|
23935
|
-
corner: configureCanvas(cornerBodyCanvasRef.current, cornerBodyCanvasWidth2, cornerBodyCanvasHeight2),
|
|
23936
|
-
left: configureCanvas(leftBodyCanvasRef.current, leftBodyCanvasWidth2, leftBodyCanvasHeight2),
|
|
23937
|
-
scroll: configureCanvas(scrollBodyCanvasRef.current, scrollBodyCanvasWidth2, scrollBodyCanvasHeight2),
|
|
23938
|
-
top: configureCanvas(topBodyCanvasRef.current, topBodyCanvasWidth2, topBodyCanvasHeight2)
|
|
24350
|
+
corner: configureCanvas(cornerBodyCanvasRef.current, cornerBodyCanvasWidth2, cornerBodyCanvasHeight2, { clear: !canBlitBody }),
|
|
24351
|
+
left: configureCanvas(leftBodyCanvasRef.current, leftBodyCanvasWidth2, leftBodyCanvasHeight2, { clear: !canBlitBody }),
|
|
24352
|
+
scroll: configureCanvas(scrollBodyCanvasRef.current, scrollBodyCanvasWidth2, scrollBodyCanvasHeight2, { clear: !canBlitBody }),
|
|
24353
|
+
top: configureCanvas(topBodyCanvasRef.current, topBodyCanvasWidth2, topBodyCanvasHeight2, { clear: !canBlitBody })
|
|
23939
24354
|
} : {
|
|
23940
24355
|
corner: null,
|
|
23941
24356
|
left: null,
|
|
23942
24357
|
scroll: null,
|
|
23943
24358
|
top: null
|
|
23944
24359
|
};
|
|
23945
|
-
const
|
|
23946
|
-
|
|
24360
|
+
const topHeaderContexts = shouldRepaintHeaders ? {
|
|
24361
|
+
frozen: configureCanvas(topFrozenHeaderCanvasRef.current, topFrozenHeaderCanvasWidth2, headerHeight),
|
|
24362
|
+
scroll: configureCanvas(topScrollHeaderCanvasRef.current, topScrollHeaderCanvasWidth2, headerHeight, { clear: !canBlitTopHeader })
|
|
24363
|
+
} : {
|
|
24364
|
+
frozen: null,
|
|
24365
|
+
scroll: null
|
|
24366
|
+
};
|
|
24367
|
+
const leftHeaderContexts = shouldRepaintHeaders ? {
|
|
24368
|
+
frozen: configureCanvas(leftFrozenHeaderCanvasRef.current, rowHeaderWidth, leftFrozenHeaderCanvasHeight2),
|
|
24369
|
+
scroll: configureCanvas(leftScrollHeaderCanvasRef.current, rowHeaderWidth, leftScrollHeaderCanvasHeight2, { clear: !canBlitLeftHeader })
|
|
24370
|
+
} : {
|
|
24371
|
+
frozen: null,
|
|
24372
|
+
scroll: null
|
|
24373
|
+
};
|
|
23947
24374
|
const cornerContext = shouldRepaintHeaders ? configureCanvas(cornerHeaderCanvasRef.current, rowHeaderWidth, headerHeight) : null;
|
|
23948
|
-
if (shouldRepaintBody && (!bodyContexts.scroll || !bodyContexts.top || !bodyContexts.left || !bodyContexts.corner) || shouldRepaintHeaders && (!
|
|
24375
|
+
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)) {
|
|
23949
24376
|
return;
|
|
23950
24377
|
}
|
|
23951
24378
|
const showGridLines = activeSheet?.showGridLines ?? true;
|
|
24379
|
+
const sheetSurface = resolveSheetSurface(activeSheet, palette);
|
|
23952
24380
|
const deferredSpillTextsByPane = {
|
|
23953
24381
|
corner: [],
|
|
23954
24382
|
left: [],
|
|
23955
24383
|
scroll: [],
|
|
23956
24384
|
top: []
|
|
23957
24385
|
};
|
|
24386
|
+
const bodyDirtyRectsByPane = {
|
|
24387
|
+
corner: [],
|
|
24388
|
+
left: [],
|
|
24389
|
+
scroll: [],
|
|
24390
|
+
top: []
|
|
24391
|
+
};
|
|
24392
|
+
let topScrollHeaderDirtyRects = buildFullCanvasDirtyRect(topScrollHeaderCanvasWidth2, headerHeight);
|
|
24393
|
+
let leftScrollHeaderDirtyRects = buildFullCanvasDirtyRect(rowHeaderWidth, leftScrollHeaderCanvasHeight2);
|
|
23958
24394
|
const cellPaneOrder = ["scroll", "top", "left", "corner"];
|
|
23959
24395
|
if (shouldRepaintBody) {
|
|
23960
24396
|
for (const pane of Object.keys(bodyContexts)) {
|
|
@@ -23963,14 +24399,44 @@ function XlsxGrid({
|
|
|
23963
24399
|
if (!context || bounds.width <= 0 || bounds.height <= 0) {
|
|
23964
24400
|
continue;
|
|
23965
24401
|
}
|
|
23966
|
-
|
|
23967
|
-
|
|
24402
|
+
let dirtyRects = buildFullCanvasDirtyRect(bounds.width, bounds.height);
|
|
24403
|
+
if (canBlitBody) {
|
|
24404
|
+
const bufferCanvas = getBodyBlitBufferCanvas(pane);
|
|
24405
|
+
const deltaX = pane === "scroll" || pane === "top" ? drawingViewport.left - previousPaintedViewport.left : 0;
|
|
24406
|
+
const deltaY = pane === "scroll" || pane === "left" ? drawingViewport.top - previousPaintedViewport.top : 0;
|
|
24407
|
+
if (bufferCanvas) {
|
|
24408
|
+
const blittedDirtyRects = blitCanvasWithScrollDelta(
|
|
24409
|
+
pane === "corner" ? cornerBodyCanvasRef.current : pane === "left" ? leftBodyCanvasRef.current : pane === "top" ? topBodyCanvasRef.current : scrollBodyCanvasRef.current,
|
|
24410
|
+
context,
|
|
24411
|
+
bufferCanvas,
|
|
24412
|
+
dpr,
|
|
24413
|
+
bounds.width,
|
|
24414
|
+
bounds.height,
|
|
24415
|
+
deltaX,
|
|
24416
|
+
deltaY
|
|
24417
|
+
);
|
|
24418
|
+
if (blittedDirtyRects) {
|
|
24419
|
+
dirtyRects = blittedDirtyRects;
|
|
24420
|
+
}
|
|
24421
|
+
}
|
|
24422
|
+
} else {
|
|
24423
|
+
context.clearRect(0, 0, bounds.width, bounds.height);
|
|
24424
|
+
}
|
|
24425
|
+
bodyDirtyRectsByPane[pane] = dirtyRects;
|
|
24426
|
+
if (dirtyRects.length === 0) {
|
|
24427
|
+
continue;
|
|
24428
|
+
}
|
|
24429
|
+
context.fillStyle = sheetSurface;
|
|
24430
|
+
for (const dirtyRect of dirtyRects) {
|
|
24431
|
+
context.fillRect(dirtyRect.left, dirtyRect.top, dirtyRect.width, dirtyRect.height);
|
|
24432
|
+
}
|
|
23968
24433
|
}
|
|
23969
24434
|
for (const pane of cellPaneOrder) {
|
|
23970
24435
|
const paneContext = bodyContexts[pane];
|
|
23971
24436
|
const paneBoundsForCell = paneBounds[pane];
|
|
24437
|
+
const paneDirtyRects = bodyDirtyRectsByPane[pane];
|
|
23972
24438
|
const paneAxisItems = canvasPaneAxisItems[pane];
|
|
23973
|
-
if (!paneContext || paneBoundsForCell.width <= 0 || paneBoundsForCell.height <= 0 || paneAxisItems.rows.length === 0 || paneAxisItems.cols.length === 0) {
|
|
24439
|
+
if (!paneContext || paneDirtyRects.length === 0 || paneBoundsForCell.width <= 0 || paneBoundsForCell.height <= 0 || paneAxisItems.rows.length === 0 || paneAxisItems.cols.length === 0) {
|
|
23974
24440
|
continue;
|
|
23975
24441
|
}
|
|
23976
24442
|
const drawnMergedAnchorKeys = /* @__PURE__ */ new Set();
|
|
@@ -24010,11 +24476,14 @@ function XlsxGrid({
|
|
|
24010
24476
|
if (localRect.left + drawableWidth < 0 || localRect.top + localRect.height < 0 || localRect.left > paneBoundsForCell.width || localRect.top > paneBoundsForCell.height) {
|
|
24011
24477
|
continue;
|
|
24012
24478
|
}
|
|
24479
|
+
if (!intersectsCanvasDirtyRects(localRect.left, localRect.top, drawableWidth, localRect.height, paneDirtyRects)) {
|
|
24480
|
+
continue;
|
|
24481
|
+
}
|
|
24013
24482
|
const cellStyle = cellData.style;
|
|
24014
24483
|
const canvasCellStyle = cellData.canvas ?? buildCanvasCellStyleCache(cellStyle);
|
|
24015
|
-
const fillColor = cellData.conditionalColorScale?.color ?? (typeof cellStyle.backgroundColor === "string" ? cellStyle.backgroundColor :
|
|
24484
|
+
const fillColor = cellData.conditionalColorScale?.color ?? (typeof cellStyle.backgroundColor === "string" ? cellStyle.backgroundColor : sheetSurface);
|
|
24016
24485
|
const gradientFill = !cellData.conditionalColorScale && typeof cellStyle.backgroundImage === "string" ? resolveCanvasGradientFill(paneContext, localRect, cellStyle.backgroundImage) : null;
|
|
24017
|
-
const hasExplicitCellFill = cellData.conditionalColorScale !== null || gradientFill !== null || typeof cellStyle.backgroundColor === "string" && cellStyle.backgroundColor !==
|
|
24486
|
+
const hasExplicitCellFill = cellData.conditionalColorScale !== null || gradientFill !== null || typeof cellStyle.backgroundColor === "string" && cellStyle.backgroundColor !== sheetSurface;
|
|
24018
24487
|
paneContext.fillStyle = gradientFill ?? fillColor;
|
|
24019
24488
|
paneContext.fillRect(localRect.left, localRect.top, localRect.width, localRect.height);
|
|
24020
24489
|
if (cellData.chartHighlight) {
|
|
@@ -24368,55 +24837,139 @@ function XlsxGrid({
|
|
|
24368
24837
|
}
|
|
24369
24838
|
}
|
|
24370
24839
|
}
|
|
24371
|
-
if (shouldRepaintHeaders &&
|
|
24372
|
-
|
|
24373
|
-
|
|
24374
|
-
|
|
24375
|
-
|
|
24376
|
-
|
|
24377
|
-
const
|
|
24378
|
-
if (
|
|
24840
|
+
if (shouldRepaintHeaders && cornerContext) {
|
|
24841
|
+
const topFrozenHeaderContext = topHeaderContexts.frozen;
|
|
24842
|
+
const topScrollHeaderContext = topHeaderContexts.scroll;
|
|
24843
|
+
const leftFrozenHeaderContext = leftHeaderContexts.frozen;
|
|
24844
|
+
const leftScrollHeaderContext = leftHeaderContexts.scroll;
|
|
24845
|
+
if (canBlitTopHeader) {
|
|
24846
|
+
const bufferCanvas = getHeaderBlitBufferCanvas("top");
|
|
24847
|
+
if (bufferCanvas && topScrollHeaderContext && topScrollHeaderCanvasRef.current) {
|
|
24848
|
+
const blittedDirtyRects = blitCanvasWithScrollDelta(
|
|
24849
|
+
topScrollHeaderCanvasRef.current,
|
|
24850
|
+
topScrollHeaderContext,
|
|
24851
|
+
bufferCanvas,
|
|
24852
|
+
dpr,
|
|
24853
|
+
topScrollHeaderCanvasWidth2,
|
|
24854
|
+
headerHeight,
|
|
24855
|
+
drawingViewport.left - previousPaintedViewport.left,
|
|
24856
|
+
0
|
|
24857
|
+
);
|
|
24858
|
+
if (blittedDirtyRects) {
|
|
24859
|
+
topScrollHeaderDirtyRects = blittedDirtyRects;
|
|
24860
|
+
}
|
|
24861
|
+
}
|
|
24862
|
+
}
|
|
24863
|
+
if (canBlitLeftHeader) {
|
|
24864
|
+
const bufferCanvas = getHeaderBlitBufferCanvas("left");
|
|
24865
|
+
if (bufferCanvas && leftScrollHeaderContext && leftScrollHeaderCanvasRef.current) {
|
|
24866
|
+
const blittedDirtyRects = blitCanvasWithScrollDelta(
|
|
24867
|
+
leftScrollHeaderCanvasRef.current,
|
|
24868
|
+
leftScrollHeaderContext,
|
|
24869
|
+
bufferCanvas,
|
|
24870
|
+
dpr,
|
|
24871
|
+
rowHeaderWidth,
|
|
24872
|
+
leftScrollHeaderCanvasHeight2,
|
|
24873
|
+
0,
|
|
24874
|
+
drawingViewport.top - previousPaintedViewport.top
|
|
24875
|
+
);
|
|
24876
|
+
if (blittedDirtyRects) {
|
|
24877
|
+
leftScrollHeaderDirtyRects = blittedDirtyRects;
|
|
24878
|
+
}
|
|
24879
|
+
}
|
|
24880
|
+
}
|
|
24881
|
+
if (topFrozenHeaderContext && topFrozenHeaderCanvasWidth2 > 0) {
|
|
24882
|
+
topFrozenHeaderContext.fillStyle = palette.headerSurface;
|
|
24883
|
+
topFrozenHeaderContext.fillRect(0, 0, topFrozenHeaderCanvasWidth2, headerHeight);
|
|
24884
|
+
}
|
|
24885
|
+
if (topScrollHeaderContext && topScrollHeaderCanvasWidth2 > 0) {
|
|
24886
|
+
topScrollHeaderContext.fillStyle = palette.headerSurface;
|
|
24887
|
+
for (const dirtyRect of topScrollHeaderDirtyRects) {
|
|
24888
|
+
topScrollHeaderContext.fillRect(dirtyRect.left, dirtyRect.top, dirtyRect.width, dirtyRect.height);
|
|
24889
|
+
}
|
|
24890
|
+
}
|
|
24891
|
+
if (topFrozenHeaderContext) {
|
|
24892
|
+
topFrozenHeaderContext.strokeStyle = palette.border;
|
|
24893
|
+
topFrozenHeaderContext.lineWidth = 1;
|
|
24894
|
+
}
|
|
24895
|
+
if (topScrollHeaderContext) {
|
|
24896
|
+
topScrollHeaderContext.strokeStyle = palette.border;
|
|
24897
|
+
topScrollHeaderContext.lineWidth = 1;
|
|
24898
|
+
}
|
|
24899
|
+
for (const column of canvasColumnHeaderCells) {
|
|
24900
|
+
const paneContext = column.isFrozen ? topFrozenHeaderContext : topScrollHeaderContext;
|
|
24901
|
+
if (!paneContext) {
|
|
24902
|
+
continue;
|
|
24903
|
+
}
|
|
24904
|
+
if (column.localLeft + column.width < 0 || column.localLeft > (column.isFrozen ? topFrozenHeaderCanvasWidth2 : topScrollHeaderCanvasWidth2)) {
|
|
24905
|
+
continue;
|
|
24906
|
+
}
|
|
24907
|
+
if (!column.isFrozen && !intersectsCanvasDirtyRects(column.localLeft, 0, column.width, column.height, topScrollHeaderDirtyRects)) {
|
|
24908
|
+
continue;
|
|
24909
|
+
}
|
|
24910
|
+
const selected = normalizedVisibleRange && column.actualCol >= normalizedVisibleRange.start.col && column.actualCol <= normalizedVisibleRange.end.col;
|
|
24911
|
+
paneContext.fillStyle = selected ? selectionHeaderSurface : palette.headerSurface;
|
|
24912
|
+
paneContext.fillRect(column.localLeft, 0, column.width, column.height);
|
|
24913
|
+
paneContext.strokeStyle = palette.border;
|
|
24914
|
+
paneContext.beginPath();
|
|
24915
|
+
paneContext.moveTo(column.localLeft + column.width - 0.5, 0);
|
|
24916
|
+
paneContext.lineTo(column.localLeft + column.width - 0.5, column.height);
|
|
24917
|
+
paneContext.moveTo(column.localLeft, column.height - 0.5);
|
|
24918
|
+
paneContext.lineTo(column.localLeft + column.width, column.height - 0.5);
|
|
24919
|
+
paneContext.stroke();
|
|
24920
|
+
paneContext.font = `600 ${11 * zoomFactor}px ui-sans-serif, system-ui, sans-serif`;
|
|
24921
|
+
paneContext.fillStyle = palette.mutedText;
|
|
24922
|
+
paneContext.textAlign = "center";
|
|
24923
|
+
paneContext.textBaseline = "middle";
|
|
24924
|
+
paneContext.fillText(
|
|
24925
|
+
columnLabel2(column.actualCol),
|
|
24926
|
+
column.localLeft + column.width / 2,
|
|
24927
|
+
column.height / 2
|
|
24928
|
+
);
|
|
24929
|
+
}
|
|
24930
|
+
if (leftFrozenHeaderContext && leftFrozenHeaderCanvasHeight2 > 0) {
|
|
24931
|
+
leftFrozenHeaderContext.fillStyle = palette.rowHeaderSurface;
|
|
24932
|
+
leftFrozenHeaderContext.fillRect(0, 0, rowHeaderWidth, leftFrozenHeaderCanvasHeight2);
|
|
24933
|
+
}
|
|
24934
|
+
if (leftScrollHeaderContext && leftScrollHeaderCanvasHeight2 > 0) {
|
|
24935
|
+
leftScrollHeaderContext.fillStyle = palette.rowHeaderSurface;
|
|
24936
|
+
for (const dirtyRect of leftScrollHeaderDirtyRects) {
|
|
24937
|
+
leftScrollHeaderContext.fillRect(dirtyRect.left, dirtyRect.top, dirtyRect.width, dirtyRect.height);
|
|
24938
|
+
}
|
|
24939
|
+
}
|
|
24940
|
+
if (leftFrozenHeaderContext) {
|
|
24941
|
+
leftFrozenHeaderContext.strokeStyle = palette.border;
|
|
24942
|
+
leftFrozenHeaderContext.lineWidth = 1;
|
|
24943
|
+
}
|
|
24944
|
+
if (leftScrollHeaderContext) {
|
|
24945
|
+
leftScrollHeaderContext.strokeStyle = palette.border;
|
|
24946
|
+
leftScrollHeaderContext.lineWidth = 1;
|
|
24947
|
+
}
|
|
24948
|
+
for (const row of canvasRowHeaderCells) {
|
|
24949
|
+
const paneContext = row.isFrozen ? leftFrozenHeaderContext : leftScrollHeaderContext;
|
|
24950
|
+
if (!paneContext) {
|
|
24951
|
+
continue;
|
|
24952
|
+
}
|
|
24953
|
+
if (row.localTop + row.height < 0 || row.localTop > (row.isFrozen ? leftFrozenHeaderCanvasHeight2 : leftScrollHeaderCanvasHeight2)) {
|
|
24379
24954
|
continue;
|
|
24380
24955
|
}
|
|
24381
|
-
|
|
24382
|
-
topHeaderContext.fillStyle = selected ? selectionHeaderSurface : palette.headerSurface;
|
|
24383
|
-
topHeaderContext.fillRect(rect.left, 0, rect.width, headerHeight);
|
|
24384
|
-
topHeaderContext.strokeStyle = palette.border;
|
|
24385
|
-
topHeaderContext.beginPath();
|
|
24386
|
-
topHeaderContext.moveTo(rect.left + rect.width - 0.5, 0);
|
|
24387
|
-
topHeaderContext.lineTo(rect.left + rect.width - 0.5, headerHeight);
|
|
24388
|
-
topHeaderContext.moveTo(rect.left, headerHeight - 0.5);
|
|
24389
|
-
topHeaderContext.lineTo(rect.left + rect.width, headerHeight - 0.5);
|
|
24390
|
-
topHeaderContext.stroke();
|
|
24391
|
-
topHeaderContext.font = `600 ${11 * zoomFactor}px ui-sans-serif, system-ui, sans-serif`;
|
|
24392
|
-
topHeaderContext.fillStyle = palette.mutedText;
|
|
24393
|
-
topHeaderContext.textAlign = "center";
|
|
24394
|
-
topHeaderContext.textBaseline = "middle";
|
|
24395
|
-
topHeaderContext.fillText(columnLabel2(colItem.actualCol), rect.left + rect.width / 2, headerHeight / 2);
|
|
24396
|
-
}
|
|
24397
|
-
leftHeaderContext.fillStyle = palette.rowHeaderSurface;
|
|
24398
|
-
leftHeaderContext.fillRect(0, 0, rowHeaderWidth, bodyHeight);
|
|
24399
|
-
leftHeaderContext.strokeStyle = palette.border;
|
|
24400
|
-
leftHeaderContext.lineWidth = 1;
|
|
24401
|
-
for (const rowItem of canvasVisibleRowItems) {
|
|
24402
|
-
const rect = resolveCanvasRowHeaderRect(rowItem.actualRow);
|
|
24403
|
-
if (!rect || rect.top + rect.height < displayHeaderHeight || rect.top > bodyHeight) {
|
|
24956
|
+
if (!row.isFrozen && !intersectsCanvasDirtyRects(0, row.localTop, rowHeaderWidth, row.height, leftScrollHeaderDirtyRects)) {
|
|
24404
24957
|
continue;
|
|
24405
24958
|
}
|
|
24406
|
-
const selected = normalizedVisibleRange &&
|
|
24407
|
-
|
|
24408
|
-
|
|
24409
|
-
|
|
24410
|
-
|
|
24411
|
-
|
|
24412
|
-
|
|
24413
|
-
|
|
24414
|
-
|
|
24415
|
-
|
|
24416
|
-
|
|
24417
|
-
|
|
24418
|
-
|
|
24419
|
-
|
|
24959
|
+
const selected = normalizedVisibleRange && row.actualRow >= normalizedVisibleRange.start.row && row.actualRow <= normalizedVisibleRange.end.row;
|
|
24960
|
+
paneContext.fillStyle = selected ? selectionHeaderSurface : palette.rowHeaderSurface;
|
|
24961
|
+
paneContext.fillRect(0, row.localTop, rowHeaderWidth, row.height);
|
|
24962
|
+
paneContext.beginPath();
|
|
24963
|
+
paneContext.moveTo(0, row.localTop + row.height - 0.5);
|
|
24964
|
+
paneContext.lineTo(rowHeaderWidth, row.localTop + row.height - 0.5);
|
|
24965
|
+
paneContext.moveTo(rowHeaderWidth - 0.5, row.localTop);
|
|
24966
|
+
paneContext.lineTo(rowHeaderWidth - 0.5, row.localTop + row.height);
|
|
24967
|
+
paneContext.stroke();
|
|
24968
|
+
paneContext.font = `600 ${11 * zoomFactor}px ui-sans-serif, system-ui, sans-serif`;
|
|
24969
|
+
paneContext.fillStyle = palette.mutedText;
|
|
24970
|
+
paneContext.textAlign = "center";
|
|
24971
|
+
paneContext.textBaseline = "middle";
|
|
24972
|
+
paneContext.fillText(`${row.actualRow + 1}`, rowHeaderWidth / 2, row.localTop + row.height / 2);
|
|
24420
24973
|
}
|
|
24421
24974
|
cornerContext.fillStyle = palette.rowHeaderSurface;
|
|
24422
24975
|
cornerContext.fillRect(0, 0, rowHeaderWidth, headerHeight);
|
|
@@ -24440,7 +24993,9 @@ function XlsxGrid({
|
|
|
24440
24993
|
}, [
|
|
24441
24994
|
activeSheet,
|
|
24442
24995
|
applyCanvasViewportCompensation,
|
|
24996
|
+
canvasColumnHeaderCells,
|
|
24443
24997
|
canvasPaneAxisItems,
|
|
24998
|
+
canvasRowHeaderCells,
|
|
24444
24999
|
canvasVisibleColItems,
|
|
24445
25000
|
canvasVisibleRowItems,
|
|
24446
25001
|
colIndexByActual,
|
|
@@ -24455,11 +25010,13 @@ function XlsxGrid({
|
|
|
24455
25010
|
drawingViewport.height,
|
|
24456
25011
|
drawingViewport.width,
|
|
24457
25012
|
experimentalCanvas,
|
|
25013
|
+
frozenPaneBottom,
|
|
25014
|
+
frozenPaneRight,
|
|
24458
25015
|
getCellData,
|
|
25016
|
+
getBodyBlitBufferCanvas,
|
|
25017
|
+
getHeaderBlitBufferCanvas,
|
|
24459
25018
|
palette,
|
|
24460
25019
|
resolveCellDisplayRect,
|
|
24461
|
-
resolveCanvasColumnHeaderRect,
|
|
24462
|
-
resolveCanvasRowHeaderRect,
|
|
24463
25020
|
resolveMergeAnchorCell,
|
|
24464
25021
|
resizeGuide,
|
|
24465
25022
|
rowIndexByActual,
|
|
@@ -24753,6 +25310,10 @@ function XlsxGrid({
|
|
|
24753
25310
|
const leftBodyCanvasHeight = scrollBodyCanvasHeight;
|
|
24754
25311
|
const cornerBodyCanvasWidth = leftBodyCanvasWidth;
|
|
24755
25312
|
const cornerBodyCanvasHeight = topBodyCanvasHeight;
|
|
25313
|
+
const topFrozenHeaderCanvasWidth = leftBodyCanvasWidth;
|
|
25314
|
+
const topScrollHeaderCanvasWidth = scrollBodyCanvasWidth;
|
|
25315
|
+
const leftFrozenHeaderCanvasHeight = topBodyCanvasHeight;
|
|
25316
|
+
const leftScrollHeaderCanvasHeight = scrollBodyCanvasHeight;
|
|
24756
25317
|
const canvasBodyBaseStyle = {
|
|
24757
25318
|
cursor: "cell",
|
|
24758
25319
|
pointerEvents: "auto",
|
|
@@ -24788,22 +25349,38 @@ function XlsxGrid({
|
|
|
24788
25349
|
top: displayHeaderHeight,
|
|
24789
25350
|
zIndex: 31
|
|
24790
25351
|
};
|
|
24791
|
-
const
|
|
25352
|
+
const canvasHeaderBaseStyle = {
|
|
24792
25353
|
cursor: "default",
|
|
24793
|
-
display: drawingViewport.width > 0 && drawingViewport.height > 0 ? "block" : "none",
|
|
24794
|
-
left: 0,
|
|
24795
25354
|
pointerEvents: "auto",
|
|
24796
25355
|
position: "absolute",
|
|
25356
|
+
transformOrigin: "0 0"
|
|
25357
|
+
};
|
|
25358
|
+
const canvasTopFrozenHeaderStyle = {
|
|
25359
|
+
...canvasHeaderBaseStyle,
|
|
25360
|
+
display: topFrozenHeaderCanvasWidth > 0 && drawingViewport.height > 0 ? "block" : "none",
|
|
25361
|
+
left: displayRowHeaderWidth,
|
|
25362
|
+
top: 0,
|
|
25363
|
+
zIndex: canvasHeaderOverlayZIndex + 1
|
|
25364
|
+
};
|
|
25365
|
+
const canvasTopScrollHeaderStyle = {
|
|
25366
|
+
...canvasHeaderBaseStyle,
|
|
25367
|
+
display: topScrollHeaderCanvasWidth > 0 && drawingViewport.height > 0 ? "block" : "none",
|
|
25368
|
+
left: frozenPaneRight,
|
|
24797
25369
|
top: 0,
|
|
24798
25370
|
zIndex: canvasHeaderOverlayZIndex
|
|
24799
25371
|
};
|
|
24800
|
-
const
|
|
24801
|
-
|
|
24802
|
-
display:
|
|
25372
|
+
const canvasLeftFrozenHeaderStyle = {
|
|
25373
|
+
...canvasHeaderBaseStyle,
|
|
25374
|
+
display: leftFrozenHeaderCanvasHeight > 0 && drawingViewport.width > 0 ? "block" : "none",
|
|
24803
25375
|
left: 0,
|
|
24804
|
-
|
|
24805
|
-
|
|
24806
|
-
|
|
25376
|
+
top: displayHeaderHeight,
|
|
25377
|
+
zIndex: canvasHeaderOverlayZIndex + 1
|
|
25378
|
+
};
|
|
25379
|
+
const canvasLeftScrollHeaderStyle = {
|
|
25380
|
+
...canvasHeaderBaseStyle,
|
|
25381
|
+
display: leftScrollHeaderCanvasHeight > 0 && drawingViewport.width > 0 ? "block" : "none",
|
|
25382
|
+
left: 0,
|
|
25383
|
+
top: frozenPaneBottom,
|
|
24807
25384
|
zIndex: canvasHeaderOverlayZIndex
|
|
24808
25385
|
};
|
|
24809
25386
|
const canvasCornerHeaderStyle = {
|
|
@@ -24812,6 +25389,7 @@ function XlsxGrid({
|
|
|
24812
25389
|
pointerEvents: "none",
|
|
24813
25390
|
position: "absolute",
|
|
24814
25391
|
top: 0,
|
|
25392
|
+
transformOrigin: "0 0",
|
|
24815
25393
|
zIndex: canvasHeaderOverlayZIndex + 1
|
|
24816
25394
|
};
|
|
24817
25395
|
const editingOverlayRect = experimentalCanvas && editingCell ? resolveCellDisplayRect(editingCell) : null;
|
|
@@ -25958,7 +26536,7 @@ function XlsxGrid({
|
|
|
25958
26536
|
pointerEvents: "none",
|
|
25959
26537
|
position: "absolute",
|
|
25960
26538
|
top: 0,
|
|
25961
|
-
transform: `translate(${-drawingViewport.left}px, ${-drawingViewport.top}px)`,
|
|
26539
|
+
transform: `translate(${-drawingViewport.left - frozenPaneRight}px, ${-drawingViewport.top - frozenPaneBottom}px)`,
|
|
25962
26540
|
width: totalWidth
|
|
25963
26541
|
},
|
|
25964
26542
|
children: paneDrawingNodes.scroll
|
|
@@ -25973,7 +26551,7 @@ function XlsxGrid({
|
|
|
25973
26551
|
pointerEvents: "none",
|
|
25974
26552
|
position: "absolute",
|
|
25975
26553
|
top: 0,
|
|
25976
|
-
transform: `translate(${-drawingViewport.left}px, ${-displayHeaderHeight}px)`,
|
|
26554
|
+
transform: `translate(${-drawingViewport.left - frozenPaneRight}px, ${-displayHeaderHeight}px)`,
|
|
25977
26555
|
width: totalWidth
|
|
25978
26556
|
},
|
|
25979
26557
|
children: paneDrawingNodes.top
|
|
@@ -25988,7 +26566,7 @@ function XlsxGrid({
|
|
|
25988
26566
|
pointerEvents: "none",
|
|
25989
26567
|
position: "absolute",
|
|
25990
26568
|
top: 0,
|
|
25991
|
-
transform: `translate(${-displayRowHeaderWidth}px, ${-drawingViewport.top}px)`,
|
|
26569
|
+
transform: `translate(${-displayRowHeaderWidth}px, ${-drawingViewport.top - frozenPaneBottom}px)`,
|
|
25992
26570
|
width: totalWidth
|
|
25993
26571
|
},
|
|
25994
26572
|
children: paneDrawingNodes.left
|
|
@@ -26015,21 +26593,41 @@ function XlsxGrid({
|
|
|
26015
26593
|
/* @__PURE__ */ jsx3(
|
|
26016
26594
|
"canvas",
|
|
26017
26595
|
{
|
|
26018
|
-
ref:
|
|
26596
|
+
ref: topFrozenHeaderCanvasRef,
|
|
26597
|
+
onPointerLeave: handleCanvasHeaderPointerLeave,
|
|
26598
|
+
onPointerMove: handleCanvasColumnHeaderPointerMove,
|
|
26599
|
+
onPointerDown: handleCanvasColumnHeaderPointerDown,
|
|
26600
|
+
style: canvasTopFrozenHeaderStyle
|
|
26601
|
+
}
|
|
26602
|
+
),
|
|
26603
|
+
/* @__PURE__ */ jsx3(
|
|
26604
|
+
"canvas",
|
|
26605
|
+
{
|
|
26606
|
+
ref: topScrollHeaderCanvasRef,
|
|
26019
26607
|
onPointerLeave: handleCanvasHeaderPointerLeave,
|
|
26020
26608
|
onPointerMove: handleCanvasColumnHeaderPointerMove,
|
|
26021
26609
|
onPointerDown: handleCanvasColumnHeaderPointerDown,
|
|
26022
|
-
style:
|
|
26610
|
+
style: canvasTopScrollHeaderStyle
|
|
26023
26611
|
}
|
|
26024
26612
|
),
|
|
26025
26613
|
/* @__PURE__ */ jsx3(
|
|
26026
26614
|
"canvas",
|
|
26027
26615
|
{
|
|
26028
|
-
ref:
|
|
26616
|
+
ref: leftFrozenHeaderCanvasRef,
|
|
26029
26617
|
onPointerLeave: handleCanvasHeaderPointerLeave,
|
|
26030
26618
|
onPointerMove: handleCanvasRowHeaderPointerMove,
|
|
26031
26619
|
onPointerDown: handleCanvasRowHeaderPointerDown,
|
|
26032
|
-
style:
|
|
26620
|
+
style: canvasLeftFrozenHeaderStyle
|
|
26621
|
+
}
|
|
26622
|
+
),
|
|
26623
|
+
/* @__PURE__ */ jsx3(
|
|
26624
|
+
"canvas",
|
|
26625
|
+
{
|
|
26626
|
+
ref: leftScrollHeaderCanvasRef,
|
|
26627
|
+
onPointerLeave: handleCanvasHeaderPointerLeave,
|
|
26628
|
+
onPointerMove: handleCanvasRowHeaderPointerMove,
|
|
26629
|
+
onPointerDown: handleCanvasRowHeaderPointerDown,
|
|
26630
|
+
style: canvasLeftScrollHeaderStyle
|
|
26033
26631
|
}
|
|
26034
26632
|
),
|
|
26035
26633
|
/* @__PURE__ */ jsx3("canvas", { ref: cornerHeaderCanvasRef, style: canvasCornerHeaderStyle })
|
|
@@ -26339,7 +26937,7 @@ function XlsxGrid({
|
|
|
26339
26937
|
}
|
|
26340
26938
|
}
|
|
26341
26939
|
) : null,
|
|
26342
|
-
openTableMenuState ? /* @__PURE__ */ jsx3(
|
|
26940
|
+
!renderTableHeaderMenu && openTableMenuState ? /* @__PURE__ */ jsx3(
|
|
26343
26941
|
"div",
|
|
26344
26942
|
{
|
|
26345
26943
|
ref: tableMenuRef,
|
|
@@ -26350,22 +26948,23 @@ function XlsxGrid({
|
|
|
26350
26948
|
top: openTableMenuState.top,
|
|
26351
26949
|
zIndex: 50
|
|
26352
26950
|
},
|
|
26353
|
-
children:
|
|
26354
|
-
close: () => setOpenTableMenu(null),
|
|
26355
|
-
column: openTableMenuState.column,
|
|
26356
|
-
direction: sortState && sortState.tableName === openTableMenuState.table.name && sortState.columnIndex === openTableMenuState.column.index ? sortState.direction : null,
|
|
26357
|
-
sortAscending: () => sortTable(openTableMenuState.table.name, openTableMenuState.column.index, "ascending"),
|
|
26358
|
-
sortDescending: () => sortTable(openTableMenuState.table.name, openTableMenuState.column.index, "descending"),
|
|
26359
|
-
table: openTableMenuState.table
|
|
26360
|
-
}) : /* @__PURE__ */ jsx3(
|
|
26951
|
+
children: /* @__PURE__ */ jsx3(
|
|
26361
26952
|
DefaultTableHeaderMenu,
|
|
26362
26953
|
{
|
|
26363
|
-
|
|
26954
|
+
cell: { col: openTableMenuState.column.index + openTableMenuState.table.start.col, row: openTableMenuState.table.start.row },
|
|
26364
26955
|
column: openTableMenuState.column,
|
|
26365
26956
|
direction: sortState && sortState.tableName === openTableMenuState.table.name && sortState.columnIndex === openTableMenuState.column.index ? sortState.direction : null,
|
|
26366
|
-
sortAscending: () =>
|
|
26367
|
-
|
|
26368
|
-
|
|
26957
|
+
sortAscending: () => {
|
|
26958
|
+
sortTable(openTableMenuState.table.name, openTableMenuState.column.index, "ascending");
|
|
26959
|
+
setOpenTableMenu(null);
|
|
26960
|
+
},
|
|
26961
|
+
sortDescending: () => {
|
|
26962
|
+
sortTable(openTableMenuState.table.name, openTableMenuState.column.index, "descending");
|
|
26963
|
+
setOpenTableMenu(null);
|
|
26964
|
+
},
|
|
26965
|
+
table: openTableMenuState.table,
|
|
26966
|
+
triggerIcon: "\u25BE",
|
|
26967
|
+
triggerProps: { type: "button" }
|
|
26369
26968
|
}
|
|
26370
26969
|
)
|
|
26371
26970
|
}
|
|
@@ -26796,6 +27395,476 @@ function useXlsxViewerCharts() {
|
|
|
26796
27395
|
]
|
|
26797
27396
|
);
|
|
26798
27397
|
}
|
|
27398
|
+
function useXlsxViewerThumbnails(options = {}) {
|
|
27399
|
+
const { workbook, sheets } = useXlsxViewer();
|
|
27400
|
+
const { isDark } = React4.useContext(ViewerAppearanceContext);
|
|
27401
|
+
const palette = useViewerPalette(isDark);
|
|
27402
|
+
const includeHeaders = options.includeHeaders ?? true;
|
|
27403
|
+
const resolution = options.resolution;
|
|
27404
|
+
const thumbnails = React4.useMemo(() => {
|
|
27405
|
+
return sheets.map((sheet, sheetIndex) => {
|
|
27406
|
+
const worksheet = workbook?.getSheet(sheet.workbookSheetIndex) ?? null;
|
|
27407
|
+
const showGridLines = sheet.showGridLines ?? true;
|
|
27408
|
+
const hiddenRowSet = new Set(sheet.hiddenRows ?? []);
|
|
27409
|
+
const hiddenColSet = new Set(sheet.hiddenCols ?? []);
|
|
27410
|
+
const visibleRows = buildVisibleAxisIndices(
|
|
27411
|
+
sheet.visibleRows ?? [],
|
|
27412
|
+
Math.max(THUMBNAIL_FALLBACK_ROWS, (sheet.maxUsedRow ?? -1) + THUMBNAIL_FALLBACK_ROWS + 1),
|
|
27413
|
+
sheet.maxUsedRow ?? -1,
|
|
27414
|
+
hiddenRowSet
|
|
27415
|
+
);
|
|
27416
|
+
const visibleCols = buildVisibleAxisIndices(
|
|
27417
|
+
sheet.visibleCols ?? [],
|
|
27418
|
+
Math.max(THUMBNAIL_FALLBACK_COLS, (sheet.maxUsedCol ?? -1) + THUMBNAIL_FALLBACK_COLS + 1),
|
|
27419
|
+
sheet.maxUsedCol ?? -1,
|
|
27420
|
+
hiddenColSet
|
|
27421
|
+
);
|
|
27422
|
+
const resolveColumnWidthPx = (actualCol) => {
|
|
27423
|
+
if (worksheet && !worksheet.isColumnHidden(actualCol)) {
|
|
27424
|
+
const width = worksheet.getColumnWidth(actualCol);
|
|
27425
|
+
if (width !== void 0 && width !== null) {
|
|
27426
|
+
return Math.max(
|
|
27427
|
+
resolveRenderedSheetAxisPixels(resolveSheetColumnWidthPixels(width, sheet.columnWidthCharacterWidthPx), showGridLines),
|
|
27428
|
+
DEFAULT_COL_WIDTH2 / 2
|
|
27429
|
+
);
|
|
27430
|
+
}
|
|
27431
|
+
}
|
|
27432
|
+
return Math.max(
|
|
27433
|
+
resolveRenderedSheetAxisPixels(
|
|
27434
|
+
sheet.colWidthOverridesPx[actualCol] ?? sheet.defaultColWidthPx ?? DEFAULT_COL_WIDTH2,
|
|
27435
|
+
showGridLines
|
|
27436
|
+
),
|
|
27437
|
+
DEFAULT_COL_WIDTH2 / 2
|
|
27438
|
+
);
|
|
27439
|
+
};
|
|
27440
|
+
const resolveRowHeightPx = (actualRow) => {
|
|
27441
|
+
if (worksheet && !worksheet.isRowHidden(actualRow)) {
|
|
27442
|
+
const height = worksheet.getRowHeight(actualRow);
|
|
27443
|
+
if (height !== void 0 && height !== null) {
|
|
27444
|
+
return Math.max(
|
|
27445
|
+
resolveRenderedSheetAxisPixels(resolveSheetRowHeightPixels(height), showGridLines),
|
|
27446
|
+
DEFAULT_ROW_HEIGHT2 / 1.5
|
|
27447
|
+
);
|
|
27448
|
+
}
|
|
27449
|
+
}
|
|
27450
|
+
return Math.max(
|
|
27451
|
+
resolveRenderedSheetAxisPixels(
|
|
27452
|
+
sheet.rowHeightOverridesPx[actualRow] ?? sheet.defaultRowHeightPx ?? DEFAULT_ROW_HEIGHT2,
|
|
27453
|
+
showGridLines
|
|
27454
|
+
),
|
|
27455
|
+
DEFAULT_ROW_HEIGHT2 / 1.5
|
|
27456
|
+
);
|
|
27457
|
+
};
|
|
27458
|
+
const previewRows = resolveThumbnailAxisIndices({
|
|
27459
|
+
fallbackCount: THUMBNAIL_FALLBACK_ROWS,
|
|
27460
|
+
getSizePx: resolveRowHeightPx,
|
|
27461
|
+
maxCount: THUMBNAIL_MAX_ROWS,
|
|
27462
|
+
maxLogicalPixels: THUMBNAIL_MAX_SOURCE_HEIGHT_PX,
|
|
27463
|
+
maxUsedIndex: sheet.maxUsedRow ?? -1,
|
|
27464
|
+
minUsedIndex: Math.max(0, sheet.minUsedRow ?? 0),
|
|
27465
|
+
precomputed: visibleRows
|
|
27466
|
+
});
|
|
27467
|
+
const previewCols = resolveThumbnailAxisIndices({
|
|
27468
|
+
fallbackCount: THUMBNAIL_FALLBACK_COLS,
|
|
27469
|
+
getSizePx: resolveColumnWidthPx,
|
|
27470
|
+
maxCount: THUMBNAIL_MAX_COLS,
|
|
27471
|
+
maxLogicalPixels: THUMBNAIL_MAX_SOURCE_WIDTH_PX,
|
|
27472
|
+
maxUsedIndex: sheet.maxUsedCol ?? -1,
|
|
27473
|
+
minUsedIndex: Math.max(0, sheet.minUsedCol ?? 0),
|
|
27474
|
+
precomputed: visibleCols
|
|
27475
|
+
});
|
|
27476
|
+
const rowAxis = buildThumbnailAxisItems(previewRows, resolveRowHeightPx);
|
|
27477
|
+
const colAxis = buildThumbnailAxisItems(previewCols, resolveColumnWidthPx);
|
|
27478
|
+
const rowItemByActual = new Map(rowAxis.items.map((item) => [item.actualIndex, item]));
|
|
27479
|
+
const colItemByActual = new Map(colAxis.items.map((item) => [item.actualIndex, item]));
|
|
27480
|
+
const headerHeight = includeHeaders ? HEADER_HEIGHT : 0;
|
|
27481
|
+
const rowHeaderWidth = includeHeaders ? ROW_HEADER_WIDTH : 0;
|
|
27482
|
+
const sourceWidth = rowHeaderWidth + colAxis.totalSize;
|
|
27483
|
+
const sourceHeight = headerHeight + rowAxis.totalSize;
|
|
27484
|
+
const outputSize = resolveThumbnailOutputSize(sourceWidth, sourceHeight, resolution);
|
|
27485
|
+
const sourceRange = {
|
|
27486
|
+
start: {
|
|
27487
|
+
col: previewCols[0] ?? 0,
|
|
27488
|
+
row: previewRows[0] ?? 0
|
|
27489
|
+
},
|
|
27490
|
+
end: {
|
|
27491
|
+
col: previewCols[previewCols.length - 1] ?? 0,
|
|
27492
|
+
row: previewRows[previewRows.length - 1] ?? 0
|
|
27493
|
+
}
|
|
27494
|
+
};
|
|
27495
|
+
const sparklineByCell = new Map(
|
|
27496
|
+
(sheet.sparklines ?? []).map((sparkline) => [`${sparkline.target.row}:${sparkline.target.col}`, sparkline])
|
|
27497
|
+
);
|
|
27498
|
+
const paint = (canvas) => {
|
|
27499
|
+
if (!canvas) {
|
|
27500
|
+
return false;
|
|
27501
|
+
}
|
|
27502
|
+
const context = canvas.getContext("2d");
|
|
27503
|
+
if (!context) {
|
|
27504
|
+
return false;
|
|
27505
|
+
}
|
|
27506
|
+
const dpr = typeof window === "undefined" ? 1 : Math.max(1, window.devicePixelRatio || 1);
|
|
27507
|
+
const outputWidth = outputSize.width;
|
|
27508
|
+
const outputHeight = outputSize.height;
|
|
27509
|
+
const scale = outputSize.scale;
|
|
27510
|
+
const deviceWidth = Math.max(1, Math.round(outputWidth * dpr));
|
|
27511
|
+
const deviceHeight = Math.max(1, Math.round(outputHeight * dpr));
|
|
27512
|
+
if (canvas.width !== deviceWidth) {
|
|
27513
|
+
canvas.width = deviceWidth;
|
|
27514
|
+
}
|
|
27515
|
+
if (canvas.height !== deviceHeight) {
|
|
27516
|
+
canvas.height = deviceHeight;
|
|
27517
|
+
}
|
|
27518
|
+
if (canvas.style.width !== `${outputWidth}px`) {
|
|
27519
|
+
canvas.style.width = `${outputWidth}px`;
|
|
27520
|
+
}
|
|
27521
|
+
if (canvas.style.height !== `${outputHeight}px`) {
|
|
27522
|
+
canvas.style.height = `${outputHeight}px`;
|
|
27523
|
+
}
|
|
27524
|
+
context.setTransform(dpr * scale, 0, 0, dpr * scale, 0, 0);
|
|
27525
|
+
context.clearRect(0, 0, Math.max(1, sourceWidth), Math.max(1, sourceHeight));
|
|
27526
|
+
context.fillStyle = palette.canvas;
|
|
27527
|
+
context.fillRect(0, 0, Math.max(1, sourceWidth), Math.max(1, sourceHeight));
|
|
27528
|
+
context.fillStyle = resolveSheetSurface(sheet, palette);
|
|
27529
|
+
context.fillRect(rowHeaderWidth, headerHeight, Math.max(1, colAxis.totalSize), Math.max(1, rowAxis.totalSize));
|
|
27530
|
+
if (includeHeaders) {
|
|
27531
|
+
context.fillStyle = palette.headerSurface;
|
|
27532
|
+
context.fillRect(rowHeaderWidth, 0, Math.max(1, colAxis.totalSize), headerHeight);
|
|
27533
|
+
context.fillStyle = palette.rowHeaderSurface;
|
|
27534
|
+
context.fillRect(0, headerHeight, rowHeaderWidth, Math.max(1, rowAxis.totalSize));
|
|
27535
|
+
context.fillRect(0, 0, rowHeaderWidth, headerHeight);
|
|
27536
|
+
}
|
|
27537
|
+
if (!worksheet) {
|
|
27538
|
+
return true;
|
|
27539
|
+
}
|
|
27540
|
+
const conditionalFormatMetricsCache = /* @__PURE__ */ new Map();
|
|
27541
|
+
const cellRenderCache = /* @__PURE__ */ new Map();
|
|
27542
|
+
const getCellData = (row, col) => {
|
|
27543
|
+
const cacheKey = `${row}:${col}`;
|
|
27544
|
+
const cached = cellRenderCache.get(cacheKey);
|
|
27545
|
+
if (cached) {
|
|
27546
|
+
return cached;
|
|
27547
|
+
}
|
|
27548
|
+
if (worksheet.isMergedSecondary(row, col)) {
|
|
27549
|
+
const mergedSecondaryData = {
|
|
27550
|
+
isMergedSecondary: true,
|
|
27551
|
+
style: {},
|
|
27552
|
+
value: ""
|
|
27553
|
+
};
|
|
27554
|
+
cellRenderCache.set(cacheKey, mergedSecondaryData);
|
|
27555
|
+
return mergedSecondaryData;
|
|
27556
|
+
}
|
|
27557
|
+
const merge = worksheet.getMergeSpan(row, col);
|
|
27558
|
+
const inheritedStyle = resolveInheritedCellStyle2(sheet, row, col);
|
|
27559
|
+
const worksheetStyle = worksheet.getCellStyleAt(row, col) ?? null;
|
|
27560
|
+
const mergedStyle = mergeResolvedCellStyle(inheritedStyle, worksheetStyle, { replaceXfSubtrees: true });
|
|
27561
|
+
const alignment = mergedStyle?.alignment;
|
|
27562
|
+
const sparkline = sparklineByCell.get(cacheKey) ?? null;
|
|
27563
|
+
const sparklineValues = sparkline ? sparkline.range.start.row === sparkline.range.end.row ? Array.from(
|
|
27564
|
+
{ length: Math.abs(sparkline.range.end.col - sparkline.range.start.col) + 1 },
|
|
27565
|
+
(_, index) => getCellNumericValue(
|
|
27566
|
+
worksheet,
|
|
27567
|
+
sparkline.range.start.row,
|
|
27568
|
+
Math.min(sparkline.range.start.col, sparkline.range.end.col) + index
|
|
27569
|
+
)
|
|
27570
|
+
) : Array.from(
|
|
27571
|
+
{ length: Math.abs(sparkline.range.end.row - sparkline.range.start.row) + 1 },
|
|
27572
|
+
(_, index) => getCellNumericValue(
|
|
27573
|
+
worksheet,
|
|
27574
|
+
Math.min(sparkline.range.start.row, sparkline.range.end.row) + index,
|
|
27575
|
+
sparkline.range.start.col
|
|
27576
|
+
)
|
|
27577
|
+
) : null;
|
|
27578
|
+
const checkboxState = mergedStyle?.cellControl ? getCellBooleanValue(worksheet, row, col) : null;
|
|
27579
|
+
const nextData = {
|
|
27580
|
+
canvas: void 0,
|
|
27581
|
+
checkboxState,
|
|
27582
|
+
colSpan: merge?.colSpan,
|
|
27583
|
+
conditionalColorScale: resolveConditionalColorScaleForCell(
|
|
27584
|
+
row,
|
|
27585
|
+
col,
|
|
27586
|
+
worksheet,
|
|
27587
|
+
sheet,
|
|
27588
|
+
conditionalFormatMetricsCache
|
|
27589
|
+
),
|
|
27590
|
+
conditionalDataBar: resolveConditionalDataBarForCell(
|
|
27591
|
+
row,
|
|
27592
|
+
col,
|
|
27593
|
+
worksheet,
|
|
27594
|
+
sheet,
|
|
27595
|
+
conditionalFormatMetricsCache
|
|
27596
|
+
),
|
|
27597
|
+
conditionalIcon: resolveConditionalIconForCell(
|
|
27598
|
+
row,
|
|
27599
|
+
col,
|
|
27600
|
+
worksheet,
|
|
27601
|
+
sheet,
|
|
27602
|
+
conditionalFormatMetricsCache
|
|
27603
|
+
),
|
|
27604
|
+
isMergedSecondary: false,
|
|
27605
|
+
rowSpan: merge?.rowSpan,
|
|
27606
|
+
sparkline: sparkline && sparklineValues ? { config: sparkline, values: sparklineValues } : null,
|
|
27607
|
+
style: buildCellStyle(mergedStyle, palette, sheet.themePalette, {
|
|
27608
|
+
showGridLines
|
|
27609
|
+
}),
|
|
27610
|
+
textRotationDeg: resolveSpreadsheetTextRotation(alignment?.textRotation),
|
|
27611
|
+
value: sparkline ? "" : checkboxState !== null ? "" : getCellDisplayValue(worksheet, row, col, sheet)
|
|
27612
|
+
};
|
|
27613
|
+
nextData.canvas = buildCanvasCellStyleCache(nextData.style);
|
|
27614
|
+
cellRenderCache.set(cacheKey, nextData);
|
|
27615
|
+
return nextData;
|
|
27616
|
+
};
|
|
27617
|
+
for (const rowItem of rowAxis.items) {
|
|
27618
|
+
for (const colItem of colAxis.items) {
|
|
27619
|
+
const cellData = getCellData(rowItem.actualIndex, colItem.actualIndex);
|
|
27620
|
+
if (cellData.isMergedSecondary) {
|
|
27621
|
+
continue;
|
|
27622
|
+
}
|
|
27623
|
+
const colSpan = Math.max(1, cellData.colSpan ?? 1);
|
|
27624
|
+
const rowSpan = Math.max(1, cellData.rowSpan ?? 1);
|
|
27625
|
+
let width = colItem.size;
|
|
27626
|
+
let height = rowItem.size;
|
|
27627
|
+
for (let colOffset = 1; colOffset < colSpan; colOffset += 1) {
|
|
27628
|
+
const nextCol = colItemByActual.get(colItem.actualIndex + colOffset);
|
|
27629
|
+
if (!nextCol) {
|
|
27630
|
+
break;
|
|
27631
|
+
}
|
|
27632
|
+
width += nextCol.size;
|
|
27633
|
+
}
|
|
27634
|
+
for (let rowOffset = 1; rowOffset < rowSpan; rowOffset += 1) {
|
|
27635
|
+
const nextRow = rowItemByActual.get(rowItem.actualIndex + rowOffset);
|
|
27636
|
+
if (!nextRow) {
|
|
27637
|
+
break;
|
|
27638
|
+
}
|
|
27639
|
+
height += nextRow.size;
|
|
27640
|
+
}
|
|
27641
|
+
const rect = {
|
|
27642
|
+
height,
|
|
27643
|
+
left: rowHeaderWidth + colItem.start,
|
|
27644
|
+
top: headerHeight + rowItem.start,
|
|
27645
|
+
width
|
|
27646
|
+
};
|
|
27647
|
+
const canvasCellStyle = cellData.canvas ?? buildCanvasCellStyleCache(cellData.style);
|
|
27648
|
+
const gradientFill = typeof cellData.style.backgroundImage === "string" ? resolveCanvasGradientFill(context, rect, cellData.style.backgroundImage) : null;
|
|
27649
|
+
const fillColor = cellData.conditionalColorScale?.color ?? (typeof cellData.style.backgroundColor === "string" ? cellData.style.backgroundColor : resolveSheetSurface(sheet, palette));
|
|
27650
|
+
const hasExplicitCellFill = cellData.conditionalColorScale !== null || gradientFill !== null || typeof cellData.style.backgroundColor === "string" && cellData.style.backgroundColor !== resolveSheetSurface(sheet, palette);
|
|
27651
|
+
context.fillStyle = gradientFill ?? fillColor;
|
|
27652
|
+
context.fillRect(rect.left, rect.top, rect.width, rect.height);
|
|
27653
|
+
if (cellData.conditionalDataBar) {
|
|
27654
|
+
const barLeft = rect.left + 4;
|
|
27655
|
+
const barTop = rect.top + 4;
|
|
27656
|
+
const barWidth = Math.max(0, (rect.width - 8) * (cellData.conditionalDataBar.widthPercent / 100));
|
|
27657
|
+
const barHeight = Math.max(0, rect.height - 8);
|
|
27658
|
+
if (barWidth > 0 && barHeight > 0) {
|
|
27659
|
+
context.fillStyle = resolveCanvasDataBarFill(
|
|
27660
|
+
context,
|
|
27661
|
+
barLeft,
|
|
27662
|
+
barTop,
|
|
27663
|
+
barWidth,
|
|
27664
|
+
barHeight,
|
|
27665
|
+
cellData.conditionalDataBar
|
|
27666
|
+
);
|
|
27667
|
+
context.fillRect(barLeft, barTop, barWidth, barHeight);
|
|
27668
|
+
if (cellData.conditionalDataBar.border !== false && cellData.conditionalDataBar.borderColor) {
|
|
27669
|
+
context.strokeStyle = cellData.conditionalDataBar.borderColor;
|
|
27670
|
+
context.lineWidth = 1;
|
|
27671
|
+
context.strokeRect(barLeft + 0.5, barTop + 0.5, Math.max(0, barWidth - 1), Math.max(0, barHeight - 1));
|
|
27672
|
+
}
|
|
27673
|
+
}
|
|
27674
|
+
}
|
|
27675
|
+
if (showGridLines && !hasExplicitCellFill) {
|
|
27676
|
+
context.strokeStyle = palette.border;
|
|
27677
|
+
context.lineWidth = 1;
|
|
27678
|
+
context.beginPath();
|
|
27679
|
+
if (colItem.start === 0) {
|
|
27680
|
+
context.moveTo(rect.left + 0.5, rect.top);
|
|
27681
|
+
context.lineTo(rect.left + 0.5, rect.top + rect.height);
|
|
27682
|
+
}
|
|
27683
|
+
if (rowItem.start === 0) {
|
|
27684
|
+
context.moveTo(rect.left, rect.top + 0.5);
|
|
27685
|
+
context.lineTo(rect.left + rect.width, rect.top + 0.5);
|
|
27686
|
+
}
|
|
27687
|
+
context.moveTo(rect.left + rect.width - 0.5, rect.top);
|
|
27688
|
+
context.lineTo(rect.left + rect.width - 0.5, rect.top + rect.height);
|
|
27689
|
+
context.moveTo(rect.left, rect.top + rect.height - 0.5);
|
|
27690
|
+
context.lineTo(rect.left + rect.width, rect.top + rect.height - 0.5);
|
|
27691
|
+
context.stroke();
|
|
27692
|
+
}
|
|
27693
|
+
if (canvasCellStyle.topBorder) {
|
|
27694
|
+
strokeCanvasBorderSide(context, "top", rect, canvasCellStyle.topBorder);
|
|
27695
|
+
}
|
|
27696
|
+
if (canvasCellStyle.rightBorder) {
|
|
27697
|
+
strokeCanvasBorderSide(context, "right", rect, canvasCellStyle.rightBorder);
|
|
27698
|
+
}
|
|
27699
|
+
if (canvasCellStyle.bottomBorder) {
|
|
27700
|
+
strokeCanvasBorderSide(context, "bottom", rect, canvasCellStyle.bottomBorder);
|
|
27701
|
+
}
|
|
27702
|
+
if (canvasCellStyle.leftBorder) {
|
|
27703
|
+
strokeCanvasBorderSide(context, "left", rect, canvasCellStyle.leftBorder);
|
|
27704
|
+
}
|
|
27705
|
+
const padding = canvasCellStyle.padding;
|
|
27706
|
+
const contentLeft = rect.left + padding.left;
|
|
27707
|
+
const contentTop = rect.top + padding.top;
|
|
27708
|
+
const contentWidth = Math.max(0, rect.width - padding.left - padding.right);
|
|
27709
|
+
const contentHeight = Math.max(0, rect.height - padding.top - padding.bottom);
|
|
27710
|
+
const rawText = cellData.value ?? "";
|
|
27711
|
+
context.save();
|
|
27712
|
+
context.beginPath();
|
|
27713
|
+
context.rect(contentLeft, contentTop, contentWidth, contentHeight);
|
|
27714
|
+
context.clip();
|
|
27715
|
+
context.font = canvasCellStyle.baseFont;
|
|
27716
|
+
context.fillStyle = canvasCellStyle.textColor;
|
|
27717
|
+
context.textBaseline = "middle";
|
|
27718
|
+
if (cellData.checkboxState != null) {
|
|
27719
|
+
const boxSize = Math.min(14, contentWidth, contentHeight);
|
|
27720
|
+
const boxLeft = rect.left + (rect.width - boxSize) / 2;
|
|
27721
|
+
const boxTop = rect.top + (rect.height - boxSize) / 2;
|
|
27722
|
+
context.strokeStyle = paletteIsDark(palette) ? "#cbd5e1" : "#475569";
|
|
27723
|
+
context.lineWidth = 1.25;
|
|
27724
|
+
context.strokeRect(boxLeft, boxTop, boxSize, boxSize);
|
|
27725
|
+
if (cellData.checkboxState) {
|
|
27726
|
+
context.fillStyle = paletteIsDark(palette) ? "#60a5fa" : "#2563eb";
|
|
27727
|
+
context.fillRect(boxLeft + 1.5, boxTop + 1.5, Math.max(0, boxSize - 3), Math.max(0, boxSize - 3));
|
|
27728
|
+
}
|
|
27729
|
+
} else if (cellData.sparkline) {
|
|
27730
|
+
const sparkline = cellData.sparkline.config;
|
|
27731
|
+
const sparklineValues = cellData.sparkline.values;
|
|
27732
|
+
const points = sparklineValues.map((value, index) => ({ index, value })).filter((entry) => typeof entry.value === "number" && Number.isFinite(entry.value));
|
|
27733
|
+
if (points.length > 1) {
|
|
27734
|
+
const minValue = Math.min(...points.map((entry) => entry.value));
|
|
27735
|
+
const maxValue = Math.max(...points.map((entry) => entry.value));
|
|
27736
|
+
const sparkLeft = contentLeft + 1;
|
|
27737
|
+
const sparkTop = contentTop + 2;
|
|
27738
|
+
const sparkWidth = Math.max(1, contentWidth - 2);
|
|
27739
|
+
const sparkHeight = Math.max(1, contentHeight - 4);
|
|
27740
|
+
const xStep = points.length > 1 ? sparkWidth / (points.length - 1) : 0;
|
|
27741
|
+
context.strokeStyle = sparkline.color ?? "#2563eb";
|
|
27742
|
+
context.lineCap = "round";
|
|
27743
|
+
context.lineJoin = "round";
|
|
27744
|
+
context.lineWidth = 1.25;
|
|
27745
|
+
context.beginPath();
|
|
27746
|
+
points.forEach((entry, index) => {
|
|
27747
|
+
const x = sparkLeft + index * xStep;
|
|
27748
|
+
const y = sparkTop + sparkHeight - clampSparklineValue(entry.value, minValue, maxValue) * sparkHeight;
|
|
27749
|
+
if (index === 0) {
|
|
27750
|
+
context.moveTo(x, y);
|
|
27751
|
+
} else {
|
|
27752
|
+
context.lineTo(x, y);
|
|
27753
|
+
}
|
|
27754
|
+
});
|
|
27755
|
+
context.stroke();
|
|
27756
|
+
}
|
|
27757
|
+
} else if (rawText.length > 0) {
|
|
27758
|
+
const align = canvasCellStyle.textAlign;
|
|
27759
|
+
context.textAlign = align;
|
|
27760
|
+
const textX = align === "right" ? contentLeft + contentWidth : align === "center" ? contentLeft + contentWidth / 2 : contentLeft;
|
|
27761
|
+
const textY = contentTop + contentHeight / 2;
|
|
27762
|
+
const trailingInset = cellData.conditionalIcon ? 18 : 0;
|
|
27763
|
+
const maxTextWidth = Math.max(0, contentWidth - trailingInset);
|
|
27764
|
+
if (cellData.textRotationDeg) {
|
|
27765
|
+
const rotationOriginX = contentLeft + contentWidth / 2;
|
|
27766
|
+
context.save();
|
|
27767
|
+
context.translate(rotationOriginX, textY);
|
|
27768
|
+
context.rotate(cellData.textRotationDeg * Math.PI / 180);
|
|
27769
|
+
context.fillText(
|
|
27770
|
+
rawText,
|
|
27771
|
+
align === "right" ? contentWidth / 2 : align === "center" ? 0 : -(contentWidth / 2),
|
|
27772
|
+
0
|
|
27773
|
+
);
|
|
27774
|
+
context.restore();
|
|
27775
|
+
} else if (canvasCellStyle.usesWrappedText || rawText.includes("\n")) {
|
|
27776
|
+
const lines = wrapCanvasText(context, rawText, maxTextWidth);
|
|
27777
|
+
const lineHeight = resolveCanvasLineHeight(cellData.style, 12);
|
|
27778
|
+
const textBlockHeight = lines.length * lineHeight;
|
|
27779
|
+
let textBlockTop = contentTop;
|
|
27780
|
+
if (cellData.style.verticalAlign === "middle") {
|
|
27781
|
+
textBlockTop = contentTop + (contentHeight - textBlockHeight) / 2;
|
|
27782
|
+
} else if (cellData.style.verticalAlign !== "top") {
|
|
27783
|
+
textBlockTop = contentTop + contentHeight - textBlockHeight;
|
|
27784
|
+
}
|
|
27785
|
+
lines.forEach((line, lineIndex) => {
|
|
27786
|
+
context.fillText(line, textX, textBlockTop + lineIndex * lineHeight + lineHeight / 2);
|
|
27787
|
+
});
|
|
27788
|
+
} else {
|
|
27789
|
+
const text = canvasCellStyle.textOverflowEllipsis ? truncateCanvasText(context, rawText, maxTextWidth) : rawText;
|
|
27790
|
+
context.fillText(text, textX, textY);
|
|
27791
|
+
}
|
|
27792
|
+
}
|
|
27793
|
+
if (cellData.conditionalIcon) {
|
|
27794
|
+
const iconSize = 10;
|
|
27795
|
+
const iconX = rect.left + rect.width - (padding.right + iconSize + 4);
|
|
27796
|
+
const iconY = rect.top + rect.height / 2;
|
|
27797
|
+
drawCanvasConditionalIcon(context, cellData.conditionalIcon, iconX + iconSize / 2, iconY, iconSize);
|
|
27798
|
+
}
|
|
27799
|
+
context.restore();
|
|
27800
|
+
}
|
|
27801
|
+
}
|
|
27802
|
+
if (includeHeaders) {
|
|
27803
|
+
context.strokeStyle = palette.border;
|
|
27804
|
+
context.lineWidth = 1;
|
|
27805
|
+
context.font = "600 11px ui-sans-serif, system-ui, sans-serif";
|
|
27806
|
+
context.fillStyle = palette.mutedText;
|
|
27807
|
+
context.textBaseline = "middle";
|
|
27808
|
+
for (const colItem of colAxis.items) {
|
|
27809
|
+
const left = rowHeaderWidth + colItem.start;
|
|
27810
|
+
context.beginPath();
|
|
27811
|
+
context.moveTo(left + colItem.size - 0.5, 0);
|
|
27812
|
+
context.lineTo(left + colItem.size - 0.5, headerHeight);
|
|
27813
|
+
context.moveTo(left, headerHeight - 0.5);
|
|
27814
|
+
context.lineTo(left + colItem.size, headerHeight - 0.5);
|
|
27815
|
+
context.stroke();
|
|
27816
|
+
context.textAlign = "center";
|
|
27817
|
+
context.fillText(columnLabel2(colItem.actualIndex), left + colItem.size / 2, headerHeight / 2);
|
|
27818
|
+
}
|
|
27819
|
+
for (const rowItem of rowAxis.items) {
|
|
27820
|
+
const top = headerHeight + rowItem.start;
|
|
27821
|
+
context.beginPath();
|
|
27822
|
+
context.moveTo(0, top + rowItem.size - 0.5);
|
|
27823
|
+
context.lineTo(rowHeaderWidth, top + rowItem.size - 0.5);
|
|
27824
|
+
context.moveTo(rowHeaderWidth - 0.5, top);
|
|
27825
|
+
context.lineTo(rowHeaderWidth - 0.5, top + rowItem.size);
|
|
27826
|
+
context.stroke();
|
|
27827
|
+
context.textAlign = "center";
|
|
27828
|
+
context.fillText(`${rowItem.actualIndex + 1}`, rowHeaderWidth / 2, top + rowItem.size / 2);
|
|
27829
|
+
}
|
|
27830
|
+
context.beginPath();
|
|
27831
|
+
context.moveTo(rowHeaderWidth - 0.5, 0);
|
|
27832
|
+
context.lineTo(rowHeaderWidth - 0.5, headerHeight);
|
|
27833
|
+
context.moveTo(0, headerHeight - 0.5);
|
|
27834
|
+
context.lineTo(rowHeaderWidth, headerHeight - 0.5);
|
|
27835
|
+
context.stroke();
|
|
27836
|
+
}
|
|
27837
|
+
return true;
|
|
27838
|
+
};
|
|
27839
|
+
const plan = {
|
|
27840
|
+
aspectRatio: sourceWidth / Math.max(1, sourceHeight),
|
|
27841
|
+
contentHeight: rowAxis.totalSize,
|
|
27842
|
+
contentWidth: colAxis.totalSize,
|
|
27843
|
+
height: outputSize.height,
|
|
27844
|
+
paint,
|
|
27845
|
+
sourceRange,
|
|
27846
|
+
width: outputSize.width
|
|
27847
|
+
};
|
|
27848
|
+
return {
|
|
27849
|
+
...plan,
|
|
27850
|
+
sheet,
|
|
27851
|
+
sheetIndex,
|
|
27852
|
+
workbookSheetIndex: sheet.workbookSheetIndex
|
|
27853
|
+
};
|
|
27854
|
+
});
|
|
27855
|
+
}, [includeHeaders, palette, resolution, sheets, workbook]);
|
|
27856
|
+
const paintThumbnail = React4.useCallback(
|
|
27857
|
+
(sheetIndex, canvas) => thumbnails[sheetIndex]?.paint(canvas) ?? false,
|
|
27858
|
+
[thumbnails]
|
|
27859
|
+
);
|
|
27860
|
+
return React4.useMemo(
|
|
27861
|
+
() => ({
|
|
27862
|
+
paintThumbnail,
|
|
27863
|
+
thumbnails
|
|
27864
|
+
}),
|
|
27865
|
+
[paintThumbnail, thumbnails]
|
|
27866
|
+
);
|
|
27867
|
+
}
|
|
26799
27868
|
function XlsxViewer(props) {
|
|
26800
27869
|
const contextController = React4.useContext(ViewerContext);
|
|
26801
27870
|
if (props.controller) {
|
|
@@ -26824,6 +27893,7 @@ export {
|
|
|
26824
27893
|
useXlsxViewerImages,
|
|
26825
27894
|
useXlsxViewerSelection,
|
|
26826
27895
|
useXlsxViewerTables,
|
|
27896
|
+
useXlsxViewerThumbnails,
|
|
26827
27897
|
useXlsxViewerZoom
|
|
26828
27898
|
};
|
|
26829
27899
|
//# sourceMappingURL=index.js.map
|