handsontable 0.0.0-next-49293f5-20240205 → 0.0.0-next-7a416a0-20240206

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


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

Files changed (54) hide show
  1. package/base.js +2 -2
  2. package/base.mjs +2 -2
  3. package/core/viewportScroll/index.js +4 -1
  4. package/core/viewportScroll/index.mjs +4 -1
  5. package/core/viewportScroll/scrollStrategies/focusScroll.js +15 -0
  6. package/core/viewportScroll/scrollStrategies/focusScroll.mjs +11 -0
  7. package/core.js +14 -0
  8. package/core.mjs +14 -0
  9. package/dist/handsontable.css +2 -2
  10. package/dist/handsontable.full.css +2 -2
  11. package/dist/handsontable.full.js +1261 -1010
  12. package/dist/handsontable.full.min.css +2 -2
  13. package/dist/handsontable.full.min.js +48 -48
  14. package/dist/handsontable.js +1263 -1012
  15. package/dist/handsontable.min.css +2 -2
  16. package/dist/handsontable.min.js +32 -32
  17. package/editors/autocompleteEditor/autocompleteEditor.js +1 -1
  18. package/editors/autocompleteEditor/autocompleteEditor.mjs +1 -1
  19. package/helpers/mixed.js +1 -1
  20. package/helpers/mixed.mjs +1 -1
  21. package/package.json +1 -1
  22. package/pluginHooks.d.ts +1 -0
  23. package/pluginHooks.js +43 -1
  24. package/pluginHooks.mjs +43 -1
  25. package/plugins/collapsibleColumns/collapsibleColumns.js +7 -1
  26. package/plugins/collapsibleColumns/collapsibleColumns.mjs +7 -1
  27. package/plugins/columnSorting/columnSorting.js +6 -0
  28. package/plugins/columnSorting/columnSorting.mjs +6 -0
  29. package/plugins/contextMenu/menu/defaultShortcutsList.js +26 -10
  30. package/plugins/contextMenu/menu/defaultShortcutsList.mjs +26 -10
  31. package/plugins/mergeCells/mergeCells.js +3 -1
  32. package/plugins/mergeCells/mergeCells.mjs +3 -1
  33. package/plugins/multiColumnSorting/multiColumnSorting.js +6 -0
  34. package/plugins/multiColumnSorting/multiColumnSorting.mjs +6 -0
  35. package/plugins/nestedHeaders/nestedHeaders.js +1 -0
  36. package/plugins/nestedHeaders/nestedHeaders.mjs +1 -0
  37. package/plugins/nestedRows/nestedRows.js +7 -1
  38. package/plugins/nestedRows/nestedRows.mjs +7 -1
  39. package/renderers/checkboxRenderer/checkboxRenderer.js +4 -4
  40. package/renderers/checkboxRenderer/checkboxRenderer.mjs +4 -4
  41. package/selection/selection.js +144 -30
  42. package/selection/selection.mjs +143 -29
  43. package/selection/transformation.js +18 -27
  44. package/selection/transformation.mjs +18 -27
  45. package/shortcutContexts/commands/editor/open.js +14 -0
  46. package/shortcutContexts/commands/editor/open.mjs +14 -0
  47. package/shortcutContexts/commands/moveCellSelection/inlineEnd.js +5 -1
  48. package/shortcutContexts/commands/moveCellSelection/inlineEnd.mjs +5 -1
  49. package/shortcutContexts/commands/moveCellSelection/inlineStart.js +5 -1
  50. package/shortcutContexts/commands/moveCellSelection/inlineStart.mjs +5 -1
  51. package/shortcutContexts/grid.js +2 -2
  52. package/shortcutContexts/grid.mjs +2 -2
  53. package/shortcuts/context.js +2 -1
  54. package/shortcuts/context.mjs +2 -1
