handsontable 0.0.0-next-ba17d71-20240207 → 0.0.0-next-a2cc849-20240208

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 (59) hide show
  1. package/3rdparty/walkontable/src/cell/range.d.ts +1 -0
  2. package/3rdparty/walkontable/src/cell/range.js +12 -0
  3. package/3rdparty/walkontable/src/cell/range.mjs +12 -0
  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.js +14 -0
  11. package/core.mjs +14 -0
  12. package/dist/handsontable.css +2 -2
  13. package/dist/handsontable.full.css +2 -2
  14. package/dist/handsontable.full.js +1304 -1022
  15. package/dist/handsontable.full.min.css +2 -2
  16. package/dist/handsontable.full.min.js +151 -151
  17. package/dist/handsontable.js +1306 -1024
  18. package/dist/handsontable.min.css +2 -2
  19. package/dist/handsontable.min.js +32 -32
  20. package/editorManager.js +12 -8
  21. package/editorManager.mjs +12 -8
  22. package/helpers/mixed.js +1 -1
  23. package/helpers/mixed.mjs +1 -1
  24. package/package.json +1 -1
  25. package/pluginHooks.d.ts +1 -0
  26. package/pluginHooks.js +43 -1
  27. package/pluginHooks.mjs +43 -1
  28. package/plugins/collapsibleColumns/collapsibleColumns.js +7 -1
  29. package/plugins/collapsibleColumns/collapsibleColumns.mjs +7 -1
  30. package/plugins/columnSorting/columnSorting.js +6 -0
  31. package/plugins/columnSorting/columnSorting.mjs +6 -0
  32. package/plugins/contextMenu/menu/defaultShortcutsList.js +26 -10
  33. package/plugins/contextMenu/menu/defaultShortcutsList.mjs +26 -10
  34. package/plugins/mergeCells/mergeCells.js +3 -1
  35. package/plugins/mergeCells/mergeCells.mjs +3 -1
  36. package/plugins/multiColumnSorting/multiColumnSorting.js +6 -0
  37. package/plugins/multiColumnSorting/multiColumnSorting.mjs +6 -0
  38. package/plugins/nestedHeaders/nestedHeaders.js +1 -0
  39. package/plugins/nestedHeaders/nestedHeaders.mjs +1 -0
  40. package/plugins/nestedRows/nestedRows.js +7 -1
  41. package/plugins/nestedRows/nestedRows.mjs +7 -1
  42. package/renderers/checkboxRenderer/checkboxRenderer.js +4 -4
  43. package/renderers/checkboxRenderer/checkboxRenderer.mjs +4 -4
  44. package/selection/selection.js +156 -30
  45. package/selection/selection.mjs +155 -29
  46. package/selection/transformation.js +18 -27
  47. package/selection/transformation.mjs +18 -27
  48. package/shortcutContexts/commands/editor/closeAndSave.js +2 -2
  49. package/shortcutContexts/commands/editor/closeAndSave.mjs +2 -2
  50. package/shortcutContexts/commands/editor/open.js +18 -3
  51. package/shortcutContexts/commands/editor/open.mjs +18 -3
  52. package/shortcutContexts/commands/moveCellSelection/inlineEnd.js +6 -1
  53. package/shortcutContexts/commands/moveCellSelection/inlineEnd.mjs +6 -1
  54. package/shortcutContexts/commands/moveCellSelection/inlineStart.js +6 -1
  55. package/shortcutContexts/commands/moveCellSelection/inlineStart.mjs +6 -1
  56. package/shortcutContexts/grid.js +2 -2
  57. package/shortcutContexts/grid.mjs +2 -2
  58. package/shortcuts/context.js +2 -1
  59. package/shortcuts/context.mjs +2 -1
package/editorManager.js CHANGED
@@ -318,18 +318,22 @@ class EditorManager {
318
318
  }
319
319
 
320
320
  /**
321
- * Controls selection's behaviour after clicking `Enter`.
321
+ * Controls selection's behavior after clicking `Enter`.
322
322
  *
323
323
  * @private
324
- * @param {boolean} isShiftPressed If `true`, then the selection will move up after hit enter.
324
+ * @param {KeyboardEvent} event The keyboard event object.
325
325
  */
