@extend-ai/react-xlsx 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +632 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -2
- package/dist/index.d.ts +29 -2
- package/dist/index.js +631 -39
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -41,6 +41,7 @@ __export(index_exports, {
|
|
|
41
41
|
useXlsxViewerImages: () => useXlsxViewerImages,
|
|
42
42
|
useXlsxViewerSelection: () => useXlsxViewerSelection,
|
|
43
43
|
useXlsxViewerTables: () => useXlsxViewerTables,
|
|
44
|
+
useXlsxViewerThumbnails: () => useXlsxViewerThumbnails,
|
|
44
45
|
useXlsxViewerZoom: () => useXlsxViewerZoom
|
|
45
46
|
});
|
|
46
47
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -16348,6 +16349,13 @@ var IMAGE_MIN_SIZE_PX = 16;
|
|
|
16348
16349
|
var IMAGE_HANDLE_SIZE_PX = 10;
|
|
16349
16350
|
var CANVAS_RESIZE_HIT_SLOP_PX = 8;
|
|
16350
16351
|
var CANVAS_VIEWPORT_OVERSCAN_PX = 240;
|
|
16352
|
+
var THUMBNAIL_DEFAULT_MAX_DIMENSION = 192;
|
|
16353
|
+
var THUMBNAIL_FALLBACK_ROWS = 12;
|
|
16354
|
+
var THUMBNAIL_FALLBACK_COLS = 8;
|
|
16355
|
+
var THUMBNAIL_MAX_ROWS = 200;
|
|
16356
|
+
var THUMBNAIL_MAX_COLS = 80;
|
|
16357
|
+
var THUMBNAIL_MAX_SOURCE_HEIGHT_PX = 900;
|
|
16358
|
+
var THUMBNAIL_MAX_SOURCE_WIDTH_PX = 1440;
|
|
16351
16359
|
var LIVE_ZOOM_COMMIT_IDLE_MS = 48;
|
|
16352
16360
|
var WHEEL_ZOOM_SENSITIVITY = 25e-5;
|
|
16353
16361
|
var WHEEL_LINE_DELTA_PX = 16;
|
|
@@ -18354,6 +18362,97 @@ function resolveImageHandleStyle(position, stroke, surface, scale = 1) {
|
|
|
18354
18362
|
function useViewerPalette(isDark = false) {
|
|
18355
18363
|
return isDark ? DARK_PALETTE : LIGHT_PALETTE;
|
|
18356
18364
|
}
|
|
18365
|
+
function normalizeThumbnailResolution(resolution) {
|
|
18366
|
+
if (typeof resolution === "number" && Number.isFinite(resolution) && resolution > 0) {
|
|
18367
|
+
return {
|
|
18368
|
+
maxHeight: resolution,
|
|
18369
|
+
maxWidth: resolution
|
|
18370
|
+
};
|
|
18371
|
+
}
|
|
18372
|
+
const resolvedObject = typeof resolution === "object" && resolution ? resolution : void 0;
|
|
18373
|
+
return {
|
|
18374
|
+
maxHeight: resolvedObject?.maxHeight && Number.isFinite(resolvedObject.maxHeight) && resolvedObject.maxHeight > 0 ? resolvedObject.maxHeight : THUMBNAIL_DEFAULT_MAX_DIMENSION,
|
|
18375
|
+
maxWidth: resolvedObject?.maxWidth && Number.isFinite(resolvedObject.maxWidth) && resolvedObject.maxWidth > 0 ? resolvedObject.maxWidth : THUMBNAIL_DEFAULT_MAX_DIMENSION
|
|
18376
|
+
};
|
|
18377
|
+
}
|
|
18378
|
+
function resolveThumbnailOutputSize(sourceWidth, sourceHeight, resolution) {
|
|
18379
|
+
const normalized = normalizeThumbnailResolution(resolution);
|
|
18380
|
+
const safeSourceWidth = Math.max(1, sourceWidth);
|
|
18381
|
+
const safeSourceHeight = Math.max(1, sourceHeight);
|
|
18382
|
+
const scale = Math.min(
|
|
18383
|
+
normalized.maxWidth / safeSourceWidth,
|
|
18384
|
+
normalized.maxHeight / safeSourceHeight,
|
|
18385
|
+
1
|
|
18386
|
+
);
|
|
18387
|
+
return {
|
|
18388
|
+
height: Math.max(1, Math.round(safeSourceHeight * scale)),
|
|
18389
|
+
maxHeight: normalized.maxHeight,
|
|
18390
|
+
maxWidth: normalized.maxWidth,
|
|
18391
|
+
scale,
|
|
18392
|
+
width: Math.max(1, Math.round(safeSourceWidth * scale))
|
|
18393
|
+
};
|
|
18394
|
+
}
|
|
18395
|
+
function resolveThumbnailAxisIndices({
|
|
18396
|
+
fallbackCount,
|
|
18397
|
+
getSizePx,
|
|
18398
|
+
maxCount,
|
|
18399
|
+
maxLogicalPixels,
|
|
18400
|
+
maxUsedIndex,
|
|
18401
|
+
minUsedIndex,
|
|
18402
|
+
precomputed
|
|
18403
|
+
}) {
|
|
18404
|
+
const sourceIndices = precomputed.length > 0 ? precomputed : Array.from({
|
|
18405
|
+
length: Math.max(fallbackCount, Math.max(0, maxUsedIndex + 1))
|
|
18406
|
+
}, (_, index) => index);
|
|
18407
|
+
const hasUsedRange = maxUsedIndex >= minUsedIndex && maxUsedIndex >= 0;
|
|
18408
|
+
const preferredStart = hasUsedRange ? Math.max(0, minUsedIndex) : 0;
|
|
18409
|
+
const preferredEnd = hasUsedRange ? maxUsedIndex : Math.max(0, preferredStart + fallbackCount - 1);
|
|
18410
|
+
const picked = [];
|
|
18411
|
+
let totalSize = 0;
|
|
18412
|
+
for (const actualIndex of sourceIndices) {
|
|
18413
|
+
if (actualIndex < preferredStart) {
|
|
18414
|
+
continue;
|
|
18415
|
+
}
|
|
18416
|
+
if (hasUsedRange && actualIndex > preferredEnd) {
|
|
18417
|
+
break;
|
|
18418
|
+
}
|
|
18419
|
+
const size = Math.max(1, getSizePx(actualIndex));
|
|
18420
|
+
picked.push(actualIndex);
|
|
18421
|
+
totalSize += size;
|
|
18422
|
+
if (picked.length >= maxCount || totalSize >= maxLogicalPixels) {
|
|
18423
|
+
break;
|
|
18424
|
+
}
|
|
18425
|
+
}
|
|
18426
|
+
if (picked.length > 0) {
|
|
18427
|
+
return picked;
|
|
18428
|
+
}
|
|
18429
|
+
for (const actualIndex of sourceIndices) {
|
|
18430
|
+
const size = Math.max(1, getSizePx(actualIndex));
|
|
18431
|
+
picked.push(actualIndex);
|
|
18432
|
+
totalSize += size;
|
|
18433
|
+
if (picked.length >= fallbackCount || picked.length >= maxCount || totalSize >= maxLogicalPixels) {
|
|
18434
|
+
break;
|
|
18435
|
+
}
|
|
18436
|
+
}
|
|
18437
|
+
return picked.length > 0 ? picked : [0];
|
|
18438
|
+
}
|
|
18439
|
+
function buildThumbnailAxisItems(actualIndices, getSizePx) {
|
|
18440
|
+
const items = [];
|
|
18441
|
+
let offset = 0;
|
|
18442
|
+
for (const actualIndex of actualIndices) {
|
|
18443
|
+
const size = Math.max(1, getSizePx(actualIndex));
|
|
18444
|
+
items.push({
|
|
18445
|
+
actualIndex,
|
|
18446
|
+
size,
|
|
18447
|
+
start: offset
|
|
18448
|
+
});
|
|
18449
|
+
offset += size;
|
|
18450
|
+
}
|
|
18451
|
+
return {
|
|
18452
|
+
items,
|
|
18453
|
+
totalSize: offset
|
|
18454
|
+
};
|
|
18455
|
+
}
|
|
18357
18456
|
function columnLabel2(col) {
|
|
18358
18457
|
let label = "";
|
|
18359
18458
|
let nextValue = col;
|
|
@@ -19260,7 +19359,6 @@ function getTableHeaderColumn(table, row, col) {
|
|
|
19260
19359
|
return table.columns[index] ?? null;
|
|
19261
19360
|
}
|
|
19262
19361
|
function DefaultTableHeaderMenu({
|
|
19263
|
-
close,
|
|
19264
19362
|
direction,
|
|
19265
19363
|
sortAscending,
|
|
19266
19364
|
sortDescending
|
|
@@ -19282,10 +19380,7 @@ function DefaultTableHeaderMenu({
|
|
|
19282
19380
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
19283
19381
|
"button",
|
|
19284
19382
|
{
|
|
19285
|
-
onClick:
|
|
19286
|
-
sortAscending();
|
|
19287
|
-
close();
|
|
19288
|
-
},
|
|
19383
|
+
onClick: sortAscending,
|
|
19289
19384
|
style: {
|
|
19290
19385
|
background: direction === "ascending" ? "var(--xlsx-menu-active)" : "transparent",
|
|
19291
19386
|
border: "none",
|
|
@@ -19303,10 +19398,7 @@ function DefaultTableHeaderMenu({
|
|
|
19303
19398
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
19304
19399
|
"button",
|
|
19305
19400
|
{
|
|
19306
|
-
onClick:
|
|
19307
|
-
sortDescending();
|
|
19308
|
-
close();
|
|
19309
|
-
},
|
|
19401
|
+
onClick: sortDescending,
|
|
19310
19402
|
style: {
|
|
19311
19403
|
background: direction === "descending" ? "var(--xlsx-menu-active)" : "transparent",
|
|
19312
19404
|
border: "none",
|
|
@@ -19325,6 +19417,25 @@ function DefaultTableHeaderMenu({
|
|
|
19325
19417
|
}
|
|
19326
19418
|
);
|
|
19327
19419
|
}
|
|
19420
|
+
function resolveTableHeaderTriggerStyle(palette, zoomFactor) {
|
|
19421
|
+
return {
|
|
19422
|
+
alignItems: "center",
|
|
19423
|
+
background: "transparent",
|
|
19424
|
+
border: "none",
|
|
19425
|
+
color: palette.mutedText,
|
|
19426
|
+
cursor: "pointer",
|
|
19427
|
+
display: "inline-flex",
|
|
19428
|
+
fontSize: 10 * zoomFactor,
|
|
19429
|
+
height: 16 * zoomFactor,
|
|
19430
|
+
justifyContent: "center",
|
|
19431
|
+
padding: 0,
|
|
19432
|
+
position: "absolute",
|
|
19433
|
+
right: 4 * zoomFactor,
|
|
19434
|
+
top: 3 * zoomFactor,
|
|
19435
|
+
width: 16 * zoomFactor,
|
|
19436
|
+
zIndex: 6
|
|
19437
|
+
};
|
|
19438
|
+
}
|
|
19328
19439
|
function SegmentedControl({
|
|
19329
19440
|
items,
|
|
19330
19441
|
onValueChange,
|
|
@@ -23539,6 +23650,30 @@ function XlsxGrid({
|
|
|
23539
23650
|
return null;
|
|
23540
23651
|
}
|
|
23541
23652
|
const direction = sortState && sortState.tableName === table.name && sortState.columnIndex === tableColumn.index ? sortState.direction : null;
|
|
23653
|
+
const triggerIcon = direction === "ascending" ? "\u25B2" : direction === "descending" ? "\u25BC" : "\u25BE";
|
|
23654
|
+
if (renderTableHeaderMenu) {
|
|
23655
|
+
return renderTableHeaderMenu({
|
|
23656
|
+
cell,
|
|
23657
|
+
column: tableColumn,
|
|
23658
|
+
direction,
|
|
23659
|
+
sortAscending: () => sortTable(table.name, tableColumn.index, "ascending"),
|
|
23660
|
+
sortDescending: () => sortTable(table.name, tableColumn.index, "descending"),
|
|
23661
|
+
table,
|
|
23662
|
+
triggerIcon,
|
|
23663
|
+
triggerProps: {
|
|
23664
|
+
"aria-haspopup": "menu",
|
|
23665
|
+
"aria-label": `Open menu for ${tableColumn.name}`,
|
|
23666
|
+
onClick: (event) => {
|
|
23667
|
+
event.stopPropagation();
|
|
23668
|
+
},
|
|
23669
|
+
onPointerDown: (event) => {
|
|
23670
|
+
event.stopPropagation();
|
|
23671
|
+
},
|
|
23672
|
+
style: resolveTableHeaderTriggerStyle(palette, zoomFactor),
|
|
23673
|
+
type: "button"
|
|
23674
|
+
}
|
|
23675
|
+
});
|
|
23676
|
+
}
|
|
23542
23677
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
23543
23678
|
"button",
|
|
23544
23679
|
{
|
|
@@ -23554,27 +23689,13 @@ function XlsxGrid({
|
|
|
23554
23689
|
);
|
|
23555
23690
|
},
|
|
23556
23691
|
style: {
|
|
23557
|
-
|
|
23558
|
-
background: "transparent",
|
|
23559
|
-
border: "none",
|
|
23560
|
-
color: palette.mutedText,
|
|
23561
|
-
cursor: "pointer",
|
|
23562
|
-
display: "inline-flex",
|
|
23563
|
-
fontSize: 10 * zoomFactor,
|
|
23564
|
-
height: 16 * zoomFactor,
|
|
23565
|
-
justifyContent: "center",
|
|
23566
|
-
padding: 0,
|
|
23567
|
-
position: "absolute",
|
|
23568
|
-
right: 4 * zoomFactor,
|
|
23569
|
-
top: 3 * zoomFactor,
|
|
23570
|
-
width: 16 * zoomFactor,
|
|
23571
|
-
zIndex: 6
|
|
23692
|
+
...resolveTableHeaderTriggerStyle(palette, zoomFactor)
|
|
23572
23693
|
},
|
|
23573
23694
|
type: "button",
|
|
23574
|
-
children:
|
|
23695
|
+
children: triggerIcon
|
|
23575
23696
|
}
|
|
23576
23697
|
);
|
|
23577
|
-
}, [effectiveTables, palette
|
|
23698
|
+
}, [effectiveTables, palette, renderTableHeaderMenu, sortState, sortTable, zoomFactor]);
|
|
23578
23699
|
const resolveCanvasColumnHeaderRect = React4.useCallback((actualCol) => {
|
|
23579
23700
|
const colIndex = colIndexByActual.get(actualCol);
|
|
23580
23701
|
if (colIndex === void 0) {
|
|
@@ -26370,7 +26491,7 @@ function XlsxGrid({
|
|
|
26370
26491
|
}
|
|
26371
26492
|
}
|
|
26372
26493
|
) : null,
|
|
26373
|
-
openTableMenuState ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
26494
|
+
!renderTableHeaderMenu && openTableMenuState ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
26374
26495
|
"div",
|
|
26375
26496
|
{
|
|
26376
26497
|
ref: tableMenuRef,
|
|
@@ -26381,22 +26502,23 @@ function XlsxGrid({
|
|
|
26381
26502
|
top: openTableMenuState.top,
|
|
26382
26503
|
zIndex: 50
|
|
26383
26504
|
},
|
|
26384
|
-
children:
|
|
26385
|
-
close: () => setOpenTableMenu(null),
|
|
26386
|
-
column: openTableMenuState.column,
|
|
26387
|
-
direction: sortState && sortState.tableName === openTableMenuState.table.name && sortState.columnIndex === openTableMenuState.column.index ? sortState.direction : null,
|
|
26388
|
-
sortAscending: () => sortTable(openTableMenuState.table.name, openTableMenuState.column.index, "ascending"),
|
|
26389
|
-
sortDescending: () => sortTable(openTableMenuState.table.name, openTableMenuState.column.index, "descending"),
|
|
26390
|
-
table: openTableMenuState.table
|
|
26391
|
-
}) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
26505
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
26392
26506
|
DefaultTableHeaderMenu,
|
|
26393
26507
|
{
|
|
26394
|
-
|
|
26508
|
+
cell: { col: openTableMenuState.column.index + openTableMenuState.table.start.col, row: openTableMenuState.table.start.row },
|
|
26395
26509
|
column: openTableMenuState.column,
|
|
26396
26510
|
direction: sortState && sortState.tableName === openTableMenuState.table.name && sortState.columnIndex === openTableMenuState.column.index ? sortState.direction : null,
|
|
26397
|
-
sortAscending: () =>
|
|
26398
|
-
|
|
26399
|
-
|
|
26511
|
+
sortAscending: () => {
|
|
26512
|
+
sortTable(openTableMenuState.table.name, openTableMenuState.column.index, "ascending");
|
|
26513
|
+
setOpenTableMenu(null);
|
|
26514
|
+
},
|
|
26515
|
+
sortDescending: () => {
|
|
26516
|
+
sortTable(openTableMenuState.table.name, openTableMenuState.column.index, "descending");
|
|
26517
|
+
setOpenTableMenu(null);
|
|
26518
|
+
},
|
|
26519
|
+
table: openTableMenuState.table,
|
|
26520
|
+
triggerIcon: "\u25BE",
|
|
26521
|
+
triggerProps: { type: "button" }
|
|
26400
26522
|
}
|
|
26401
26523
|
)
|
|
26402
26524
|
}
|
|
@@ -26827,6 +26949,476 @@ function useXlsxViewerCharts() {
|
|
|
26827
26949
|
]
|
|
26828
26950
|
);
|
|
26829
26951
|
}
|
|
26952
|
+
function useXlsxViewerThumbnails(options = {}) {
|
|
26953
|
+
const { workbook, sheets } = useXlsxViewer();
|
|
26954
|
+
const { isDark } = React4.useContext(ViewerAppearanceContext);
|
|
26955
|
+
const palette = useViewerPalette(isDark);
|
|
26956
|
+
const includeHeaders = options.includeHeaders ?? true;
|
|
26957
|
+
const resolution = options.resolution;
|
|
26958
|
+
const thumbnails = React4.useMemo(() => {
|
|
26959
|
+
return sheets.map((sheet, sheetIndex) => {
|
|
26960
|
+
const worksheet = workbook?.getSheet(sheet.workbookSheetIndex) ?? null;
|
|
26961
|
+
const showGridLines = sheet.showGridLines ?? true;
|
|
26962
|
+
const hiddenRowSet = new Set(sheet.hiddenRows ?? []);
|
|
26963
|
+
const hiddenColSet = new Set(sheet.hiddenCols ?? []);
|
|
26964
|
+
const visibleRows = buildVisibleAxisIndices(
|
|
26965
|
+
sheet.visibleRows ?? [],
|
|
26966
|
+
Math.max(THUMBNAIL_FALLBACK_ROWS, (sheet.maxUsedRow ?? -1) + THUMBNAIL_FALLBACK_ROWS + 1),
|
|
26967
|
+
sheet.maxUsedRow ?? -1,
|
|
26968
|
+
hiddenRowSet
|
|
26969
|
+
);
|
|
26970
|
+
const visibleCols = buildVisibleAxisIndices(
|
|
26971
|
+
sheet.visibleCols ?? [],
|
|
26972
|
+
Math.max(THUMBNAIL_FALLBACK_COLS, (sheet.maxUsedCol ?? -1) + THUMBNAIL_FALLBACK_COLS + 1),
|
|
26973
|
+
sheet.maxUsedCol ?? -1,
|
|
26974
|
+
hiddenColSet
|
|
26975
|
+
);
|
|
26976
|
+
const resolveColumnWidthPx = (actualCol) => {
|
|
26977
|
+
if (worksheet && !worksheet.isColumnHidden(actualCol)) {
|
|
26978
|
+
const width = worksheet.getColumnWidth(actualCol);
|
|
26979
|
+
if (width !== void 0 && width !== null) {
|
|
26980
|
+
return Math.max(
|
|
26981
|
+
resolveRenderedSheetAxisPixels(resolveSheetColumnWidthPixels(width, sheet.columnWidthCharacterWidthPx), showGridLines),
|
|
26982
|
+
DEFAULT_COL_WIDTH2 / 2
|
|
26983
|
+
);
|
|
26984
|
+
}
|
|
26985
|
+
}
|
|
26986
|
+
return Math.max(
|
|
26987
|
+
resolveRenderedSheetAxisPixels(
|
|
26988
|
+
sheet.colWidthOverridesPx[actualCol] ?? sheet.defaultColWidthPx ?? DEFAULT_COL_WIDTH2,
|
|
26989
|
+
showGridLines
|
|
26990
|
+
),
|
|
26991
|
+
DEFAULT_COL_WIDTH2 / 2
|
|
26992
|
+
);
|
|
26993
|
+
};
|
|
26994
|
+
const resolveRowHeightPx = (actualRow) => {
|
|
26995
|
+
if (worksheet && !worksheet.isRowHidden(actualRow)) {
|
|
26996
|
+
const height = worksheet.getRowHeight(actualRow);
|
|
26997
|
+
if (height !== void 0 && height !== null) {
|
|
26998
|
+
return Math.max(
|
|
26999
|
+
resolveRenderedSheetAxisPixels(resolveSheetRowHeightPixels(height), showGridLines),
|
|
27000
|
+
DEFAULT_ROW_HEIGHT2 / 1.5
|
|
27001
|
+
);
|
|
27002
|
+
}
|
|
27003
|
+
}
|
|
27004
|
+
return Math.max(
|
|
27005
|
+
resolveRenderedSheetAxisPixels(
|
|
27006
|
+
sheet.rowHeightOverridesPx[actualRow] ?? sheet.defaultRowHeightPx ?? DEFAULT_ROW_HEIGHT2,
|
|
27007
|
+
showGridLines
|
|
27008
|
+
),
|
|
27009
|
+
DEFAULT_ROW_HEIGHT2 / 1.5
|
|
27010
|
+
);
|
|
27011
|
+
};
|
|
27012
|
+
const previewRows = resolveThumbnailAxisIndices({
|
|
27013
|
+
fallbackCount: THUMBNAIL_FALLBACK_ROWS,
|
|
27014
|
+
getSizePx: resolveRowHeightPx,
|
|
27015
|
+
maxCount: THUMBNAIL_MAX_ROWS,
|
|
27016
|
+
maxLogicalPixels: THUMBNAIL_MAX_SOURCE_HEIGHT_PX,
|
|
27017
|
+
maxUsedIndex: sheet.maxUsedRow ?? -1,
|
|
27018
|
+
minUsedIndex: Math.max(0, sheet.minUsedRow ?? 0),
|
|
27019
|
+
precomputed: visibleRows
|
|
27020
|
+
});
|
|
27021
|
+
const previewCols = resolveThumbnailAxisIndices({
|
|
27022
|
+
fallbackCount: THUMBNAIL_FALLBACK_COLS,
|
|
27023
|
+
getSizePx: resolveColumnWidthPx,
|
|
27024
|
+
maxCount: THUMBNAIL_MAX_COLS,
|
|
27025
|
+
maxLogicalPixels: THUMBNAIL_MAX_SOURCE_WIDTH_PX,
|
|
27026
|
+
maxUsedIndex: sheet.maxUsedCol ?? -1,
|
|
27027
|
+
minUsedIndex: Math.max(0, sheet.minUsedCol ?? 0),
|
|
27028
|
+
precomputed: visibleCols
|
|
27029
|
+
});
|
|
27030
|
+
const rowAxis = buildThumbnailAxisItems(previewRows, resolveRowHeightPx);
|
|
27031
|
+
const colAxis = buildThumbnailAxisItems(previewCols, resolveColumnWidthPx);
|
|
27032
|
+
const rowItemByActual = new Map(rowAxis.items.map((item) => [item.actualIndex, item]));
|
|
27033
|
+
const colItemByActual = new Map(colAxis.items.map((item) => [item.actualIndex, item]));
|
|
27034
|
+
const headerHeight = includeHeaders ? HEADER_HEIGHT : 0;
|
|
27035
|
+
const rowHeaderWidth = includeHeaders ? ROW_HEADER_WIDTH : 0;
|
|
27036
|
+
const sourceWidth = rowHeaderWidth + colAxis.totalSize;
|
|
27037
|
+
const sourceHeight = headerHeight + rowAxis.totalSize;
|
|
27038
|
+
const outputSize = resolveThumbnailOutputSize(sourceWidth, sourceHeight, resolution);
|
|
27039
|
+
const sourceRange = {
|
|
27040
|
+
start: {
|
|
27041
|
+
col: previewCols[0] ?? 0,
|
|
27042
|
+
row: previewRows[0] ?? 0
|
|
27043
|
+
},
|
|
27044
|
+
end: {
|
|
27045
|
+
col: previewCols[previewCols.length - 1] ?? 0,
|
|
27046
|
+
row: previewRows[previewRows.length - 1] ?? 0
|
|
27047
|
+
}
|
|
27048
|
+
};
|
|
27049
|
+
const sparklineByCell = new Map(
|
|
27050
|
+
(sheet.sparklines ?? []).map((sparkline) => [`${sparkline.target.row}:${sparkline.target.col}`, sparkline])
|
|
27051
|
+
);
|
|
27052
|
+
const paint = (canvas) => {
|
|
27053
|
+
if (!canvas) {
|
|
27054
|
+
return false;
|
|
27055
|
+
}
|
|
27056
|
+
const context = canvas.getContext("2d");
|
|
27057
|
+
if (!context) {
|
|
27058
|
+
return false;
|
|
27059
|
+
}
|
|
27060
|
+
const dpr = typeof window === "undefined" ? 1 : Math.max(1, window.devicePixelRatio || 1);
|
|
27061
|
+
const outputWidth = outputSize.width;
|
|
27062
|
+
const outputHeight = outputSize.height;
|
|
27063
|
+
const scale = outputSize.scale;
|
|
27064
|
+
const deviceWidth = Math.max(1, Math.round(outputWidth * dpr));
|
|
27065
|
+
const deviceHeight = Math.max(1, Math.round(outputHeight * dpr));
|
|
27066
|
+
if (canvas.width !== deviceWidth) {
|
|
27067
|
+
canvas.width = deviceWidth;
|
|
27068
|
+
}
|
|
27069
|
+
if (canvas.height !== deviceHeight) {
|
|
27070
|
+
canvas.height = deviceHeight;
|
|
27071
|
+
}
|
|
27072
|
+
if (canvas.style.width !== `${outputWidth}px`) {
|
|
27073
|
+
canvas.style.width = `${outputWidth}px`;
|
|
27074
|
+
}
|
|
27075
|
+
if (canvas.style.height !== `${outputHeight}px`) {
|
|
27076
|
+
canvas.style.height = `${outputHeight}px`;
|
|
27077
|
+
}
|
|
27078
|
+
context.setTransform(dpr * scale, 0, 0, dpr * scale, 0, 0);
|
|
27079
|
+
context.clearRect(0, 0, Math.max(1, sourceWidth), Math.max(1, sourceHeight));
|
|
27080
|
+
context.fillStyle = palette.canvas;
|
|
27081
|
+
context.fillRect(0, 0, Math.max(1, sourceWidth), Math.max(1, sourceHeight));
|
|
27082
|
+
context.fillStyle = resolveSheetSurface(sheet, palette);
|
|
27083
|
+
context.fillRect(rowHeaderWidth, headerHeight, Math.max(1, colAxis.totalSize), Math.max(1, rowAxis.totalSize));
|
|
27084
|
+
if (includeHeaders) {
|
|
27085
|
+
context.fillStyle = palette.headerSurface;
|
|
27086
|
+
context.fillRect(rowHeaderWidth, 0, Math.max(1, colAxis.totalSize), headerHeight);
|
|
27087
|
+
context.fillStyle = palette.rowHeaderSurface;
|
|
27088
|
+
context.fillRect(0, headerHeight, rowHeaderWidth, Math.max(1, rowAxis.totalSize));
|
|
27089
|
+
context.fillRect(0, 0, rowHeaderWidth, headerHeight);
|
|
27090
|
+
}
|
|
27091
|
+
if (!worksheet) {
|
|
27092
|
+
return true;
|
|
27093
|
+
}
|
|
27094
|
+
const conditionalFormatMetricsCache = /* @__PURE__ */ new Map();
|
|
27095
|
+
const cellRenderCache = /* @__PURE__ */ new Map();
|
|
27096
|
+
const getCellData = (row, col) => {
|
|
27097
|
+
const cacheKey = `${row}:${col}`;
|
|
27098
|
+
const cached = cellRenderCache.get(cacheKey);
|
|
27099
|
+
if (cached) {
|
|
27100
|
+
return cached;
|
|
27101
|
+
}
|
|
27102
|
+
if (worksheet.isMergedSecondary(row, col)) {
|
|
27103
|
+
const mergedSecondaryData = {
|
|
27104
|
+
isMergedSecondary: true,
|
|
27105
|
+
style: {},
|
|
27106
|
+
value: ""
|
|
27107
|
+
};
|
|
27108
|
+
cellRenderCache.set(cacheKey, mergedSecondaryData);
|
|
27109
|
+
return mergedSecondaryData;
|
|
27110
|
+
}
|
|
27111
|
+
const merge = worksheet.getMergeSpan(row, col);
|
|
27112
|
+
const inheritedStyle = resolveInheritedCellStyle2(sheet, row, col);
|
|
27113
|
+
const worksheetStyle = worksheet.getCellStyleAt(row, col) ?? null;
|
|
27114
|
+
const mergedStyle = mergeResolvedCellStyle(inheritedStyle, worksheetStyle, { replaceXfSubtrees: true });
|
|
27115
|
+
const alignment = mergedStyle?.alignment;
|
|
27116
|
+
const sparkline = sparklineByCell.get(cacheKey) ?? null;
|
|
27117
|
+
const sparklineValues = sparkline ? sparkline.range.start.row === sparkline.range.end.row ? Array.from(
|
|
27118
|
+
{ length: Math.abs(sparkline.range.end.col - sparkline.range.start.col) + 1 },
|
|
27119
|
+
(_, index) => getCellNumericValue(
|
|
27120
|
+
worksheet,
|
|
27121
|
+
sparkline.range.start.row,
|
|
27122
|
+
Math.min(sparkline.range.start.col, sparkline.range.end.col) + index
|
|
27123
|
+
)
|
|
27124
|
+
) : Array.from(
|
|
27125
|
+
{ length: Math.abs(sparkline.range.end.row - sparkline.range.start.row) + 1 },
|
|
27126
|
+
(_, index) => getCellNumericValue(
|
|
27127
|
+
worksheet,
|
|
27128
|
+
Math.min(sparkline.range.start.row, sparkline.range.end.row) + index,
|
|
27129
|
+
sparkline.range.start.col
|
|
27130
|
+
)
|
|
27131
|
+
) : null;
|
|
27132
|
+
const checkboxState = mergedStyle?.cellControl ? getCellBooleanValue(worksheet, row, col) : null;
|
|
27133
|
+
const nextData = {
|
|
27134
|
+
canvas: void 0,
|
|
27135
|
+
checkboxState,
|
|
27136
|
+
colSpan: merge?.colSpan,
|
|
27137
|
+
conditionalColorScale: resolveConditionalColorScaleForCell(
|
|
27138
|
+
row,
|
|
27139
|
+
col,
|
|
27140
|
+
worksheet,
|
|
27141
|
+
sheet,
|
|
27142
|
+
conditionalFormatMetricsCache
|
|
27143
|
+
),
|
|
27144
|
+
conditionalDataBar: resolveConditionalDataBarForCell(
|
|
27145
|
+
row,
|
|
27146
|
+
col,
|
|
27147
|
+
worksheet,
|
|
27148
|
+
sheet,
|
|
27149
|
+
conditionalFormatMetricsCache
|
|
27150
|
+
),
|
|
27151
|
+
conditionalIcon: resolveConditionalIconForCell(
|
|
27152
|
+
row,
|
|
27153
|
+
col,
|
|
27154
|
+
worksheet,
|
|
27155
|
+
sheet,
|
|
27156
|
+
conditionalFormatMetricsCache
|
|
27157
|
+
),
|
|
27158
|
+
isMergedSecondary: false,
|
|
27159
|
+
rowSpan: merge?.rowSpan,
|
|
27160
|
+
sparkline: sparkline && sparklineValues ? { config: sparkline, values: sparklineValues } : null,
|
|
27161
|
+
style: buildCellStyle(mergedStyle, palette, sheet.themePalette, {
|
|
27162
|
+
showGridLines
|
|
27163
|
+
}),
|
|
27164
|
+
textRotationDeg: resolveSpreadsheetTextRotation(alignment?.textRotation),
|
|
27165
|
+
value: sparkline ? "" : checkboxState !== null ? "" : getCellDisplayValue(worksheet, row, col, sheet)
|
|
27166
|
+
};
|
|
27167
|
+
nextData.canvas = buildCanvasCellStyleCache(nextData.style);
|
|
27168
|
+
cellRenderCache.set(cacheKey, nextData);
|
|
27169
|
+
return nextData;
|
|
27170
|
+
};
|
|
27171
|
+
for (const rowItem of rowAxis.items) {
|
|
27172
|
+
for (const colItem of colAxis.items) {
|
|
27173
|
+
const cellData = getCellData(rowItem.actualIndex, colItem.actualIndex);
|
|
27174
|
+
if (cellData.isMergedSecondary) {
|
|
27175
|
+
continue;
|
|
27176
|
+
}
|
|
27177
|
+
const colSpan = Math.max(1, cellData.colSpan ?? 1);
|
|
27178
|
+
const rowSpan = Math.max(1, cellData.rowSpan ?? 1);
|
|
27179
|
+
let width = colItem.size;
|
|
27180
|
+
let height = rowItem.size;
|
|
27181
|
+
for (let colOffset = 1; colOffset < colSpan; colOffset += 1) {
|
|
27182
|
+
const nextCol = colItemByActual.get(colItem.actualIndex + colOffset);
|
|
27183
|
+
if (!nextCol) {
|
|
27184
|
+
break;
|
|
27185
|
+
}
|
|
27186
|
+
width += nextCol.size;
|
|
27187
|
+
}
|
|
27188
|
+
for (let rowOffset = 1; rowOffset < rowSpan; rowOffset += 1) {
|
|
27189
|
+
const nextRow = rowItemByActual.get(rowItem.actualIndex + rowOffset);
|
|
27190
|
+
if (!nextRow) {
|
|
27191
|
+
break;
|
|
27192
|
+
}
|
|
27193
|
+
height += nextRow.size;
|
|
27194
|
+
}
|
|
27195
|
+
const rect = {
|
|
27196
|
+
height,
|
|
27197
|
+
left: rowHeaderWidth + colItem.start,
|
|
27198
|
+
top: headerHeight + rowItem.start,
|
|
27199
|
+
width
|
|
27200
|
+
};
|
|
27201
|
+
const canvasCellStyle = cellData.canvas ?? buildCanvasCellStyleCache(cellData.style);
|
|
27202
|
+
const gradientFill = typeof cellData.style.backgroundImage === "string" ? resolveCanvasGradientFill(context, rect, cellData.style.backgroundImage) : null;
|
|
27203
|
+
const fillColor = cellData.conditionalColorScale?.color ?? (typeof cellData.style.backgroundColor === "string" ? cellData.style.backgroundColor : resolveSheetSurface(sheet, palette));
|
|
27204
|
+
const hasExplicitCellFill = cellData.conditionalColorScale !== null || gradientFill !== null || typeof cellData.style.backgroundColor === "string" && cellData.style.backgroundColor !== resolveSheetSurface(sheet, palette);
|
|
27205
|
+
context.fillStyle = gradientFill ?? fillColor;
|
|
27206
|
+
context.fillRect(rect.left, rect.top, rect.width, rect.height);
|
|
27207
|
+
if (cellData.conditionalDataBar) {
|
|
27208
|
+
const barLeft = rect.left + 4;
|
|
27209
|
+
const barTop = rect.top + 4;
|
|
27210
|
+
const barWidth = Math.max(0, (rect.width - 8) * (cellData.conditionalDataBar.widthPercent / 100));
|
|
27211
|
+
const barHeight = Math.max(0, rect.height - 8);
|
|
27212
|
+
if (barWidth > 0 && barHeight > 0) {
|
|
27213
|
+
context.fillStyle = resolveCanvasDataBarFill(
|
|
27214
|
+
context,
|
|
27215
|
+
barLeft,
|
|
27216
|
+
barTop,
|
|
27217
|
+
barWidth,
|
|
27218
|
+
barHeight,
|
|
27219
|
+
cellData.conditionalDataBar
|
|
27220
|
+
);
|
|
27221
|
+
context.fillRect(barLeft, barTop, barWidth, barHeight);
|
|
27222
|
+
if (cellData.conditionalDataBar.border !== false && cellData.conditionalDataBar.borderColor) {
|
|
27223
|
+
context.strokeStyle = cellData.conditionalDataBar.borderColor;
|
|
27224
|
+
context.lineWidth = 1;
|
|
27225
|
+
context.strokeRect(barLeft + 0.5, barTop + 0.5, Math.max(0, barWidth - 1), Math.max(0, barHeight - 1));
|
|
27226
|
+
}
|
|
27227
|
+
}
|
|
27228
|
+
}
|
|
27229
|
+
if (showGridLines && !hasExplicitCellFill) {
|
|
27230
|
+
context.strokeStyle = palette.border;
|
|
27231
|
+
context.lineWidth = 1;
|
|
27232
|
+
context.beginPath();
|
|
27233
|
+
if (colItem.start === 0) {
|
|
27234
|
+
context.moveTo(rect.left + 0.5, rect.top);
|
|
27235
|
+
context.lineTo(rect.left + 0.5, rect.top + rect.height);
|
|
27236
|
+
}
|
|
27237
|
+
if (rowItem.start === 0) {
|
|
27238
|
+
context.moveTo(rect.left, rect.top + 0.5);
|
|
27239
|
+
context.lineTo(rect.left + rect.width, rect.top + 0.5);
|
|
27240
|
+
}
|
|
27241
|
+
context.moveTo(rect.left + rect.width - 0.5, rect.top);
|
|
27242
|
+
context.lineTo(rect.left + rect.width - 0.5, rect.top + rect.height);
|
|
27243
|
+
context.moveTo(rect.left, rect.top + rect.height - 0.5);
|
|
27244
|
+
context.lineTo(rect.left + rect.width, rect.top + rect.height - 0.5);
|
|
27245
|
+
context.stroke();
|
|
27246
|
+
}
|
|
27247
|
+
if (canvasCellStyle.topBorder) {
|
|
27248
|
+
strokeCanvasBorderSide(context, "top", rect, canvasCellStyle.topBorder);
|
|
27249
|
+
}
|
|
27250
|
+
if (canvasCellStyle.rightBorder) {
|
|
27251
|
+
strokeCanvasBorderSide(context, "right", rect, canvasCellStyle.rightBorder);
|
|
27252
|
+
}
|
|
27253
|
+
if (canvasCellStyle.bottomBorder) {
|
|
27254
|
+
strokeCanvasBorderSide(context, "bottom", rect, canvasCellStyle.bottomBorder);
|
|
27255
|
+
}
|
|
27256
|
+
if (canvasCellStyle.leftBorder) {
|
|
27257
|
+
strokeCanvasBorderSide(context, "left", rect, canvasCellStyle.leftBorder);
|
|
27258
|
+
}
|
|
27259
|
+
const padding = canvasCellStyle.padding;
|
|
27260
|
+
const contentLeft = rect.left + padding.left;
|
|
27261
|
+
const contentTop = rect.top + padding.top;
|
|
27262
|
+
const contentWidth = Math.max(0, rect.width - padding.left - padding.right);
|
|
27263
|
+
const contentHeight = Math.max(0, rect.height - padding.top - padding.bottom);
|
|
27264
|
+
const rawText = cellData.value ?? "";
|
|
27265
|
+
context.save();
|
|
27266
|
+
context.beginPath();
|
|
27267
|
+
context.rect(contentLeft, contentTop, contentWidth, contentHeight);
|
|
27268
|
+
context.clip();
|
|
27269
|
+
context.font = canvasCellStyle.baseFont;
|
|
27270
|
+
context.fillStyle = canvasCellStyle.textColor;
|
|
27271
|
+
context.textBaseline = "middle";
|
|
27272
|
+
if (cellData.checkboxState != null) {
|
|
27273
|
+
const boxSize = Math.min(14, contentWidth, contentHeight);
|
|
27274
|
+
const boxLeft = rect.left + (rect.width - boxSize) / 2;
|
|
27275
|
+
const boxTop = rect.top + (rect.height - boxSize) / 2;
|
|
27276
|
+
context.strokeStyle = paletteIsDark(palette) ? "#cbd5e1" : "#475569";
|
|
27277
|
+
context.lineWidth = 1.25;
|
|
27278
|
+
context.strokeRect(boxLeft, boxTop, boxSize, boxSize);
|
|
27279
|
+
if (cellData.checkboxState) {
|
|
27280
|
+
context.fillStyle = paletteIsDark(palette) ? "#60a5fa" : "#2563eb";
|
|
27281
|
+
context.fillRect(boxLeft + 1.5, boxTop + 1.5, Math.max(0, boxSize - 3), Math.max(0, boxSize - 3));
|
|
27282
|
+
}
|
|
27283
|
+
} else if (cellData.sparkline) {
|
|
27284
|
+
const sparkline = cellData.sparkline.config;
|
|
27285
|
+
const sparklineValues = cellData.sparkline.values;
|
|
27286
|
+
const points = sparklineValues.map((value, index) => ({ index, value })).filter((entry) => typeof entry.value === "number" && Number.isFinite(entry.value));
|
|
27287
|
+
if (points.length > 1) {
|
|
27288
|
+
const minValue = Math.min(...points.map((entry) => entry.value));
|
|
27289
|
+
const maxValue = Math.max(...points.map((entry) => entry.value));
|
|
27290
|
+
const sparkLeft = contentLeft + 1;
|
|
27291
|
+
const sparkTop = contentTop + 2;
|
|
27292
|
+
const sparkWidth = Math.max(1, contentWidth - 2);
|
|
27293
|
+
const sparkHeight = Math.max(1, contentHeight - 4);
|
|
27294
|
+
const xStep = points.length > 1 ? sparkWidth / (points.length - 1) : 0;
|
|
27295
|
+
context.strokeStyle = sparkline.color ?? "#2563eb";
|
|
27296
|
+
context.lineCap = "round";
|
|
27297
|
+
context.lineJoin = "round";
|
|
27298
|
+
context.lineWidth = 1.25;
|
|
27299
|
+
context.beginPath();
|
|
27300
|
+
points.forEach((entry, index) => {
|
|
27301
|
+
const x = sparkLeft + index * xStep;
|
|
27302
|
+
const y = sparkTop + sparkHeight - clampSparklineValue(entry.value, minValue, maxValue) * sparkHeight;
|
|
27303
|
+
if (index === 0) {
|
|
27304
|
+
context.moveTo(x, y);
|
|
27305
|
+
} else {
|
|
27306
|
+
context.lineTo(x, y);
|
|
27307
|
+
}
|
|
27308
|
+
});
|
|
27309
|
+
context.stroke();
|
|
27310
|
+
}
|
|
27311
|
+
} else if (rawText.length > 0) {
|
|
27312
|
+
const align = canvasCellStyle.textAlign;
|
|
27313
|
+
context.textAlign = align;
|
|
27314
|
+
const textX = align === "right" ? contentLeft + contentWidth : align === "center" ? contentLeft + contentWidth / 2 : contentLeft;
|
|
27315
|
+
const textY = contentTop + contentHeight / 2;
|
|
27316
|
+
const trailingInset = cellData.conditionalIcon ? 18 : 0;
|
|
27317
|
+
const maxTextWidth = Math.max(0, contentWidth - trailingInset);
|
|
27318
|
+
if (cellData.textRotationDeg) {
|
|
27319
|
+
const rotationOriginX = contentLeft + contentWidth / 2;
|
|
27320
|
+
context.save();
|
|
27321
|
+
context.translate(rotationOriginX, textY);
|
|
27322
|
+
context.rotate(cellData.textRotationDeg * Math.PI / 180);
|
|
27323
|
+
context.fillText(
|
|
27324
|
+
rawText,
|
|
27325
|
+
align === "right" ? contentWidth / 2 : align === "center" ? 0 : -(contentWidth / 2),
|
|
27326
|
+
0
|
|
27327
|
+
);
|
|
27328
|
+
context.restore();
|
|
27329
|
+
} else if (canvasCellStyle.usesWrappedText || rawText.includes("\n")) {
|
|
27330
|
+
const lines = wrapCanvasText(context, rawText, maxTextWidth);
|
|
27331
|
+
const lineHeight = resolveCanvasLineHeight(cellData.style, 12);
|
|
27332
|
+
const textBlockHeight = lines.length * lineHeight;
|
|
27333
|
+
let textBlockTop = contentTop;
|
|
27334
|
+
if (cellData.style.verticalAlign === "middle") {
|
|
27335
|
+
textBlockTop = contentTop + (contentHeight - textBlockHeight) / 2;
|
|
27336
|
+
} else if (cellData.style.verticalAlign !== "top") {
|
|
27337
|
+
textBlockTop = contentTop + contentHeight - textBlockHeight;
|
|
27338
|
+
}
|
|
27339
|
+
lines.forEach((line, lineIndex) => {
|
|
27340
|
+
context.fillText(line, textX, textBlockTop + lineIndex * lineHeight + lineHeight / 2);
|
|
27341
|
+
});
|
|
27342
|
+
} else {
|
|
27343
|
+
const text = canvasCellStyle.textOverflowEllipsis ? truncateCanvasText(context, rawText, maxTextWidth) : rawText;
|
|
27344
|
+
context.fillText(text, textX, textY);
|
|
27345
|
+
}
|
|
27346
|
+
}
|
|
27347
|
+
if (cellData.conditionalIcon) {
|
|
27348
|
+
const iconSize = 10;
|
|
27349
|
+
const iconX = rect.left + rect.width - (padding.right + iconSize + 4);
|
|
27350
|
+
const iconY = rect.top + rect.height / 2;
|
|
27351
|
+
drawCanvasConditionalIcon(context, cellData.conditionalIcon, iconX + iconSize / 2, iconY, iconSize);
|
|
27352
|
+
}
|
|
27353
|
+
context.restore();
|
|
27354
|
+
}
|
|
27355
|
+
}
|
|
27356
|
+
if (includeHeaders) {
|
|
27357
|
+
context.strokeStyle = palette.border;
|
|
27358
|
+
context.lineWidth = 1;
|
|
27359
|
+
context.font = "600 11px ui-sans-serif, system-ui, sans-serif";
|
|
27360
|
+
context.fillStyle = palette.mutedText;
|
|
27361
|
+
context.textBaseline = "middle";
|
|
27362
|
+
for (const colItem of colAxis.items) {
|
|
27363
|
+
const left = rowHeaderWidth + colItem.start;
|
|
27364
|
+
context.beginPath();
|
|
27365
|
+
context.moveTo(left + colItem.size - 0.5, 0);
|
|
27366
|
+
context.lineTo(left + colItem.size - 0.5, headerHeight);
|
|
27367
|
+
context.moveTo(left, headerHeight - 0.5);
|
|
27368
|
+
context.lineTo(left + colItem.size, headerHeight - 0.5);
|
|
27369
|
+
context.stroke();
|
|
27370
|
+
context.textAlign = "center";
|
|
27371
|
+
context.fillText(columnLabel2(colItem.actualIndex), left + colItem.size / 2, headerHeight / 2);
|
|
27372
|
+
}
|
|
27373
|
+
for (const rowItem of rowAxis.items) {
|
|
27374
|
+
const top = headerHeight + rowItem.start;
|
|
27375
|
+
context.beginPath();
|
|
27376
|
+
context.moveTo(0, top + rowItem.size - 0.5);
|
|
27377
|
+
context.lineTo(rowHeaderWidth, top + rowItem.size - 0.5);
|
|
27378
|
+
context.moveTo(rowHeaderWidth - 0.5, top);
|
|
27379
|
+
context.lineTo(rowHeaderWidth - 0.5, top + rowItem.size);
|
|
27380
|
+
context.stroke();
|
|
27381
|
+
context.textAlign = "center";
|
|
27382
|
+
context.fillText(`${rowItem.actualIndex + 1}`, rowHeaderWidth / 2, top + rowItem.size / 2);
|
|
27383
|
+
}
|
|
27384
|
+
context.beginPath();
|
|
27385
|
+
context.moveTo(rowHeaderWidth - 0.5, 0);
|
|
27386
|
+
context.lineTo(rowHeaderWidth - 0.5, headerHeight);
|
|
27387
|
+
context.moveTo(0, headerHeight - 0.5);
|
|
27388
|
+
context.lineTo(rowHeaderWidth, headerHeight - 0.5);
|
|
27389
|
+
context.stroke();
|
|
27390
|
+
}
|
|
27391
|
+
return true;
|
|
27392
|
+
};
|
|
27393
|
+
const plan = {
|
|
27394
|
+
aspectRatio: sourceWidth / Math.max(1, sourceHeight),
|
|
27395
|
+
contentHeight: rowAxis.totalSize,
|
|
27396
|
+
contentWidth: colAxis.totalSize,
|
|
27397
|
+
height: outputSize.height,
|
|
27398
|
+
paint,
|
|
27399
|
+
sourceRange,
|
|
27400
|
+
width: outputSize.width
|
|
27401
|
+
};
|
|
27402
|
+
return {
|
|
27403
|
+
...plan,
|
|
27404
|
+
sheet,
|
|
27405
|
+
sheetIndex,
|
|
27406
|
+
workbookSheetIndex: sheet.workbookSheetIndex
|
|
27407
|
+
};
|
|
27408
|
+
});
|
|
27409
|
+
}, [includeHeaders, palette, resolution, sheets, workbook]);
|
|
27410
|
+
const paintThumbnail = React4.useCallback(
|
|
27411
|
+
(sheetIndex, canvas) => thumbnails[sheetIndex]?.paint(canvas) ?? false,
|
|
27412
|
+
[thumbnails]
|
|
27413
|
+
);
|
|
27414
|
+
return React4.useMemo(
|
|
27415
|
+
() => ({
|
|
27416
|
+
paintThumbnail,
|
|
27417
|
+
thumbnails
|
|
27418
|
+
}),
|
|
27419
|
+
[paintThumbnail, thumbnails]
|
|
27420
|
+
);
|
|
27421
|
+
}
|
|
26830
27422
|
function XlsxViewer(props) {
|
|
26831
27423
|
const contextController = React4.useContext(ViewerContext);
|
|
26832
27424
|
if (props.controller) {
|
|
@@ -26856,6 +27448,7 @@ function DefaultXlsxToolbar() {
|
|
|
26856
27448
|
useXlsxViewerImages,
|
|
26857
27449
|
useXlsxViewerSelection,
|
|
26858
27450
|
useXlsxViewerTables,
|
|
27451
|
+
useXlsxViewerThumbnails,
|
|
26859
27452
|
useXlsxViewerZoom
|
|
26860
27453
|
});
|
|
26861
27454
|
//# sourceMappingURL=index.cjs.map
|