handsontable 0.0.0-next-f86a877-20250819 → 0.0.0-next-fce5825-20250822

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (73) hide show
  1. package/base.js +2 -2
  2. package/base.mjs +2 -2
  3. package/core/focusCatcher/index.js +37 -20
  4. package/core/focusCatcher/index.mjs +37 -20
  5. package/core/focusCatcher/utils.js +3 -64
  6. package/core/focusCatcher/utils.mjs +1 -60
  7. package/core/hooks/constants.js +58 -0
  8. package/core/hooks/constants.mjs +58 -0
  9. package/core/hooks/index.d.ts +7 -0
  10. package/core.js +13 -4
  11. package/core.mjs +13 -4
  12. package/dataMap/metaManager/metaSchema.js +95 -0
  13. package/dataMap/metaManager/metaSchema.mjs +95 -0
  14. package/dist/handsontable.css +103 -5
  15. package/dist/handsontable.full.css +103 -5
  16. package/dist/handsontable.full.js +1600 -282
  17. package/dist/handsontable.full.min.css +3 -3
  18. package/dist/handsontable.full.min.js +65 -65
  19. package/dist/handsontable.js +1600 -282
  20. package/dist/handsontable.min.css +3 -3
  21. package/dist/handsontable.min.js +27 -27
  22. package/editors/baseEditor/baseEditor.js +1 -0
  23. package/editors/baseEditor/baseEditor.mjs +1 -0
  24. package/helpers/a11y.js +5 -1
  25. package/helpers/a11y.mjs +3 -1
  26. package/helpers/mixed.js +64 -1
  27. package/helpers/mixed.mjs +62 -1
  28. package/index.d.ts +9 -0
  29. package/package.json +6 -1
  30. package/plugins/base/base.js +75 -14
  31. package/plugins/base/base.mjs +75 -14
  32. package/plugins/contextMenu/contextMenu.js +1 -0
  33. package/plugins/contextMenu/contextMenu.mjs +1 -0
  34. package/plugins/dialog/dialog.d.ts +23 -0
  35. package/plugins/dialog/dialog.js +469 -0
  36. package/plugins/dialog/dialog.mjs +465 -0
  37. package/plugins/dialog/index.d.ts +1 -0
  38. package/plugins/dialog/index.js +7 -0
  39. package/plugins/dialog/index.mjs +1 -0
  40. package/plugins/dialog/ui.js +240 -0
  41. package/plugins/dialog/ui.mjs +235 -0
  42. package/plugins/dropdownMenu/dropdownMenu.js +1 -0
  43. package/plugins/dropdownMenu/dropdownMenu.mjs +1 -0
  44. package/plugins/index.d.ts +3 -0
  45. package/plugins/index.js +3 -0
  46. package/plugins/index.mjs +3 -1
  47. package/plugins/pagination/focusController.js +27 -0
  48. package/plugins/pagination/focusController.mjs +23 -0
  49. package/plugins/pagination/pagination.js +165 -18
  50. package/plugins/pagination/pagination.mjs +165 -18
  51. package/plugins/pagination/ui.js +101 -62
  52. package/plugins/pagination/ui.mjs +102 -63
  53. package/selection/range.js +11 -0
  54. package/selection/range.mjs +11 -0
  55. package/selection/selection.js +63 -2
  56. package/selection/selection.mjs +63 -2
  57. package/selection/utils.js +2 -1
  58. package/selection/utils.mjs +2 -1
  59. package/settings.d.ts +2 -0
  60. package/shortcuts/context.js +4 -1
  61. package/shortcuts/context.mjs +4 -1
  62. package/shortcuts/manager.js +17 -3
  63. package/shortcuts/manager.mjs +17 -3
  64. package/styles/handsontable.css +106 -22
  65. package/styles/handsontable.min.css +3 -3
  66. package/styles/ht-theme-horizon.css +24 -6
  67. package/styles/ht-theme-horizon.min.css +3 -3
  68. package/styles/ht-theme-main.css +52 -34
  69. package/styles/ht-theme-main.min.css +3 -3
  70. package/tableView.js +7 -2
  71. package/tableView.mjs +7 -2
  72. package/{core/focusCatcher → utils}/focusDetector.js +29 -11
  73. package/{core/focusCatcher → utils}/focusDetector.mjs +29 -11
package/base.js CHANGED
@@ -45,8 +45,8 @@ Handsontable.hooks = _hooks.Hooks.getSingleton();
45
45
  Handsontable.CellCoords = _src.CellCoords;
46
46
  Handsontable.CellRange = _src.CellRange;
47
47
  Handsontable.packageName = 'handsontable';
