handsontable 0.0.0-next-221e46b-20240307 → 0.0.0-next-2becb78-20240313

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 +81 -21
  12. package/core.mjs +81 -21
  13. package/dist/handsontable.css +2 -2
  14. package/dist/handsontable.full.css +2 -2
  15. package/dist/handsontable.full.js +2721 -1361
  16. package/dist/handsontable.full.min.css +2 -2
  17. package/dist/handsontable.full.min.js +152 -152
  18. package/dist/handsontable.js +2721 -1361
  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 +327 -0
  42. package/plugins/mergeCells/focusOrder.mjs +322 -0
  43. package/plugins/mergeCells/mergeCells.js +392 -197
  44. package/plugins/mergeCells/mergeCells.mjs +392 -197
  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 +8 -5
  52. package/renderers/checkboxRenderer/checkboxRenderer.mjs +8 -5
  53. package/selection/highlight/visualSelection.js +16 -2
  54. package/selection/highlight/visualSelection.mjs +16 -2
  55. package/selection/selection.js +228 -44
  56. package/selection/selection.mjs +227 -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,31 @@ 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
+ if (!this.inProgress) {
546
+ this.runLocalHooks('beforeSetFocus', coords);
547
+ }
548
+ const focusHighlight = this.highlight.getFocus();
549
+ focusHighlight.clear();
550
+ cellRange.setHighlight(coords);
551
+ if (!this.inProgress) {
552
+ this.runLocalHooks('beforeHighlightSet');
553
+ }
554
+ if (this.highlight.isEnabledFor(_highlight.FOCUS_TYPE, cellRange.highlight)) {
555
+ focusHighlight.add(cellRange.highlight).commit().syncWith(cellRange);
556
+ }
557
+ if (!this.inProgress) {
558
+ _classPrivateFieldSet(this, _isFocusSelectionChanged, true);
559
+ this.runLocalHooks('afterSetFocus', cellRange.highlight);
560
+ }
464
561
  }
465
562
 
466
563
  /**
@@ -473,7 +570,13 @@ class Selection {
473
570
  */
474
571
  transformStart(rowDelta, colDelta) {
475
572
  let createMissingRecords = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
476
- this.setRangeStart(this.transformation.transformStart(rowDelta, colDelta, createMissingRecords));
573
+ if (this.settings.navigableHeaders) {
574
+ _classPrivateFieldGet(this, _transformation).setOffsetSize({
575
+ x: this.tableProps.countRowHeaders(),
576
+ y: this.tableProps.countColHeaders()
577
+ });
578
+ }
579
+ this.setRangeStart(_classPrivateFieldGet(this, _transformation).transformStart(rowDelta, colDelta, createMissingRecords));
477
580
  }
478
581
 
479
582
  /**
@@ -483,7 +586,44 @@ class Selection {
483
586
  * @param {number} colDelta Columns number to move, value can be passed as negative number.
484
587
  */
485
588
  transformEnd(rowDelta, colDelta) {
486
- this.setRangeEnd(this.transformation.transformEnd(rowDelta, colDelta));
589
+ if (this.settings.navigableHeaders) {
590
+ _classPrivateFieldGet(this, _transformation).setOffsetSize({
591
+ x: this.tableProps.countRowHeaders(),
592
+ y: this.tableProps.countColHeaders()
593
+ });
594
+ }
595
+ this.setRangeEnd(_classPrivateFieldGet(this, _transformation).transformEnd(rowDelta, colDelta));
596
+ }
597
+
598
+ /**
599
+ * Transforms the focus cell selection relative to the current focus position.
600
+ *
601
+ * @param {number} rowDelta Rows number to move, value can be passed as negative number.
602
+ * @param {number} colDelta Columns number to move, value can be passed as negative number.
603
+ */
604
+ transformFocus(rowDelta, colDelta) {
605
+ const range = this.selectedRange.current();
606
+ const {
607
+ row,
608
+ col
609
+ } = range.getOuterTopStartCorner();
610
+ const columnsInRange = this.tableProps.countRenderableColumnsInRange(0, col - 1);
611
+ const rowsInRange = this.tableProps.countRenderableRowsInRange(0, row - 1);
612
+ if (range.highlight.isHeader()) {
613
+ // for header focus selection calculate the new coords based on the selection including headers
614
+ _classPrivateFieldGet(this, _focusTransformation).setOffsetSize({
615
+ x: col < 0 ? Math.abs(col) : -columnsInRange,
616
+ y: row < 0 ? Math.abs(row) : -rowsInRange
617
+ });
618
+ } else {
619
+ // for focus selection in cells calculate the new coords only based on the selected cells
620
+ _classPrivateFieldGet(this, _focusTransformation).setOffsetSize({
621
+ x: col < 0 ? 0 : -columnsInRange,
622
+ y: row < 0 ? 0 : -rowsInRange
623
+ });
624
+ }
625
+ const focusCoords = _classPrivateFieldGet(this, _focusTransformation).transformStart(rowDelta, colDelta);
626
+ this.setRangeFocus(focusCoords.normalize());
487
627
  }
488
628
 