@@ -134,7 +134,9 @@ export function checkboxRenderer(hotInstance, TD, row, col, prop, value, cellPro
134
134
  const shortcutManager = hotInstance.getShortcutManager();
135
135
  const gridContext = shortcutManager.getContext('grid');
136
136
  const config = {
137
- group: SHORTCUTS_GROUP
137
+ group: SHORTCUTS_GROUP,
138
+ relativeToGroup: SHORTCUTS_GROUP_EDITOR,
139
+ position: 'before'
138
140
  };
139
141
  gridContext.addShortcuts([{
140
142
  keys: [['space']],
@@ -154,9 +156,7 @@ export function checkboxRenderer(hotInstance, TD, row, col, prop, value, cellPro
154
156
  callback: () => {
155
157
  changeSelectedCheckboxesState(true);
156
158
  return !areSelectedCheckboxCells(); // False blocks next action associated with the keyboard shortcut.
157
- },
158
- relativeToGroup: SHORTCUTS_GROUP_EDITOR,
159
- position: 'before'
159
+ }
160
160
  }], config);
161
161
  }
162
162
 
@@ -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,100 @@ 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),
150
172
  createCellCoords: (row, column) => this.tableProps.createCellCoords(row, column),
151
- navigableHeaders: () => settings.navigableHeaders,
152
173
  fixedRowsBottom: () => settings.fixedRowsBottom,
153
174
  minSpareRows: () => settings.minSpareRows,
154
175
  minSpareCols: () => settings.minSpareCols,
155
176
  autoWrapRow: () => settings.autoWrapRow,
156
177
  autoWrapCol: () => settings.autoWrapCol
157
- });
158
- this.transformation.addLocalHook('beforeTransformStart', function () {
178
+ }));
179
+ _classPrivateFieldSet(this, _focusTransformation, new _transformation2.default(this.selectedRange, {
180
+ rowIndexMapper: this.tableProps.rowIndexMapper,
181
+ columnIndexMapper: this.tableProps.columnIndexMapper,
182
+ countRenderableRows: () => {
183
+ const range = this.selectedRange.current();
184
+ return this.tableProps.countRenderableRowsInRange(0, range.getOuterBottomEndCorner().row);
185
+ },
186
+ countRenderableColumns: () => {
187
+ const range = this.selectedRange.current();
188
+ return this.tableProps.countRenderableColumnsInRange(0, range.getOuterBottomEndCorner().col);
189
+ },
190
+ visualToRenderableCoords: coords => this.tableProps.visualToRenderableCoords(coords),
191
+ renderableToVisualCoords: coords => this.tableProps.renderableToVisualCoords(coords),
192
+ createCellCoords: (row, column) => this.tableProps.createCellCoords(row, column),
193
+ fixedRowsBottom: () => 0,
194
+ minSpareRows: () => 0,
195
+ minSpareCols: () => 0,
196
+ autoWrapRow: () => true,
197
+ autoWrapCol: () => true
198
+ }));
199
+ _classPrivateFieldGet(this, _transformation).addLocalHook('beforeTransformStart', function () {
159
200
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
160
201
  args[_key] = arguments[_key];
161
202
  }
162
203
  return _this.runLocalHooks('beforeModifyTransformStart', ...args);
163
204
  });
