@ricsam/react-spreadsheets 0.0.9 → 0.0.11
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 +28 -0
- package/dist/cjs/lib.cjs +85 -34
- package/dist/cjs/lib.cjs.map +5 -5
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/lib.mjs +88 -37
- package/dist/mjs/lib.mjs.map +5 -5
- package/dist/mjs/package.json +1 -1
- package/dist/types/lib.d.ts +2 -2
- package/dist/types/workbook/workbook-selection-manager.d.ts +22 -7
- package/dist/types/workbook/workbook.d.ts +8 -4
- package/package.json +3 -3
package/dist/cjs/package.json
CHANGED
package/dist/mjs/lib.mjs
CHANGED
|
@@ -1326,6 +1326,7 @@ var resizeCellSnapAnchorToNearestEdges = (anchor, rect, handle, columnWidths, ro
|
|
|
1326
1326
|
|
|
1327
1327
|
// src/spreadsheet/spreadsheet.tsx
|
|
1328
1328
|
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1329
|
+
var SPREADSHEET_OVERLAY_SELECTOR = "[data-rsp-overlay]";
|
|
1329
1330
|
var resolveGridLineColor = (probe, colorScheme) => {
|
|
1330
1331
|
const fallback = colorScheme === "dark" ? "#232c3d" : "#e8ebf1";
|
|
1331
1332
|
if (!probe || typeof getComputedStyle !== "function") {
|
|
@@ -2286,6 +2287,12 @@ var Spreadsheet = forwardRef(({
|
|
|
2286
2287
|
});
|
|
2287
2288
|
}, [selectionManager, clipboardManager, disableClipboard]);
|
|
2288
2289
|
const handleWheel = useCallback3((e) => {
|
|
2290
|
+
const target = e.target;
|
|
2291
|
+
const currentTarget = e.currentTarget;
|
|
2292
|
+
const overlay = target instanceof Element ? target.closest(SPREADSHEET_OVERLAY_SELECTOR) : null;
|
|
2293
|
+
if (overlay && currentTarget instanceof Node && currentTarget.contains(overlay)) {
|
|
2294
|
+
return;
|
|
2295
|
+
}
|
|
2289
2296
|
e.preventDefault();
|
|
2290
2297
|
e.stopPropagation();
|
|
2291
2298
|
setViewport((previous) => ({
|
|
@@ -3011,6 +3018,7 @@ var Spreadsheet = forwardRef(({
|
|
|
3011
3018
|
const isTextBox = child.component === "RichText";
|
|
3012
3019
|
const isMinimized = Boolean(child.minimized && !isTextBox);
|
|
3013
3020
|
return /* @__PURE__ */ jsxs2("div", {
|
|
3021
|
+
"data-rsp-overlay": child.id,
|
|
3014
3022
|
style: {
|
|
3015
3023
|
position: "absolute",
|
|
3016
3024
|
width: child.width,
|
|
@@ -3079,7 +3087,7 @@ Spreadsheet.displayName = "Spreadsheet";
|
|
|
3079
3087
|
// src/workbook/workbook.tsx
|
|
3080
3088
|
import {
|
|
3081
3089
|
parseCellReference as parseCellReference2,
|
|
3082
|
-
getCellReference as
|
|
3090
|
+
getCellReference as getCellReference2
|
|
3083
3091
|
} from "@ricsam/formula-engine";
|
|
3084
3092
|
import React3, { useCallback as useCallback4, useMemo as useMemo2, useRef as useRef4, useState as useState6 } from "react";
|
|
3085
3093
|
|
|
@@ -3207,9 +3215,24 @@ import { indexToColumn as indexToColumn2 } from "@ricsam/formula-engine";
|
|
|
3207
3215
|
class WorkbookSelectionManager {
|
|
3208
3216
|
managers = new Map;
|
|
3209
3217
|
lastFocusedManager = null;
|
|
3218
|
+
lastSelections = [];
|
|
3219
|
+
selectionsByView = new Map;
|
|
3210
3220
|
listeners = new Set;
|
|
3211
3221
|
cleanupFunctions = new Map;
|
|
3212
3222
|
pendingRangeFocus = null;
|
|
3223
|
+
applyingRangeFocus = new Set;
|
|
3224
|
+
getViewKey(context) {
|
|
3225
|
+
return JSON.stringify([context.workbookName, context.sheetName, context.viewId ?? null]);
|
|
3226
|
+
}
|
|
3227
|
+
cloneSmArea(area) {
|
|
3228
|
+
return {
|
|
3229
|
+
start: { row: area.start.row, col: area.start.col },
|
|
3230
|
+
end: {
|
|
3231
|
+
row: area.end.row.type === "infinity" ? { type: "infinity" } : { type: "number", value: area.end.row.value },
|
|
3232
|
+
col: area.end.col.type === "infinity" ? { type: "infinity" } : { type: "number", value: area.end.col.value }
|
|
3233
|
+
}
|
|
3234
|
+
};
|
|
3235
|
+
}
|
|
3213
3236
|
smAreaToSpreadsheetRange(area) {
|
|
3214
3237
|
const rowEnd = area.end.row.type === "infinity" ? { type: "infinity", sign: "positive" } : { type: "number", value: area.end.row.value };
|
|
3215
3238
|
const colEnd = area.end.col.type === "infinity" ? { type: "infinity", sign: "positive" } : { type: "number", value: area.end.col.value };
|
|
@@ -3240,43 +3263,69 @@ class WorkbookSelectionManager {
|
|
|
3240
3263
|
range: this.smAreaToSpreadsheetRange(this.spreadsheetRangeToSmArea(address.range))
|
|
3241
3264
|
};
|
|
3242
3265
|
}
|
|
3243
|
-
|
|
3244
|
-
return
|
|
3266
|
+
areasToRangeAddresses(areas, context) {
|
|
3267
|
+
return areas.map((area) => ({
|
|
3268
|
+
workbookName: context.workbookName,
|
|
3269
|
+
sheetName: context.sheetName,
|
|
3270
|
+
range: this.smAreaToSpreadsheetRange(area)
|
|
3271
|
+
}));
|
|
3272
|
+
}
|
|
3273
|
+
rememberSelections(manager, context, areas = manager.getState().selections) {
|
|
3274
|
+
const cachedAreas = areas.map((area) => this.cloneSmArea(area));
|
|
3275
|
+
this.selectionsByView.set(this.getViewKey(context), cachedAreas);
|
|
3276
|
+
this.lastFocusedManager = { sm: manager, context };
|
|
3277
|
+
this.lastSelections = this.areasToRangeAddresses(cachedAreas, context);
|
|
3278
|
+
}
|
|
3279
|
+
matchesContext(address, context, viewId) {
|
|
3280
|
+
return address.workbookName === context.workbookName && address.sheetName === context.sheetName && (viewId === undefined || context.viewId === viewId);
|
|
3245
3281
|
}
|
|
3246
3282
|
applyRangeFocus(manager, context, request) {
|
|
3247
3283
|
const selection = this.spreadsheetRangeToSmArea(request.address.range);
|
|
3248
|
-
|
|
3249
|
-
|
|
3284
|
+
this.applyingRangeFocus.add(manager);
|
|
3285
|
+
try {
|
|
3286
|
+
manager.replaceSelections([selection]);
|
|
3287
|
+
manager.focus();
|
|
3288
|
+
} finally {
|
|
3289
|
+
this.applyingRangeFocus.delete(manager);
|
|
3290
|
+
}
|
|
3250
3291
|
manager.revealRange(selection, request.options);
|
|
3251
|
-
this.
|
|
3292
|
+
this.rememberSelections(manager, context, [selection]);
|
|
3252
3293
|
this.emitChange();
|
|
3253
3294
|
}
|
|
3254
3295
|
applyPendingRangeFocusOnMount(manager, context) {
|
|
3255
3296
|
const pending = this.pendingRangeFocus;
|
|
3256
|
-
if (!pending || !this.matchesContext(pending.address, context))
|
|
3297
|
+
if (!pending || !this.matchesContext(pending.address, context, pending.options.viewId))
|
|
3257
3298
|
return;
|
|
3258
3299
|
queueMicrotask(() => {
|
|
3259
3300
|
if (this.pendingRangeFocus !== pending)
|
|
3260
3301
|
return;
|
|
3261
3302
|
const mountedContext = this.managers.get(manager);
|
|
3262
|
-
if (!mountedContext || !this.matchesContext(pending.address, mountedContext))
|
|
3303
|
+
if (!mountedContext || !this.matchesContext(pending.address, mountedContext, pending.options.viewId)) {
|
|
3263
3304
|
return;
|
|
3305
|
+
}
|
|
3264
3306
|
this.pendingRangeFocus = null;
|
|
3265
3307
|
this.applyRangeFocus(manager, mountedContext, pending);
|
|
3266
3308
|
});
|
|
3267
3309
|
}
|
|
3268
3310
|
add(manager, context) {
|
|
3269
|
-
|
|
3311
|
+
const registeredContext = { ...context };
|
|
3312
|
+
this.managers.set(manager, registeredContext);
|
|
3313
|
+
const cachedSelections = this.selectionsByView.get(this.getViewKey(registeredContext));
|
|
3314
|
+
if (cachedSelections && manager.getState().selections.length === 0) {
|
|
3315
|
+
manager.replaceSelections(cachedSelections);
|
|
3316
|
+
}
|
|
3270
3317
|
const focusCleanup = manager.observeStateChange((state) => state.hasFocus, (hasFocus) => {
|
|
3271
|
-
if (hasFocus) {
|
|
3272
|
-
this.
|
|
3318
|
+
if (hasFocus && !this.applyingRangeFocus.has(manager)) {
|
|
3319
|
+
this.rememberSelections(manager, registeredContext);
|
|
3273
3320
|
this.emitChange();
|
|
3274
3321
|
}
|
|
3275
3322
|
});
|
|
3276
3323
|
const selectionCleanup = manager.observeStateChange((state) => JSON.stringify(state.selections), (selectionsJson) => {
|
|
3324
|
+
if (this.applyingRangeFocus.has(manager))
|
|
3325
|
+
return;
|
|
3277
3326
|
const selections = JSON.parse(selectionsJson);
|
|
3278
3327
|
if (selections && selections.length > 0) {
|
|
3279
|
-
this.
|
|
3328
|
+
this.rememberSelections(manager, registeredContext, selections);
|
|
3280
3329
|
this.emitChange();
|
|
3281
3330
|
}
|
|
3282
3331
|
});
|
|
@@ -3286,27 +3335,19 @@ class WorkbookSelectionManager {
|
|
|
3286
3335
|
this.managers.delete(manager);
|
|
3287
3336
|
this.cleanupFunctions.delete(manager);
|
|
3288
3337
|
if (this.lastFocusedManager?.sm === manager) {
|
|
3338
|
+
this.rememberSelections(manager, registeredContext);
|
|
3289
3339
|
this.lastFocusedManager = null;
|
|
3290
3340
|
}
|
|
3291
3341
|
};
|
|
3292
3342
|
this.cleanupFunctions.set(manager, cleanup);
|
|
3293
|
-
this.applyPendingRangeFocusOnMount(manager,
|
|
3343
|
+
this.applyPendingRangeFocusOnMount(manager, registeredContext);
|
|
3294
3344
|
return cleanup;
|
|
3295
3345
|
}
|
|
3296
3346
|
getLastFocusedSelectionManager() {
|
|
3297
3347
|
return this.lastFocusedManager;
|
|
3298
3348
|
}
|
|
3299
3349
|
getSelections() {
|
|
3300
|
-
|
|
3301
|
-
return [];
|
|
3302
|
-
}
|
|
3303
|
-
const { sm, context } = this.lastFocusedManager;
|
|
3304
|
-
const state = sm.getState();
|
|
3305
|
-
return state.selections.map((area) => ({
|
|
3306
|
-
workbookName: context.workbookName,
|
|
3307
|
-
sheetName: context.sheetName,
|
|
3308
|
-
range: this.smAreaToSpreadsheetRange(area)
|
|
3309
|
-
}));
|
|
3350
|
+
return this.lastSelections.map((selection) => this.cloneRangeAddress(selection));
|
|
3310
3351
|
}
|
|
3311
3352
|
getLastSelection() {
|
|
3312
3353
|
const selections = this.getSelections();
|
|
@@ -3355,35 +3396,37 @@ class WorkbookSelectionManager {
|
|
|
3355
3396
|
return `[${workbookName}]${sheetRef}!${rangeStr}`;
|
|
3356
3397
|
}
|
|
3357
3398
|
blur() {
|
|
3358
|
-
this.managers.forEach((
|
|
3399
|
+
this.managers.forEach((_context, manager) => {
|
|
3359
3400
|
manager.clearSelections();
|
|
3360
3401
|
manager.blur();
|
|
3361
3402
|
});
|
|
3403
|
+
this.selectionsByView.clear();
|
|
3362
3404
|
this.lastFocusedManager = null;
|
|
3405
|
+
this.lastSelections = [];
|
|
3363
3406
|
this.emitChange();
|
|
3364
3407
|
}
|
|
3365
|
-
focusWorkbook(workbookName) {
|
|
3408
|
+
focusWorkbook(workbookName, viewId) {
|
|
3366
3409
|
for (const [manager, context] of this.managers) {
|
|
3367
|
-
if (context.workbookName === workbookName) {
|
|
3410
|
+
if (context.workbookName === workbookName && (viewId === undefined || context.viewId === viewId)) {
|
|
3368
3411
|
manager.focus();
|
|
3369
|
-
this.
|
|
3412
|
+
this.rememberSelections(manager, context);
|
|
3370
3413
|
this.emitChange();
|
|
3371
3414
|
return;
|
|
3372
3415
|
}
|
|
3373
3416
|
}
|
|
3374
3417
|
}
|
|
3375
|
-
focusSheet(workbookName, sheetName) {
|
|
3418
|
+
focusSheet(workbookName, sheetName, viewId) {
|
|
3376
3419
|
for (const [manager, context] of this.managers) {
|
|
3377
|
-
if (context.workbookName === workbookName && context.sheetName === sheetName) {
|
|
3420
|
+
if (context.workbookName === workbookName && context.sheetName === sheetName && (viewId === undefined || context.viewId === viewId)) {
|
|
3378
3421
|
manager.focus();
|
|
3379
|
-
this.
|
|
3422
|
+
this.rememberSelections(manager, context);
|
|
3380
3423
|
this.emitChange();
|
|
3381
3424
|
return true;
|
|
3382
3425
|
}
|
|
3383
3426
|
}
|
|
3384
3427
|
return false;
|
|
3385
3428
|
}
|
|
3386
|
-
focusCell(workbookName, sheetName, row, col) {
|
|
3429
|
+
focusCell(workbookName, sheetName, row, col, options = {}) {
|
|
3387
3430
|
return this.focusRange({
|
|
3388
3431
|
workbookName,
|
|
3389
3432
|
sheetName,
|
|
@@ -3394,7 +3437,7 @@ class WorkbookSelectionManager {
|
|
|
3394
3437
|
col: { type: "number", value: col }
|
|
3395
3438
|
}
|
|
3396
3439
|
}
|
|
3397
|
-
});
|
|
3440
|
+
}, options);
|
|
3398
3441
|
}
|
|
3399
3442
|
focusRange(address, options = {}) {
|
|
3400
3443
|
const request = {
|
|
@@ -3402,7 +3445,7 @@ class WorkbookSelectionManager {
|
|
|
3402
3445
|
options: { ...options }
|
|
3403
3446
|
};
|
|
3404
3447
|
for (const [manager, context] of this.managers) {
|
|
3405
|
-
if (!this.matchesContext(request.address, context))
|
|
3448
|
+
if (!this.matchesContext(request.address, context, request.options.viewId))
|
|
3406
3449
|
continue;
|
|
3407
3450
|
this.pendingRangeFocus = null;
|
|
3408
3451
|
this.applyRangeFocus(manager, context, request);
|
|
@@ -3411,6 +3454,9 @@ class WorkbookSelectionManager {
|
|
|
3411
3454
|
this.pendingRangeFocus = request;
|
|
3412
3455
|
return false;
|
|
3413
3456
|
}
|
|
3457
|
+
cancelPendingFocusRange() {
|
|
3458
|
+
this.pendingRangeFocus = null;
|
|
3459
|
+
}
|
|
3414
3460
|
emitChange() {
|
|
3415
3461
|
const currentSelection = this.getLastSelection();
|
|
3416
3462
|
const selections = currentSelection ? [currentSelection] : [];
|
|
@@ -3589,7 +3635,7 @@ class WorkbookClipboardManager extends ClipboardUtils {
|
|
|
3589
3635
|
};
|
|
3590
3636
|
this.copiedCells.push(cellAddress);
|
|
3591
3637
|
const value = this.engine.getCellValue(cellAddress, false);
|
|
3592
|
-
const formula = cellData.get(
|
|
3638
|
+
const formula = cellData.get(getCellReference2(cellAddress));
|
|
3593
3639
|
valueExportGrid[relative.rowIndex][relative.columnIndex] = getCellDisplayValue(value);
|
|
3594
3640
|
formulaExportGrid[relative.rowIndex][relative.columnIndex] = formula;
|
|
3595
3641
|
});
|
|
@@ -3637,6 +3683,7 @@ function FormulaSheet({
|
|
|
3637
3683
|
verboseErrors = false,
|
|
3638
3684
|
selection,
|
|
3639
3685
|
selectionManager,
|
|
3686
|
+
viewId,
|
|
3640
3687
|
customCellStyle,
|
|
3641
3688
|
customCellRenderer,
|
|
3642
3689
|
onCellDataChangeError = queueCellEditError,
|
|
@@ -3808,7 +3855,8 @@ function FormulaSheet({
|
|
|
3808
3855
|
if (selectionManager) {
|
|
3809
3856
|
const workbookManagerCleanup = selectionManager.add(spreadsheetSelectionManager, {
|
|
3810
3857
|
workbookName,
|
|
3811
|
-
sheetName
|
|
3858
|
+
sheetName,
|
|
3859
|
+
...viewId === undefined ? {} : { viewId }
|
|
3812
3860
|
});
|
|
3813
3861
|
cleanups.push(workbookManagerCleanup);
|
|
3814
3862
|
}
|
|
@@ -3829,6 +3877,7 @@ function FormulaSheet({
|
|
|
3829
3877
|
selectionManager,
|
|
3830
3878
|
sheetName,
|
|
3831
3879
|
showFormulas,
|
|
3880
|
+
viewId,
|
|
3832
3881
|
workbookName
|
|
3833
3882
|
]);
|
|
3834
3883
|
if (!sheet) {
|
|
@@ -3968,7 +4017,7 @@ function FormulaSheet({
|
|
|
3968
4017
|
return style;
|
|
3969
4018
|
},
|
|
3970
4019
|
customCellRenderer: (cell) => {
|
|
3971
|
-
const cellRef =
|
|
4020
|
+
const cellRef = getCellReference2({
|
|
3972
4021
|
colIndex: cell.colIndex,
|
|
3973
4022
|
rowIndex: cell.rowIndex
|
|
3974
4023
|
});
|
|
@@ -4062,6 +4111,7 @@ function FormulaWorkbook({
|
|
|
4062
4111
|
onActiveSheetChange,
|
|
4063
4112
|
verboseErrors = false,
|
|
4064
4113
|
selectionManager,
|
|
4114
|
+
viewId,
|
|
4065
4115
|
components,
|
|
4066
4116
|
sheetOverlayChildren,
|
|
4067
4117
|
sheetSelectedOverlayIds,
|
|
@@ -4229,6 +4279,7 @@ function FormulaWorkbook({
|
|
|
4229
4279
|
engine,
|
|
4230
4280
|
verboseErrors,
|
|
4231
4281
|
selectionManager,
|
|
4282
|
+
viewId,
|
|
4232
4283
|
...rest,
|
|
4233
4284
|
components,
|
|
4234
4285
|
overlayChildren: activeSheetOverlayChildren,
|
|
@@ -4456,4 +4507,4 @@ export {
|
|
|
4456
4507
|
useResizeObserver
|
|
4457
4508
|
};
|
|
4458
4509
|
|
|
4459
|
-
//# debugId=
|
|
4510
|
+
//# debugId=7847981F1291DEF064756E2164756E21
|