326
- moveSelectionAfterEnter(isShiftPressed) {
327
- const enterMoves = typeof this.tableMeta.enterMoves === 'function' ? this.tableMeta.enterMoves(event) : this.tableMeta.enterMoves;
328
- if (isShiftPressed) {
329
- // move selection up
330
- this.selection.transformStart(-enterMoves.row, -enterMoves.col);
326
+ moveSelectionAfterEnter(event) {
327
+ const enterMoves = {
328
+ ...(typeof this.tableMeta.enterMoves === 'function' ? this.tableMeta.enterMoves(event) : this.tableMeta.enterMoves)
329
+ };
330
+ if (event.shiftKey) {
331
+ enterMoves.row = -enterMoves.row;
332
+ enterMoves.col = -enterMoves.col;
333
+ }
334
+ if (this.hot.selection.isMultiple()) {
335
+ this.selection.transformFocus(enterMoves.row, enterMoves.col);
331
336
  } else {
332
- // move selection down (add a new row if needed)
333
337
  this.selection.transformStart(enterMoves.row, enterMoves.col, true);
334
338
  }
335
339
  }
package/editorManager.mjs CHANGED
@@ -314,18 +314,22 @@ class EditorManager {
314
314
  }
315
315
 
316
316
  /**
317
- * Controls selection's behaviour after clicking `Enter`.
317
+ * Controls selection's behavior after clicking `Enter`.
318
318
  *
319
319
  * @private
320
- * @param {boolean} isShiftPressed If `true`, then the selection will move up after hit enter.
320
+ * @param {KeyboardEvent} event The keyboard event object.
321
321
  */
322
- moveSelectionAfterEnter(isShiftPressed) {
323
- const enterMoves = typeof this.tableMeta.enterMoves === 'function' ? this.tableMeta.enterMoves(event) : this.tableMeta.enterMoves;
324
- if (isShiftPressed) {
325
- // move selection up
326
- this.selection.transformStart(-enterMoves.row, -enterMoves.col);
322
+ moveSelectionAfterEnter(event) {
323
+ const enterMoves = {
324
+ ...(typeof this.tableMeta.enterMoves === 'function' ? this.tableMeta.enterMoves(event) : this.tableMeta.enterMoves)
325
+ };
326
+ if (event.shiftKey) {
327
+ enterMoves.row = -enterMoves.row;
328
+ enterMoves.col = -enterMoves.col;
329
+ }
330
+ if (this.hot.selection.isMultiple()) {
331
+ this.selection.transformFocus(enterMoves.row, enterMoves.col);
327
332
  } else {
328
- // move selection down (add a new row if needed)
329
333
  this.selection.transformStart(enterMoves.row, enterMoves.col, true);
330
334
  }
331
335
  }
package/helpers/mixed.js CHANGED
@@ -134,7 +134,7 @@ const domMessages = {
134
134
  function _injectProductInfo(key, element) {
135
135
  const hasValidType = !isEmpty(key);
136
136
  const isNonCommercial = typeof key === 'string' && key.toLowerCase() === 'non-commercial-and-evaluation';
137
- const hotVersion = "0.0.0-next-ba17d71-20240207";
137
+ const hotVersion = "0.0.0-next-a2cc849-20240208";
138
138
  let keyValidityDate;
139
139
  let consoleMessageState = 'invalid';
140
140
  let domMessageState = 'invalid';
package/helpers/mixed.mjs CHANGED
@@ -124,7 +124,7 @@ const domMessages = {
124
124
  export function _injectProductInfo(key, element) {
125
125
  const hasValidType = !isEmpty(key);
126
126
  const isNonCommercial = typeof key === 'string' && key.toLowerCase() === 'non-commercial-and-evaluation';
127
- const hotVersion = "0.0.0-next-ba17d71-20240207";
127
+ const hotVersion = "0.0.0-next-a2cc849-20240208";
128
128
  let keyValidityDate;
129
129
  let consoleMessageState = 'invalid';
130
130
  let domMessageState = 'invalid';
package/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "url": "https://github.com/handsontable/handsontable/issues"
11
11
  },
12
12
  "author": "Handsoncode <hello@handsontable.com>",
13
- "version": "0.0.0-next-ba17d71-20240207",
13
+ "version": "0.0.0-next-a2cc849-20240208",
14
14
  "main": "index",
15
15
  "module": "index.mjs",
16
16
  "jsnext:main": "index.mjs",
package/pluginHooks.d.ts CHANGED
@@ -133,6 +133,7 @@ export interface Events {
133
133
  afterSelectionByProp?: (row: number, prop: string, row2: number, prop2: string, preventScrolling: { value: boolean }, selectionLayerLevel: number) => void;
134
134
  afterSelectionEnd?: (row: number, column: number, row2: number, column2: number, selectionLayerLevel: number) => void;
135
135
  afterSelectionEndByProp?: (row: number, prop: string, row2: number, prop2: string, selectionLayerLevel: number) => void;
136
+ afterSelectionFocusSet?: (row: number, column: number, preventScrolling: { value: boolean }) => void;
136
137
  afterSelectRows?: (from: CellCoords, to: CellCoords, highlight: CellCoords) => void;
137
138
  afterSetCellMeta?: (row: number, column: number, key: string, value: any) => void;
138
139
  afterSetDataAtCell?: (changes: CellChange[], source?: ChangeSource) => void;
package/pluginHooks.js CHANGED
@@ -650,7 +650,9 @@ const REGISTERED_HOOKS = [/* eslint-disable jsdoc/require-description-complete-s
650
650
  * @param {string} prop Selection start data source object property name.
651
651
  * @param {number} row2 Selection end visual row index.
652
652
  * @param {string} prop2 Selection end data source object property name.
653
- * @param {object} preventScrolling Object with `value` property where its value change will be observed.
653
+ * @param {object} preventScrolling A reference to the observable object with the `value` property.
654
+ * Property `preventScrolling.value` expects a boolean value that
655
+ * Handsontable uses to control scroll behavior after selection.
654
656
  * @param {number} selectionLayerLevel The number which indicates what selection layer is currently modified.
655
657
  * @example
656
658
  * ```js
@@ -700,6 +702,46 @@ const REGISTERED_HOOKS = [/* eslint-disable jsdoc/require-description-complete-s
700
702
  * @param {number} selectionLayerLevel The number which indicates what selection layer is currently modified.
701
703
  */
702
704
  'afterSelectionEndByProp',
705
+ /**
706
+ * Fired after the focus position within a selected range is changed.
707
+ *
708
+ * @since 14.2.0
709
+ * @event Hooks#afterSelectionFocusSet
710
+ * @param {number} row The focus visual row index position.
711
+ * @param {number} column The focus visual column index position.
712
+ * @param {object} preventScrolling A reference to the observable object with the `value` property.
713
+ * Property `preventScrolling.value` expects a boolean value that
714
+ * Handsontable uses to control scroll behavior after selection.
715
+ * @example
716
+ * ```js
717
+ * ::: only-for javascript
718
+ * new Handsontable(element, {
719
+ * afterSelectionFocusSet: (row, column, preventScrolling) => {
720
+ * // If set to `false` (default): when focused cell selection is outside the viewport,
721
+ * // Handsontable scrolls the viewport to that cell.
722
+ * // If set to `true`: when focused cell selection is outside the viewport,
723
+ * // Handsontable doesn't scroll the viewport.
724
+ * preventScrolling.value = true;
725
+ * }
726
+ * })
727
+ * ```
728
+ * :::
729
+ *
730
+ * ::: only-for react
731
+ * ```jsx
732
+ * <HotTable
733
+ * afterSelectionFocusSet={(row, column, preventScrolling) => {
734
+ * // If set to `false` (default): when focused cell selection is outside the viewport,
735
+ * // Handsontable scrolls the viewport to that cell.
736
+ * // If set to `true`: when focused cell selection is outside the viewport,
737
+ * // Handsontable doesn't scroll the viewport.
738
+ * preventScrolling.value = true;
739
+ * }}
740
+ * />
741
+ * ```
742
+ * :::
743
+ */
744
+ 'afterSelectionFocusSet',
703
745
  /**
704
746
  * Fired before one or more columns are selected (e.g. During mouse header click or {@link Core#selectColumns} API call).
705
747
  *
package/pluginHooks.mjs CHANGED
@@ -646,7 +646,9 @@ const REGISTERED_HOOKS = [/* eslint-disable jsdoc/require-description-complete-s
646
646
  * @param {string} prop Selection start data source object property name.
647
647
  * @param {number} row2 Selection end visual row index.
648
648
  * @param {string} prop2 Selection end data source object property name.
649
- * @param {object} preventScrolling Object with `value` property where its value change will be observed.
649
+ * @param {object} preventScrolling A reference to the observable object with the `value` property.
650
+ * Property `preventScrolling.value` expects a boolean value that
651
+ * Handsontable uses to control scroll behavior after selection.
650
652
  * @param {number} selectionLayerLevel The number which indicates what selection layer is currently modified.
651
653
  * @example
652
654
  * ```js
@@ -696,6 +698,46 @@ const REGISTERED_HOOKS = [/* eslint-disable jsdoc/require-description-complete-s
696
698
  * @param {number} selectionLayerLevel The number which indicates what selection layer is currently modified.
697
699
  */
698
700
  'afterSelectionEndByProp',
701
+ /**
702
+ * Fired after the focus position within a selected range is changed.
703
+ *
704
+ * @since 14.2.0
705
+ * @event Hooks#afterSelectionFocusSet
706
+ * @param {number} row The focus visual row index position.
707
+ * @param {number} column The focus visual column index position.
708
+ * @param {object} preventScrolling A reference to the observable object with the `value` property.
709
+ * Property `preventScrolling.value` expects a boolean value that
710
+ * Handsontable uses to control scroll behavior after selection.
711
+ * @example
712
+ * ```js
713
+ * ::: only-for javascript
714
+ * new Handsontable(element, {
715
+ * afterSelectionFocusSet: (row, column, preventScrolling) => {
716
+ * // If set to `false` (default): when focused cell selection is outside the viewport,
717
+ * // Handsontable scrolls the viewport to that cell.
718
+ * // If set to `true`: when focused cell selection is outside the viewport,
719
+ * // Handsontable doesn't scroll the viewport.
720
+ * preventScrolling.value = true;
721
+ * }
722
+ * })
723
+ * ```
724
+ * :::
725
+ *
726
+ * ::: only-for react
727
+ * ```jsx
728
+ * <HotTable
729
+ * afterSelectionFocusSet={(row, column, preventScrolling) => {
730
+ * // If set to `false` (default): when focused cell selection is outside the viewport,
731
+ * // Handsontable scrolls the viewport to that cell.
732
+ * // If set to `true`: when focused cell selection is outside the viewport,
733
+ * // Handsontable doesn't scroll the viewport.
734
+ * preventScrolling.value = true;
735
+ * }}
736
+ * />
737
+ * ```
738
+ * :::
739
+ */
740
+ 'afterSelectionFocusSet',
699
741
  /**
700
742
  * Fired before one or more columns are selected (e.g. During mouse header click or {@link Core#selectColumns} API call).
701
743
  *
@@ -9,6 +9,7 @@ var _number = require("../../helpers/number");
9
9
  var _console = require("../../helpers/console");
10
10
  var _element = require("../../helpers/dom/element");
11
11
  var _event = require("../../helpers/dom/event");
12
+ var _shortcutContexts = require("../../shortcutContexts");
12
13
  var _a11y = require("../../helpers/a11y");
13
14
  function _classPrivateMethodInitSpec(obj, privateSet) { _checkPrivateRedeclaration(obj, privateSet); privateSet.add(obj); }
14
15
  function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); }
@@ -308,12 +309,17 @@ class CollapsibleColumns extends _base.BasePlugin {
308
309
  col: columnIndex
309
310
  });
310
311
  }
312
+
313
+ // prevent default Enter behavior (move to the next row within a selection range)
314
+ return false;
311
315
  },
312
316
  runOnlyIf: () => {
313
317
  var _this$hot$getSelected;
314
318
  return (_this$hot$getSelected = this.hot.getSelectedRangeLast()) === null || _this$hot$getSelected === void 0 ? void 0 : _this$hot$getSelected.highlight.isHeader();
315
319
  },
316
- group: SHORTCUTS_GROUP
320
+ group: SHORTCUTS_GROUP,
321
+ relativeToGroup: _shortcutContexts.EDITOR_EDIT_GROUP,
322
+ position: 'before'
317
323
  });
318
324
  }
319
325
 
@@ -18,6 +18,7 @@ import { rangeEach } from "../../helpers/number.mjs";
18
18
  import { warn } from "../../helpers/console.mjs";
19
19
  import { addClass, hasClass, removeClass, fastInnerText, removeAttribute, setAttribute } from "../../helpers/dom/element.mjs";
20
20
  import { stopImmediatePropagation } from "../../helpers/dom/event.mjs";
21
+ import { EDITOR_EDIT_GROUP as SHORTCUTS_GROUP_EDITOR } from "../../shortcutContexts/index.mjs";
21
22
  import { A11Y_EXPANDED, A11Y_HIDDEN } from "../../helpers/a11y.mjs";
22
23
  export const PLUGIN_KEY = 'collapsibleColumns';
23
24
  export const PLUGIN_PRIORITY = 290;
@@ -305,12 +306,17 @@ export class CollapsibleColumns extends BasePlugin {
305
306
  col: columnIndex
306
307
  });
307
308
  }
309
+
310
+ // prevent default Enter behavior (move to the next row within a selection range)
311
+ return false;
308
312
  },
309
313
  runOnlyIf: () => {
310
314
  var _this$hot$getSelected;
311
315
  return (_this$hot$getSelected = this.hot.getSelectedRangeLast()) === null || _this$hot$getSelected === void 0 ? void 0 : _this$hot$getSelected.highlight.isHeader();
312
316
  },
313
- group: SHORTCUTS_GROUP
317
+ group: SHORTCUTS_GROUP,
318
+ relativeToGroup: SHORTCUTS_GROUP_EDITOR,
319
+ position: 'before'
314
320
  });
315
321
  }
316
322
 
@@ -12,6 +12,7 @@ var _base = require("../base");
12
12
  var _translations = require("../../translations");
13
13
  var _pluginHooks = _interopRequireDefault(require("../../pluginHooks"));
14
14
  var _columnStatesManager = require("./columnStatesManager");
15
+ var _shortcutContexts = require("../../shortcutContexts");
15
16
  var _utils = require("./utils");
16
17
  var _domHelpers = require("./domHelpers");
17
18
  var _rootComparator = require("./rootComparator");
@@ -249,12 +250,17 @@ class ColumnSorting extends _base.BasePlugin {
249
250
  if (highlight.row === -1 && highlight.col >= 0) {
250
251
  this.sort(this.getColumnNextConfig(highlight.col));
251
252
  }
253
+
254
+ // prevent default Enter behavior (move to the next row within a selection range)
255
+ return false;
252
256
  },
253
257
  runOnlyIf: () => {
254
258
  var _this$hot$getSelected;
255
259
  const highlight = (_this$hot$getSelected = this.hot.getSelectedRangeLast()) === null || _this$hot$getSelected === void 0 ? void 0 : _this$hot$getSelected.highlight;
256
260
  return highlight && this.hot.selection.isCellVisible(highlight) && highlight.isHeader();
257
261
  },
262
+ relativeToGroup: _shortcutContexts.EDITOR_EDIT_GROUP,
263
+ position: 'before',
258
264
  group: SHORTCUTS_GROUP
259
265
  });
260
266
  }
@@ -15,6 +15,7 @@ import { BasePlugin } from "../base/index.mjs";
15
15
  import { IndexesSequence, PhysicalIndexToValueMap as IndexToValueMap } from "../../translations/index.mjs";
16
16
  import Hooks from "../../pluginHooks.mjs";
17
17
  import { ColumnStatesManager } from "./columnStatesManager.mjs";
18
+ import { EDITOR_EDIT_GROUP as SHORTCUTS_GROUP_EDITOR } from "../../shortcutContexts/index.mjs";
18
19
  import { HEADER_SPAN_CLASS, getNextSortOrder, areValidSortStates, getHeaderSpanElement, isFirstLevelColumnHeader, wasHeaderClickedProperly } from "./utils.mjs";
19
20
  import { getClassesToRemove, getClassesToAdd } from "./domHelpers.mjs";
20
21
  import { rootComparator } from "./rootComparator.mjs";
@@ -245,12 +246,17 @@ export class ColumnSorting extends BasePlugin {
245
246
  if (highlight.row === -1 && highlight.col >= 0) {
246
247
  this.sort(this.getColumnNextConfig(highlight.col));
247
248
  }
249
+
250
+ // prevent default Enter behavior (move to the next row within a selection range)
251
+ return false;
248
252
  },
249
253
  runOnlyIf: () => {
250
254
  var _this$hot$getSelected;
251
255
  const highlight = (_this$hot$getSelected = this.hot.getSelectedRangeLast()) === null || _this$hot$getSelected === void 0 ? void 0 : _this$hot$getSelected.highlight;
252
256
  return highlight && this.hot.selection.isCellVisible(highlight) && highlight.isHeader();
253
257
  },
258
+ relativeToGroup: SHORTCUTS_GROUP_EDITOR,
259
+ position: 'before',
254
260
  group: SHORTCUTS_GROUP
255
261
  });
256
262
  }
@@ -9,10 +9,26 @@ exports.createDefaultShortcutsList = createDefaultShortcutsList;
9
9
  * @returns {KeyboardShortcut[]}
10
10
  */
11
11
  function createDefaultShortcutsList(menu) {
12
+ const {
13
+ hot,
14
+ hotMenu
15
+ } = menu;
12
16
  return [{
13
- keys: [['Tab'], ['Shift', 'Tab'], ['Control/Meta', 'A']],
14
- forwardToContext: menu.hot.getShortcutManager().getContext('grid'),
17
+ keys: [['Control/Meta', 'A']],
18
+ forwardToContext: hot.getShortcutManager().getContext('grid'),
15
19
  callback: () => menu.close(true)
20
+ }, {
21
+ keys: [['Tab'], ['Shift', 'Tab']],
22
+ callback: (event, keys) => {
23
+ const settings = hot.getSettings();
24
+ const tabMoves = typeof settings.tabMoves === 'function' ? settings.tabMoves(event) : settings.tabMoves;
25
+ if (keys.includes('shift')) {
26
+ hot.selection.transformStart(-tabMoves.row, -tabMoves.col);
27
+ } else {
28
+ hot.selection.transformStart(tabMoves.row, tabMoves.col);
29
+ }
30
+ menu.close(true);
31
+ }
16
32
  }, {
17
33
  keys: [['Escape']],
18
34
  callback: () => menu.close()
@@ -25,7 +41,7 @@ function createDefaultShortcutsList(menu) {
25
41
  }, {
26
42
  keys: [['ArrowRight']],
27
43
  callback: () => {
28
- const selection = menu.hotMenu.getSelectedLast();
44
+ const selection = hotMenu.getSelectedLast();
29
45
  if (selection) {
30
46
  const subMenu = menu.openSubMenu(selection[0]);
31
47
  if (subMenu) {
@@ -36,7 +52,7 @@ function createDefaultShortcutsList(menu) {
36
52
  }, {
37
53
  keys: [['ArrowLeft']],
38
54
  callback: () => {
39
- const selection = menu.hotMenu.getSelectedLast();
55
+ const selection = hotMenu.getSelectedLast();
40
56
  if (selection && menu.isSubMenu()) {
41
57
  menu.close();
42
58
  if (menu.isSubMenu()) {
@@ -53,11 +69,11 @@ function createDefaultShortcutsList(menu) {
53
69
  }, {
54
70
  keys: [['Enter'], ['Space']],
55
71
  callback: event => {
56
- const selection = menu.hotMenu.getSelectedLast();
72
+ const selection = hotMenu.getSelectedLast();
57
73
  if (!selection) {
58
74
  return;
59
75
  }
60
- if (menu.hotMenu.getSourceDataAtRow(selection[0]).submenu) {
76
+ if (hotMenu.getSourceDataAtRow(selection[0]).submenu) {
61
77
  menu.openSubMenu(selection[0]).getNavigator().toFirstItem();
62
78
  } else {
63
79
  menu.executeCommand(event);
@@ -67,9 +83,9 @@ function createDefaultShortcutsList(menu) {
67
83
  }, {
68
84
  keys: [['PageUp']],
69
85
  callback: () => {
70
- const selection = menu.hotMenu.getSelectedLast();
86
+ const selection = hotMenu.getSelectedLast();
71
87
  if (selection) {
72
- menu.hotMenu.selection.transformStart(-menu.hotMenu.countVisibleRows(), 0);
88
+ hotMenu.selection.transformStart(-hotMenu.countVisibleRows(), 0);
73
89
  } else {
74
90
  menu.getNavigator().toFirstItem();
75
91
  }
@@ -77,9 +93,9 @@ function createDefaultShortcutsList(menu) {
77
93
  }, {
78
94
  keys: [['PageDown']],
79
95
  callback: () => {
80
- const selection = menu.hotMenu.getSelectedLast();
96
+ const selection = hotMenu.getSelectedLast();
81
97
  if (selection) {
82
- menu.hotMenu.selection.transformStart(menu.hotMenu.countVisibleRows(), 0);
98
+ hotMenu.selection.transformStart(hotMenu.countVisibleRows(), 0);
83
99
  } else {
84
100
  menu.getNavigator().toLastItem();
85
101
  }
@@ -5,10 +5,26 @@
5
5
  * @returns {KeyboardShortcut[]}
6
6
  */
7
7
  export function createDefaultShortcutsList(menu) {
8
+ const {
9
+ hot,
10
+ hotMenu
11
+ } = menu;
8
12
  return [{
9
- keys: [['Tab'], ['Shift', 'Tab'], ['Control/Meta', 'A']],
10
- forwardToContext: menu.hot.getShortcutManager().getContext('grid'),
13
+ keys: [['Control/Meta', 'A']],
14
+ forwardToContext: hot.getShortcutManager().getContext('grid'),
11
15
  callback: () => menu.close(true)
16
+ }, {
17
+ keys: [['Tab'], ['Shift', 'Tab']],
18
+ callback: (event, keys) => {
19
+ const settings = hot.getSettings();
20
+ const tabMoves = typeof settings.tabMoves === 'function' ? settings.tabMoves(event) : settings.tabMoves;
21
+ if (keys.includes('shift')) {
22
+ hot.selection.transformStart(-tabMoves.row, -tabMoves.col);
23
+ } else {
24
+ hot.selection.transformStart(tabMoves.row, tabMoves.col);
25
+ }
26
+ menu.close(true);
27
+ }
12
28
  }, {
13
29
  keys: [['Escape']],
14
30
  callback: () => menu.close()
@@ -21,7 +37,7 @@ export function createDefaultShortcutsList(menu) {
21
37
  }, {
22
38
  keys: [['ArrowRight']],
23
39
  callback: () => {
24
- const selection = menu.hotMenu.getSelectedLast();
40
+ const selection = hotMenu.getSelectedLast();
25
41
  if (selection) {
26
42
  const subMenu = menu.openSubMenu(selection[0]);
27
43
  if (subMenu) {
@@ -32,7 +48,7 @@ export function createDefaultShortcutsList(menu) {
32
48
  }, {
33
49
  keys: [['ArrowLeft']],
34
50
  callback: () => {
35
- const selection = menu.hotMenu.getSelectedLast();
51
+ const selection = hotMenu.getSelectedLast();
36
52
  if (selection && menu.isSubMenu()) {
37
53
  menu.close();
38
54
  if (menu.isSubMenu()) {
@@ -49,11 +65,11 @@ export function createDefaultShortcutsList(menu) {
49
65
  }, {
50
66
  keys: [['Enter'], ['Space']],
51
67
  callback: event => {
52
- const selection = menu.hotMenu.getSelectedLast();
68
+ const selection = hotMenu.getSelectedLast();
53
69
  if (!selection) {
54
70
  return;
55
71
  }
56
- if (menu.hotMenu.getSourceDataAtRow(selection[0]).submenu) {
72
+ if (hotMenu.getSourceDataAtRow(selection[0]).submenu) {
57
73
  menu.openSubMenu(selection[0]).getNavigator().toFirstItem();
58
74
  } else {
59
75
  menu.executeCommand(event);
@@ -63,9 +79,9 @@ export function createDefaultShortcutsList(menu) {
63
79
  }, {
64
80
  keys: [['PageUp']],
65
81
  callback: () => {
66
- const selection = menu.hotMenu.getSelectedLast();
82
+ const selection = hotMenu.getSelectedLast();
67
83
  if (selection) {
68
- menu.hotMenu.selection.transformStart(-menu.hotMenu.countVisibleRows(), 0);
84
+ hotMenu.selection.transformStart(-hotMenu.countVisibleRows(), 0);
69
85
  } else {
70
86
  menu.getNavigator().toFirstItem();
71
87
  }
@@ -73,9 +89,9 @@ export function createDefaultShortcutsList(menu) {
73
89
  }, {
74
90
  keys: [['PageDown']],
75
91
  callback: () => {
76
- const selection = menu.hotMenu.getSelectedLast();
92
+ const selection = hotMenu.getSelectedLast();
77
93
  if (selection) {
78
- menu.hotMenu.selection.transformStart(menu.hotMenu.countVisibleRows(), 0);
94
+ hotMenu.selection.transformStart(hotMenu.countVisibleRows(), 0);
79
95
  } else {
80
96
  menu.getNavigator().toLastItem();
81
97
  }
@@ -1031,8 +1031,10 @@ function _onAfterIsMultipleSelection2(isMultiple) {
1031
1031
  if (isMultiple) {
1032
1032
  const mergedCells = this.mergedCellsCollection.mergedCells;
1033
1033
  const selectionRange = this.hot.getSelectedRangeLast();
1034
+ const topStartCoords = selectionRange.getTopStartCorner();
1035
+ const bottomEndCoords = selectionRange.getBottomEndCorner();
1034
1036
  for (let group = 0; group < mergedCells.length; group += 1) {
1035
- if (selectionRange.from.row === mergedCells[group].row && selectionRange.from.col === mergedCells[group].col && selectionRange.to.row === mergedCells[group].row + mergedCells[group].rowspan - 1 && selectionRange.to.col === mergedCells[group].col + mergedCells[group].colspan - 1) {
1037
+ if (topStartCoords.row === mergedCells[group].row && topStartCoords.col === mergedCells[group].col && bottomEndCoords.row === mergedCells[group].row + mergedCells[group].rowspan - 1 && bottomEndCoords.col === mergedCells[group].col + mergedCells[group].colspan - 1) {
1036
1038
  return false;
1037
1039
  }
1038
1040
  }
@@ -1026,8 +1026,10 @@ function _onAfterIsMultipleSelection2(isMultiple) {
1026
1026
  if (isMultiple) {
1027
1027
  const mergedCells = this.mergedCellsCollection.mergedCells;
1028
1028
  const selectionRange = this.hot.getSelectedRangeLast();
1029
+ const topStartCoords = selectionRange.getTopStartCorner();
1030
+ const bottomEndCoords = selectionRange.getBottomEndCorner();
1029
1031
  for (let group = 0; group < mergedCells.length; group += 1) {
1030
- if (selectionRange.from.row === mergedCells[group].row && selectionRange.from.col === mergedCells[group].col && selectionRange.to.row === mergedCells[group].row + mergedCells[group].rowspan - 1 && selectionRange.to.col === mergedCells[group].col + mergedCells[group].colspan - 1) {
1032
+ if (topStartCoords.row === mergedCells[group].row && topStartCoords.col === mergedCells[group].col && bottomEndCoords.row === mergedCells[group].row + mergedCells[group].rowspan - 1 && bottomEndCoords.col === mergedCells[group].col + mergedCells[group].colspan - 1) {
1031
1033
  return false;
1032
1034
  }
1033
1035
  }
@@ -9,6 +9,7 @@ var _element = require("../../helpers/dom/element");
9
9
  var _rootComparator = require("./rootComparator");
10
10
  var _utils2 = require("./utils");
11
11
  var _domHelpers = require("./domHelpers");
12
+ var _shortcutContexts = require("../../shortcutContexts");
12
13
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
13
14
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : String(i); }
14
15
  function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
@@ -130,12 +131,17 @@ class MultiColumnSorting extends _columnSorting.ColumnSorting {
130
131
  if (highlight.row === -1 && highlight.col >= 0) {
131
132
  this.sort(this.getNextSortConfig(highlight.col, _columnSorting.APPEND_COLUMN_CONFIG_STRATEGY));
132
133
  }
134
+
135
+ // prevent default Enter behavior (move to the next row within a selection range)
136
+ return false;
133
137
  },
134
138
  runOnlyIf: () => {
135
139
  var _this$hot$getSelected;
136
140
  const highlight = (_this$hot$getSelected = this.hot.getSelectedRangeLast()) === null || _this$hot$getSelected === void 0 ? void 0 : _this$hot$getSelected.highlight;
137
141
  return highlight && this.hot.selection.isCellVisible(highlight) && highlight.isHeader();
138
142
  },
143
+ relativeToGroup: _shortcutContexts.EDITOR_EDIT_GROUP,
144
+ position: 'before',
139
145
  group: SHORTCUTS_GROUP
140
146
  });
141
147
  }
@@ -9,6 +9,7 @@ import { addClass, removeClass } from "../../helpers/dom/element.mjs";
9
9
  import { rootComparator } from "./rootComparator.mjs";
10
10
  import { warnAboutPluginsConflict } from "./utils.mjs";
11
11
  import { getClassesToAdd, getClassesToRemove } from "./domHelpers.mjs";
12
+ import { EDITOR_EDIT_GROUP as SHORTCUTS_GROUP_EDITOR } from "../../shortcutContexts/index.mjs";
12
13
  export const PLUGIN_KEY = 'multiColumnSorting';
13
14
  export const PLUGIN_PRIORITY = 170;
14
15
  const CONFLICTED_PLUGIN_KEY = 'columnSorting';
@@ -127,12 +128,17 @@ export class MultiColumnSorting extends ColumnSorting {
127
128
  if (highlight.row === -1 && highlight.col >= 0) {
128
129
  this.sort(this.getNextSortConfig(highlight.col, APPEND_COLUMN_CONFIG_STRATEGY));
129
130
  }
131
+
132
+ // prevent default Enter behavior (move to the next row within a selection range)
133
+ return false;
130
134
  },
131
135
  runOnlyIf: () => {
132
136
  var _this$hot$getSelected;
133
137
  const highlight = (_this$hot$getSelected = this.hot.getSelectedRangeLast()) === null || _this$hot$getSelected === void 0 ? void 0 : _this$hot$getSelected.highlight;
134
138
  return highlight && this.hot.selection.isCellVisible(highlight) && highlight.isHeader();
135
139
  },
140
+ relativeToGroup: SHORTCUTS_GROUP_EDITOR,
141
+ position: 'before',
136
142
  group: SHORTCUTS_GROUP
137
143
  });
138
144
  }
@@ -364,6 +364,7 @@ class NestedHeaders extends _base.BasePlugin {
364
364
  return _classPrivateMethodGet(_this, _onModifyTransformStart, _onModifyTransformStart2).call(_this, ...args);
365
365
  });
366
366
  this.addHook('afterSelection', () => _classPrivateMethodGet(this, _updateFocusHighlightPosition, _updateFocusHighlightPosition2).call(this));
367
+ this.addHook('afterSelectionFocusSet', () => _classPrivateMethodGet(this, _updateFocusHighlightPosition, _updateFocusHighlightPosition2).call(this));
367
368
  this.addHook('beforeViewportScrollHorizontally', function () {
368
369
  for (var _len8 = arguments.length, args = new Array(_len8), _key8 = 0; _key8 < _len8; _key8++) {
369
370
  args[_key8] = arguments[_key8];
@@ -360,6 +360,7 @@ export class NestedHeaders extends BasePlugin {
360
360
  return _classPrivateMethodGet(_this, _onModifyTransformStart, _onModifyTransformStart2).call(_this, ...args);
361
361
  });
362
362
  this.addHook('afterSelection', () => _classPrivateMethodGet(this, _updateFocusHighlightPosition, _updateFocusHighlightPosition2).call(this));
363
+ this.addHook('afterSelectionFocusSet', () => _classPrivateMethodGet(this, _updateFocusHighlightPosition, _updateFocusHighlightPosition2).call(this));
363
364
  this.addHook('beforeViewportScrollHorizontally', function () {
364
365
  for (var _len8 = arguments.length, args = new Array(_len8), _key8 = 0; _key8 < _len8; _key8++) {
365
366
  args[_key8] = arguments[_key8];
@@ -11,6 +11,7 @@ var _contextMenu = _interopRequireDefault(require("./ui/contextMenu"));
11
11
  var _console = require("../../helpers/console");
12
12
  var _data = require("../../helpers/data");
13
13
  var _translations = require("../../translations");
14
+ var _shortcutContexts = require("../../shortcutContexts");
14
15
  var _rowMoveController = _interopRequireDefault(require("./utils/rowMoveController"));
15
16
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16
17
  function _classPrivateMethodInitSpec(obj, privateSet) { _checkPrivateRedeclaration(obj, privateSet); privateSet.add(obj); }
@@ -400,13 +401,18 @@ class NestedRows extends _base.BasePlugin {
400
401
  this.collapsingUI.collapseChildren(row);
401
402
  }
402
403
  }
404
+
405
+ // prevent default Enter behavior (move to the next row within a selection range)
406
+ return false;
403
407
  },
404
408
  runOnlyIf: () => {
405
409
  var _this$hot$getSelected;
406
410
  const highlight = (_this$hot$getSelected = this.hot.getSelectedRangeLast()) === null || _this$hot$getSelected === void 0 ? void 0 : _this$hot$getSelected.highlight;
407
411
  return highlight && this.hot.selection.isCellVisible(highlight) && highlight.isHeader();
408
412
  },
409
- group: SHORTCUTS_GROUP
413
+ group: SHORTCUTS_GROUP,
414
+ relativeToGroup: _shortcutContexts.EDITOR_EDIT_GROUP,
415
+ position: 'before'
410
416
  });
411
417
  }
412
418