handsontable 0.0.0-next-8dc7078-20240322 → 0.0.0-next-28fc088-20240325
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.
- package/3rdparty/walkontable/src/cell/range.d.ts +2 -1
- package/3rdparty/walkontable/src/cell/range.js +22 -5
- package/3rdparty/walkontable/src/cell/range.mjs +22 -5
- package/base.js +2 -2
- package/base.mjs +2 -2
- package/core/viewportScroll/index.js +4 -1
- package/core/viewportScroll/index.mjs +4 -1
- package/core/viewportScroll/scrollStrategies/focusScroll.js +15 -0
- package/core/viewportScroll/scrollStrategies/focusScroll.mjs +11 -0
- package/core.d.ts +4 -3
- package/core.js +76 -21
- package/core.mjs +76 -21
- package/dist/handsontable.css +2 -2
- package/dist/handsontable.full.css +2 -2
- package/dist/handsontable.full.js +2649 -1389
- package/dist/handsontable.full.min.css +2 -2
- package/dist/handsontable.full.min.js +71 -71
- package/dist/handsontable.js +2653 -1393
- package/dist/handsontable.min.css +2 -2
- package/dist/handsontable.min.js +19 -19
- package/editorManager.js +12 -8
- package/editorManager.mjs +12 -8
- package/focusManager.js +7 -1
- package/focusManager.mjs +7 -1
- package/helpers/mixed.js +1 -1
- package/helpers/mixed.mjs +1 -1
- package/package.json +1 -1
- package/pluginHooks.d.ts +4 -0
- package/pluginHooks.js +98 -37
- package/pluginHooks.mjs +98 -37
- package/plugins/collapsibleColumns/collapsibleColumns.js +9 -3
- package/plugins/collapsibleColumns/collapsibleColumns.mjs +9 -3
- package/plugins/columnSorting/columnSorting.js +8 -2
- package/plugins/columnSorting/columnSorting.mjs +8 -2
- package/plugins/contextMenu/menu/defaultShortcutsList.js +26 -10
- package/plugins/contextMenu/menu/defaultShortcutsList.mjs +26 -10
- package/plugins/mergeCells/calculations/selection.js +1 -70
- package/plugins/mergeCells/calculations/selection.mjs +1 -70
- package/plugins/mergeCells/cellsCollection.js +116 -0
- package/plugins/mergeCells/cellsCollection.mjs +116 -0
- package/plugins/mergeCells/contextMenuItem/toggleMerge.js +11 -1
- package/plugins/mergeCells/contextMenuItem/toggleMerge.mjs +11 -1
- package/plugins/mergeCells/focusOrder.js +305 -0
- package/plugins/mergeCells/focusOrder.mjs +300 -0
- package/plugins/mergeCells/mergeCells.js +336 -192
- package/plugins/mergeCells/mergeCells.mjs +336 -192
- package/plugins/multiColumnSorting/multiColumnSorting.js +8 -2
- package/plugins/multiColumnSorting/multiColumnSorting.mjs +8 -2
- package/plugins/nestedHeaders/nestedHeaders.js +1 -0
- package/plugins/nestedHeaders/nestedHeaders.mjs +1 -0
- package/plugins/nestedRows/nestedRows.js +9 -3
- package/plugins/nestedRows/nestedRows.mjs +9 -3
- package/renderers/checkboxRenderer/checkboxRenderer.js +8 -5
- package/renderers/checkboxRenderer/checkboxRenderer.mjs +8 -5
- package/selection/highlight/visualSelection.js +2 -0
- package/selection/highlight/visualSelection.mjs +2 -0
- package/selection/selection.js +209 -40
- package/selection/selection.mjs +208 -39
- package/selection/transformation.js +83 -32
- package/selection/transformation.mjs +83 -32
- package/shortcutContexts/commands/editor/closeAndSave.js +2 -2
- package/shortcutContexts/commands/editor/closeAndSave.mjs +2 -2
- package/shortcutContexts/commands/editor/open.js +18 -3
- package/shortcutContexts/commands/editor/open.mjs +18 -3
- package/shortcutContexts/commands/extendCellsSelection/down.js +1 -1
- package/shortcutContexts/commands/extendCellsSelection/down.mjs +1 -1
- package/shortcutContexts/commands/extendCellsSelection/left.js +1 -1
- package/shortcutContexts/commands/extendCellsSelection/left.mjs +1 -1
- package/shortcutContexts/commands/extendCellsSelection/right.js +1 -1
- package/shortcutContexts/commands/extendCellsSelection/right.mjs +1 -1
- package/shortcutContexts/commands/extendCellsSelection/toColumns.js +1 -1
- package/shortcutContexts/commands/extendCellsSelection/toColumns.mjs +1 -1
- package/shortcutContexts/commands/extendCellsSelection/toMostBottom.js +3 -1
- package/shortcutContexts/commands/extendCellsSelection/toMostBottom.mjs +3 -1
- package/shortcutContexts/commands/extendCellsSelection/toMostInlineEnd.js +9 -3
- package/shortcutContexts/commands/extendCellsSelection/toMostInlineEnd.mjs +9 -3
- package/shortcutContexts/commands/extendCellsSelection/toMostInlineStart.js +10 -3
- package/shortcutContexts/commands/extendCellsSelection/toMostInlineStart.mjs +10 -3
- package/shortcutContexts/commands/extendCellsSelection/toMostLeft.js +3 -1
- package/shortcutContexts/commands/extendCellsSelection/toMostLeft.mjs +3 -1
- package/shortcutContexts/commands/extendCellsSelection/toMostRight.js +3 -1
- package/shortcutContexts/commands/extendCellsSelection/toMostRight.mjs +3 -1
- package/shortcutContexts/commands/extendCellsSelection/toMostTop.js +3 -1
- package/shortcutContexts/commands/extendCellsSelection/toMostTop.mjs +3 -1
- package/shortcutContexts/commands/extendCellsSelection/toRows.js +1 -1
- package/shortcutContexts/commands/extendCellsSelection/toRows.mjs +1 -1
- package/shortcutContexts/commands/extendCellsSelection/up.js +1 -1
- package/shortcutContexts/commands/extendCellsSelection/up.mjs +1 -1
- package/shortcutContexts/commands/moveCellSelection/inlineEnd.js +6 -1
- package/shortcutContexts/commands/moveCellSelection/inlineEnd.mjs +6 -1
- package/shortcutContexts/commands/moveCellSelection/inlineStart.js +6 -1
- package/shortcutContexts/commands/moveCellSelection/inlineStart.mjs +6 -1
- package/shortcutContexts/grid.js +2 -2
- package/shortcutContexts/grid.mjs +2 -2
- package/shortcuts/context.js +2 -1
- package/shortcuts/context.mjs +2 -1
- package/utils/dataStructures/linkedList.js +6 -1
- package/utils/dataStructures/linkedList.mjs +6 -1
package/selection/selection.mjs
CHANGED
@@ -22,6 +22,9 @@ import { A11Y_SELECTED } from "../helpers/a11y.mjs";
|
|
22
22
|
* @class Selection
|
23
23
|
* @util
|
24
24
|
*/
|
25
|
+
var _transformation = /*#__PURE__*/new WeakMap();
|
26
|
+
var _focusTransformation = /*#__PURE__*/new WeakMap();
|
27
|
+
var _isFocusSelectionChanged = /*#__PURE__*/new WeakMap();
|
25
28
|
var _disableHeadersHighlight = /*#__PURE__*/new WeakMap();
|
26
29
|
var _selectionSource = /*#__PURE__*/new WeakMap();
|
27
30
|
var _expectedLayersCount = /*#__PURE__*/new WeakMap();
|
@@ -61,11 +64,17 @@ class Selection {
|
|
61
64
|
*/
|
62
65
|
_defineProperty(this, "highlight", void 0);
|
63
66
|
/**
|
64
|
-
* The module for modifying coordinates.
|
67
|
+
* The module for modifying coordinates of the start and end selection.
|
65
68
|
*
|
66
69
|
* @type {Transformation}
|
67
70
|
*/
|
68
|
-
|
71
|
+
_classPrivateFieldInitSpec(this, _transformation, void 0);
|
72
|
+
/**
|
73
|
+
* The module for modifying coordinates of the focus selection.
|
74
|
+
*
|
75
|
+
* @type {Transformation}
|
76
|
+
*/
|
77
|
+
_classPrivateFieldInitSpec(this, _focusTransformation, void 0);
|
69
78
|
/**
|
70
79
|
* The collection of the selection layer levels where the whole row was selected using the row header or
|
71
80
|
* the corner header.
|
@@ -80,6 +89,12 @@ class Selection {
|
|
80
89
|
* @type {Set<number>}
|
81
90
|
*/
|
82
91
|
_defineProperty(this, "selectedByColumnHeader", new Set());
|
92
|
+
/**
|
93
|
+
* The flag which determines if the focus selection was changed.
|
94
|
+
*
|
95
|
+
* @type {boolean}
|
96
|
+
*/
|
97
|
+
_classPrivateFieldInitSpec(this, _isFocusSelectionChanged, false);
|
83
98
|
/**
|
84
99
|
* When sets disable highlighting the headers even when the logical coordinates points on them.
|
85
100
|
*
|
@@ -121,71 +136,112 @@ class Selection {
|
|
121
136
|
createCellCoords: (row, column) => this.tableProps.createCellCoords(row, column),
|
122
137
|
createCellRange: (highlight, from, to) => this.tableProps.createCellRange(highlight, from, to)
|
123
138
|
});
|
124
|
-
this
|
139
|
+
_classPrivateFieldSet(_transformation, this, new Transformation(this.selectedRange, {
|
125
140
|
rowIndexMapper: this.tableProps.rowIndexMapper,
|
126
141
|
columnIndexMapper: this.tableProps.columnIndexMapper,
|
127
142
|
countRenderableRows: () => this.tableProps.countRenderableRows(),
|
128
143
|
countRenderableColumns: () => this.tableProps.countRenderableColumns(),
|
129
|
-
countRowHeaders: () => this.tableProps.countRowHeaders(),
|
130
|
-
countColHeaders: () => this.tableProps.countColHeaders(),
|
131
144
|
visualToRenderableCoords: coords => this.tableProps.visualToRenderableCoords(coords),
|
132
145
|
renderableToVisualCoords: coords => this.tableProps.renderableToVisualCoords(coords),
|
146
|
+
findFirstNonHiddenRenderableRow: function () {
|
147
|
+
return _this.tableProps.findFirstNonHiddenRenderableRow(...arguments);
|
148
|
+
},
|
149
|
+
findFirstNonHiddenRenderableColumn: function () {
|
150
|
+
return _this.tableProps.findFirstNonHiddenRenderableColumn(...arguments);
|
151
|
+
},
|
133
152
|
createCellCoords: (row, column) => this.tableProps.createCellCoords(row, column),
|
134
|
-
navigableHeaders: () => settings.navigableHeaders,
|
135
153
|
fixedRowsBottom: () => settings.fixedRowsBottom,
|
136
154
|
minSpareRows: () => settings.minSpareRows,
|
137
155
|
minSpareCols: () => settings.minSpareCols,
|
138
156
|
autoWrapRow: () => settings.autoWrapRow,
|
139
157
|
autoWrapCol: () => settings.autoWrapCol
|
140
|
-
});
|
141
|
-
|
158
|
+
}));
|
159
|
+
_classPrivateFieldSet(_focusTransformation, this, new Transformation(this.selectedRange, {
|
160
|
+
rowIndexMapper: this.tableProps.rowIndexMapper,
|
161
|
+
columnIndexMapper: this.tableProps.columnIndexMapper,
|
162
|
+
countRenderableRows: () => {
|
163
|
+
const range = this.selectedRange.current();
|
164
|
+
return this.tableProps.countRenderableRowsInRange(0, range.getOuterBottomEndCorner().row);
|
165
|
+
},
|
166
|
+
countRenderableColumns: () => {
|
167
|
+
const range = this.selectedRange.current();
|
168
|
+
return this.tableProps.countRenderableColumnsInRange(0, range.getOuterBottomEndCorner().col);
|
169
|
+
},
|
170
|
+
visualToRenderableCoords: coords => this.tableProps.visualToRenderableCoords(coords),
|
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
|
+
},
|
178
|
+
createCellCoords: (row, column) => this.tableProps.createCellCoords(row, column),
|
179
|
+
fixedRowsBottom: () => 0,
|
180
|
+
minSpareRows: () => 0,
|
181
|
+
minSpareCols: () => 0,
|
182
|
+
autoWrapRow: () => true,
|
183
|
+
autoWrapCol: () => true
|
184
|
+
}));
|
185
|
+
_classPrivateFieldGet(_transformation, this).addLocalHook('beforeTransformStart', function () {
|
142
186
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
143
187
|
args[_key] = arguments[_key];
|
144
188
|
}
|
145
189
|
return _this.runLocalHooks('beforeModifyTransformStart', ...args);
|
146
190
|
});
|
147
|
-
this.
|
191
|
+
_classPrivateFieldGet(_transformation, this).addLocalHook('afterTransformStart', function () {
|
148
192
|
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
149
193
|
args[_key2] = arguments[_key2];
|
150
194
|
}
|
151
195
|
return _this.runLocalHooks('afterModifyTransformStart', ...args);
|
152
196
|
});
|
153
|
-
this.
|
197
|
+
_classPrivateFieldGet(_transformation, this).addLocalHook('beforeTransformEnd', function () {
|
154
198
|
for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
|
155
199
|
args[_key3] = arguments[_key3];
|
156
200
|
}
|
157
201
|
return _this.runLocalHooks('beforeModifyTransformEnd', ...args);
|
158
202
|
});
|
159
|
-
this.
|
203
|
+
_classPrivateFieldGet(_transformation, this).addLocalHook('afterTransformEnd', function () {
|
160
204
|
for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
|
161
205
|
args[_key4] = arguments[_key4];
|
162
206
|
}
|
163
207
|
return _this.runLocalHooks('afterModifyTransformEnd', ...args);
|
164
208
|
});
|
165
|
-
this.
|
209
|
+
_classPrivateFieldGet(_transformation, this).addLocalHook('insertRowRequire', function () {
|
166
210
|
for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
|
167
211
|
args[_key5] = arguments[_key5];
|
168
212
|
}
|
169
213
|
return _this.runLocalHooks('insertRowRequire', ...args);
|
170
214
|
});
|
171
|
-
this.
|
215
|
+
_classPrivateFieldGet(_transformation, this).addLocalHook('insertColRequire', function () {
|
172
216
|
for (var _len6 = arguments.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
|
173
217
|
args[_key6] = arguments[_key6];
|
174
218
|
}
|
175
219
|
return _this.runLocalHooks('insertColRequire', ...args);
|
176
220
|
});
|
177
|
-
this.
|
221
|
+
_classPrivateFieldGet(_transformation, this).addLocalHook('beforeRowWrap', function () {
|
178
222
|
for (var _len7 = arguments.length, args = new Array(_len7), _key7 = 0; _key7 < _len7; _key7++) {
|
179
223
|
args[_key7] = arguments[_key7];
|
180
224
|
}
|
181
225
|
return _this.runLocalHooks('beforeRowWrap', ...args);
|
182
226
|
});
|
183
|
-
this.
|
227
|
+
_classPrivateFieldGet(_transformation, this).addLocalHook('beforeColumnWrap', function () {
|
184
228
|
for (var _len8 = arguments.length, args = new Array(_len8), _key8 = 0; _key8 < _len8; _key8++) {
|
185
229
|
args[_key8] = arguments[_key8];
|
186
230
|
}
|
187
231
|
return _this.runLocalHooks('beforeColumnWrap', ...args);
|
188
232
|
});
|
233
|
+
_classPrivateFieldGet(_focusTransformation, this).addLocalHook('beforeTransformStart', function () {
|
234
|
+
for (var _len9 = arguments.length, args = new Array(_len9), _key9 = 0; _key9 < _len9; _key9++) {
|
235
|
+
args[_key9] = arguments[_key9];
|
236
|
+
}
|
237
|
+
return _this.runLocalHooks('beforeModifyTransformFocus', ...args);
|
238
|
+
});
|
239
|
+
_classPrivateFieldGet(_focusTransformation, this).addLocalHook('afterTransformStart', function () {
|
240
|
+
for (var _len10 = arguments.length, args = new Array(_len10), _key10 = 0; _key10 < _len10; _key10++) {
|
241
|
+
args[_key10] = arguments[_key10];
|
242
|
+
}
|
243
|
+
return _this.runLocalHooks('afterModifyTransformFocus', ...args);
|
244
|
+
});
|
189
245
|
}
|
190
246
|
|
191
247
|
/**
|
@@ -276,6 +332,7 @@ class Selection {
|
|
276
332
|
// We are creating copy. We would like to modify just the start of the selection by below hook. Then original coords
|
277
333
|
// should be handled by next methods.
|
278
334
|
const coordsClone = coords.clone();
|
335
|
+
_classPrivateFieldSet(_isFocusSelectionChanged, this, false);
|
279
336
|
this.runLocalHooks(`beforeSetRangeStart${fragment ? 'Only' : ''}`, coordsClone);
|
280
337
|
if (!isMultipleMode || isMultipleMode && !isMultipleSelection && isUndefined(multipleSelection)) {
|
281
338
|
this.selectedRange.clear();
|
@@ -333,7 +390,20 @@ class Selection {
|
|
333
390
|
cellRange.setFrom(cellRange.highlight);
|
334
391
|
cellRange.setTo(cellRange.highlight);
|
335
392
|
} else {
|
393
|
+
const horizontalDir = cellRange.getHorizontalDirection();
|
394
|
+
const verticalDir = cellRange.getVerticalDirection();
|
395
|
+
const isMultiple = this.isMultiple();
|
336
396
|
cellRange.setTo(coordsClone);
|
397
|
+
if (isMultiple && (horizontalDir !== cellRange.getHorizontalDirection() || cellRange.getWidth() === 1 && !cellRange.includes(cellRange.highlight))) {
|
398
|
+
cellRange.from.assign({
|
399
|
+
col: cellRange.highlight.col
|
400
|
+
});
|
401
|
+
}
|
402
|
+
if (isMultiple && (verticalDir !== cellRange.getVerticalDirection() || cellRange.getHeight() === 1 && !cellRange.includes(cellRange.highlight))) {
|
403
|
+
cellRange.from.assign({
|
404
|
+
row: cellRange.highlight.row
|
405
|
+
});
|
406
|
+
}
|
337
407
|
}
|
338
408
|
|
339
409
|
// Prevent creating "area" selection that overlaps headers.
|
@@ -343,11 +413,7 @@ class Selection {
|
|
343
413
|
}
|
344
414
|
}
|
345
415
|
this.runLocalHooks('beforeHighlightSet');
|
346
|
-
|
347
|
-
focusHighlight.clear();
|
348
|
-
if (this.highlight.isEnabledFor(FOCUS_TYPE, cellRange.highlight)) {
|
349
|
-
focusHighlight.add(this.selectedRange.current().highlight).commit().syncWith(cellRange);
|
350
|
-
}
|
416
|
+
this.setRangeFocus(this.selectedRange.current().highlight);
|
351
417
|
const layerLevel = this.getLayerLevel();
|
352
418
|
|
353
419
|
// If the next layer level is lower than previous then clear all area and header highlights. This is the
|
@@ -435,15 +501,31 @@ class Selection {
|
|
435
501
|
}
|
436
502
|
|
437
503
|
/**
|
438
|
-
*
|
439
|
-
* the selection.
|
504
|
+
* Sets the selection focus position at the specified coordinates.
|
440
505
|
*
|
441
|
-
* @
|
506
|
+
* @param {CellCoords} coords The CellCoords instance with defined visual coordinates.
|
442
507
|
*/
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
508
|
+
setRangeFocus(coords) {
|
509
|
+
if (this.selectedRange.isEmpty()) {
|
510
|
+
return;
|
511
|
+
}
|
512
|
+
const cellRange = this.selectedRange.current();
|
513
|
+
if (!this.inProgress) {
|
514
|
+
this.runLocalHooks('beforeSetFocus', coords);
|
515
|
+
}
|
516
|
+
const focusHighlight = this.highlight.getFocus();
|
517
|
+
focusHighlight.clear();
|
518
|
+
cellRange.setHighlight(coords);
|
519
|
+
if (!this.inProgress) {
|
520
|
+
this.runLocalHooks('beforeHighlightSet');
|
521
|
+
}
|
522
|
+
if (this.highlight.isEnabledFor(FOCUS_TYPE, cellRange.highlight)) {
|
523
|
+
focusHighlight.add(cellRange.highlight).commit().syncWith(cellRange);
|
524
|
+
}
|
525
|
+
if (!this.inProgress) {
|
526
|
+
_classPrivateFieldSet(_isFocusSelectionChanged, this, true);
|
527
|
+
this.runLocalHooks('afterSetFocus', cellRange.highlight);
|
528
|
+
}
|
447
529
|
}
|
448
530
|
|
449
531
|
/**
|
@@ -456,7 +538,13 @@ class Selection {
|
|
456
538
|
*/
|
457
539
|
transformStart(rowDelta, colDelta) {
|
458
540
|
let createMissingRecords = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
459
|
-
|
541
|
+
if (this.settings.navigableHeaders) {
|
542
|
+
_classPrivateFieldGet(_transformation, this).setOffsetSize({
|
543
|
+
x: this.tableProps.countRowHeaders(),
|
544
|
+
y: this.tableProps.countColHeaders()
|
545
|
+
});
|
546
|
+
}
|
547
|
+
this.setRangeStart(_classPrivateFieldGet(_transformation, this).transformStart(rowDelta, colDelta, createMissingRecords));
|
460
548
|
}
|
461
549
|
|
462
550
|
/**
|
@@ -466,7 +554,44 @@ class Selection {
|
|
466
554
|
* @param {number} colDelta Columns number to move, value can be passed as negative number.
|
467
555
|
*/
|
468
556
|
transformEnd(rowDelta, colDelta) {
|
469
|
-
|
557
|
+
if (this.settings.navigableHeaders) {
|
558
|
+
_classPrivateFieldGet(_transformation, this).setOffsetSize({
|
559
|
+
x: this.tableProps.countRowHeaders(),
|
560
|
+
y: this.tableProps.countColHeaders()
|
561
|
+
});
|
562
|
+
}
|
563
|
+
this.setRangeEnd(_classPrivateFieldGet(_transformation, this).transformEnd(rowDelta, colDelta));
|
564
|
+
}
|
565
|
+
|
566
|
+
/**
|
567
|
+
* Transforms the focus cell selection relative to the current focus position.
|
568
|
+
*
|
569
|
+
* @param {number} rowDelta Rows number to move, value can be passed as negative number.
|
570
|
+
* @param {number} colDelta Columns number to move, value can be passed as negative number.
|
571
|
+
*/
|
572
|
+
transformFocus(rowDelta, colDelta) {
|
573
|
+
const range = this.selectedRange.current();
|
574
|
+
const {
|
575
|
+
row,
|
576
|
+
col
|
577
|
+
} = range.getOuterTopStartCorner();
|
578
|
+
const columnsInRange = this.tableProps.countRenderableColumnsInRange(0, col - 1);
|
579
|
+
const rowsInRange = this.tableProps.countRenderableRowsInRange(0, row - 1);
|
580
|
+
if (range.highlight.isHeader()) {
|
581
|
+
// for header focus selection calculate the new coords based on the selection including headers
|
582
|
+
_classPrivateFieldGet(_focusTransformation, this).setOffsetSize({
|
583
|
+
x: col < 0 ? Math.abs(col) : -columnsInRange,
|
584
|
+
y: row < 0 ? Math.abs(row) : -rowsInRange
|
585
|
+
});
|
586
|
+
} else {
|
587
|
+
// for focus selection in cells calculate the new coords only based on the selected cells
|
588
|
+
_classPrivateFieldGet(_focusTransformation, this).setOffsetSize({
|
589
|
+
x: col < 0 ? 0 : -columnsInRange,
|
590
|
+
y: row < 0 ? 0 : -rowsInRange
|
591
|
+
});
|
592
|
+
}
|
593
|
+
const focusCoords = _classPrivateFieldGet(_focusTransformation, this).transformStart(rowDelta, colDelta);
|
594
|
+
this.setRangeFocus(focusCoords.normalize());
|
470
595
|
}
|
471
596
|
|
472
597
|
/**
|
@@ -487,6 +612,30 @@ class Selection {
|
|
487
612
|
return !this.selectedRange.isEmpty();
|
488
613
|
}
|
489
614
|
|
615
|
+
/**
|
616
|
+
* Returns information if we have a multi-selection. This method check multi-selection only on the latest layer of
|
617
|
+
* the selection.
|
618
|
+
*
|
619
|
+
* @returns {boolean}
|
620
|
+
*/
|
621
|
+
isMultiple() {
|
622
|
+
if (!this.isSelected()) {
|
623
|
+
return false;
|
624
|
+
}
|
625
|
+
const isMultipleListener = createObjectPropListener(!this.selectedRange.current().isSingle());
|
626
|
+
this.runLocalHooks('afterIsMultipleSelection', isMultipleListener);
|
627
|
+
return isMultipleListener.value;
|
628
|
+
}
|
629
|
+
|
630
|
+
/**
|
631
|
+
* Checks if the last selection involves changing the focus cell position only.
|
632
|
+
*
|
633
|
+
* @returns {boolean}
|
634
|
+
*/
|
635
|
+
isFocusSelectionChanged() {
|
636
|
+
return this.isSelected() && _classPrivateFieldGet(_isFocusSelectionChanged, this);
|
637
|
+
}
|
638
|
+
|
490
639
|
/**
|
491
640
|
* Returns `true` if the selection was applied by clicking to the row header. If the `layerLevel`
|
492
641
|
* argument is passed then only that layer will be checked. Otherwise, it checks if any row header
|
@@ -769,9 +918,10 @@ class Selection {
|
|
769
918
|
*
|
770
919
|
* @param {number|string} startColumn Visual column index or column property from which the selection starts.
|
771
920
|
* @param {number|string} [endColumn] Visual column index or column property from to the selection finishes.
|
772
|
-
* @param {number} [focusPosition=0] The argument allows changing the cell/header focus
|
773
|
-
*
|
774
|
-
*
|
921
|
+
* @param {number | { row: number, col: number }} [focusPosition=0] The argument allows changing the cell/header focus
|
922
|
+
* position. The value can take visual row index from -N to N, where negative values point to the headers and positive
|
923
|
+
* values point to the cell range. An object with `row` and `col` properties also can be passed to change the focus
|
924
|
+
* position horizontally.
|
775
925
|
* @returns {boolean} Returns `true` if selection was successful, `false` otherwise.
|
776
926
|
*/
|
777
927
|
selectColumns(startColumn) {
|
@@ -792,11 +942,20 @@ class Selection {
|
|
792
942
|
countColHeaders
|
793
943
|
});
|
794
944
|
if (isValid) {
|
795
|
-
|
945
|
+
let highlightRow = 0;
|
946
|
+
let highlightColumn = 0;
|
947
|
+
if (Number.isInteger(focusPosition === null || focusPosition === void 0 ? void 0 : focusPosition.row) && Number.isInteger(focusPosition === null || focusPosition === void 0 ? void 0 : focusPosition.col)) {
|
948
|
+
highlightRow = clamp(focusPosition.row, columnHeaderLastIndex, countRows - 1);
|
949
|
+
highlightColumn = clamp(focusPosition.col, Math.min(start, end), Math.max(start, end));
|
950
|
+
} else {
|
951
|
+
highlightRow = clamp(focusPosition, columnHeaderLastIndex, countRows - 1);
|
952
|
+
highlightColumn = start;
|
953
|
+
}
|
954
|
+
const highlight = this.tableProps.createCellCoords(highlightRow, highlightColumn);
|
955
|
+
const fromRow = countColHeaders === 0 ? 0 : clamp(highlight.row, columnHeaderLastIndex, -1);
|
796
956
|
const toRow = countRows - 1;
|
797
957
|
const from = this.tableProps.createCellCoords(fromRow, start);
|
798
958
|
const to = this.tableProps.createCellCoords(toRow, end);
|
799
|
-
const highlight = this.tableProps.createCellCoords(clamp(focusPosition, columnHeaderLastIndex, countRows - 1), start);
|
800
959
|
this.runLocalHooks('beforeSelectColumns', from, to, highlight);
|
801
960
|
|
802
961
|
// disallow modifying row axis for that hooks
|
@@ -816,9 +975,10 @@ class Selection {
|
|
816
975
|
*
|
817
976
|
* @param {number} startRow Visual row index from which the selection starts.
|
818
977
|
* @param {number} [endRow] Visual row index from to the selection finishes.
|
819
|
-
* @param {number} [focusPosition=0] The argument allows changing the cell/header focus
|
820
|
-
*
|
821
|
-
*
|
978
|
+
* @param {number | { row: number, col: number }} [focusPosition=0] The argument allows changing the cell/header focus
|
979
|
+
* position. The value can take visual row index from -N to N, where negative values point to the headers and positive
|
980
|
+
* values point to the cell range. An object with `row` and `col` properties also can be passed to change the focus
|
981
|
+
* position horizontally.
|
822
982
|
* @returns {boolean} Returns `true` if selection was successful, `false` otherwise.
|
823
983
|
*/
|
824
984
|
selectRows(startRow) {
|
@@ -837,11 +997,20 @@ class Selection {
|
|
837
997
|
countColHeaders: 0
|
838
998
|
});
|
839
999
|
if (isValid) {
|
840
|
-
|
1000
|
+
let highlightRow = 0;
|
1001
|
+
let highlightColumn = 0;
|
1002
|
+
if (Number.isInteger(focusPosition === null || focusPosition === void 0 ? void 0 : focusPosition.row) && Number.isInteger(focusPosition === null || focusPosition === void 0 ? void 0 : focusPosition.col)) {
|
1003
|
+
highlightRow = clamp(focusPosition.row, Math.min(startRow, endRow), Math.max(startRow, endRow));
|
1004
|
+
highlightColumn = clamp(focusPosition.col, rowHeaderLastIndex, countCols - 1);
|
1005
|
+
} else {
|
1006
|
+
highlightRow = startRow;
|
1007
|
+
highlightColumn = clamp(focusPosition, rowHeaderLastIndex, countCols - 1);
|
1008
|
+
}
|
1009
|
+
const highlight = this.tableProps.createCellCoords(highlightRow, highlightColumn);
|
1010
|
+
const fromColumn = countRowHeaders === 0 ? 0 : clamp(highlight.col, rowHeaderLastIndex, -1);
|
841
1011
|
const toColumn = countCols - 1;
|
842
1012
|
const from = this.tableProps.createCellCoords(startRow, fromColumn);
|
843
1013
|
const to = this.tableProps.createCellCoords(endRow, toColumn);
|
844
|
-
const highlight = this.tableProps.createCellCoords(startRow, clamp(focusPosition, rowHeaderLastIndex, countCols - 1));
|
845
1014
|
this.runLocalHooks('beforeSelectRows', from, to, highlight);
|
846
1015
|
|
847
1016
|
// disallow modifying column axis for that hooks
|
@@ -33,10 +33,10 @@ var _Transformation_brand = /*#__PURE__*/new WeakSet();
|
|
33
33
|
class Transformation {
|
34
34
|
constructor(range, options) {
|
35
35
|
/**
|
36
|
-
*
|
37
|
-
* is enabled.
|
36
|
+
* Clamps the coords to make sure they points to the cell (or header) in the table range.
|
38
37
|
*
|
39
|
-
* @param {
|
38
|
+
* @param {CellCoords} zeroBasedCoords The coords object to clamp.
|
39
|
+
* @returns {{rowDir: 1|0|-1, colDir: 1|0|-1}}
|
40
40
|
*/
|
41
41
|
_classPrivateMethodInitSpec(this, _Transformation_brand);
|
42
42
|
/**
|
@@ -77,10 +77,6 @@ class Transformation {
|
|
77
77
|
*/
|
78
78
|
transformStart(rowDelta, colDelta) {
|
79
79
|
let createMissingRecords = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
80
|
-
_assertClassBrand(_Transformation_brand, this, _setOffsetSize).call(this, {
|
81
|
-
x: _classPrivateFieldGet(_options, this).navigableHeaders() ? _classPrivateFieldGet(_options, this).countRowHeaders() : 0,
|
82
|
-
y: _classPrivateFieldGet(_options, this).navigableHeaders() ? _classPrivateFieldGet(_options, this).countColHeaders() : 0
|
83
|
-
});
|
84
80
|
const delta = _classPrivateFieldGet(_options, this).createCellCoords(rowDelta, colDelta);
|
85
81
|
let visualCoords = _classPrivateFieldGet(_range, this).current().highlight;
|
86
82
|
const highlightRenderableCoords = _classPrivateFieldGet(_options, this).visualToRenderableCoords(visualCoords);
|
@@ -160,23 +156,46 @@ class Transformation {
|
|
160
156
|
* @returns {CellCoords} Visual coordinates after transformation.
|
161
157
|
*/
|
162
158
|
transformEnd(rowDelta, colDelta) {
|
163
|
-
_assertClassBrand(_Transformation_brand, this, _setOffsetSize).call(this, {
|
164
|
-
x: _classPrivateFieldGet(_options, this).navigableHeaders() ? _classPrivateFieldGet(_options, this).countRowHeaders() : 0,
|
165
|
-
y: _classPrivateFieldGet(_options, this).navigableHeaders() ? _classPrivateFieldGet(_options, this).countColHeaders() : 0
|
166
|
-
});
|
167
159
|
const delta = _classPrivateFieldGet(_options, this).createCellCoords(rowDelta, colDelta);
|
168
160
|
const cellRange = _classPrivateFieldGet(_range, this).current();
|
169
161
|
const highlightRenderableCoords = _classPrivateFieldGet(_options, this).visualToRenderableCoords(cellRange.highlight);
|
162
|
+
const toRow = _assertClassBrand(_Transformation_brand, this, _findFirstNonHiddenZeroBasedRow).call(this, cellRange.to.row, cellRange.from.row);
|
163
|
+
const toColumn = _assertClassBrand(_Transformation_brand, this, _findFirstNonHiddenZeroBasedColumn).call(this, cellRange.to.col, cellRange.from.col);
|
170
164
|
const visualCoords = cellRange.to.clone();
|
171
165
|
let rowTransformDir = 0;
|
172
166
|
let colTransformDir = 0;
|
173
167
|
this.runLocalHooks('beforeTransformEnd', delta);
|
174
|
-
if (highlightRenderableCoords.row !== null && highlightRenderableCoords.col !== null) {
|
168
|
+
if (highlightRenderableCoords.row !== null && highlightRenderableCoords.col !== null && toRow !== null && toColumn !== null) {
|
175
169
|
const {
|
176
|
-
row,
|
177
|
-
col
|
178
|
-
} = _assertClassBrand(_Transformation_brand, this, _visualToZeroBasedCoords).call(this, cellRange.
|
179
|
-
const coords = _classPrivateFieldGet(_options, this).createCellCoords(
|
170
|
+
row: highlightRow,
|
171
|
+
col: highlightColumn
|
172
|
+
} = _assertClassBrand(_Transformation_brand, this, _visualToZeroBasedCoords).call(this, cellRange.highlight);
|
173
|
+
const coords = _classPrivateFieldGet(_options, this).createCellCoords(toRow + delta.row, toColumn + delta.col);
|
174
|
+
const topStartCorner = cellRange.getTopStartCorner();
|
175
|
+
const topEndCorner = cellRange.getTopEndCorner();
|
176
|
+
const bottomEndCorner = cellRange.getBottomEndCorner();
|
177
|
+
const restDelta = {
|
178
|
+
row: coords.row - highlightRow,
|
179
|
+
col: coords.col - highlightColumn
|
180
|
+
};
|
181
|
+
if (delta.col < 0) {
|
182
|
+
if (toColumn >= highlightColumn && coords.col < highlightColumn) {
|
183
|
+
coords.col = _assertClassBrand(_Transformation_brand, this, _findFirstNonHiddenZeroBasedColumn).call(this, topStartCorner.col, topEndCorner.col) + restDelta.col;
|
184
|
+
}
|
185
|
+
} else if (delta.col > 0) {
|
186
|
+
if (toColumn <= highlightColumn && coords.col > highlightColumn) {
|
187
|
+
coords.col = _assertClassBrand(_Transformation_brand, this, _findFirstNonHiddenZeroBasedColumn).call(this, topEndCorner.col, topStartCorner.col) + restDelta.col;
|
188
|
+
}
|
189
|
+
}
|
190
|
+
if (delta.row < 0) {
|
191
|
+
if (toRow >= highlightRow && coords.row < highlightRow) {
|
192
|
+
coords.row = _assertClassBrand(_Transformation_brand, this, _findFirstNonHiddenZeroBasedRow).call(this, topStartCorner.row, bottomEndCorner.row) + restDelta.row;
|
193
|
+
}
|
194
|
+
} else if (delta.row > 0) {
|
195
|
+
if (toRow <= highlightRow && coords.row > highlightRow) {
|
196
|
+
coords.row = _assertClassBrand(_Transformation_brand, this, _findFirstNonHiddenZeroBasedRow).call(this, bottomEndCorner.row, topStartCorner.row) + restDelta.row;
|
197
|
+
}
|
198
|
+
}
|
180
199
|
const {
|
181
200
|
rowDir,
|
182
201
|
colDir
|
@@ -196,23 +215,24 @@ class Transformation {
|
|
196
215
|
this.runLocalHooks('afterTransformEnd', visualCoords, rowTransformDir, colTransformDir);
|
197
216
|
return visualCoords;
|
198
217
|
}
|
218
|
+
|
219
|
+
/**
|
220
|
+
* Sets the additional offset in table size that may occur when the `navigableHeaders` option
|
221
|
+
* is enabled.
|
222
|
+
*
|
223
|
+
* @param {{x: number, y: number}} offset Offset as x and y properties.
|
224
|
+
*/
|
225
|
+
setOffsetSize(_ref) {
|
226
|
+
let {
|
227
|
+
x,
|
228
|
+
y
|
229
|
+
} = _ref;
|
230
|
+
_classPrivateFieldSet(_offset, this, {
|
231
|
+
x,
|
232
|
+
y
|
233
|
+
});
|
234
|
+
}
|
199
235
|
}
|
200
|
-
function _setOffsetSize(_ref) {
|
201
|
-
let {
|
202
|
-
x,
|
203
|
-
y
|
204
|
-
} = _ref;
|
205
|
-
_classPrivateFieldSet(_offset, this, {
|
206
|
-
x,
|
207
|
-
y
|
208
|
-
});
|
209
|
-
}
|
210
|
-
/**
|
211
|
-
* Clamps the coords to make sure they points to the cell (or header) in the table range.
|
212
|
-
*
|
213
|
-
* @param {CellCoords} zeroBasedCoords The coords object to clamp.
|
214
|
-
* @returns {{rowDir: 1|0|-1, colDir: 1|0|-1}}
|
215
|
-
*/
|
216
236
|
function _clampCoords(zeroBasedCoords) {
|
217
237
|
const {
|
218
238
|
width,
|
@@ -251,6 +271,34 @@ function _getTableSize() {
|
|
251
271
|
height: _classPrivateFieldGet(_offset, this).y + _classPrivateFieldGet(_options, this).countRenderableRows()
|
252
272
|
};
|
253
273
|
}
|
274
|
+
/**
|
275
|
+
* Finds the first non-hidden zero-based row in the table range.
|
276
|
+
*
|
277
|
+
* @param {number} visualRowFrom The visual row from which the search should start.
|
278
|
+
* @param {number} visualRowTo The visual row to which the search should end.
|
279
|
+
* @returns {number | null}
|
280
|
+
*/
|
281
|
+
function _findFirstNonHiddenZeroBasedRow(visualRowFrom, visualRowTo) {
|
282
|
+
const row = _classPrivateFieldGet(_options, this).findFirstNonHiddenRenderableRow(visualRowFrom, visualRowTo);
|
283
|
+
if (row === null) {
|
284
|
+
return null;
|
285
|
+
}
|
286
|
+
return _classPrivateFieldGet(_offset, this).y + row;
|
287
|
+
}
|
288
|
+
/**
|
289
|
+
* Finds the first non-hidden zero-based column in the table range.
|
290
|
+
*
|
291
|
+
* @param {number} visualColumnFrom The visual column from which the search should start.
|
292
|
+
* @param {number} visualColumnTo The visual column to which the search should end.
|
293
|
+
* @returns {number | null}
|
294
|
+
*/
|
295
|
+
function _findFirstNonHiddenZeroBasedColumn(visualColumnFrom, visualColumnTo) {
|
296
|
+
const column = _classPrivateFieldGet(_options, this).findFirstNonHiddenRenderableColumn(visualColumnFrom, visualColumnTo);
|
297
|
+
if (column === null) {
|
298
|
+
return null;
|
299
|
+
}
|
300
|
+
return _classPrivateFieldGet(_offset, this).x + column;
|
301
|
+
}
|
254
302
|
/**
|
255
303
|
* Translates the visual coordinates to zero-based ones.
|
256
304
|
*
|
@@ -262,6 +310,9 @@ function _visualToZeroBasedCoords(visualCoords) {
|
|
262
310
|
row,
|
263
311
|
col
|
264
312
|
} = _classPrivateFieldGet(_options, this).visualToRenderableCoords(visualCoords);
|
313
|
+
if (row === null || col === null) {
|
314
|
+
throw new Error('Renderable coords are not visible.');
|
315
|
+
}
|
265
316
|
return _classPrivateFieldGet(_options, this).createCellCoords(_classPrivateFieldGet(_offset, this).y + row, _classPrivateFieldGet(_offset, this).x + col);
|
266
317
|
}
|
267
318
|
/**
|