@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.
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@ricsam/react-spreadsheets",
3
- "version": "0.0.9",
3
+ "version": "0.0.10",
4
4
  "type": "commonjs"
5
5
  }
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 getCellReference3
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
- matchesContext(address, context) {
3244
- return address.workbookName === context.workbookName && address.sheetName === context.sheetName;
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
- manager.setState({ selections: [selection] });
3249
- manager.focus();
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.lastFocusedManager = { sm: manager, context };
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
- this.managers.set(manager, context);
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.lastFocusedManager = { sm: manager, context };
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.lastFocusedManager = { sm: manager, context };
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, context);
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
- if (!this.lastFocusedManager) {
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((context, manager) => {
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.lastFocusedManager = { sm: manager, context };
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.lastFocusedManager = { sm: manager, context };
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(getCellReference3(cellAddress));
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 = getCellReference3({
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=58E97FA1EA7F33CF64756E2164756E21
4502
+ //# debugId=27095BB366C4630864756E2164756E21