489
629
  /**
@@ -504,6 +644,30 @@ class Selection {
504
644
  return !this.selectedRange.isEmpty();
505
645
  }
506
646
 
647
+ /**
648
+ * Returns information if we have a multi-selection. This method check multi-selection only on the latest layer of
649
+ * the selection.
650
+ *
651
+ * @returns {boolean}
652
+ */
653
+ isMultiple() {
654
+ if (!this.isSelected()) {
655
+ return false;
656
+ }
657
+ const isMultipleListener = (0, _object.createObjectPropListener)(!this.selectedRange.current().isSingle());
658
+ this.runLocalHooks('afterIsMultipleSelection', isMultipleListener);
659
+ return isMultipleListener.value;
660
+ }
661
+
662
+ /**
663
+ * Checks if the last selection involves changing the focus cell position only.
664
+ *
665
+ * @returns {boolean}
666
+ */
667
+ isFocusSelectionChanged() {
668
+ return this.isSelected() && _classPrivateFieldGet(this, _isFocusSelectionChanged);
669
+ }
670
+
507
671
  /**
508
672
  * Returns `true` if the selection was applied by clicking to the row header. If the `layerLevel`
509
673
  * argument is passed then only that layer will be checked. Otherwise, it checks if any row header
@@ -786,9 +950,10 @@ class Selection {
786
950
  *
787
951
  * @param {number|string} startColumn Visual column index or column property from which the selection starts.
788
952
  * @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.
953
+ * @param {number | { row: number, col: number }} [focusPosition=0] The argument allows changing the cell/header focus
954
+ * position. The value can take visual row index from -N to N, where negative values point to the headers and positive
955
+ * values point to the cell range. An object with `row` and `col` properties also can be passed to change the focus
956
+ * position horizontally.
792
957
  * @returns {boolean} Returns `true` if selection was successful, `false` otherwise.
793
958
  */
794
959
  selectColumns(startColumn) {
@@ -809,11 +974,20 @@ class Selection {
809
974
  countColHeaders
810
975
  });
811
976
  if (isValid) {
812
- const fromRow = countColHeaders === 0 ? 0 : (0, _number.clamp)(focusPosition, columnHeaderLastIndex, -1);
977
+ let highlightRow = 0;
978
+ let highlightColumn = 0;
979
+ if (Number.isInteger(focusPosition === null || focusPosition === void 0 ? void 0 : focusPosition.row) && Number.isInteger(focusPosition === null || focusPosition === void 0 ? void 0 : focusPosition.col)) {
980
+ highlightRow = (0, _number.clamp)(focusPosition.row, columnHeaderLastIndex, countRows - 1);
981
+ highlightColumn = (0, _number.clamp)(focusPosition.col, Math.min(start, end), Math.max(start, end));
982
+ } else {
983
+ highlightRow = (0, _number.clamp)(focusPosition, columnHeaderLastIndex, countRows - 1);
984
+ highlightColumn = start;
985
+ }
986
+ const highlight = this.tableProps.createCellCoords(highlightRow, highlightColumn);
987
+ const fromRow = countColHeaders === 0 ? 0 : (0, _number.clamp)(highlight.row, columnHeaderLastIndex, -1);
813
988
  const toRow = countRows - 1;
814
989
  const from = this.tableProps.createCellCoords(fromRow, start);
815
990
  const to = this.tableProps.createCellCoords(toRow, end);
816
- const highlight = this.tableProps.createCellCoords((0, _number.clamp)(focusPosition, columnHeaderLastIndex, countRows - 1), start);
817
991
  this.runLocalHooks('beforeSelectColumns', from, to, highlight);
818
992
 
819
993
  // disallow modifying row axis for that hooks
@@ -833,9 +1007,10 @@ class Selection {
833
1007
  *
834
1008
  * @param {number} startRow Visual row index from which the selection starts.
835
1009
  * @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.
1010
+ * @param {number | { row: number, col: number }} [focusPosition=0] The argument allows changing the cell/header focus
1011
+ * position. The value can take visual row index from -N to N, where negative values point to the headers and positive
1012
+ * values point to the cell range. An object with `row` and `col` properties also can be passed to change the focus
1013
+ * position horizontally.
839
1014
  * @returns {boolean} Returns `true` if selection was successful, `false` otherwise.
840
1015
  */
841
1016
  selectRows(startRow) {
@@ -854,11 +1029,20 @@ class Selection {
854
1029
  countColHeaders: 0
855
1030
  });
856
1031
  if (isValid) {
857
- const fromColumn = countRowHeaders === 0 ? 0 : (0, _number.clamp)(focusPosition, rowHeaderLastIndex, -1);
1032
+ let highlightRow = 0;
1033
+ let highlightColumn = 0;
1034
+ if (Number.isInteger(focusPosition === null || focusPosition === void 0 ? void 0 : focusPosition.row) && Number.isInteger(focusPosition === null || focusPosition === void 0 ? void 0 : focusPosition.col)) {
1035
+ highlightRow = (0, _number.clamp)(focusPosition.row, Math.min(startRow, endRow), Math.max(startRow, endRow));
1036
+ highlightColumn = (0, _number.clamp)(focusPosition.col, rowHeaderLastIndex, countCols - 1);
1037
+ } else {
1038
+ highlightRow = startRow;
1039
+ highlightColumn = (0, _number.clamp)(focusPosition, rowHeaderLastIndex, countCols - 1);
1040
+ }
1041
+ const highlight = this.tableProps.createCellCoords(highlightRow, highlightColumn);
1042
+ const fromColumn = countRowHeaders === 0 ? 0 : (0, _number.clamp)(highlight.col, rowHeaderLastIndex, -1);
858
1043
  const toColumn = countCols - 1;
859
1044
  const from = this.tableProps.createCellCoords(startRow, fromColumn);
860
1045
  const to = this.tableProps.createCellCoords(endRow, toColumn);
861
- const highlight = this.tableProps.createCellCoords(startRow, (0, _number.clamp)(focusPosition, rowHeaderLastIndex, countCols - 1));
862
1046
  this.runLocalHooks('beforeSelectRows', from, to, highlight);
863
1047
 
864
1048
  // disallow modifying column axis for that hooks