@ricsam/react-spreadsheets 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -3
- package/dist/cjs/lib.cjs +123 -30
- package/dist/cjs/lib.cjs.map +4 -4
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/lib.mjs +123 -30
- package/dist/mjs/lib.mjs.map +4 -4
- package/dist/mjs/package.json +1 -1
- package/dist/types/lib.d.ts +2 -1
- package/dist/types/spreadsheet/spreadsheet.d.ts +6 -1
- package/dist/types/workbook/workbook-selection-manager.d.ts +23 -3
- package/package.json +3 -3
package/dist/cjs/package.json
CHANGED
package/dist/mjs/lib.mjs
CHANGED
|
@@ -1364,12 +1364,37 @@ var alignScrollOffset = (current, itemStart, itemEnd, viewportSize, align) => {
|
|
|
1364
1364
|
return itemStart;
|
|
1365
1365
|
if (align === "end")
|
|
1366
1366
|
return itemEnd - viewportSize;
|
|
1367
|
+
if (itemEnd - itemStart > viewportSize) {
|
|
1368
|
+
if (itemEnd <= current)
|
|
1369
|
+
return itemEnd - viewportSize;
|
|
1370
|
+
if (itemStart >= current + viewportSize)
|
|
1371
|
+
return itemStart;
|
|
1372
|
+
return current;
|
|
1373
|
+
}
|
|
1367
1374
|
if (itemStart < current)
|
|
1368
1375
|
return itemStart;
|
|
1369
1376
|
if (itemEnd > current + viewportSize)
|
|
1370
1377
|
return itemEnd - viewportSize;
|
|
1371
1378
|
return current;
|
|
1372
1379
|
};
|
|
1380
|
+
var normalizeScrollRangeAxis = (start, end, finiteCount) => {
|
|
1381
|
+
if (!Number.isFinite(start) || end.type === "number" && !Number.isFinite(end.value)) {
|
|
1382
|
+
return;
|
|
1383
|
+
}
|
|
1384
|
+
const normalizedStart = Math.max(0, Math.floor(start));
|
|
1385
|
+
const normalizedEnd = end.type === "infinity" ? finiteCount === undefined ? normalizedStart : Math.max(0, finiteCount - 1) : Math.max(0, Math.floor(end.value));
|
|
1386
|
+
const lower = Math.min(normalizedStart, normalizedEnd);
|
|
1387
|
+
const upper = Math.max(normalizedStart, normalizedEnd);
|
|
1388
|
+
if (finiteCount === undefined)
|
|
1389
|
+
return { start: lower, end: upper };
|
|
1390
|
+
if (finiteCount === 0)
|
|
1391
|
+
return;
|
|
1392
|
+
const lastIndex = finiteCount - 1;
|
|
1393
|
+
return {
|
|
1394
|
+
start: Math.min(lower, lastIndex),
|
|
1395
|
+
end: Math.min(upper, lastIndex)
|
|
1396
|
+
};
|
|
1397
|
+
};
|
|
1373
1398
|
var hasCellData = (value) => value !== undefined && value !== "";
|
|
1374
1399
|
var getSparseUsedRange = (cellData, rowCount, columnCount) => {
|
|
1375
1400
|
let minRow = Infinity;
|
|
@@ -2126,22 +2151,20 @@ var Spreadsheet = forwardRef(({
|
|
|
2126
2151
|
scrollY: Math.min(Math.max(0, scrollY), maxScrollY)
|
|
2127
2152
|
};
|
|
2128
2153
|
}, [columnWidths, finiteColumnCount, finiteRowCount, height, rowHeights, width]);
|
|
2129
|
-
const
|
|
2154
|
+
const revealRange = useCallback3((range, options = {}) => {
|
|
2130
2155
|
if (finiteRowCount === 0 || finiteColumnCount === 0)
|
|
2131
2156
|
return;
|
|
2132
|
-
|
|
2157
|
+
const rows = normalizeScrollRangeAxis(range.start.row, range.end.row, finiteRowCount);
|
|
2158
|
+
const columns = normalizeScrollRangeAxis(range.start.col, range.end.col, finiteColumnCount);
|
|
2159
|
+
if (!rows || !columns)
|
|
2133
2160
|
return;
|
|
2134
|
-
const requestedRow = Math.max(0, Math.floor(cell.row));
|
|
2135
|
-
const requestedCol = Math.max(0, Math.floor(cell.col));
|
|
2136
|
-
const row = finiteRowCount === undefined ? requestedRow : Math.min(requestedRow, finiteRowCount - 1);
|
|
2137
|
-
const col = finiteColumnCount === undefined ? requestedCol : Math.min(requestedCol, finiteColumnCount - 1);
|
|
2138
2161
|
setViewport((previous) => {
|
|
2139
2162
|
const bodyWidth = Math.max(0, width - HEADER_WIDTH * previous.zoom);
|
|
2140
2163
|
const bodyHeight = Math.max(0, height - HEADER_HEIGHT * previous.zoom);
|
|
2141
|
-
const left = getColumnEdgePosition(
|
|
2142
|
-
const right = getColumnEdgePosition(
|
|
2143
|
-
const top = getRowEdgePosition(
|
|
2144
|
-
const bottom = getRowEdgePosition(
|
|
2164
|
+
const left = getColumnEdgePosition(columns.start, columnWidths) * previous.zoom;
|
|
2165
|
+
const right = getColumnEdgePosition(columns.end + 1, columnWidths) * previous.zoom;
|
|
2166
|
+
const top = getRowEdgePosition(rows.start, rowHeights) * previous.zoom;
|
|
2167
|
+
const bottom = getRowEdgePosition(rows.end + 1, rowHeights) * previous.zoom;
|
|
2145
2168
|
const desired = clampViewportOffsets(alignScrollOffset(previous.scrollX, left, right, bodyWidth, options.columnAlign ?? "nearest"), alignScrollOffset(previous.scrollY, top, bottom, bodyHeight, options.rowAlign ?? "nearest"), previous.zoom);
|
|
2146
2169
|
if (desired.scrollX === previous.scrollX && desired.scrollY === previous.scrollY) {
|
|
2147
2170
|
return previous;
|
|
@@ -2157,17 +2180,34 @@ var Spreadsheet = forwardRef(({
|
|
|
2157
2180
|
rowHeights,
|
|
2158
2181
|
width
|
|
2159
2182
|
]);
|
|
2183
|
+
const revealCell = useCallback3((cell, options = {}) => {
|
|
2184
|
+
revealRange({
|
|
2185
|
+
start: { row: cell.row, col: cell.col },
|
|
2186
|
+
end: {
|
|
2187
|
+
row: { type: "number", value: cell.row },
|
|
2188
|
+
col: { type: "number", value: cell.col }
|
|
2189
|
+
}
|
|
2190
|
+
}, options);
|
|
2191
|
+
}, [revealRange]);
|
|
2160
2192
|
const scrollToCell = useCallback3((cell, options = {}) => {
|
|
2161
2193
|
const align = options.align ?? "nearest";
|
|
2162
2194
|
revealCell(cell, { rowAlign: align, columnAlign: align });
|
|
2163
2195
|
}, [revealCell]);
|
|
2196
|
+
const scrollToRange = useCallback3((range, options = {}) => {
|
|
2197
|
+
const align = options.align ?? "nearest";
|
|
2198
|
+
revealRange(range, { rowAlign: align, columnAlign: align });
|
|
2199
|
+
}, [revealRange]);
|
|
2164
2200
|
useEffect3(() => selectionManager.listenToViewportRequest((request) => {
|
|
2201
|
+
if (request.type === "reveal-range") {
|
|
2202
|
+
scrollToRange(request.range, { align: request.align });
|
|
2203
|
+
return;
|
|
2204
|
+
}
|
|
2165
2205
|
const isVertical = request.direction === "up" || request.direction === "down";
|
|
2166
2206
|
revealCell(request.cell, {
|
|
2167
2207
|
rowAlign: isVertical ? request.align : "nearest",
|
|
2168
2208
|
columnAlign: isVertical ? "nearest" : request.align
|
|
2169
2209
|
});
|
|
2170
|
-
}), [revealCell, selectionManager]);
|
|
2210
|
+
}), [revealCell, scrollToRange, selectionManager]);
|
|
2171
2211
|
useEffect3(() => {
|
|
2172
2212
|
setViewport((previous) => {
|
|
2173
2213
|
const next = clampViewportOffsets(previous.scrollX, previous.scrollY, previous.zoom);
|
|
@@ -2802,7 +2842,7 @@ var Spreadsheet = forwardRef(({
|
|
|
2802
2842
|
visibleCells
|
|
2803
2843
|
]);
|
|
2804
2844
|
React2.useEffect(() => {
|
|
2805
|
-
if (!containerDivRef || !
|
|
2845
|
+
if (!containerDivRef || !parentSelected) {
|
|
2806
2846
|
return;
|
|
2807
2847
|
}
|
|
2808
2848
|
containerDivRef.addEventListener("wheel", handleWheel, {
|
|
@@ -2811,7 +2851,7 @@ var Spreadsheet = forwardRef(({
|
|
|
2811
2851
|
return () => {
|
|
2812
2852
|
containerDivRef.removeEventListener("wheel", handleWheel);
|
|
2813
2853
|
};
|
|
2814
|
-
}, [containerDivRef, handleWheel,
|
|
2854
|
+
}, [containerDivRef, handleWheel, parentSelected]);
|
|
2815
2855
|
useImperativeHandle(ref, () => ({
|
|
2816
2856
|
focus: () => {
|
|
2817
2857
|
selectionManager.focus();
|
|
@@ -2819,8 +2859,9 @@ var Spreadsheet = forwardRef(({
|
|
|
2819
2859
|
blur: () => {
|
|
2820
2860
|
selectionManager.blur();
|
|
2821
2861
|
},
|
|
2822
|
-
scrollToCell
|
|
2823
|
-
|
|
2862
|
+
scrollToCell,
|
|
2863
|
+
scrollToRange
|
|
2864
|
+
}), [scrollToCell, scrollToRange, selectionManager]);
|
|
2824
2865
|
return /* @__PURE__ */ jsx3("div", {
|
|
2825
2866
|
className: cn("rsp-root", className),
|
|
2826
2867
|
"data-rsp-scheme": colorScheme,
|
|
@@ -3168,6 +3209,7 @@ class WorkbookSelectionManager {
|
|
|
3168
3209
|
lastFocusedManager = null;
|
|
3169
3210
|
listeners = new Set;
|
|
3170
3211
|
cleanupFunctions = new Map;
|
|
3212
|
+
pendingRangeFocus = null;
|
|
3171
3213
|
smAreaToSpreadsheetRange(area) {
|
|
3172
3214
|
const rowEnd = area.end.row.type === "infinity" ? { type: "infinity", sign: "positive" } : { type: "number", value: area.end.row.value };
|
|
3173
3215
|
const colEnd = area.end.col.type === "infinity" ? { type: "infinity", sign: "positive" } : { type: "number", value: area.end.col.value };
|
|
@@ -3182,6 +3224,47 @@ class WorkbookSelectionManager {
|
|
|
3182
3224
|
}
|
|
3183
3225
|
};
|
|
3184
3226
|
}
|
|
3227
|
+
spreadsheetRangeToSmArea(range) {
|
|
3228
|
+
return {
|
|
3229
|
+
start: { row: range.start.row, col: range.start.col },
|
|
3230
|
+
end: {
|
|
3231
|
+
row: range.end.row.type === "infinity" ? { type: "infinity" } : { type: "number", value: range.end.row.value },
|
|
3232
|
+
col: range.end.col.type === "infinity" ? { type: "infinity" } : { type: "number", value: range.end.col.value }
|
|
3233
|
+
}
|
|
3234
|
+
};
|
|
3235
|
+
}
|
|
3236
|
+
cloneRangeAddress(address) {
|
|
3237
|
+
return {
|
|
3238
|
+
workbookName: address.workbookName,
|
|
3239
|
+
sheetName: address.sheetName,
|
|
3240
|
+
range: this.smAreaToSpreadsheetRange(this.spreadsheetRangeToSmArea(address.range))
|
|
3241
|
+
};
|
|
3242
|
+
}
|
|
3243
|
+
matchesContext(address, context) {
|
|
3244
|
+
return address.workbookName === context.workbookName && address.sheetName === context.sheetName;
|
|
3245
|
+
}
|
|
3246
|
+
applyRangeFocus(manager, context, request) {
|
|
3247
|
+
const selection = this.spreadsheetRangeToSmArea(request.address.range);
|
|
3248
|
+
manager.setState({ selections: [selection] });
|
|
3249
|
+
manager.focus();
|
|
3250
|
+
manager.revealRange(selection, request.options);
|
|
3251
|
+
this.lastFocusedManager = { sm: manager, context };
|
|
3252
|
+
this.emitChange();
|
|
3253
|
+
}
|
|
3254
|
+
applyPendingRangeFocusOnMount(manager, context) {
|
|
3255
|
+
const pending = this.pendingRangeFocus;
|
|
3256
|
+
if (!pending || !this.matchesContext(pending.address, context))
|
|
3257
|
+
return;
|
|
3258
|
+
queueMicrotask(() => {
|
|
3259
|
+
if (this.pendingRangeFocus !== pending)
|
|
3260
|
+
return;
|
|
3261
|
+
const mountedContext = this.managers.get(manager);
|
|
3262
|
+
if (!mountedContext || !this.matchesContext(pending.address, mountedContext))
|
|
3263
|
+
return;
|
|
3264
|
+
this.pendingRangeFocus = null;
|
|
3265
|
+
this.applyRangeFocus(manager, mountedContext, pending);
|
|
3266
|
+
});
|
|
3267
|
+
}
|
|
3185
3268
|
add(manager, context) {
|
|
3186
3269
|
this.managers.set(manager, context);
|
|
3187
3270
|
const focusCleanup = manager.observeStateChange((state) => state.hasFocus, (hasFocus) => {
|
|
@@ -3207,6 +3290,7 @@ class WorkbookSelectionManager {
|
|
|
3207
3290
|
}
|
|
3208
3291
|
};
|
|
3209
3292
|
this.cleanupFunctions.set(manager, cleanup);
|
|
3293
|
+
this.applyPendingRangeFocusOnMount(manager, context);
|
|
3210
3294
|
return cleanup;
|
|
3211
3295
|
}
|
|
3212
3296
|
getLastFocusedSelectionManager() {
|
|
@@ -3300,22 +3384,31 @@ class WorkbookSelectionManager {
|
|
|
3300
3384
|
return false;
|
|
3301
3385
|
}
|
|
3302
3386
|
focusCell(workbookName, sheetName, row, col) {
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
}
|
|
3311
|
-
}
|
|
3312
|
-
manager.setState({ selections: [selection] });
|
|
3313
|
-
manager.focus();
|
|
3314
|
-
this.lastFocusedManager = { sm: manager, context };
|
|
3315
|
-
this.emitChange();
|
|
3316
|
-
return true;
|
|
3387
|
+
return this.focusRange({
|
|
3388
|
+
workbookName,
|
|
3389
|
+
sheetName,
|
|
3390
|
+
range: {
|
|
3391
|
+
start: { row, col },
|
|
3392
|
+
end: {
|
|
3393
|
+
row: { type: "number", value: row },
|
|
3394
|
+
col: { type: "number", value: col }
|
|
3395
|
+
}
|
|
3317
3396
|
}
|
|
3397
|
+
});
|
|
3398
|
+
}
|
|
3399
|
+
focusRange(address, options = {}) {
|
|
3400
|
+
const request = {
|
|
3401
|
+
address: this.cloneRangeAddress(address),
|
|
3402
|
+
options: { ...options }
|
|
3403
|
+
};
|
|
3404
|
+
for (const [manager, context] of this.managers) {
|
|
3405
|
+
if (!this.matchesContext(request.address, context))
|
|
3406
|
+
continue;
|
|
3407
|
+
this.pendingRangeFocus = null;
|
|
3408
|
+
this.applyRangeFocus(manager, context, request);
|
|
3409
|
+
return true;
|
|
3318
3410
|
}
|
|
3411
|
+
this.pendingRangeFocus = request;
|
|
3319
3412
|
return false;
|
|
3320
3413
|
}
|
|
3321
3414
|
emitChange() {
|
|
@@ -4363,4 +4456,4 @@ export {
|
|
|
4363
4456
|
useResizeObserver
|
|
4364
4457
|
};
|
|
4365
4458
|
|
|
4366
|
-
//# debugId=
|
|
4459
|
+
//# debugId=58E97FA1EA7F33CF64756E2164756E21
|