48
- Handsontable.buildDate = "19/08/2025 13:12:41";
49
- Handsontable.version = "0.0.0-next-f86a877-20250819";
48
+ Handsontable.buildDate = "22/08/2025 10:29:56";
49
+ Handsontable.version = "0.0.0-next-fce5825-20250822";
50
50
  Handsontable.languages = {
51
51
  dictionaryKeys: _registry.dictionaryKeys,
52
52
  getLanguageDictionary: _registry.getLanguageDictionary,
package/base.mjs CHANGED
@@ -35,8 +35,8 @@ Handsontable.hooks = Hooks.getSingleton();
35
35
  Handsontable.CellCoords = CellCoords;
36
36
  Handsontable.CellRange = CellRange;
37
37
  Handsontable.packageName = 'handsontable';
38
- Handsontable.buildDate = "19/08/2025 13:12:47";
39
- Handsontable.version = "0.0.0-next-f86a877-20250819";
38
+ Handsontable.buildDate = "22/08/2025 10:30:02";
39
+ Handsontable.version = "0.0.0-next-fce5825-20250822";
40
40
  Handsontable.languages = {
41
41
  dictionaryKeys,
42
42
  getLanguageDictionary,
@@ -3,8 +3,9 @@
3
3
  exports.__esModule = true;
4
4
  exports.installFocusCatcher = installFocusCatcher;
5
5
  var _shortcutContexts = require("../../shortcutContexts");
6
- var _focusDetector = require("./focusDetector");
6
+ var _focusDetector = require("../../utils/focusDetector");
7
7
  var _utils = require("./utils");
8
+ var _mixed = require("../../helpers/mixed");
8
9
  /**
9
10
  * Installs a focus catcher module. The module observes when the table is focused and depending on
10
11
  * from the which side it was focused on it selects a specified cell or releases the TAB navigation
@@ -18,22 +19,26 @@ function installFocusCatcher(hot) {
18
19
  const {
19
20
  activate,
20
21
  deactivate
21
- } = (0, _focusDetector.installFocusDetector)(hot, {
22
- onFocusFromTop() {
23
- var _clampCoordsIfNeeded;
24
- const mostTopStartCoords = (_clampCoordsIfNeeded = clampCoordsIfNeeded(recentlyAddedFocusCoords)) !== null && _clampCoordsIfNeeded !== void 0 ? _clampCoordsIfNeeded : (0, _utils.getMostTopStartPosition)(hot);
25
- if (mostTopStartCoords) {
26
- hot.runHooks('modifyFocusOnTabNavigation', 'from_above', mostTopStartCoords);
27
- hot.selectCell(mostTopStartCoords.row, mostTopStartCoords.col);
28
- }
29
- hot.listen();
30
- },
31
- onFocusFromBottom() {
32
- var _clampCoordsIfNeeded2;
33
- const mostBottomEndCoords = (_clampCoordsIfNeeded2 = clampCoordsIfNeeded(recentlyAddedFocusCoords)) !== null && _clampCoordsIfNeeded2 !== void 0 ? _clampCoordsIfNeeded2 : (0, _utils.getMostBottomEndPosition)(hot);
34
- if (mostBottomEndCoords) {
35
- hot.runHooks('modifyFocusOnTabNavigation', 'from_below', mostBottomEndCoords);
36
- hot.selectCell(mostBottomEndCoords.row, mostBottomEndCoords.col);
22
+ } = (0, _focusDetector.installFocusDetector)(hot, hot.rootGridElement, {
23
+ onFocus(from) {
24
+ if (from === 'from_above') {
25
+ var _clampCoordsIfNeeded;
26
+ const mostTopStartCoords = (_clampCoordsIfNeeded = clampCoordsIfNeeded(recentlyAddedFocusCoords)) !== null && _clampCoordsIfNeeded !== void 0 ? _clampCoordsIfNeeded : (0, _mixed.getMostTopStartPosition)(hot);
27
+ if (mostTopStartCoords) {
28
+ const result = hot.runHooks('modifyFocusOnTabNavigation', 'from_above', mostTopStartCoords);
29
+ if (result !== false) {
30
+ hot.selectCell(mostTopStartCoords.row, mostTopStartCoords.col);
31
+ }
32
+ }
33
+ } else {
34
+ var _clampCoordsIfNeeded2;
35
+ const mostBottomEndCoords = (_clampCoordsIfNeeded2 = clampCoordsIfNeeded(recentlyAddedFocusCoords)) !== null && _clampCoordsIfNeeded2 !== void 0 ? _clampCoordsIfNeeded2 : (0, _mixed.getMostBottomEndPosition)(hot);
36
+ if (mostBottomEndCoords) {
37
+ const result = hot.runHooks('modifyFocusOnTabNavigation', 'from_below', mostBottomEndCoords);
38
+ if (result !== false) {
39
+ hot.selectCell(mostBottomEndCoords.row, mostBottomEndCoords.col);
40
+ }
41
+ }
37
42
  }
38
43
  hot.listen();
39
44
  }
@@ -45,8 +50,20 @@ function installFocusCatcher(hot) {
45
50
  let isSavingCoordsEnabled = true;
46
51
  let isTabOrShiftTabPressed = false;
47
52
  let preventViewportScroll = false;
48
- hot.addHook('afterListen', () => deactivate());
49
- hot.addHook('afterUnlisten', () => activate());
53
+ hot.addHook('afterListen', () => {
54
+ const activeContextName = hot.getShortcutManager().getActiveContextName();
55
+ const activeContext = hot.getShortcutManager().getContext(activeContextName);
56
+ if ((activeContext === null || activeContext === void 0 ? void 0 : activeContext.scope) === 'table') {
57
+ deactivate();
58
+ }
59
+ });
60
+ hot.addHook('afterUnlisten', () => {
61
+ const activeContextName = hot.getShortcutManager().getActiveContextName();
62
+ const activeContext = hot.getShortcutManager().getContext(activeContextName);
63
+ if ((activeContext === null || activeContext === void 0 ? void 0 : activeContext.scope) === 'table') {
64
+ activate();
65
+ }
66
+ });
50
67
  hot.addHook('afterSelection', (row, column, row2, column2, preventScrolling) => {
51
68
  if (isTabOrShiftTabPressed && (rowWrapState.wrapped && rowWrapState.flipped || preventViewportScroll)) {
52
69
  preventViewportScroll = false;
@@ -104,7 +121,7 @@ function installFocusCatcher(hot) {
104
121
  isSavingCoordsEnabled = true;
105
122
  if (!tabNavigation || !hot.selection.isSelected() || autoWrapRow && rowWrapState.wrapped && rowWrapState.flipped || !autoWrapRow && rowWrapState.wrapped) {
106
123
  if (autoWrapRow && rowWrapState.wrapped && rowWrapState.flipped) {
107
- recentlyAddedFocusCoords = event.shiftKey ? (0, _utils.getMostTopStartPosition)(hot) : (0, _utils.getMostBottomEndPosition)(hot);
124
+ recentlyAddedFocusCoords = event.shiftKey ? (0, _mixed.getMostTopStartPosition)(hot) : (0, _mixed.getMostBottomEndPosition)(hot);
108
125
  }
109
126
  deactivateTable();
110
127
  return false;
@@ -1,6 +1,7 @@
1
1
  import { GRID_GROUP } from "../../shortcutContexts/index.mjs";
2
- import { installFocusDetector } from "./focusDetector.mjs";
3
- import { normalizeCoordsIfNeeded, getMostTopStartPosition, getMostBottomEndPosition } from "./utils.mjs";
2
+ import { installFocusDetector } from "../../utils/focusDetector.mjs";
3
+ import { normalizeCoordsIfNeeded } from "./utils.mjs";
4
+ import { getMostTopStartPosition, getMostBottomEndPosition } from "../../helpers/mixed.mjs";
4
5
  /**
5
6
  * Installs a focus catcher module. The module observes when the table is focused and depending on
6
7
  * from the which side it was focused on it selects a specified cell or releases the TAB navigation
@@ -14,22 +15,26 @@ export function installFocusCatcher(hot) {
14
15
  const {
15
16
  activate,
16
17
  deactivate
17
- } = installFocusDetector(hot, {
18
- onFocusFromTop() {
19
- var _clampCoordsIfNeeded;
20
- const mostTopStartCoords = (_clampCoordsIfNeeded = clampCoordsIfNeeded(recentlyAddedFocusCoords)) !== null && _clampCoordsIfNeeded !== void 0 ? _clampCoordsIfNeeded : getMostTopStartPosition(hot);
21
- if (mostTopStartCoords) {
22
- hot.runHooks('modifyFocusOnTabNavigation', 'from_above', mostTopStartCoords);
23
- hot.selectCell(mostTopStartCoords.row, mostTopStartCoords.col);
24
- }
25
- hot.listen();
26
- },
27
- onFocusFromBottom() {
28
- var _clampCoordsIfNeeded2;
29
- const mostBottomEndCoords = (_clampCoordsIfNeeded2 = clampCoordsIfNeeded(recentlyAddedFocusCoords)) !== null && _clampCoordsIfNeeded2 !== void 0 ? _clampCoordsIfNeeded2 : getMostBottomEndPosition(hot);
30
- if (mostBottomEndCoords) {
31
- hot.runHooks('modifyFocusOnTabNavigation', 'from_below', mostBottomEndCoords);
32
- hot.selectCell(mostBottomEndCoords.row, mostBottomEndCoords.col);
18
+ } = installFocusDetector(hot, hot.rootGridElement, {
19
+ onFocus(from) {
20
+ if (from === 'from_above') {
21
+ var _clampCoordsIfNeeded;
22
+ const mostTopStartCoords = (_clampCoordsIfNeeded = clampCoordsIfNeeded(recentlyAddedFocusCoords)) !== null && _clampCoordsIfNeeded !== void 0 ? _clampCoordsIfNeeded : getMostTopStartPosition(hot);
23
+ if (mostTopStartCoords) {
24
+ const result = hot.runHooks('modifyFocusOnTabNavigation', 'from_above', mostTopStartCoords);
25
+ if (result !== false) {
26
+ hot.selectCell(mostTopStartCoords.row, mostTopStartCoords.col);
27
+ }
28
+ }
29
+ } else {
30
+ var _clampCoordsIfNeeded2;
31
+ const mostBottomEndCoords = (_clampCoordsIfNeeded2 = clampCoordsIfNeeded(recentlyAddedFocusCoords)) !== null && _clampCoordsIfNeeded2 !== void 0 ? _clampCoordsIfNeeded2 : getMostBottomEndPosition(hot);
32
+ if (mostBottomEndCoords) {
33
+ const result = hot.runHooks('modifyFocusOnTabNavigation', 'from_below', mostBottomEndCoords);
34
+ if (result !== false) {
35
+ hot.selectCell(mostBottomEndCoords.row, mostBottomEndCoords.col);
36
+ }
37
+ }
33
38
  }
34
39
  hot.listen();
35
40
  }
@@ -41,8 +46,20 @@ export function installFocusCatcher(hot) {
41
46
  let isSavingCoordsEnabled = true;
42
47
  let isTabOrShiftTabPressed = false;
43
48
  let preventViewportScroll = false;
44
- hot.addHook('afterListen', () => deactivate());
45
- hot.addHook('afterUnlisten', () => activate());
49
+ hot.addHook('afterListen', () => {
50
+ const activeContextName = hot.getShortcutManager().getActiveContextName();
51
+ const activeContext = hot.getShortcutManager().getContext(activeContextName);
52
+ if ((activeContext === null || activeContext === void 0 ? void 0 : activeContext.scope) === 'table') {
53
+ deactivate();
54
+ }
55
+ });
56
+ hot.addHook('afterUnlisten', () => {
57
+ const activeContextName = hot.getShortcutManager().getActiveContextName();
58
+ const activeContext = hot.getShortcutManager().getContext(activeContextName);
59
+ if ((activeContext === null || activeContext === void 0 ? void 0 : activeContext.scope) === 'table') {
60
+ activate();
61
+ }
62
+ });
46
63
  hot.addHook('afterSelection', (row, column, row2, column2, preventScrolling) => {
47
64
  if (isTabOrShiftTabPressed && (rowWrapState.wrapped && rowWrapState.flipped || preventViewportScroll)) {
48
65
  preventViewportScroll = false;
@@ -1,10 +1,9 @@
1
1
  "use strict";
2
2
 
3
3
  exports.__esModule = true;
4
- exports.getMostBottomEndPosition = getMostBottomEndPosition;
5
- exports.getMostTopStartPosition = getMostTopStartPosition;
6
4
  exports.normalizeCoordsIfNeeded = normalizeCoordsIfNeeded;
7
5
  var _number = require("../../helpers/number");
6
+ var _mixed = require("../../helpers/mixed");
8
7
  /**
9
8
  * Normalizes the coordinates (clamps to nearest visible cell position within dataset range).
10
9
  *
@@ -23,70 +22,10 @@ function normalizeCoordsIfNeeded(hot) {
23
22
  if (rowIndexMapper.isHidden(coords.row) || columnIndexMapper.isHidden(coords.col)) {
24
23
  return null;
25
24
  }
26
- const mostTopStartCoords = getMostTopStartPosition(hot);
27
- const mostBottomEndCoords = getMostBottomEndPosition(hot);
25
+ const mostTopStartCoords = (0, _mixed.getMostTopStartPosition)(hot);
26
+ const mostBottomEndCoords = (0, _mixed.getMostBottomEndPosition)(hot);
28
27
  coords.row = (0, _number.clamp)(coords.row, mostTopStartCoords.row, mostBottomEndCoords.row);
29
28
  coords.col = (0, _number.clamp)(coords.col, mostTopStartCoords.col, mostBottomEndCoords.col);
30
29
  return coords;
31
30
  };
32
- }
33
-
34
- /**
35
- * Gets the coordinates of the most top-start cell or header (depends on the table settings and its size).
36
- *
37
- * @param {Core} hot The Handsontable instance.
38
- * @returns {CellCoords|null}
39
- */
40
- function getMostTopStartPosition(hot) {
41
- const {
42
- rowIndexMapper,
43
- columnIndexMapper
44
- } = hot;
45
- const {
46
- navigableHeaders
47
- } = hot.getSettings();
48
- let topRow = navigableHeaders && hot.countColHeaders() > 0 ? -hot.countColHeaders() : 0;
49
- let startColumn = navigableHeaders && hot.countRowHeaders() > 0 ? -hot.countRowHeaders() : 0;
50
- if (topRow === 0) {
51
- topRow = rowIndexMapper.getVisualFromRenderableIndex(topRow);
52
- }
53
- if (startColumn === 0) {
54
- startColumn = columnIndexMapper.getVisualFromRenderableIndex(startColumn);
55
- }
56
- if (topRow === null || startColumn === null) {
57
- return null;
58
- }
59
- return hot._createCellCoords(topRow, startColumn);
60
- }
61
-
62
- /**
63
- * Gets the coordinates of the most bottom-end cell or header (depends on the table settings and its size).
64
- *
65
- * @param {Core} hot The Handsontable instance.
66
- * @returns {CellCoords|null}
67
- */
68
- function getMostBottomEndPosition(hot) {
69
- var _rowIndexMapper$getVi, _columnIndexMapper$ge;
70
- const {
71
- rowIndexMapper,
72
- columnIndexMapper
73
- } = hot;
74
- const {
75
- navigableHeaders
76
- } = hot.getSettings();
77
- let bottomRow = rowIndexMapper.getRenderableIndexesLength() - 1;
78
- let endColumn = columnIndexMapper.getRenderableIndexesLength() - 1;
79
- if (bottomRow < 0) {
80
- if (!navigableHeaders || hot.countColHeaders() === 0) {
81
- return null;
82
- }
83
- bottomRow = -1;
84
- }
85
- if (endColumn < 0) {
86
- if (!navigableHeaders || hot.countColHeaders() === 0) {
87
- return null;
88
- }
89
- endColumn = -1;
90
- }
91
- return hot._createCellCoords((_rowIndexMapper$getVi = rowIndexMapper.getVisualFromRenderableIndex(bottomRow)) !== null && _rowIndexMapper$getVi !== void 0 ? _rowIndexMapper$getVi : bottomRow, (_columnIndexMapper$ge = columnIndexMapper.getVisualFromRenderableIndex(endColumn)) !== null && _columnIndexMapper$ge !== void 0 ? _columnIndexMapper$ge : endColumn);
92
31
  }
@@ -1,4 +1,5 @@
1
1
  import { clamp } from "../../helpers/number.mjs";
2
+ import { getMostTopStartPosition, getMostBottomEndPosition } from "../../helpers/mixed.mjs";
2
3
  /**
3
4
  * Normalizes the coordinates (clamps to nearest visible cell position within dataset range).
4
5
  *
@@ -23,64 +24,4 @@ export function normalizeCoordsIfNeeded(hot) {
23
24
  coords.col = clamp(coords.col, mostTopStartCoords.col, mostBottomEndCoords.col);
24
25
  return coords;
25
26
  };
26
- }
27
-
28
- /**
29
- * Gets the coordinates of the most top-start cell or header (depends on the table settings and its size).
30
- *
31
- * @param {Core} hot The Handsontable instance.
32
- * @returns {CellCoords|null}
33
- */
34
- export function getMostTopStartPosition(hot) {
35
- const {
36
- rowIndexMapper,
37
- columnIndexMapper
38
- } = hot;
39
- const {
40
- navigableHeaders
41
- } = hot.getSettings();
42
- let topRow = navigableHeaders && hot.countColHeaders() > 0 ? -hot.countColHeaders() : 0;
43
- let startColumn = navigableHeaders && hot.countRowHeaders() > 0 ? -hot.countRowHeaders() : 0;
44
- if (topRow === 0) {
45
- topRow = rowIndexMapper.getVisualFromRenderableIndex(topRow);
46
- }
47
- if (startColumn === 0) {
48
- startColumn = columnIndexMapper.getVisualFromRenderableIndex(startColumn);
49
- }
50
- if (topRow === null || startColumn === null) {
51
- return null;
52
- }
53
- return hot._createCellCoords(topRow, startColumn);
54
- }
55
-
56
- /**
57
- * Gets the coordinates of the most bottom-end cell or header (depends on the table settings and its size).
58
- *
59
- * @param {Core} hot The Handsontable instance.
60
- * @returns {CellCoords|null}
61
- */
62
- export function getMostBottomEndPosition(hot) {
63
- var _rowIndexMapper$getVi, _columnIndexMapper$ge;
64
- const {
65
- rowIndexMapper,
66
- columnIndexMapper
67
- } = hot;
68
- const {
69
- navigableHeaders
70
- } = hot.getSettings();
71
- let bottomRow = rowIndexMapper.getRenderableIndexesLength() - 1;
72
- let endColumn = columnIndexMapper.getRenderableIndexesLength() - 1;
73
- if (bottomRow < 0) {
74
- if (!navigableHeaders || hot.countColHeaders() === 0) {
75
- return null;
76
- }
77
- bottomRow = -1;
78
- }
79
- if (endColumn < 0) {
80
- if (!navigableHeaders || hot.countColHeaders() === 0) {
81
- return null;
82
- }
83
- endColumn = -1;
84
- }
85
- return hot._createCellCoords((_rowIndexMapper$getVi = rowIndexMapper.getVisualFromRenderableIndex(bottomRow)) !== null && _rowIndexMapper$getVi !== void 0 ? _rowIndexMapper$getVi : bottomRow, (_columnIndexMapper$ge = columnIndexMapper.getVisualFromRenderableIndex(endColumn)) !== null && _columnIndexMapper$ge !== void 0 ? _columnIndexMapper$ge : endColumn);
86
27
  }
@@ -1767,6 +1767,7 @@ const REGISTERED_HOOKS = exports.REGISTERED_HOOKS = [/* eslint-disable jsdoc/req
1767
1767
  * @param {'from_above' | 'from_below'} tabActivationDir The browsers Tab navigation direction. Depending on
1768
1768
  * whether the user activated the table from the element above or below, another cell can be selected.
1769
1769
  * @param {CellCoords} visualCoords The coords that will be used to select a cell.
1770
+ * @returns {undefined|boolean} If `false` is returned, the table will not be focused.
1770
1771
  */
1771
1772
  'modifyFocusOnTabNavigation',
1772
1773
  /**
@@ -2937,6 +2938,63 @@ const REGISTERED_HOOKS = exports.REGISTERED_HOOKS = [/* eslint-disable jsdoc/req
2937
2938
  * Returning `true` removes those restrictions.
2938
2939
  */
2939
2940
  'beforeBeginEditing',
2941
+ /**
2942
+ * Fired by {@link Dialog} plugin after hiding the dialog. This hook is fired when {@link Options#dialog}
2943
+ * option is enabled.
2944
+ *
2945
+ * @since 16.1.0
2946
+ * @event Hooks#afterDialogHide
2947
+ */
2948
+ 'afterDialogHide',
2949
+ /**
2950
+ * Fired by {@link Dialog} plugin after showing the dialog. This hook is fired when {@link Options#dialog}
2951
+ * option is enabled.
2952
+ *
2953
+ * @since 16.1.0
2954
+ * @event Hooks#afterDialogShow
2955
+ */
2956
+ 'afterDialogShow',
2957
+ /**
2958
+ * Fired by {@link Dialog} plugin before hiding the dialog. This hook is fired when {@link Options#dialog}
2959
+ * option is enabled.
2960
+ *
2961
+ * @since 16.1.0
2962
+ * @event Hooks#beforeDialogHide
2963
+ */
2964
+ 'beforeDialogHide',
2965
+ /**
2966
+ * Fired by {@link Dialog} plugin before showing the dialog. This hook is fired when {@link Options#dialog}
2967
+ * option is enabled.
2968
+ *
2969
+ * @since 16.1.0
2970
+ * @event Hooks#beforeDialogShow
2971
+ */
2972
+ 'beforeDialogShow',
2973
+ /**
2974
+ * Fired by {@link Dialog} plugin before focusing the previous element. This hook is fired when {@link Options#dialog}
2975
+ * option is enabled.
2976
+ *
2977
+ * @since 16.1.0
2978
+ * @event Hooks#dialogFocusPreviousElement
2979
+ */
2980
+ 'dialogFocusPreviousElement',
2981
+ /**
2982
+ * Fired by {@link Dialog} plugin before focusing the next element. This hook is fired when {@link Options#dialog}
2983
+ * option is enabled.
2984
+ *
2985
+ * @since 16.1.0
2986
+ * @event Hooks#dialogFocusNextElement
2987
+ */
2988
+ 'dialogFocusNextElement',
2989
+ /**
2990
+ * Fired by {@link Dialog} plugin when the focus is set. This hook is fired when {@link Options#dialog}
2991
+ * option is enabled.
2992
+ *
2993
+ * @since 16.1.0
2994
+ * @event Hooks#afterDialogFocus
2995
+ * @param {'tab_from_above' | 'tab_from_below' | 'click' | 'show'} focusSource The source of the focus.
2996
+ */
2997
+ 'afterDialogFocus',
2940
2998
  /**
2941
2999
  * Fired after the editor is opened and rendered.
2942
3000
  *
@@ -1764,6 +1764,7 @@ export const REGISTERED_HOOKS = [/* eslint-disable jsdoc/require-description-com
1764
1764
  * @param {'from_above' | 'from_below'} tabActivationDir The browsers Tab navigation direction. Depending on
1765
1765
  * whether the user activated the table from the element above or below, another cell can be selected.
1766
1766
  * @param {CellCoords} visualCoords The coords that will be used to select a cell.
1767
+ * @returns {undefined|boolean} If `false` is returned, the table will not be focused.
1767
1768
  */
1768
1769
  'modifyFocusOnTabNavigation',
1769
1770
  /**
@@ -2934,6 +2935,63 @@ export const REGISTERED_HOOKS = [/* eslint-disable jsdoc/require-description-com
2934
2935
  * Returning `true` removes those restrictions.
2935
2936
  */
2936
2937
  'beforeBeginEditing',
2938
+ /**
2939
+ * Fired by {@link Dialog} plugin after hiding the dialog. This hook is fired when {@link Options#dialog}
2940
+ * option is enabled.
2941
+ *
2942
+ * @since 16.1.0
2943
+ * @event Hooks#afterDialogHide
2944
+ */
2945
+ 'afterDialogHide',
2946
+ /**
2947
+ * Fired by {@link Dialog} plugin after showing the dialog. This hook is fired when {@link Options#dialog}
2948
+ * option is enabled.
2949
+ *
2950
+ * @since 16.1.0
2951
+ * @event Hooks#afterDialogShow
2952
+ */
2953
+ 'afterDialogShow',
2954
+ /**
2955
+ * Fired by {@link Dialog} plugin before hiding the dialog. This hook is fired when {@link Options#dialog}
2956
+ * option is enabled.
2957
+ *
2958
+ * @since 16.1.0
2959
+ * @event Hooks#beforeDialogHide
2960
+ */
2961
+ 'beforeDialogHide',
2962
+ /**
2963
+ * Fired by {@link Dialog} plugin before showing the dialog. This hook is fired when {@link Options#dialog}
2964
+ * option is enabled.
2965
+ *
2966
+ * @since 16.1.0
2967
+ * @event Hooks#beforeDialogShow
2968
+ */
2969
+ 'beforeDialogShow',
2970
+ /**
2971
+ * Fired by {@link Dialog} plugin before focusing the previous element. This hook is fired when {@link Options#dialog}
2972
+ * option is enabled.
2973
+ *
2974
+ * @since 16.1.0
2975
+ * @event Hooks#dialogFocusPreviousElement
2976
+ */
2977
+ 'dialogFocusPreviousElement',
2978
+ /**
2979
+ * Fired by {@link Dialog} plugin before focusing the next element. This hook is fired when {@link Options#dialog}
2980
+ * option is enabled.
2981
+ *
2982
+ * @since 16.1.0
2983
+ * @event Hooks#dialogFocusNextElement
2984
+ */
2985
+ 'dialogFocusNextElement',
2986
+ /**
2987
+ * Fired by {@link Dialog} plugin when the focus is set. This hook is fired when {@link Options#dialog}
2988
+ * option is enabled.
2989
+ *
2990
+ * @since 16.1.0
2991
+ * @event Hooks#afterDialogFocus
2992
+ * @param {'tab_from_above' | 'tab_from_below' | 'click' | 'show'} focusSource The source of the focus.
2993
+ */
2994
+ 'afterDialogFocus',
2937
2995
  /**
2938
2996
  * Fired after the editor is opened and rendered.
2939
2997
  *
@@ -68,6 +68,9 @@ export interface Events {
68
68
  afterContextMenuHide?: (context: ContextMenu) => void;
69
69
  afterContextMenuShow?: (context: ContextMenu) => void;
70
70
  afterCopy?: (data: CellValue[][], coords: RangeType[], copiedHeadersCount: { columnHeadersCount: number }) => void;
71
+ afterDialogFocus?: (focusSource: 'tab_from_above' | 'tab_from_below' | 'click' | 'show') => void;
72
+ afterDialogHide?: () => void;
73
+ afterDialogShow?: () => void;
71
74
  afterCopyLimit?: (selectedRows: number, selectedColumns: number, copyRowsLimit: number, copyColumnsLimit: number) => void;
72
75
  afterCreateCol?: (index: number, amount: number, source?: ChangeSource) => void;
73
76
  afterCreateRow?: (index: number, amount: number, source?: ChangeSource) => void;
@@ -178,6 +181,8 @@ export interface Events {
178
181
  beforeContextMenuShow?: (context: ContextMenu) => void;
179
182
  beforeCopy?: (data: CellValue[][], coords: RangeType[], copiedHeadersCount: { columnHeadersCount: number }) => void | boolean;
180
183
  beforeCreateCol?: (index: number, amount: number, source?: ChangeSource) => void | boolean;
184
+ beforeDialogHide?: () => void;
185
+ beforeDialogShow?: () => void;
181
186
  beforeCreateRow?: (index: number, amount: number, source?: ChangeSource) => void | boolean;
182
187
  beforeCut?: (data: CellValue[][], coords: RangeType[]) => void | boolean;
183
188
  beforeDetachChild?: (parent: RowObject, element: RowObject) => void;
@@ -244,6 +249,8 @@ export interface Events {
244
249
  beforeViewRender?: (isForced: boolean, skipRender: { skipRender?: boolean }) => void;
245
250
  beforeWidthChange?: (width: number | string) => number | string;
246
251
  construct?: () => void;
252
+ dialogFocusNextElement?: () => void;
253
+ dialogFocusPreviousElement?: () => void;
247
254
  init?: () => void;
248
255
  modifyAutoColumnSizeSeed?: (seed: string, cellProperties: CellProperties, cellValue: CellValue) => string | void;
249
256
  modifyAutofillRange?: (startArea: Array<[number, number, number, number]>, entireArea: Array<[number, number, number, number]>) => void;
package/core.js CHANGED
@@ -201,6 +201,14 @@ function Core(rootContainer, userSettings) {
201
201
  */
202
202
  this.rootWrapperElement = undefined;
203
203
 
204
+ /**
205
+ * Reference to the grid element.
206
+ *
207
+ * @private
208
+ * @type {HTMLElement}
209
+ */
210
+ this.rootGridElement = undefined;
211
+
204
212
  /**
205
213
  * Reference to the portal element.
206
214
  *
@@ -235,10 +243,13 @@ function Core(rootContainer, userSettings) {
235
243
  this.rootWindow = this.rootDocument.defaultView;
236
244
  if ((0, _rootInstance.isRootInstance)(this)) {
237
245
  this.rootWrapperElement = this.rootDocument.createElement('div');
246
+ this.rootGridElement = this.rootDocument.createElement('div');
238
247
  this.rootPortalElement = this.rootDocument.createElement('div');
239
248
  (0, _element.addClass)(this.rootElement, ['ht-wrapper', 'handsontable']);
240
249
  (0, _element.addClass)(this.rootWrapperElement, 'ht-root-wrapper');
241
- this.rootWrapperElement.appendChild(this.rootElement);
250
+ (0, _element.addClass)(this.rootGridElement, 'ht-grid');
251
+ this.rootGridElement.appendChild(this.rootElement);
252
+ this.rootWrapperElement.appendChild(this.rootGridElement);
242
253
  this.rootContainer.appendChild(this.rootWrapperElement);
243
254
  (0, _element.addClass)(this.rootPortalElement, 'ht-portal');
244
255
  this.rootDocument.body.appendChild(this.rootPortalElement);
@@ -351,9 +362,6 @@ function Core(rootContainer, userSettings) {
351
362
  const pluginsRegistry = (0, _uniqueMap.createUniqueMap)();
352
363
  this.container = this.rootDocument.createElement('div');
353
364
  this.rootElement.insertBefore(this.container, this.rootElement.firstChild);
354
- if ((0, _rootInstance.isRootInstance)(this)) {
355
- (0, _mixed._injectProductInfo)(mergedUserSettings.licenseKey, this.rootWrapperElement);
356
- }
357
365
  this.guid = `ht_${(0, _string.randomString)()}`; // this is the namespace for global events
358
366
 
359
367
  foreignHotInstances.set(this.guid, this);
@@ -1190,6 +1198,7 @@ function Core(rootContainer, userSettings) {
1190
1198
  if ((0, _rootInstance.isRootInstance)(this)) {
1191
1199
  (0, _index.installFocusCatcher)(instance);
1192
1200
  (0, _a11yAnnouncer.install)(instance.rootPortalElement);
1201
+ (0, _mixed._injectProductInfo)(mergedUserSettings.licenseKey, this.rootWrapperElement);
1193
1202
  }
1194
1203
  instance.runHooks('init');
1195
1204
  this.render();
package/core.mjs CHANGED
@@ -196,6 +196,14 @@ export default function Core(rootContainer, userSettings) {
196
196
  */
197
197
  this.rootWrapperElement = undefined;
198
198
 
199
+ /**
200
+ * Reference to the grid element.
201
+ *
202
+ * @private
203
+ * @type {HTMLElement}
204
+ */
205
+ this.rootGridElement = undefined;
206
+
199
207
  /**
200
208
  * Reference to the portal element.
201
209
  *
@@ -230,10 +238,13 @@ export default function Core(rootContainer, userSettings) {
230
238
  this.rootWindow = this.rootDocument.defaultView;
231
239
  if (isRootInstance(this)) {
232
240
  this.rootWrapperElement = this.rootDocument.createElement('div');
241
+ this.rootGridElement = this.rootDocument.createElement('div');
233
242
  this.rootPortalElement = this.rootDocument.createElement('div');
234
243
  addClass(this.rootElement, ['ht-wrapper', 'handsontable']);
235
244
  addClass(this.rootWrapperElement, 'ht-root-wrapper');
236
- this.rootWrapperElement.appendChild(this.rootElement);
245
+ addClass(this.rootGridElement, 'ht-grid');
246
+ this.rootGridElement.appendChild(this.rootElement);
247
+ this.rootWrapperElement.appendChild(this.rootGridElement);
237
248
  this.rootContainer.appendChild(this.rootWrapperElement);
238
249
  addClass(this.rootPortalElement, 'ht-portal');
239
250
  this.rootDocument.body.appendChild(this.rootPortalElement);
@@ -346,9 +357,6 @@ export default function Core(rootContainer, userSettings) {
346
357
  const pluginsRegistry = createUniqueMap();
347
358
  this.container = this.rootDocument.createElement('div');
348
359
  this.rootElement.insertBefore(this.container, this.rootElement.firstChild);
349
- if (isRootInstance(this)) {
350
- _injectProductInfo(mergedUserSettings.licenseKey, this.rootWrapperElement);
351
- }
352
360
  this.guid = `ht_${randomString()}`; // this is the namespace for global events
353
361
 
354
362
  foreignHotInstances.set(this.guid, this);
@@ -1185,6 +1193,7 @@ export default function Core(rootContainer, userSettings) {
1185
1193
  if (isRootInstance(this)) {
1186
1194
  installFocusCatcher(instance);
1187
1195
  installAccessibilityAnnouncer(instance.rootPortalElement);
1196
+ _injectProductInfo(mergedUserSettings.licenseKey, this.rootWrapperElement);
1188
1197
  }
1189
1198
  instance.runHooks('init');
1190
1199
  this.render();