@ricsam/react-spreadsheets 0.0.9 → 0.0.10
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 +23 -0
- package/dist/cjs/lib.cjs +77 -34
- package/dist/cjs/lib.cjs.map +4 -4
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/lib.mjs +80 -37
- package/dist/mjs/lib.mjs.map +4 -4
- 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
|
@@ -3079,7 +3079,7 @@ Spreadsheet.displayName = "Spreadsheet";
|
|
|
3079
3079
|
// src/workbook/workbook.tsx
|
|
3080
3080
|
import {
|
|
3081
3081
|
parseCellReference as parseCellReference2,
|
|
3082
|
-
getCellReference as
|
|
3082
|
+
getCellReference as getCellReference2
|
|
3083
3083
|
} from "@ricsam/formula-engine";
|
|
3084
3084
|
import React3, { useCallback as useCallback4, useMemo as useMemo2, useRef as useRef4, useState as useState6 } from "react";
|
|
3085
3085
|
|
|
@@ -3207,9 +3207,24 @@ import { indexToColumn as indexToColumn2 } from "@ricsam/formula-engine";
|
|
|
3207
3207
|
class WorkbookSelectionManager {
|
|
3208
3208
|
managers = new Map;
|
|
3209
3209
|
lastFocusedManager = null;
|
|
3210
|
+
lastSelections = [];
|
|
3211
|
+
selectionsByView = new Map;
|
|
3210
3212
|
listeners = new Set;
|
|
3211
3213
|
cleanupFunctions = new Map;
|
|
3212
3214
|
pendingRangeFocus = null;
|
|
3215
|
+
applyingRangeFocus = new Set;
|
|
3216
|
+
getViewKey(context) {
|
|
3217
|
+
return JSON.stringify([context.workbookName, context.sheetName, context.viewId ?? null]);
|
|
3218
|
+
}
|
|
3219
|
+
cloneSmArea(area) {
|
|
3220
|
+
return {
|
|
3221
|
+
start: { row: area.start.row, col: area.start.col },
|
|
3222
|
+
end: {
|
|
3223
|
+
row: area.end.row.type === "infinity" ? { type: "infinity" } : { type: "number", value: area.end.row.value },
|
|
3224
|
+
col: area.end.col.type === "infinity" ? { type: "infinity" } : { type: "number", value: area.end.col.value }
|
|
3225
|
+
}
|
|
3226
|
+
};
|
|
3227
|
+
}
|
|
3213
3228
|
smAreaToSpreadsheetRange(area) {
|
|
3214
3229
|
const rowEnd = area.end.row.type === "infinity" ? { type: "infinity", sign: "positive" } : { type: "number", value: area.end.row.value };
|
|
3215
3230
|
const colEnd = area.end.col.type === "infinity" ? { type: "infinity", sign: "positive" } : { type: "number", value: area.end.col.value };
|
|
@@ -3240,43 +3255,69 @@ class WorkbookSelectionManager {
|
|
|
3240
3255
|
range: this.smAreaToSpreadsheetRange(this.spreadsheetRangeToSmArea(address.range))
|
|
3241
3256
|
};
|
|
3242
3257
|
}
|
|
3243
|
-
|
|
3244
|
-
return
|
|
3258
|
+
areasToRangeAddresses(areas, context) {
|
|
3259
|
+
return areas.map((area) => ({
|
|
3260
|
+
workbookName: context.workbookName,
|
|
3261
|
+
sheetName: context.sheetName,
|
|
3262
|
+
range: this.smAreaToSpreadsheetRange(area)
|
|
3263
|
+
}));
|
|
3264
|
+
}
|
|
3265
|
+
rememberSelections(manager, context, areas = manager.getState().selections) {
|
|
3266
|
+
const cachedAreas = areas.map((area) => this.cloneSmArea(area));
|
|
3267
|
+
this.selectionsByView.set(this.getViewKey(context), cachedAreas);
|
|
3268
|
+
this.lastFocusedManager = { sm: manager, context };
|
|
3269
|
+
this.lastSelections = this.areasToRangeAddresses(cachedAreas, context);
|
|
3270
|
+
}
|
|
3271
|
+
matchesContext(address, context, viewId) {
|
|
3272
|
+
return address.workbookName === context.workbookName && address.sheetName === context.sheetName && (viewId === undefined || context.viewId === viewId);
|
|
3245
3273
|
}
|
|
3246
3274
|
applyRangeFocus(manager, context, request) {
|
|
3247
3275
|
const selection = this.spreadsheetRangeToSmArea(request.address.range);
|
|
3248
|
-
|
|
3249
|
-
|
|
3276
|
+
this.applyingRangeFocus.add(manager);
|
|
3277
|
+
try {
|
|
3278
|
+
manager.replaceSelections([selection]);
|
|
3279
|
+
manager.focus();
|
|
3280
|
+
} finally {
|
|
3281
|
+
this.applyingRangeFocus.delete(manager);
|
|
3282
|
+
}
|
|
3250
3283
|
manager.revealRange(selection, request.options);
|
|
3251
|
-
this.
|
|
3284
|
+
this.rememberSelections(manager, context, [selection]);
|
|
3252
3285
|
this.emitChange();
|
|
3253
3286
|
}
|
|
3254
3287
|
applyPendingRangeFocusOnMount(manager, context) {
|
|
3255
3288
|
const pending = this.pendingRangeFocus;
|
|
3256
|
-
if (!pending || !this.matchesContext(pending.address, context))
|
|
3289
|
+
if (!pending || !this.matchesContext(pending.address, context, pending.options.viewId))
|
|
3257
3290
|
return;
|
|
3258
3291
|
queueMicrotask(() => {
|
|
3259
3292
|
if (this.pendingRangeFocus !== pending)
|
|
3260
3293
|
return;
|
|
3261
3294
|
const mountedContext = this.managers.get(manager);
|
|
3262
|
-
if (!mountedContext || !this.matchesContext(pending.address, mountedContext))
|
|
3295
|
+
if (!mountedContext || !this.matchesContext(pending.address, mountedContext, pending.options.viewId)) {
|
|
3263
3296
|
return;
|
|
3297
|
+
}
|
|
3264
3298
|
this.pendingRangeFocus = null;
|
|
3265
3299
|
this.applyRangeFocus(manager, mountedContext, pending);
|
|
3266
3300
|
});
|
|
3267
3301
|
}
|
|
3268
3302
|
add(manager, context) {
|
|
3269
|
-
|
|
3303
|
+
const registeredContext = { ...context };
|
|
3304
|
+
this.managers.set(manager, registeredContext);
|
|
3305
|
+
const cachedSelections = this.selectionsByView.get(this.getViewKey(registeredContext));
|
|
3306
|
+
if (cachedSelections && manager.getState().selections.length === 0) {
|
|
3307
|
+
manager.replaceSelections(cachedSelections);
|
|
3308
|
+
}
|
|
3270
3309
|
const focusCleanup = manager.observeStateChange((state) => state.hasFocus, (hasFocus) => {
|
|
3271
|
-
if (hasFocus) {
|
|
3272
|
-
this.
|
|
3310
|
+
if (hasFocus && !this.applyingRangeFocus.has(manager)) {
|
|
3311
|
+
this.rememberSelections(manager, registeredContext);
|
|
3273
3312
|
this.emitChange();
|
|
3274
3313
|
}
|
|
3275
3314
|
});
|
|
3276
3315
|
const selectionCleanup = manager.observeStateChange((state) => JSON.stringify(state.selections), (selectionsJson) => {
|
|
3316
|
+
if (this.applyingRangeFocus.has(manager))
|
|
3317
|
+
return;
|
|
3277
3318
|
const selections = JSON.parse(selectionsJson);
|
|
3278
3319
|
if (selections && selections.length > 0) {
|
|
3279
|
-
this.
|
|
3320
|
+
this.rememberSelections(manager, registeredContext, selections);
|
|
3280
3321
|
this.emitChange();
|
|
3281
3322
|
}
|
|
3282
3323
|
});
|
|
@@ -3286,27 +3327,19 @@ class WorkbookSelectionManager {
|
|
|
3286
3327
|
this.managers.delete(manager);
|
|
3287
3328
|
this.cleanupFunctions.delete(manager);
|
|
3288
3329
|
if (this.lastFocusedManager?.sm === manager) {
|
|
3330
|
+
this.rememberSelections(manager, registeredContext);
|
|
3289
3331
|
this.lastFocusedManager = null;
|
|
3290
3332
|
}
|
|
3291
3333
|
};
|
|
3292
3334
|
this.cleanupFunctions.set(manager, cleanup);
|
|
3293
|
-
this.applyPendingRangeFocusOnMount(manager,
|
|
3335
|
+
this.applyPendingRangeFocusOnMount(manager, registeredContext);
|
|
3294
3336
|
return cleanup;
|
|
3295
3337
|
}
|
|
3296
3338
|
getLastFocusedSelectionManager() {
|
|
3297
3339
|
return this.lastFocusedManager;
|
|
3298
3340
|
}
|
|
3299
3341
|
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
|
-
}));
|
|
3342
|
+
return this.lastSelections.map((selection) => this.cloneRangeAddress(selection));
|
|
3310
3343
|
}
|
|
3311
3344
|
getLastSelection() {
|
|
3312
3345
|
const selections = this.getSelections();
|
|
@@ -3355,35 +3388,37 @@ class WorkbookSelectionManager {
|
|
|
3355
3388
|
return `[${workbookName}]${sheetRef}!${rangeStr}`;
|
|
3356
3389
|
}
|
|
3357
3390
|
blur() {
|
|
3358
|
-
this.managers.forEach((
|
|
3391
|
+
this.managers.forEach((_context, manager) => {
|
|
3359
3392
|
manager.clearSelections();
|
|
3360
3393
|
manager.blur();
|
|
3361
3394
|
});
|
|
3395
|
+
this.selectionsByView.clear();
|
|
3362
3396
|
this.lastFocusedManager = null;
|
|
3397
|
+
this.lastSelections = [];
|
|
3363
3398
|
this.emitChange();
|
|
3364
3399
|
}
|
|
3365
|
-
focusWorkbook(workbookName) {
|
|
3400
|
+
focusWorkbook(workbookName, viewId) {
|
|
3366
3401
|
for (const [manager, context] of this.managers) {
|
|
3367
|
-
if (context.workbookName === workbookName) {
|
|
3402
|
+
if (context.workbookName === workbookName && (viewId === undefined || context.viewId === viewId)) {
|
|
3368
3403
|
manager.focus();
|
|
3369
|
-
this.
|
|
3404
|
+
this.rememberSelections(manager, context);
|
|
3370
3405
|
this.emitChange();
|
|
3371
3406
|
return;
|
|
3372
3407
|
}
|
|
3373
3408
|
}
|
|
3374
3409
|
}
|
|
3375
|
-
focusSheet(workbookName, sheetName) {
|
|
3410
|
+
focusSheet(workbookName, sheetName, viewId) {
|
|
3376
3411
|
for (const [manager, context] of this.managers) {
|
|
3377
|
-
if (context.workbookName === workbookName && context.sheetName === sheetName) {
|
|
3412
|
+
if (context.workbookName === workbookName && context.sheetName === sheetName && (viewId === undefined || context.viewId === viewId)) {
|
|
3378
3413
|
manager.focus();
|
|
3379
|
-
this.
|
|
3414
|
+
this.rememberSelections(manager, context);
|
|
3380
3415
|
this.emitChange();
|
|
3381
3416
|
return true;
|
|
3382
3417
|
}
|
|
3383
3418
|
}
|
|
3384
3419
|
return false;
|
|
3385
3420
|
}
|
|
3386
|
-
focusCell(workbookName, sheetName, row, col) {
|
|
3421
|
+
focusCell(workbookName, sheetName, row, col, options = {}) {
|
|
3387
3422
|
return this.focusRange({
|
|
3388
3423
|
workbookName,
|
|
3389
3424
|
sheetName,
|
|
@@ -3394,7 +3429,7 @@ class WorkbookSelectionManager {
|
|
|
3394
3429
|
col: { type: "number", value: col }
|
|
3395
3430
|
}
|
|
3396
3431
|
}
|
|
3397
|
-
});
|
|
3432
|
+
}, options);
|
|
3398
3433
|
}
|
|
3399
3434
|
focusRange(address, options = {}) {
|
|
3400
3435
|
const request = {
|
|
@@ -3402,7 +3437,7 @@ class WorkbookSelectionManager {
|
|
|
3402
3437
|
options: { ...options }
|
|
3403
3438
|
};
|
|
3404
3439
|
for (const [manager, context] of this.managers) {
|
|
3405
|
-
if (!this.matchesContext(request.address, context))
|
|
3440
|
+
if (!this.matchesContext(request.address, context, request.options.viewId))
|
|
3406
3441
|
continue;
|
|
3407
3442
|
this.pendingRangeFocus = null;
|
|
3408
3443
|
this.applyRangeFocus(manager, context, request);
|
|
@@ -3411,6 +3446,9 @@ class WorkbookSelectionManager {
|
|
|
3411
3446
|
this.pendingRangeFocus = request;
|
|
3412
3447
|
return false;
|
|
3413
3448
|
}
|
|
3449
|
+
cancelPendingFocusRange() {
|
|
3450
|
+
this.pendingRangeFocus = null;
|
|
3451
|
+
}
|
|
3414
3452
|
emitChange() {
|
|
3415
3453
|
const currentSelection = this.getLastSelection();
|
|
3416
3454
|
const selections = currentSelection ? [currentSelection] : [];
|
|
@@ -3589,7 +3627,7 @@ class WorkbookClipboardManager extends ClipboardUtils {
|
|
|
3589
3627
|
};
|
|
3590
3628
|
this.copiedCells.push(cellAddress);
|
|
3591
3629
|
const value = this.engine.getCellValue(cellAddress, false);
|
|
3592
|
-
const formula = cellData.get(
|
|
3630
|
+
const formula = cellData.get(getCellReference2(cellAddress));
|
|
3593
3631
|
valueExportGrid[relative.rowIndex][relative.columnIndex] = getCellDisplayValue(value);
|
|
3594
3632
|
formulaExportGrid[relative.rowIndex][relative.columnIndex] = formula;
|
|
3595
3633
|
});
|
|
@@ -3637,6 +3675,7 @@ function FormulaSheet({
|
|
|
3637
3675
|
verboseErrors = false,
|
|
3638
3676
|
selection,
|
|
3639
3677
|
selectionManager,
|
|
3678
|
+
viewId,
|
|
3640
3679
|
customCellStyle,
|
|
3641
3680
|
customCellRenderer,
|
|
3642
3681
|
onCellDataChangeError = queueCellEditError,
|
|
@@ -3808,7 +3847,8 @@ function FormulaSheet({
|
|
|
3808
3847
|
if (selectionManager) {
|
|
3809
3848
|
const workbookManagerCleanup = selectionManager.add(spreadsheetSelectionManager, {
|
|
3810
3849
|
workbookName,
|
|
3811
|
-
sheetName
|
|
3850
|
+
sheetName,
|
|
3851
|
+
...viewId === undefined ? {} : { viewId }
|
|
3812
3852
|
});
|
|
3813
3853
|
cleanups.push(workbookManagerCleanup);
|
|
3814
3854
|
}
|
|
@@ -3829,6 +3869,7 @@ function FormulaSheet({
|
|
|
3829
3869
|
selectionManager,
|
|
3830
3870
|
sheetName,
|
|
3831
3871
|
showFormulas,
|
|
3872
|
+
viewId,
|
|
3832
3873
|
workbookName
|
|
3833
3874
|
]);
|
|
3834
3875
|
if (!sheet) {
|
|
@@ -3968,7 +4009,7 @@ function FormulaSheet({
|
|
|
3968
4009
|
return style;
|
|
3969
4010
|
},
|
|
3970
4011
|
customCellRenderer: (cell) => {
|
|
3971
|
-
const cellRef =
|
|
4012
|
+
const cellRef = getCellReference2({
|
|
3972
4013
|
colIndex: cell.colIndex,
|
|
3973
4014
|
rowIndex: cell.rowIndex
|
|
3974
4015
|
});
|
|
@@ -4062,6 +4103,7 @@ function FormulaWorkbook({
|
|
|
4062
4103
|
onActiveSheetChange,
|
|
4063
4104
|
verboseErrors = false,
|
|
4064
4105
|
selectionManager,
|
|
4106
|
+
viewId,
|
|
4065
4107
|
components,
|
|
4066
4108
|
sheetOverlayChildren,
|
|
4067
4109
|
sheetSelectedOverlayIds,
|
|
@@ -4229,6 +4271,7 @@ function FormulaWorkbook({
|
|
|
4229
4271
|
engine,
|
|
4230
4272
|
verboseErrors,
|
|
4231
4273
|
selectionManager,
|
|
4274
|
+
viewId,
|
|
4232
4275
|
...rest,
|
|
4233
4276
|
components,
|
|
4234
4277
|
overlayChildren: activeSheetOverlayChildren,
|
|
@@ -4456,4 +4499,4 @@ export {
|
|
|
4456
4499
|
useResizeObserver
|
|
4457
4500
|
};
|
|
4458
4501
|
|
|
4459
|
-
//# debugId=
|
|
4502
|
+
//# debugId=27095BB366C4630864756E2164756E21
|