164
- this.transformation.addLocalHook('afterTransformStart', function () {
205
+ _classPrivateFieldGet(this, _transformation).addLocalHook('afterTransformStart', function () {
165
206
  for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
166
207
  args[_key2] = arguments[_key2];
167
208
  }
168
209
  return _this.runLocalHooks('afterModifyTransformStart', ...args);
169
210
  });
170
- this.transformation.addLocalHook('beforeTransformEnd', function () {
211
+ _classPrivateFieldGet(this, _transformation).addLocalHook('beforeTransformEnd', function () {
171
212
  for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
172
213
  args[_key3] = arguments[_key3];
173
214
  }
174
215
  return _this.runLocalHooks('beforeModifyTransformEnd', ...args);
175
216
  });
176
- this.transformation.addLocalHook('afterTransformEnd', function () {
217
+ _classPrivateFieldGet(this, _transformation).addLocalHook('afterTransformEnd', function () {
177
218
  for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
178
219
  args[_key4] = arguments[_key4];
179
220
  }
180
221
  return _this.runLocalHooks('afterModifyTransformEnd', ...args);
181
222
  });
182
- this.transformation.addLocalHook('insertRowRequire', function () {
223
+ _classPrivateFieldGet(this, _transformation).addLocalHook('insertRowRequire', function () {
183
224
  for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
184
225
  args[_key5] = arguments[_key5];
185
226
  }
186
227
  return _this.runLocalHooks('insertRowRequire', ...args);
187
228
  });
188
- this.transformation.addLocalHook('insertColRequire', function () {
229
+ _classPrivateFieldGet(this, _transformation).addLocalHook('insertColRequire', function () {
189
230
  for (var _len6 = arguments.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
190
231
  args[_key6] = arguments[_key6];
191
232
  }
192
233
  return _this.runLocalHooks('insertColRequire', ...args);
193
234
  });
194
- this.transformation.addLocalHook('beforeRowWrap', function () {
235
+ _classPrivateFieldGet(this, _transformation).addLocalHook('beforeRowWrap', function () {
195
236
  for (var _len7 = arguments.length, args = new Array(_len7), _key7 = 0; _key7 < _len7; _key7++) {
196
237
  args[_key7] = arguments[_key7];
197
238
  }
198
239
  return _this.runLocalHooks('beforeRowWrap', ...args);
199
240
  });
200
- this.transformation.addLocalHook('beforeColumnWrap', function () {
241
+ _classPrivateFieldGet(this, _transformation).addLocalHook('beforeColumnWrap', function () {
201
242
  for (var _len8 = arguments.length, args = new Array(_len8), _key8 = 0; _key8 < _len8; _key8++) {
202
243
  args[_key8] = arguments[_key8];
203
244
  }
204
245
  return _this.runLocalHooks('beforeColumnWrap', ...args);
205
246
  });
247
+ _classPrivateFieldGet(this, _focusTransformation).addLocalHook('beforeTransformStart', function () {
248
+ for (var _len9 = arguments.length, args = new Array(_len9), _key9 = 0; _key9 < _len9; _key9++) {
249
+ args[_key9] = arguments[_key9];
250
+ }
251
+ return _this.runLocalHooks('beforeModifyTransformStart', ...args);
252
+ });
253
+ _classPrivateFieldGet(this, _focusTransformation).addLocalHook('afterTransformStart', function () {
254
+ for (var _len10 = arguments.length, args = new Array(_len10), _key10 = 0; _key10 < _len10; _key10++) {
255
+ args[_key10] = arguments[_key10];
256
+ }
257
+ return _this.runLocalHooks('afterModifyTransformStart', ...args);
258
+ });
206
259
  }
207
260
 
208
261
  /**
@@ -293,6 +346,7 @@ class Selection {
293
346
  // We are creating copy. We would like to modify just the start of the selection by below hook. Then original coords
294
347
  // should be handled by next methods.
295
348
  const coordsClone = coords.clone();
349
+ _classPrivateFieldSet(this, _isFocusSelectionChanged, false);
296
350
  this.runLocalHooks(`beforeSetRangeStart${fragment ? 'Only' : ''}`, coordsClone);
297
351
  if (!isMultipleMode || isMultipleMode && !isMultipleSelection && (0, _mixed.isUndefined)(multipleSelection)) {
298
352
  this.selectedRange.clear();
@@ -360,11 +414,7 @@ class Selection {
360
414
  }
361
415
  }
362
416
  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
- }
417
+ this.setRangeFocus(this.selectedRange.current().highlight);
368
418
  const layerLevel = this.getLayerLevel();
369
419
 
370
420
  // If the next layer level is lower than previous then clear all area and header highlights. This is the
@@ -452,15 +502,24 @@ class Selection {
452
502
  }
453
503
 
454
504
  /**
455
- * Returns information if we have a multiselection. This method check multiselection only on the latest layer of
456
- * the selection.
505
+ * Sets the selection focus position at the specified coordinates.
457
506
  *
458
- * @returns {boolean}
507
+ * @param {CellCoords} coords The CellCoords instance with defined visual coordinates.
459
508
  */
460
- isMultiple() {
461
- const isMultipleListener = (0, _object.createObjectPropListener)(!this.selectedRange.current().isSingle());
462
- this.runLocalHooks('afterIsMultipleSelection', isMultipleListener);
463
- return isMultipleListener.value;
509
+ setRangeFocus(coords) {
510
+ if (this.selectedRange.isEmpty()) {
511
+ return;
512
+ }
513
+ const cellRange = this.selectedRange.current();
514
+ const focusHighlight = this.highlight.getFocus();
515
+ focusHighlight.clear();
516
+ if (this.highlight.isEnabledFor(_highlight.FOCUS_TYPE, cellRange.highlight)) {
517
+ focusHighlight.add(coords).commit().syncWith(cellRange);
518
+ }
519
+ if (!this.inProgress) {
520
+ _classPrivateFieldSet(this, _isFocusSelectionChanged, true);
521
+ this.runLocalHooks('afterSetFocus', coords);
522
+ }
464
523
  }
465
524
 
466
525
  /**
@@ -473,7 +532,13 @@ class Selection {
473
532
  */
474
533
  transformStart(rowDelta, colDelta) {
475
534
  let createMissingRecords = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
476
- this.setRangeStart(this.transformation.transformStart(rowDelta, colDelta, createMissingRecords));
535
+ if (this.settings.navigableHeaders) {
536
+ _classPrivateFieldGet(this, _transformation).setOffsetSize({
537
+ x: this.tableProps.countRowHeaders(),
538
+ y: this.tableProps.countColHeaders()
539
+ });
540
+ }
541
+ this.setRangeStart(_classPrivateFieldGet(this, _transformation).transformStart(rowDelta, colDelta, createMissingRecords));
477
542
  }
478
543
 
479
544
  /**
@@ -483,7 +548,32 @@ class Selection {
483
548
  * @param {number} colDelta Columns number to move, value can be passed as negative number.
484
549
  */
485
550
  transformEnd(rowDelta, colDelta) {
486
- this.setRangeEnd(this.transformation.transformEnd(rowDelta, colDelta));
551
+ if (this.settings.navigableHeaders) {
552
+ _classPrivateFieldGet(this, _transformation).setOffsetSize({
553
+ x: this.tableProps.countRowHeaders(),
554
+ y: this.tableProps.countColHeaders()
555
+ });
556
+ }
557
+ this.setRangeEnd(_classPrivateFieldGet(this, _transformation).transformEnd(rowDelta, colDelta));
558
+ }
559
+
560
+ /**
561
+ * Transforms the focus cell selection relative to the current focus position.
562
+ *
563
+ * @param {number} rowDelta Rows number to move, value can be passed as negative number.
564
+ * @param {number} colDelta Columns number to move, value can be passed as negative number.
565
+ */
566
+ transformFocus(rowDelta, colDelta) {
567
+ const range = this.selectedRange.current();
568
+ const {
569
+ row,
570
+ col
571
+ } = range.getOuterTopStartCorner();
572
+ _classPrivateFieldGet(this, _focusTransformation).setOffsetSize({
573
+ x: col < 0 ? Math.abs(col) : -this.tableProps.countRenderableColumnsInRange(0, col - 1),
574
+ y: row < 0 ? Math.abs(row) : -this.tableProps.countRenderableRowsInRange(0, row - 1)
575
+ });
576
+ this.setRangeFocus(_classPrivateFieldGet(this, _focusTransformation).transformStart(rowDelta, colDelta));
487
577
  }
488
578
 
489
579
  /**
@@ -504,6 +594,30 @@ class Selection {
504
594
  return !this.selectedRange.isEmpty();
505
595
  }
506
596
 
597
+ /**
598
+ * Returns information if we have a multi-selection. This method check multi-selection only on the latest layer of
599
+ * the selection.
600
+ *
601
+ * @returns {boolean}
602
+ */
603
+ isMultiple() {
604
+ if (!this.isSelected()) {
605
+ return false;
606
+ }
607
+ const isMultipleListener = (0, _object.createObjectPropListener)(!this.selectedRange.current().isSingle());
608
+ this.runLocalHooks('afterIsMultipleSelection', isMultipleListener);
609
+ return isMultipleListener.value;
610
+ }
611
+
612
+ /**
613
+ * Checks if the last selection involves changing the focus cell position only.
614
+ *
615
+ * @returns {boolean}
616
+ */
617
+ isFocusSelectionChanged() {
618
+ return this.isSelected() && _classPrivateFieldGet(this, _isFocusSelectionChanged);
619
+ }
620
+
507
621
  /**
508
622
  * Returns `true` if the selection was applied by clicking to the row header. If the `layerLevel`
509
623
  * argument is passed then only that layer will be checked. Otherwise, it checks if any row header
@@ -24,6 +24,9 @@ import { A11Y_SELECTED } from "../helpers/a11y.mjs";
24
24
  * @class Selection
25
25
  * @util
26
26
  */
27
+ var _transformation = /*#__PURE__*/new WeakMap();
28
+ var _focusTransformation = /*#__PURE__*/new WeakMap();
29
+ var _isFocusSelectionChanged = /*#__PURE__*/new WeakMap();
27
30
  var _disableHeadersHighlight = /*#__PURE__*/new WeakMap();
28
31
  var _selectionSource = /*#__PURE__*/new WeakMap();
29
32
  var _expectedLayersCount = /*#__PURE__*/new WeakMap();
@@ -63,11 +66,23 @@ class Selection {
63
66
  */
64
67
  _defineProperty(this, "highlight", void 0);
65
68
  /**
66
- * The module for modifying coordinates.
69
+ * The module for modifying coordinates of the start and end selection.
67
70
  *
68
71
  * @type {Transformation}
69
72
  */
70
- _defineProperty(this, "transformation", void 0);
73
+ _classPrivateFieldInitSpec(this, _transformation, {
74
+ writable: true,
75
+ value: void 0
76
+ });
77
+ /**
78
+ * The module for modifying coordinates of the focus selection.
79
+ *
80
+ * @type {Transformation}
81
+ */
82
+ _classPrivateFieldInitSpec(this, _focusTransformation, {
83
+ writable: true,
84
+ value: void 0
85
+ });
71
86
  /**
72
87
  * The collection of the selection layer levels where the whole row was selected using the row header or
73
88
  * the corner header.
@@ -82,6 +97,15 @@ class Selection {
82
97
  * @type {Set<number>}
83
98
  */
84
99
  _defineProperty(this, "selectedByColumnHeader", new Set());
100
+ /**
101
+ * The flag which determines if the focus selection was changed.
102
+ *
103
+ * @type {boolean}
104
+ */
105
+ _classPrivateFieldInitSpec(this, _isFocusSelectionChanged, {
106
+ writable: true,
107
+ value: false
108
+ });
85
109
  /**
86
110
  * When sets disable highlighting the headers even when the logical coordinates points on them.
87
111
  *
@@ -132,71 +156,100 @@ class Selection {
132
156
  createCellCoords: (row, column) => this.tableProps.createCellCoords(row, column),
133
157
  createCellRange: (highlight, from, to) => this.tableProps.createCellRange(highlight, from, to)
134
158
  });
135
- this.transformation = new Transformation(this.selectedRange, {
159
+ _classPrivateFieldSet(this, _transformation, new Transformation(this.selectedRange, {
136
160
  rowIndexMapper: this.tableProps.rowIndexMapper,
137
161
  columnIndexMapper: this.tableProps.columnIndexMapper,
138
162
  countRenderableRows: () => this.tableProps.countRenderableRows(),
139
163
  countRenderableColumns: () => this.tableProps.countRenderableColumns(),
140
- countRowHeaders: () => this.tableProps.countRowHeaders(),
141
- countColHeaders: () => this.tableProps.countColHeaders(),
142
164
  visualToRenderableCoords: coords => this.tableProps.visualToRenderableCoords(coords),
143
165
  renderableToVisualCoords: coords => this.tableProps.renderableToVisualCoords(coords),
144
166
  createCellCoords: (row, column) => this.tableProps.createCellCoords(row, column),
145
- navigableHeaders: () => settings.navigableHeaders,
146
167
  fixedRowsBottom: () => settings.fixedRowsBottom,
147
168
  minSpareRows: () => settings.minSpareRows,
148
169
  minSpareCols: () => settings.minSpareCols,
149
170
  autoWrapRow: () => settings.autoWrapRow,
150
171
  autoWrapCol: () => settings.autoWrapCol
151
- });
152
- this.transformation.addLocalHook('beforeTransformStart', function () {
172
+ }));
173
+ _classPrivateFieldSet(this, _focusTransformation, new Transformation(this.selectedRange, {
174
+ rowIndexMapper: this.tableProps.rowIndexMapper,
175
+ columnIndexMapper: this.tableProps.columnIndexMapper,
176
+ countRenderableRows: () => {
177
+ const range = this.selectedRange.current();
178
+ return this.tableProps.countRenderableRowsInRange(0, range.getOuterBottomEndCorner().row);
179
+ },
180
+ countRenderableColumns: () => {
181
+ const range = this.selectedRange.current();
182
+ return this.tableProps.countRenderableColumnsInRange(0, range.getOuterBottomEndCorner().col);
183
+ },
184
+ visualToRenderableCoords: coords => this.tableProps.visualToRenderableCoords(coords),
185
+ renderableToVisualCoords: coords => this.tableProps.renderableToVisualCoords(coords),
186
+ createCellCoords: (row, column) => this.tableProps.createCellCoords(row, column),
187
+ fixedRowsBottom: () => 0,
188
+ minSpareRows: () => 0,
189
+ minSpareCols: () => 0,
190
+ autoWrapRow: () => true,
191
+ autoWrapCol: () => true
192
+ }));
193
+ _classPrivateFieldGet(this, _transformation).addLocalHook('beforeTransformStart', function () {
153
194
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
154
195
  args[_key] = arguments[_key];
155
196
  }
156
197
  return _this.runLocalHooks('beforeModifyTransformStart', ...args);
157
198
  });
158
- this.transformation.addLocalHook('afterTransformStart', function () {
199
+ _classPrivateFieldGet(this, _transformation).addLocalHook('afterTransformStart', function () {
159
200
  for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
160
201
  args[_key2] = arguments[_key2];
161
202
  }
162
203
  return _this.runLocalHooks('afterModifyTransformStart', ...args);
163
204
  });
164
- this.transformation.addLocalHook('beforeTransformEnd', function () {
205
+ _classPrivateFieldGet(this, _transformation).addLocalHook('beforeTransformEnd', function () {
165
206
  for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
166
207
  args[_key3] = arguments[_key3];
167
208
  }
168
209
  return _this.runLocalHooks('beforeModifyTransformEnd', ...args);
169
210
  });
170
- this.transformation.addLocalHook('afterTransformEnd', function () {
211
+ _classPrivateFieldGet(this, _transformation).addLocalHook('afterTransformEnd', function () {
171
212
  for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
172
213
  args[_key4] = arguments[_key4];
173
214
  }
174
215
  return _this.runLocalHooks('afterModifyTransformEnd', ...args);
175
216
  });
176
- this.transformation.addLocalHook('insertRowRequire', function () {
217
+ _classPrivateFieldGet(this, _transformation).addLocalHook('insertRowRequire', function () {
177
218
  for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
178
219
  args[_key5] = arguments[_key5];
179
220
  }
180
221
  return _this.runLocalHooks('insertRowRequire', ...args);
181
222
  });
182
- this.transformation.addLocalHook('insertColRequire', function () {
223
+ _classPrivateFieldGet(this, _transformation).addLocalHook('insertColRequire', function () {
183
224
  for (var _len6 = arguments.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
184
225
  args[_key6] = arguments[_key6];
185
226
  }
186
227
  return _this.runLocalHooks('insertColRequire', ...args);
187
228
  });
188
- this.transformation.addLocalHook('beforeRowWrap', function () {
229
+ _classPrivateFieldGet(this, _transformation).addLocalHook('beforeRowWrap', function () {
189
230
  for (var _len7 = arguments.length, args = new Array(_len7), _key7 = 0; _key7 < _len7; _key7++) {
190
231
  args[_key7] = arguments[_key7];
191
232
  }
192
233
  return _this.runLocalHooks('beforeRowWrap', ...args);
193
234
  });
194
- this.transformation.addLocalHook('beforeColumnWrap', function () {
235
+ _classPrivateFieldGet(this, _transformation).addLocalHook('beforeColumnWrap', function () {
195
236
  for (var _len8 = arguments.length, args = new Array(_len8), _key8 = 0; _key8 < _len8; _key8++) {
196
237
  args[_key8] = arguments[_key8];
197
238
  }
198
239
  return _this.runLocalHooks('beforeColumnWrap', ...args);
199
240
  });
241
+ _classPrivateFieldGet(this, _focusTransformation).addLocalHook('beforeTransformStart', function () {
242
+ for (var _len9 = arguments.length, args = new Array(_len9), _key9 = 0; _key9 < _len9; _key9++) {
243
+ args[_key9] = arguments[_key9];
244
+ }
245
+ return _this.runLocalHooks('beforeModifyTransformStart', ...args);
246
+ });
247
+ _classPrivateFieldGet(this, _focusTransformation).addLocalHook('afterTransformStart', function () {
248
+ for (var _len10 = arguments.length, args = new Array(_len10), _key10 = 0; _key10 < _len10; _key10++) {
249
+ args[_key10] = arguments[_key10];
250
+ }
251
+ return _this.runLocalHooks('afterModifyTransformStart', ...args);
252
+ });
200
253
  }
201
254
 
202
255
  /**
@@ -287,6 +340,7 @@ class Selection {
287
340
  // We are creating copy. We would like to modify just the start of the selection by below hook. Then original coords
288
341
  // should be handled by next methods.
289
342
  const coordsClone = coords.clone();
343
+ _classPrivateFieldSet(this, _isFocusSelectionChanged, false);
290
344
  this.runLocalHooks(`beforeSetRangeStart${fragment ? 'Only' : ''}`, coordsClone);
291
345
  if (!isMultipleMode || isMultipleMode && !isMultipleSelection && isUndefined(multipleSelection)) {
292
346
  this.selectedRange.clear();
@@ -354,11 +408,7 @@ class Selection {
354
408
  }
355
409
  }
356
410
  this.runLocalHooks('beforeHighlightSet');
357
- const focusHighlight = this.highlight.getFocus();
358
- focusHighlight.clear();
359
- if (this.highlight.isEnabledFor(FOCUS_TYPE, cellRange.highlight)) {
360
- focusHighlight.add(this.selectedRange.current().highlight).commit().syncWith(cellRange);
361
- }
411
+ this.setRangeFocus(this.selectedRange.current().highlight);
362
412
  const layerLevel = this.getLayerLevel();
363
413
 
364
414
  // If the next layer level is lower than previous then clear all area and header highlights. This is the
@@ -446,15 +496,24 @@ class Selection {
446
496
  }
447
497
 
448
498
  /**
449
- * Returns information if we have a multiselection. This method check multiselection only on the latest layer of
450
- * the selection.
499
+ * Sets the selection focus position at the specified coordinates.
451
500
  *
452
- * @returns {boolean}
501
+ * @param {CellCoords} coords The CellCoords instance with defined visual coordinates.
453
502
  */
454
- isMultiple() {
455
- const isMultipleListener = createObjectPropListener(!this.selectedRange.current().isSingle());
456
- this.runLocalHooks('afterIsMultipleSelection', isMultipleListener);
457
- return isMultipleListener.value;
503
+ setRangeFocus(coords) {
504
+ if (this.selectedRange.isEmpty()) {
505
+ return;
506
+ }
507
+ const cellRange = this.selectedRange.current();
508
+ const focusHighlight = this.highlight.getFocus();
509
+ focusHighlight.clear();
510
+ if (this.highlight.isEnabledFor(FOCUS_TYPE, cellRange.highlight)) {
511
+ focusHighlight.add(coords).commit().syncWith(cellRange);
512
+ }
513
+ if (!this.inProgress) {
514
+ _classPrivateFieldSet(this, _isFocusSelectionChanged, true);
515
+ this.runLocalHooks('afterSetFocus', coords);
516
+ }
458
517
  }
459
518
 
460
519
  /**
@@ -467,7 +526,13 @@ class Selection {
467
526
  */
468
527
  transformStart(rowDelta, colDelta) {
469
528
  let createMissingRecords = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
470
- this.setRangeStart(this.transformation.transformStart(rowDelta, colDelta, createMissingRecords));
529
+ if (this.settings.navigableHeaders) {
530
+ _classPrivateFieldGet(this, _transformation).setOffsetSize({
531
+ x: this.tableProps.countRowHeaders(),
532
+ y: this.tableProps.countColHeaders()
533
+ });
534
+ }
535
+ this.setRangeStart(_classPrivateFieldGet(this, _transformation).transformStart(rowDelta, colDelta, createMissingRecords));
471
536
  }
472
537
 
473
538
  /**
@@ -477,7 +542,32 @@ class Selection {
477
542
  * @param {number} colDelta Columns number to move, value can be passed as negative number.
478
543
  */
479
544
  transformEnd(rowDelta, colDelta) {
480
- this.setRangeEnd(this.transformation.transformEnd(rowDelta, colDelta));
545
+ if (this.settings.navigableHeaders) {
546
+ _classPrivateFieldGet(this, _transformation).setOffsetSize({
547
+ x: this.tableProps.countRowHeaders(),
548
+ y: this.tableProps.countColHeaders()
549
+ });
550
+ }
551
+ this.setRangeEnd(_classPrivateFieldGet(this, _transformation).transformEnd(rowDelta, colDelta));
552
+ }
553
+
554
+ /**
555
+ * Transforms the focus cell selection relative to the current focus position.
556
+ *
557
+ * @param {number} rowDelta Rows number to move, value can be passed as negative number.
558
+ * @param {number} colDelta Columns number to move, value can be passed as negative number.
559
+ */
560
+ transformFocus(rowDelta, colDelta) {
561
+ const range = this.selectedRange.current();
562
+ const {
563
+ row,
564
+ col
565
+ } = range.getOuterTopStartCorner();
566
+ _classPrivateFieldGet(this, _focusTransformation).setOffsetSize({
567
+ x: col < 0 ? Math.abs(col) : -this.tableProps.countRenderableColumnsInRange(0, col - 1),
568
+ y: row < 0 ? Math.abs(row) : -this.tableProps.countRenderableRowsInRange(0, row - 1)
569
+ });
570
+ this.setRangeFocus(_classPrivateFieldGet(this, _focusTransformation).transformStart(rowDelta, colDelta));
481
571
  }
482
572
 
483
573
  /**
@@ -498,6 +588,30 @@ class Selection {
498
588
  return !this.selectedRange.isEmpty();
499
589
  }
500
590
 
591
+ /**
592
+ * Returns information if we have a multi-selection. This method check multi-selection only on the latest layer of
593
+ * the selection.
594
+ *
595
+ * @returns {boolean}
596
+ */
597
+ isMultiple() {
598
+ if (!this.isSelected()) {
599
+ return false;
600
+ }
601
+ const isMultipleListener = createObjectPropListener(!this.selectedRange.current().isSingle());
602
+ this.runLocalHooks('afterIsMultipleSelection', isMultipleListener);
603
+ return isMultipleListener.value;
604
+ }
605
+
606
+ /**
607
+ * Checks if the last selection involves changing the focus cell position only.
608
+ *
609
+ * @returns {boolean}
610
+ */
611
+ isFocusSelectionChanged() {
612
+ return this.isSelected() && _classPrivateFieldGet(this, _isFocusSelectionChanged);
613
+ }
614
+
501
615
  /**
502
616
  * Returns `true` if the selection was applied by clicking to the row header. If the `layerLevel`
503
617
  * argument is passed then only that layer will be checked. Otherwise, it checks if any row header