handsontable 0.0.0-next-221e46b-20240307 → 0.0.0-next-200799f-20240311

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.

Potentially problematic release.


This version of handsontable might be problematic. Click here for more details.

Files changed (98) hide show
  1. package/3rdparty/walkontable/src/cell/range.d.ts +1 -0
  2. package/3rdparty/walkontable/src/cell/range.js +22 -5
  3. package/3rdparty/walkontable/src/cell/range.mjs +22 -5
  4. package/base.js +2 -2
  5. package/base.mjs +2 -2
  6. package/core/viewportScroll/index.js +4 -1
  7. package/core/viewportScroll/index.mjs +4 -1
  8. package/core/viewportScroll/scrollStrategies/focusScroll.js +15 -0
  9. package/core/viewportScroll/scrollStrategies/focusScroll.mjs +11 -0
  10. package/core.d.ts +4 -3
  11. package/core.js +78 -21
  12. package/core.mjs +78 -21
  13. package/dist/handsontable.css +2 -2
  14. package/dist/handsontable.full.css +2 -2
  15. package/dist/handsontable.full.js +2645 -1363
  16. package/dist/handsontable.full.min.css +2 -2
  17. package/dist/handsontable.full.min.js +152 -152
  18. package/dist/handsontable.js +2645 -1363
  19. package/dist/handsontable.min.css +2 -2
  20. package/dist/handsontable.min.js +32 -32
  21. package/editorManager.js +12 -8
  22. package/editorManager.mjs +12 -8
  23. package/helpers/mixed.js +1 -1
  24. package/helpers/mixed.mjs +1 -1
  25. package/package.json +1 -1
  26. package/pluginHooks.d.ts +1 -0
  27. package/pluginHooks.js +43 -1
  28. package/pluginHooks.mjs +43 -1
  29. package/plugins/collapsibleColumns/collapsibleColumns.js +7 -1
  30. package/plugins/collapsibleColumns/collapsibleColumns.mjs +7 -1
  31. package/plugins/columnSorting/columnSorting.js +6 -0
  32. package/plugins/columnSorting/columnSorting.mjs +6 -0
  33. package/plugins/contextMenu/menu/defaultShortcutsList.js +26 -10
  34. package/plugins/contextMenu/menu/defaultShortcutsList.mjs +26 -10
  35. package/plugins/mergeCells/calculations/selection.js +1 -70
  36. package/plugins/mergeCells/calculations/selection.mjs +1 -70
  37. package/plugins/mergeCells/cellsCollection.js +116 -0
  38. package/plugins/mergeCells/cellsCollection.mjs +116 -0
  39. package/plugins/mergeCells/contextMenuItem/toggleMerge.js +11 -1
  40. package/plugins/mergeCells/contextMenuItem/toggleMerge.mjs +11 -1
  41. package/plugins/mergeCells/focusOrder.js +258 -0
  42. package/plugins/mergeCells/focusOrder.mjs +253 -0
  43. package/plugins/mergeCells/mergeCells.js +394 -199
  44. package/plugins/mergeCells/mergeCells.mjs +394 -199
  45. package/plugins/multiColumnSorting/multiColumnSorting.js +6 -0
  46. package/plugins/multiColumnSorting/multiColumnSorting.mjs +6 -0
  47. package/plugins/nestedHeaders/nestedHeaders.js +1 -0
  48. package/plugins/nestedHeaders/nestedHeaders.mjs +1 -0
  49. package/plugins/nestedRows/nestedRows.js +7 -1
  50. package/plugins/nestedRows/nestedRows.mjs +7 -1
  51. package/renderers/checkboxRenderer/checkboxRenderer.js +4 -4
  52. package/renderers/checkboxRenderer/checkboxRenderer.mjs +4 -4
  53. package/selection/highlight/visualSelection.js +16 -2
  54. package/selection/highlight/visualSelection.mjs +16 -2
  55. package/selection/selection.js +225 -44
  56. package/selection/selection.mjs +224 -43
  57. package/selection/transformation.js +86 -32
  58. package/selection/transformation.mjs +86 -32
  59. package/shortcutContexts/commands/editor/closeAndSave.js +2 -2
  60. package/shortcutContexts/commands/editor/closeAndSave.mjs +2 -2
  61. package/shortcutContexts/commands/editor/open.js +18 -3
  62. package/shortcutContexts/commands/editor/open.mjs +18 -3
  63. package/shortcutContexts/commands/extendCellsSelection/down.js +1 -1
  64. package/shortcutContexts/commands/extendCellsSelection/down.mjs +1 -1
  65. package/shortcutContexts/commands/extendCellsSelection/left.js +1 -1
  66. package/shortcutContexts/commands/extendCellsSelection/left.mjs +1 -1
  67. package/shortcutContexts/commands/extendCellsSelection/right.js +1 -1
  68. package/shortcutContexts/commands/extendCellsSelection/right.mjs +1 -1
  69. package/shortcutContexts/commands/extendCellsSelection/toColumns.js +1 -1
  70. package/shortcutContexts/commands/extendCellsSelection/toColumns.mjs +1 -1
  71. package/shortcutContexts/commands/extendCellsSelection/toMostBottom.js +3 -1
  72. package/shortcutContexts/commands/extendCellsSelection/toMostBottom.mjs +3 -1
  73. package/shortcutContexts/commands/extendCellsSelection/toMostInlineEnd.js +9 -3
  74. package/shortcutContexts/commands/extendCellsSelection/toMostInlineEnd.mjs +9 -3
  75. package/shortcutContexts/commands/extendCellsSelection/toMostInlineStart.js +10 -3
  76. package/shortcutContexts/commands/extendCellsSelection/toMostInlineStart.mjs +10 -3
  77. package/shortcutContexts/commands/extendCellsSelection/toMostLeft.js +3 -1
  78. package/shortcutContexts/commands/extendCellsSelection/toMostLeft.mjs +3 -1
  79. package/shortcutContexts/commands/extendCellsSelection/toMostRight.js +3 -1
  80. package/shortcutContexts/commands/extendCellsSelection/toMostRight.mjs +3 -1
  81. package/shortcutContexts/commands/extendCellsSelection/toMostTop.js +3 -1
  82. package/shortcutContexts/commands/extendCellsSelection/toMostTop.mjs +3 -1
  83. package/shortcutContexts/commands/extendCellsSelection/toRows.js +1 -1
  84. package/shortcutContexts/commands/extendCellsSelection/toRows.mjs +1 -1
  85. package/shortcutContexts/commands/extendCellsSelection/up.js +1 -1
  86. package/shortcutContexts/commands/extendCellsSelection/up.mjs +1 -1
  87. package/shortcutContexts/commands/moveCellSelection/inlineEnd.js +6 -1
  88. package/shortcutContexts/commands/moveCellSelection/inlineEnd.mjs +6 -1
  89. package/shortcutContexts/commands/moveCellSelection/inlineStart.js +6 -1
  90. package/shortcutContexts/commands/moveCellSelection/inlineStart.mjs +6 -1
  91. package/shortcutContexts/grid.js +2 -2
  92. package/shortcutContexts/grid.mjs +2 -2
  93. package/shortcuts/context.js +2 -1
  94. package/shortcuts/context.mjs +2 -1
  95. package/tableView.js +20 -0
  96. package/tableView.mjs +20 -0
  97. package/utils/dataStructures/linkedList.js +6 -1
  98. package/utils/dataStructures/linkedList.mjs +6 -1
@@ -9,7 +9,7 @@ var _mixed = require("./../helpers/mixed");
9
9
  var _number = require("./../helpers/number");
10
10
  var _array = require("./../helpers/array");
11
11
  var _localHooks = _interopRequireDefault(require("./../mixins/localHooks"));
12
- var _transformation = _interopRequireDefault(require("./transformation"));
12
+ var _transformation2 = _interopRequireDefault(require("./transformation"));
13
13
  var _utils = require("./utils");
14
14
  var _templateLiteralTag = require("./../helpers/templateLiteralTag");
15
15
  var _a11y = require("../helpers/a11y");
@@ -30,6 +30,9 @@ function _classApplyDescriptorSet(receiver, descriptor, value) { if (descriptor.
30
30
  * @class Selection
31
31
  * @util
32
32
  */
33
+ var _transformation = /*#__PURE__*/new WeakMap();
34
+ var _focusTransformation = /*#__PURE__*/new WeakMap();
35
+ var _isFocusSelectionChanged = /*#__PURE__*/new WeakMap();
33
36
  var _disableHeadersHighlight = /*#__PURE__*/new WeakMap();
34
37
  var _selectionSource = /*#__PURE__*/new WeakMap();
35
38
  var _expectedLayersCount = /*#__PURE__*/new WeakMap();
@@ -69,11 +72,23 @@ class Selection {
69
72
  */
70
73
  _defineProperty(this, "highlight", void 0);
71
74
  /**
72
- * The module for modifying coordinates.
75
+ * The module for modifying coordinates of the start and end selection.
73
76
  *
74
77
  * @type {Transformation}
75
78
  */
76
- _defineProperty(this, "transformation", void 0);
79
+ _classPrivateFieldInitSpec(this, _transformation, {
80
+ writable: true,
81
+ value: void 0
82
+ });
83
+ /**
84
+ * The module for modifying coordinates of the focus selection.
85
+ *
86
+ * @type {Transformation}
87
+ */
88
+ _classPrivateFieldInitSpec(this, _focusTransformation, {
89
+ writable: true,
90
+ value: void 0
91
+ });
77
92
  /**
78
93
  * The collection of the selection layer levels where the whole row was selected using the row header or
79
94
  * the corner header.
@@ -88,6 +103,15 @@ class Selection {
88
103
  * @type {Set<number>}
89
104
  */
90
105
  _defineProperty(this, "selectedByColumnHeader", new Set());
106
+ /**
107
+ * The flag which determines if the focus selection was changed.
108
+ *
109
+ * @type {boolean}
110
+ */
111
+ _classPrivateFieldInitSpec(this, _isFocusSelectionChanged, {
112
+ writable: true,
113
+ value: false
114
+ });
91
115
  /**
92
116
  * When sets disable highlighting the headers even when the logical coordinates points on them.
93
117
  *
@@ -138,71 +162,118 @@ class Selection {
138
162
  createCellCoords: (row, column) => this.tableProps.createCellCoords(row, column),
139
163
  createCellRange: (highlight, from, to) => this.tableProps.createCellRange(highlight, from, to)
140
164
  });
141
- this.transformation = new _transformation.default(this.selectedRange, {
165
+ _classPrivateFieldSet(this, _transformation, new _transformation2.default(this.selectedRange, {
142
166
  rowIndexMapper: this.tableProps.rowIndexMapper,
143
167
  columnIndexMapper: this.tableProps.columnIndexMapper,
144
168
  countRenderableRows: () => this.tableProps.countRenderableRows(),
145
169
  countRenderableColumns: () => this.tableProps.countRenderableColumns(),
146
- countRowHeaders: () => this.tableProps.countRowHeaders(),
147
- countColHeaders: () => this.tableProps.countColHeaders(),
148
170
  visualToRenderableCoords: coords => this.tableProps.visualToRenderableCoords(coords),
149
171
  renderableToVisualCoords: coords => this.tableProps.renderableToVisualCoords(coords),
172
+ findFirstNonHiddenRenderableRow: function () {
173
+ return _this.tableProps.findFirstNonHiddenRenderableRow(...arguments);
174
+ },
175
+ findFirstNonHiddenRenderableColumn: function () {
176
+ return _this.tableProps.findFirstNonHiddenRenderableColumn(...arguments);
177
+ },
150
178
  createCellCoords: (row, column) => this.tableProps.createCellCoords(row, column),
151
- navigableHeaders: () => settings.navigableHeaders,
152
179
  fixedRowsBottom: () => settings.fixedRowsBottom,
153
180
  minSpareRows: () => settings.minSpareRows,
154
181
  minSpareCols: () => settings.minSpareCols,
155
182
  autoWrapRow: () => settings.autoWrapRow,
156
183
  autoWrapCol: () => settings.autoWrapCol
157
- });
158
- this.transformation.addLocalHook('beforeTransformStart', function () {
184
+ }));
185
+ _classPrivateFieldSet(this, _focusTransformation, new _transformation2.default(this.selectedRange, {
186
+ rowIndexMapper: this.tableProps.rowIndexMapper,
187
+ columnIndexMapper: this.tableProps.columnIndexMapper,
188
+ countRenderableRows: () => {
189
+ const range = this.selectedRange.current();
190
+ return this.tableProps.countRenderableRowsInRange(0, range.getOuterBottomEndCorner().row);
191
+ },
192
+ countRenderableColumns: () => {
193
+ const range = this.selectedRange.current();
194
+ return this.tableProps.countRenderableColumnsInRange(0, range.getOuterBottomEndCorner().col);
195
+ },
196
+ visualToRenderableCoords: coords => this.tableProps.visualToRenderableCoords(coords),
197
+ renderableToVisualCoords: coords => this.tableProps.renderableToVisualCoords(coords),
198
+ findFirstNonHiddenRenderableRow: function () {
199
+ return _this.tableProps.findFirstNonHiddenRenderableRow(...arguments);
200
+ },
201
+ findFirstNonHiddenRenderableColumn: function () {
202
+ return _this.tableProps.findFirstNonHiddenRenderableColumn(...arguments);
203
+ },
204
+ createCellCoords: (row, column) => this.tableProps.createCellCoords(row, column),
205
+ fixedRowsBottom: () => 0,
206
+ minSpareRows: () => 0,
207
+ minSpareCols: () => 0,
208
+ autoWrapRow: () => true,
209
+ autoWrapCol: () => true
210
+ }));
211
+ _classPrivateFieldGet(this, _transformation).addLocalHook('beforeTransformStart', function () {
159
212
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
160
213
  args[_key] = arguments[_key];
161
214
  }
162
215
  return _this.runLocalHooks('beforeModifyTransformStart', ...args);
163
216
  });
164
- this.transformation.addLocalHook('afterTransformStart', function () {
217
+ _classPrivateFieldGet(this, _transformation).addLocalHook('afterTransformStart', function () {
165
218
  for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
166
219
  args[_key2] = arguments[_key2];
167
220
  }
168
221
  return _this.runLocalHooks('afterModifyTransformStart', ...args);
169
222
  });
170
- this.transformation.addLocalHook('beforeTransformEnd', function () {
223
+ _classPrivateFieldGet(this, _transformation).addLocalHook('beforeTransformEnd', function () {
171
224
  for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
172
225
  args[_key3] = arguments[_key3];
173
226
  }
174
227
  return _this.runLocalHooks('beforeModifyTransformEnd', ...args);
175
228
  });
176
- this.transformation.addLocalHook('afterTransformEnd', function () {
229
+ _classPrivateFieldGet(this, _transformation).addLocalHook('modifyTransformEndRestDelta', function () {
177
230
  for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
178
231
  args[_key4] = arguments[_key4];
179
232
  }
180
- return _this.runLocalHooks('afterModifyTransformEnd', ...args);
233
+ return _this.runLocalHooks('modifyTransformEndRestDelta', ...args);
181
234
  });
182
- this.transformation.addLocalHook('insertRowRequire', function () {
235
+ _classPrivateFieldGet(this, _transformation).addLocalHook('afterTransformEnd', function () {
183
236
  for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
184
237
  args[_key5] = arguments[_key5];
185
238
  }
186
- return _this.runLocalHooks('insertRowRequire', ...args);
239
+ return _this.runLocalHooks('afterModifyTransformEnd', ...args);
187
240
  });
188
- this.transformation.addLocalHook('insertColRequire', function () {
241
+ _classPrivateFieldGet(this, _transformation).addLocalHook('insertRowRequire', function () {
189
242
  for (var _len6 = arguments.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
190
243
  args[_key6] = arguments[_key6];
191
244
  }
192
- return _this.runLocalHooks('insertColRequire', ...args);
245
+ return _this.runLocalHooks('insertRowRequire', ...args);
193
246
  });
194
- this.transformation.addLocalHook('beforeRowWrap', function () {
247
+ _classPrivateFieldGet(this, _transformation).addLocalHook('insertColRequire', function () {
195
248
  for (var _len7 = arguments.length, args = new Array(_len7), _key7 = 0; _key7 < _len7; _key7++) {
196
249
  args[_key7] = arguments[_key7];
197
250
  }
198
- return _this.runLocalHooks('beforeRowWrap', ...args);
251
+ return _this.runLocalHooks('insertColRequire', ...args);
199
252
  });
200
- this.transformation.addLocalHook('beforeColumnWrap', function () {
253
+ _classPrivateFieldGet(this, _transformation).addLocalHook('beforeRowWrap', function () {
201
254
  for (var _len8 = arguments.length, args = new Array(_len8), _key8 = 0; _key8 < _len8; _key8++) {
202
255
  args[_key8] = arguments[_key8];
203
256
  }
257
+ return _this.runLocalHooks('beforeRowWrap', ...args);
258
+ });
259
+ _classPrivateFieldGet(this, _transformation).addLocalHook('beforeColumnWrap', function () {
260
+ for (var _len9 = arguments.length, args = new Array(_len9), _key9 = 0; _key9 < _len9; _key9++) {
261
+ args[_key9] = arguments[_key9];
262
+ }
204
263
  return _this.runLocalHooks('beforeColumnWrap', ...args);
205
264
  });
265
+ _classPrivateFieldGet(this, _focusTransformation).addLocalHook('beforeTransformStart', function () {
266
+ for (var _len10 = arguments.length, args = new Array(_len10), _key10 = 0; _key10 < _len10; _key10++) {
267
+ args[_key10] = arguments[_key10];
268
+ }
269
+ return _this.runLocalHooks('beforeModifyTransformFocus', ...args);
270
+ });
271
+ _classPrivateFieldGet(this, _focusTransformation).addLocalHook('afterTransformStart', function () {
272
+ for (var _len11 = arguments.length, args = new Array(_len11), _key11 = 0; _key11 < _len11; _key11++) {
273
+ args[_key11] = arguments[_key11];
274
+ }
275
+ return _this.runLocalHooks('afterModifyTransformFocus', ...args);
276
+ });
206
277
  }
207
278
 
208
279
  /**
@@ -293,6 +364,7 @@ class Selection {
293
364
  // We are creating copy. We would like to modify just the start of the selection by below hook. Then original coords
294
365
  // should be handled by next methods.
295
366
  const coordsClone = coords.clone();
367
+ _classPrivateFieldSet(this, _isFocusSelectionChanged, false);
296
368
  this.runLocalHooks(`beforeSetRangeStart${fragment ? 'Only' : ''}`, coordsClone);
297
369
  if (!isMultipleMode || isMultipleMode && !isMultipleSelection && (0, _mixed.isUndefined)(multipleSelection)) {
298
370
  this.selectedRange.clear();
@@ -350,7 +422,20 @@ class Selection {
350
422
  cellRange.setFrom(cellRange.highlight);
351
423
  cellRange.setTo(cellRange.highlight);
352
424
  } else {
425
+ const horizontalDir = cellRange.getHorizontalDirection();
426
+ const verticalDir = cellRange.getVerticalDirection();
427
+ const isMultiple = this.isMultiple();
353
428
  cellRange.setTo(coordsClone);
429
+ if (isMultiple && horizontalDir !== cellRange.getHorizontalDirection()) {
430
+ cellRange.from.assign({
431
+ col: cellRange.highlight.col
432
+ });
433
+ }
434
+ if (isMultiple && verticalDir !== cellRange.getVerticalDirection()) {
435
+ cellRange.from.assign({
436
+ row: cellRange.highlight.row
437
+ });
438
+ }
354
439
  }
355
440
 
356
441
  // Prevent creating "area" selection that overlaps headers.
@@ -360,11 +445,7 @@ class Selection {
360
445
  }
361
446
  }
362
447
  this.runLocalHooks('beforeHighlightSet');
363
- const focusHighlight = this.highlight.getFocus();
364
- focusHighlight.clear();
365
- if (this.highlight.isEnabledFor(_highlight.FOCUS_TYPE, cellRange.highlight)) {
366
- focusHighlight.add(this.selectedRange.current().highlight).commit().syncWith(cellRange);
367
- }
448
+ this.setRangeFocus(this.selectedRange.current().highlight);
368
449
  const layerLevel = this.getLayerLevel();
369
450
 
370
451
  // If the next layer level is lower than previous then clear all area and header highlights. This is the
@@ -452,15 +533,28 @@ class Selection {
452
533
  }
453
534
 
454
535
  /**
455
- * Returns information if we have a multiselection. This method check multiselection only on the latest layer of
456
- * the selection.
536
+ * Sets the selection focus position at the specified coordinates.
457
537
  *
458
- * @returns {boolean}
538
+ * @param {CellCoords} coords The CellCoords instance with defined visual coordinates.
459
539
  */
460
- isMultiple() {
461
- const isMultipleListener = (0, _object.createObjectPropListener)(!this.selectedRange.current().isSingle());
462
- this.runLocalHooks('afterIsMultipleSelection', isMultipleListener);
463
- return isMultipleListener.value;
540
+ setRangeFocus(coords) {
541
+ if (this.selectedRange.isEmpty()) {
542
+ return;
543
+ }
544
+ const cellRange = this.selectedRange.current();
545
+ const focusHighlight = this.highlight.getFocus();
546
+ focusHighlight.clear();
547
+ cellRange.setHighlight(coords);
548
+ if (!this.inProgress) {
549
+ this.runLocalHooks('beforeHighlightSet');
550
+ }
551
+ if (this.highlight.isEnabledFor(_highlight.FOCUS_TYPE, cellRange.highlight)) {
552
+ focusHighlight.add(cellRange.highlight).commit().syncWith(cellRange);
553
+ }
554
+ if (!this.inProgress) {
555
+ _classPrivateFieldSet(this, _isFocusSelectionChanged, true);
556
+ this.runLocalHooks('afterSetFocus', cellRange.highlight);
557
+ }
464
558
  }
465
559
 
466
560
  /**
@@ -473,7 +567,13 @@ class Selection {
473
567
  */
474
568
  transformStart(rowDelta, colDelta) {
475
569
  let createMissingRecords = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
476
- this.setRangeStart(this.transformation.transformStart(rowDelta, colDelta, createMissingRecords));
570
+ if (this.settings.navigableHeaders) {
571
+ _classPrivateFieldGet(this, _transformation).setOffsetSize({
572
+ x: this.tableProps.countRowHeaders(),
573
+ y: this.tableProps.countColHeaders()
574
+ });
575
+ }
576
+ this.setRangeStart(_classPrivateFieldGet(this, _transformation).transformStart(rowDelta, colDelta, createMissingRecords));
477
577
  }
478
578
 
479
579
  /**
@@ -483,7 +583,44 @@ class Selection {
483
583
  * @param {number} colDelta Columns number to move, value can be passed as negative number.
484
584
  */
485
585
  transformEnd(rowDelta, colDelta) {
486
- this.setRangeEnd(this.transformation.transformEnd(rowDelta, colDelta));
586
+ if (this.settings.navigableHeaders) {
587
+ _classPrivateFieldGet(this, _transformation).setOffsetSize({
588
+ x: this.tableProps.countRowHeaders(),
589
+ y: this.tableProps.countColHeaders()
590
+ });
591
+ }
592
+ this.setRangeEnd(_classPrivateFieldGet(this, _transformation).transformEnd(rowDelta, colDelta));
593
+ }
594
+
595
+ /**
596
+ * Transforms the focus cell selection relative to the current focus position.
597
+ *
598
+ * @param {number} rowDelta Rows number to move, value can be passed as negative number.
599
+ * @param {number} colDelta Columns number to move, value can be passed as negative number.
600
+ */
601
+ transformFocus(rowDelta, colDelta) {
602
+ const range = this.selectedRange.current();
603
+ const {
604
+ row,
605
+ col
606
+ } = range.getOuterTopStartCorner();
607
+ const columnsInRange = this.tableProps.countRenderableColumnsInRange(0, col - 1);
608
+ const rowsInRange = this.tableProps.countRenderableRowsInRange(0, row - 1);
609
+ if (range.highlight.isHeader()) {
610
+ // for header focus selection calculate the new coords based on the selection including headers
611
+ _classPrivateFieldGet(this, _focusTransformation).setOffsetSize({
612
+ x: col < 0 ? Math.abs(col) : -columnsInRange,
613
+ y: row < 0 ? Math.abs(row) : -rowsInRange
614
+ });
615
+ } else {
616
+ // for focus selection in cells calculate the new coords only based on the selected cells
617
+ _classPrivateFieldGet(this, _focusTransformation).setOffsetSize({
618
+ x: col < 0 ? 0 : -columnsInRange,
619
+ y: row < 0 ? 0 : -rowsInRange
620
+ });
621
+ }
622
+ const focusCoords = _classPrivateFieldGet(this, _focusTransformation).transformStart(rowDelta, colDelta);
623
+ this.setRangeFocus(focusCoords.normalize());
487
624
  }
488
625
 
489
626
  /**
@@ -504,6 +641,30 @@ class Selection {
504
641
  return !this.selectedRange.isEmpty();
505
642
  }
506
643
 
644
+ /**
645
+ * Returns information if we have a multi-selection. This method check multi-selection only on the latest layer of
646
+ * the selection.
647
+ *
648
+ * @returns {boolean}
649
+ */
650
+ isMultiple() {
651
+ if (!this.isSelected()) {
652
+ return false;
653
+ }
654
+ const isMultipleListener = (0, _object.createObjectPropListener)(!this.selectedRange.current().isSingle());
655
+ this.runLocalHooks('afterIsMultipleSelection', isMultipleListener);
656
+ return isMultipleListener.value;
657
+ }
658
+
659
+ /**
660
+ * Checks if the last selection involves changing the focus cell position only.
661
+ *
662
+ * @returns {boolean}
663
+ */
664
+ isFocusSelectionChanged() {
665
+ return this.isSelected() && _classPrivateFieldGet(this, _isFocusSelectionChanged);
666
+ }
667
+
507
668
  /**
508
669
  * Returns `true` if the selection was applied by clicking to the row header. If the `layerLevel`
509
670
  * argument is passed then only that layer will be checked. Otherwise, it checks if any row header
@@ -786,9 +947,10 @@ class Selection {
786
947
  *
787
948
  * @param {number|string} startColumn Visual column index or column property from which the selection starts.
788
949
  * @param {number|string} [endColumn] Visual column index or column property from to the selection finishes.
789
- * @param {number} [focusPosition=0] The argument allows changing the cell/header focus position.
790
- * The value can take visual row index from -N to N, where negative values
791
- * point to the headers and positive values point to the cell range.
950
+ * @param {number | { row: number, col: number }} [focusPosition=0] The argument allows changing the cell/header focus
951
+ * position. The value can take visual row index from -N to N, where negative values point to the headers and positive
952
+ * values point to the cell range. An object with `row` and `col` properties also can be passed to change the focus
953
+ * position horizontally.
792
954
  * @returns {boolean} Returns `true` if selection was successful, `false` otherwise.
793
955
  */
794
956
  selectColumns(startColumn) {
@@ -809,11 +971,20 @@ class Selection {
809
971
  countColHeaders
810
972
  });
811
973
  if (isValid) {
812
- const fromRow = countColHeaders === 0 ? 0 : (0, _number.clamp)(focusPosition, columnHeaderLastIndex, -1);
974
+ let highlightRow = 0;
975
+ let highlightColumn = 0;
976
+ if (Number.isInteger(focusPosition === null || focusPosition === void 0 ? void 0 : focusPosition.row) && Number.isInteger(focusPosition === null || focusPosition === void 0 ? void 0 : focusPosition.col)) {
977
+ highlightRow = (0, _number.clamp)(focusPosition.row, columnHeaderLastIndex, countRows - 1);
978
+ highlightColumn = (0, _number.clamp)(focusPosition.col, Math.min(start, end), Math.max(start, end));
979
+ } else {
980
+ highlightRow = (0, _number.clamp)(focusPosition, columnHeaderLastIndex, countRows - 1);
981
+ highlightColumn = start;
982
+ }
983
+ const highlight = this.tableProps.createCellCoords(highlightRow, highlightColumn);
984
+ const fromRow = countColHeaders === 0 ? 0 : (0, _number.clamp)(highlight.row, columnHeaderLastIndex, -1);
813
985
  const toRow = countRows - 1;
814
986
  const from = this.tableProps.createCellCoords(fromRow, start);
815
987
  const to = this.tableProps.createCellCoords(toRow, end);
816
- const highlight = this.tableProps.createCellCoords((0, _number.clamp)(focusPosition, columnHeaderLastIndex, countRows - 1), start);
817
988
  this.runLocalHooks('beforeSelectColumns', from, to, highlight);
818
989
 
819
990
  // disallow modifying row axis for that hooks
@@ -833,9 +1004,10 @@ class Selection {
833
1004
  *
834
1005
  * @param {number} startRow Visual row index from which the selection starts.
835
1006
  * @param {number} [endRow] Visual row index from to the selection finishes.
836
- * @param {number} [focusPosition=0] The argument allows changing the cell/header focus position.
837
- * The value can take visual column index from -N to N, where negative values
838
- * point to the headers and positive values point to the cell range.
1007
+ * @param {number | { row: number, col: number }} [focusPosition=0] The argument allows changing the cell/header focus
1008
+ * position. The value can take visual row index from -N to N, where negative values point to the headers and positive
1009
+ * values point to the cell range. An object with `row` and `col` properties also can be passed to change the focus
1010
+ * position horizontally.
839
1011
  * @returns {boolean} Returns `true` if selection was successful, `false` otherwise.
840
1012
  */
841
1013
  selectRows(startRow) {
@@ -854,11 +1026,20 @@ class Selection {
854
1026
  countColHeaders: 0
855
1027
  });
856
1028
  if (isValid) {
857
- const fromColumn = countRowHeaders === 0 ? 0 : (0, _number.clamp)(focusPosition, rowHeaderLastIndex, -1);
1029
+ let highlightRow = 0;
1030
+ let highlightColumn = 0;
1031
+ if (Number.isInteger(focusPosition === null || focusPosition === void 0 ? void 0 : focusPosition.row) && Number.isInteger(focusPosition === null || focusPosition === void 0 ? void 0 : focusPosition.col)) {
1032
+ highlightRow = (0, _number.clamp)(focusPosition.row, Math.min(startRow, endRow), Math.max(startRow, endRow));
1033
+ highlightColumn = (0, _number.clamp)(focusPosition.col, rowHeaderLastIndex, countCols - 1);
1034
+ } else {
1035
+ highlightRow = startRow;
1036
+ highlightColumn = (0, _number.clamp)(focusPosition, rowHeaderLastIndex, countCols - 1);
1037
+ }
1038
+ const highlight = this.tableProps.createCellCoords(highlightRow, highlightColumn);
1039
+ const fromColumn = countRowHeaders === 0 ? 0 : (0, _number.clamp)(highlight.col, rowHeaderLastIndex, -1);
858
1040
  const toColumn = countCols - 1;
859
1041
  const from = this.tableProps.createCellCoords(startRow, fromColumn);
860
1042
  const to = this.tableProps.createCellCoords(endRow, toColumn);
861
- const highlight = this.tableProps.createCellCoords(startRow, (0, _number.clamp)(focusPosition, rowHeaderLastIndex, countCols - 1));
862
1043
  this.runLocalHooks('beforeSelectRows', from, to, highlight);
863
1044
 
864
1045
  // disallow modifying column axis for that hooks