handsontable 14.0.0-next-104f8c6-20231124 → 14.0.0-next-23212d5-20231127

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.
Files changed (85) hide show
  1. package/3rdparty/walkontable/src/renderer/columnHeaders.js +1 -1
  2. package/3rdparty/walkontable/src/renderer/columnHeaders.mjs +1 -1
  3. package/3rdparty/walkontable/src/selection/manager.js +20 -6
  4. package/3rdparty/walkontable/src/selection/manager.mjs +20 -6
  5. package/base.js +2 -2
  6. package/base.mjs +2 -2
  7. package/core/focusCatcher/focusDetector.js +1 -1
  8. package/core/focusCatcher/focusDetector.mjs +2 -2
  9. package/core.js +1 -1
  10. package/core.mjs +1 -1
  11. package/dist/handsontable.css +62 -44
  12. package/dist/handsontable.full.css +62 -44
  13. package/dist/handsontable.full.js +119 -306
  14. package/dist/handsontable.full.min.css +5 -5
  15. package/dist/handsontable.full.min.js +64 -64
  16. package/dist/handsontable.js +119 -306
  17. package/dist/handsontable.min.css +5 -5
  18. package/dist/handsontable.min.js +19 -19
  19. package/dist/languages/all.js +2 -24
  20. package/dist/languages/all.min.js +1 -1
  21. package/dist/languages/en-US.js +1 -12
  22. package/dist/languages/en-US.min.js +1 -1
  23. package/dist/languages/pl-PL.js +1 -12
  24. package/dist/languages/pl-PL.min.js +1 -1
  25. package/editors/dateEditor/dateEditor.js +0 -7
  26. package/editors/dateEditor/dateEditor.mjs +1 -8
  27. package/editors/handsontableEditor/handsontableEditor.js +0 -7
  28. package/editors/handsontableEditor/handsontableEditor.mjs +1 -8
  29. package/helpers/a11y.js +0 -2
  30. package/helpers/a11y.mjs +0 -1
  31. package/helpers/dom/element.js +0 -29
  32. package/helpers/dom/element.mjs +0 -28
  33. package/helpers/mixed.js +1 -1
  34. package/helpers/mixed.mjs +1 -1
  35. package/i18n/constants.js +1 -14
  36. package/i18n/constants.mjs +1 -14
  37. package/i18n/languages/en-US.js +1 -12
  38. package/i18n/languages/en-US.mjs +1 -12
  39. package/i18n/languages/pl-PL.js +1 -12
  40. package/i18n/languages/pl-PL.mjs +1 -12
  41. package/languages/all.js +2 -24
  42. package/languages/en-US.js +1 -12
  43. package/languages/en-US.mjs +1 -12
  44. package/languages/index.js +2 -24
  45. package/languages/pl-PL.js +1 -12
  46. package/languages/pl-PL.mjs +1 -12
  47. package/package.json +1 -1
  48. package/plugins/collapsibleColumns/collapsibleColumns.js +2 -3
  49. package/plugins/collapsibleColumns/collapsibleColumns.mjs +3 -4
  50. package/plugins/columnSorting/columnSorting.js +4 -30
  51. package/plugins/columnSorting/columnSorting.mjs +6 -32
  52. package/plugins/contextMenu/menu/menuItemRenderer.js +0 -12
  53. package/plugins/contextMenu/menu/menuItemRenderer.mjs +2 -14
  54. package/plugins/dropdownMenu/dropdownMenu.js +1 -2
  55. package/plugins/dropdownMenu/dropdownMenu.mjs +2 -3
  56. package/plugins/filters/filters.js +10 -1
  57. package/plugins/filters/filters.mjs +10 -1
  58. package/plugins/filters/menu/focusController.js +29 -10
  59. package/plugins/filters/menu/focusController.mjs +29 -10
  60. package/plugins/filters/ui/input.js +3 -0
  61. package/plugins/filters/ui/input.mjs +3 -0
  62. package/plugins/hiddenColumns/hiddenColumns.js +0 -44
  63. package/plugins/hiddenColumns/hiddenColumns.mjs +1 -45
  64. package/plugins/hiddenRows/hiddenRows.js +0 -44
  65. package/plugins/hiddenRows/hiddenRows.mjs +1 -45
  66. package/plugins/multiColumnSorting/multiColumnSorting.js +0 -21
  67. package/plugins/multiColumnSorting/multiColumnSorting.mjs +1 -22
  68. package/plugins/nestedRows/nestedRows.js +1 -2
  69. package/plugins/nestedRows/nestedRows.mjs +1 -2
  70. package/plugins/nestedRows/ui/headers.js +3 -3
  71. package/plugins/nestedRows/ui/headers.mjs +4 -4
  72. package/renderers/autocompleteRenderer/autocompleteRenderer.js +0 -3
  73. package/renderers/autocompleteRenderer/autocompleteRenderer.mjs +1 -4
  74. package/renderers/dateRenderer/dateRenderer.js +0 -5
  75. package/renderers/dateRenderer/dateRenderer.mjs +0 -5
  76. package/renderers/handsontableRenderer/handsontableRenderer.js +0 -5
  77. package/renderers/handsontableRenderer/handsontableRenderer.mjs +0 -5
  78. package/renderers/selectRenderer/selectRenderer.js +0 -5
  79. package/renderers/selectRenderer/selectRenderer.mjs +0 -5
  80. package/selection/highlight/types/focus.js +2 -0
  81. package/selection/highlight/types/focus.mjs +2 -0
  82. package/selection/selection.js +0 -1
  83. package/selection/selection.mjs +0 -1
  84. package/tableView.js +4 -0
  85. package/tableView.mjs +4 -0
@@ -17,7 +17,6 @@ var _domHelpers = require("./domHelpers");
17
17
  var _rootComparator = require("./rootComparator");
18
18
  var _sortService = require("./sortService");
19
19
  var _a11y = require("../../helpers/a11y");
20
- var _constants = require("../../i18n/constants");
21
20
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
22
21
  function _classPrivateMethodInitSpec(obj, privateSet) { _checkPrivateRedeclaration(obj, privateSet); privateSet.add(obj); }
23
22
  function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
@@ -30,7 +29,6 @@ const PLUGIN_PRIORITY = exports.PLUGIN_PRIORITY = 50;
30
29
  const APPEND_COLUMN_CONFIG_STRATEGY = exports.APPEND_COLUMN_CONFIG_STRATEGY = 'append';
31
30
  const REPLACE_COLUMN_CONFIG_STRATEGY = exports.REPLACE_COLUMN_CONFIG_STRATEGY = 'replace';
32
31
  const SHORTCUTS_GROUP = PLUGIN_KEY;
33
- const SORTING_INDICATOR_CLASS = 'columnSortingIndicator';
34
32
  (0, _sortService.registerRootComparator)(PLUGIN_KEY, _rootComparator.rootComparator);
35
33
  _pluginHooks.default.getSingleton().register('beforeColumnSort');
36
34
  _pluginHooks.default.getSingleton().register('afterColumnSort');
@@ -673,28 +671,6 @@ class ColumnSorting extends _base.BasePlugin {
673
671
  }
674
672
  }
675
673
 
676
- /**
677
- * Update sorting indicator.
678
- *
679
- * @private
680
- * @param {number} column Visual column index.
681
- * @param {HTMLElement} headerSpanElement Header span element.
682
- */
683
- updateSortingIndicator(column, headerSpanElement) {
684
- const pluginSettingsForColumn = this.getFirstCellSettings(column)[this.pluginKey];
685
- const ariaTags = this.hot.getSettings().ariaTags;
686
- const showSortIndicator = pluginSettingsForColumn.indicator;
687
- const isColumnSorted = this.columnStatesManager.isColumnSorted(column);
688
- const indicatorElement = headerSpanElement.querySelector(`.${SORTING_INDICATOR_CLASS}`);
689
- if (showSortIndicator && isColumnSorted && !indicatorElement) {
690
- (0, _element.appendElement)(headerSpanElement, {
691
- tagName: 'div',
692
- className: SORTING_INDICATOR_CLASS,
693
- attributes: ariaTags ? [(0, _a11y.A11Y_HIDDEN)()] : []
694
- });
695
- }
696
- }
697
-
698
674
  /**
699
675
  * Overwriting base plugin's `onUpdateSettings` method. Please keep in mind that `onAfterUpdateSettings` isn't called
700
676
  * for `updateSettings` in specific situations.
@@ -723,7 +699,7 @@ class ColumnSorting extends _base.BasePlugin {
723
699
  wasClickableHeaderClicked(event, column) {
724
700
  const pluginSettingsForColumn = this.getFirstCellSettings(column)[this.pluginKey];
725
701
  const headerActionEnabled = pluginSettingsForColumn.headerAction;
726
- return headerActionEnabled && ((0, _element.hasClass)(event.target, _utils.HEADER_SPAN_CLASS) || (0, _element.hasClass)(event.target, SORTING_INDICATOR_CLASS));
702
+ return headerActionEnabled && (0, _element.hasClass)(event.target, _utils.HEADER_SPAN_CLASS);
727
703
  }
728
704
  /**
729
705
  * Callback for the `onAfterOnCellMouseDown` hook.
@@ -772,14 +748,12 @@ function _onAfterGetColHeader2(column, TH) {
772
748
  return;
773
749
  }
774
750
  const pluginSettingsForColumn = this.getFirstCellSettings(column)[this.pluginKey];
775
- const ariaTags = this.hot.getSettings().ariaTags;
776
751
  const showSortIndicator = pluginSettingsForColumn.indicator;
777
752
  const headerActionEnabled = pluginSettingsForColumn.headerAction;
778
- const currentSortState = this.columnStatesManager.getSortOrderOfColumn(column);
779
753
  this.updateHeaderClasses(headerSpanElement, this.columnStatesManager, column, showSortIndicator, headerActionEnabled);
780
- this.updateSortingIndicator(column, headerSpanElement);
781
- if (ariaTags) {
782
- (0, _element.setAttribute)(TH, [(0, _a11y.A11Y_SORT)(currentSortState ? `${currentSortState}ending` : 'none'), (0, _a11y.A11Y_DESCRIPTION)(this.hot.getTranslatedPhrase(_constants.COLUMN_HEADER_DESCRIPTION_SORT_ROWS))]);
754
+ if (this.hot.getSettings().ariaTags) {
755
+ const currentSortState = this.columnStatesManager.getSortOrderOfColumn(column);
756
+ (0, _element.setAttribute)(TH, ...(0, _a11y.A11Y_SORT)(currentSortState ? `${currentSortState}ending` : 'none'));
783
757
  }
784
758
  }
785
759
  function _onAfterLoadData2(initialLoad) {
@@ -6,7 +6,7 @@ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key i
6
6
  function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
7
7
  function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
8
8
  function _classPrivateMethodGet(receiver, privateSet, fn) { if (!privateSet.has(receiver)) { throw new TypeError("attempted to get private field on non-instance"); } return fn; }
9
- import { addClass, appendElement, hasClass, removeClass, setAttribute } from "../../helpers/dom/element.mjs";
9
+ import { addClass, hasClass, removeClass, setAttribute } from "../../helpers/dom/element.mjs";
10
10
  import { isUndefined, isDefined } from "../../helpers/mixed.mjs";
11
11
  import { isObject } from "../../helpers/object.mjs";
12
12
  import { isFunction } from "../../helpers/function.mjs";
@@ -19,14 +19,12 @@ import { HEADER_SPAN_CLASS, getNextSortOrder, areValidSortStates, getHeaderSpanE
19
19
  import { getClassesToRemove, getClassesToAdd } from "./domHelpers.mjs";
20
20
  import { rootComparator } from "./rootComparator.mjs";
21
21
  import { registerRootComparator, sort } from "./sortService/index.mjs";
22
- import { A11Y_DESCRIPTION, A11Y_HIDDEN, A11Y_SORT } from "../../helpers/a11y.mjs";
23
- import { COLUMN_HEADER_DESCRIPTION_SORT_ROWS } from "../../i18n/constants.mjs";
22
+ import { A11Y_SORT } from "../../helpers/a11y.mjs";
24
23
  export const PLUGIN_KEY = 'columnSorting';
25
24
  export const PLUGIN_PRIORITY = 50;
26
25
  export const APPEND_COLUMN_CONFIG_STRATEGY = 'append';
27
26
  export const REPLACE_COLUMN_CONFIG_STRATEGY = 'replace';
28
27
  const SHORTCUTS_GROUP = PLUGIN_KEY;
29
- const SORTING_INDICATOR_CLASS = 'columnSortingIndicator';
30
28
  registerRootComparator(PLUGIN_KEY, rootComparator);
31
29
  Hooks.getSingleton().register('beforeColumnSort');
32
30
  Hooks.getSingleton().register('afterColumnSort');
@@ -669,28 +667,6 @@ export class ColumnSorting extends BasePlugin {
669
667
  }
670
668
  }
671
669
 
672
- /**
673
- * Update sorting indicator.
674
- *
675
- * @private
676
- * @param {number} column Visual column index.
677
- * @param {HTMLElement} headerSpanElement Header span element.
678
- */
679
- updateSortingIndicator(column, headerSpanElement) {
680
- const pluginSettingsForColumn = this.getFirstCellSettings(column)[this.pluginKey];
681
- const ariaTags = this.hot.getSettings().ariaTags;
682
- const showSortIndicator = pluginSettingsForColumn.indicator;
683
- const isColumnSorted = this.columnStatesManager.isColumnSorted(column);
684
- const indicatorElement = headerSpanElement.querySelector(`.${SORTING_INDICATOR_CLASS}`);
685
- if (showSortIndicator && isColumnSorted && !indicatorElement) {
686
- appendElement(headerSpanElement, {
687
- tagName: 'div',
688
- className: SORTING_INDICATOR_CLASS,
689
- attributes: ariaTags ? [A11Y_HIDDEN()] : []
690
- });
691
- }
692
- }
693
-
694
670
  /**
695
671
  * Overwriting base plugin's `onUpdateSettings` method. Please keep in mind that `onAfterUpdateSettings` isn't called
696
672
  * for `updateSettings` in specific situations.
@@ -719,7 +695,7 @@ export class ColumnSorting extends BasePlugin {
719
695
  wasClickableHeaderClicked(event, column) {
720
696
  const pluginSettingsForColumn = this.getFirstCellSettings(column)[this.pluginKey];
721
697
  const headerActionEnabled = pluginSettingsForColumn.headerAction;
722
- return headerActionEnabled && (hasClass(event.target, HEADER_SPAN_CLASS) || hasClass(event.target, SORTING_INDICATOR_CLASS));
698
+ return headerActionEnabled && hasClass(event.target, HEADER_SPAN_CLASS);
723
699
  }
724
700
  /**
725
701
  * Callback for the `onAfterOnCellMouseDown` hook.
@@ -767,14 +743,12 @@ function _onAfterGetColHeader2(column, TH) {
767
743
  return;
768
744
  }
769
745
  const pluginSettingsForColumn = this.getFirstCellSettings(column)[this.pluginKey];
770
- const ariaTags = this.hot.getSettings().ariaTags;
771
746
  const showSortIndicator = pluginSettingsForColumn.indicator;
772
747
  const headerActionEnabled = pluginSettingsForColumn.headerAction;
773
- const currentSortState = this.columnStatesManager.getSortOrderOfColumn(column);
774
748
  this.updateHeaderClasses(headerSpanElement, this.columnStatesManager, column, showSortIndicator, headerActionEnabled);
775
- this.updateSortingIndicator(column, headerSpanElement);
776
- if (ariaTags) {
777
- setAttribute(TH, [A11Y_SORT(currentSortState ? `${currentSortState}ending` : 'none'), A11Y_DESCRIPTION(this.hot.getTranslatedPhrase(COLUMN_HEADER_DESCRIPTION_SORT_ROWS))]);
749
+ if (this.hot.getSettings().ariaTags) {
750
+ const currentSortState = this.columnStatesManager.getSortOrderOfColumn(column);
751
+ setAttribute(TH, ...A11Y_SORT(currentSortState ? `${currentSortState}ending` : 'none'));
778
752
  }
779
753
  }
780
754
  function _onAfterLoadData2(initialLoad) {
@@ -5,8 +5,6 @@ exports.createMenuItemRenderer = createMenuItemRenderer;
5
5
  var _utils = require("./utils");
6
6
  var _element = require("../../../helpers/dom/element");
7
7
  var _a11y = require("../../../helpers/a11y");
8
- const SUBMENU_INDICATOR_CLASSNAME = 'submenuIndicator';
9
-
10
8
  /**
11
9
  * Creates the menu renderer function.
12
10
  *
@@ -39,16 +37,6 @@ function createMenuItemRenderer(mainTableHot) {
39
37
  const isFocusable = !(0, _utils.isItemDisabled)(item, mainTableHot) && !(0, _utils.isItemSelectionDisabled)(item) && !(0, _utils.isItemSeparator)(item);
40
38
  (0, _element.setAttribute)(TD, [(0, _a11y.A11Y_MENU_ITEM)(), (0, _a11y.A11Y_LABEL)(itemValue), ...(isFocusable ? [(0, _a11y.A11Y_TABINDEX)(-1)] : []), ...((0, _utils.isItemDisabled)(item, mainTableHot) ? [(0, _a11y.A11Y_DISABLED)()] : []), ...((0, _utils.isItemSubMenu)(item) ? [(0, _a11y.A11Y_EXPANDED)(false)] : [])]);
41
39
  }
42
- if ((0, _utils.isItemSubMenu)(item)) {
43
- const submenuIndicatorElement = TD.querySelector('.submenuIndicator');
44
- if (!submenuIndicatorElement) {
45
- (0, _element.appendElement)(TD, {
46
- tagName: 'div',
47
- attributes: mainTableHot.getSettings().ariaTags ? [(0, _a11y.A11Y_HIDDEN)()] : [],
48
- className: SUBMENU_INDICATOR_CLASSNAME
49
- });
50
- }
51
- }
52
40
  TD.className = '';
53
41
  TD.appendChild(wrapper);
54
42
  if ((0, _utils.isItemSeparator)(item)) {
@@ -1,8 +1,6 @@
1
1
  import { isItemSubMenu, isItemDisabled, isItemSelectionDisabled, isItemSeparator } from "./utils.mjs";
2
- import { addClass, appendElement, empty, fastInnerHTML, setAttribute } from "../../../helpers/dom/element.mjs";
3
- import { A11Y_DISABLED, A11Y_EXPANDED, A11Y_HIDDEN, A11Y_LABEL, A11Y_MENU_ITEM, A11Y_TABINDEX } from "../../../helpers/a11y.mjs";
4
- const SUBMENU_INDICATOR_CLASSNAME = 'submenuIndicator';
5
-
2
+ import { addClass, empty, fastInnerHTML, setAttribute } from "../../../helpers/dom/element.mjs";
3
+ import { A11Y_DISABLED, A11Y_EXPANDED, A11Y_LABEL, A11Y_MENU_ITEM, A11Y_TABINDEX } from "../../../helpers/a11y.mjs";
6
4
  /**
7
5
  * Creates the menu renderer function.
8
6
  *
@@ -35,16 +33,6 @@ export function createMenuItemRenderer(mainTableHot) {
35
33
  const isFocusable = !isItemDisabled(item, mainTableHot) && !isItemSelectionDisabled(item) && !isItemSeparator(item);
36
34
  setAttribute(TD, [A11Y_MENU_ITEM(), A11Y_LABEL(itemValue), ...(isFocusable ? [A11Y_TABINDEX(-1)] : []), ...(isItemDisabled(item, mainTableHot) ? [A11Y_DISABLED()] : []), ...(isItemSubMenu(item) ? [A11Y_EXPANDED(false)] : [])]);
37
35
  }
38
- if (isItemSubMenu(item)) {
39
- const submenuIndicatorElement = TD.querySelector('.submenuIndicator');
40
- if (!submenuIndicatorElement) {
41
- appendElement(TD, {
42
- tagName: 'div',
43
- attributes: mainTableHot.getSettings().ariaTags ? [A11Y_HIDDEN()] : [],
44
- className: SUBMENU_INDICATOR_CLASSNAME
45
- });
46
- }
47
- }
48
36
  TD.className = '';
49
37
  TD.appendChild(wrapper);
50
38
  if (isItemSeparator(item)) {
@@ -12,7 +12,6 @@ var _itemsFactory = require("../contextMenu/itemsFactory");
12
12
  var _menu = require("../contextMenu/menu");
13
13
  var _pluginHooks = _interopRequireDefault(require("../../pluginHooks"));
14
14
  var _predefinedItems = require("../contextMenu/predefinedItems");
15
- var _constants = require("../../i18n/constants");
16
15
  var _a11y = require("../../helpers/a11y");
17
16
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
18
17
  function _classPrivateMethodInitSpec(obj, privateSet) { _checkPrivateRedeclaration(obj, privateSet); privateSet.add(obj); }
@@ -490,7 +489,7 @@ function _onAfterGetColHeader2(col, TH) {
490
489
  button.type = 'button';
491
490
  button.tabIndex = -1;
492
491
  if (this.hot.getSettings().ariaTags) {
493
- (0, _element.setAttribute)(button, [(0, _a11y.A11Y_LABEL)(this.hot.getTranslatedPhrase(_constants.COLUMN_HEADER_LABEL_OPEN_MENU))]);
492
+ (0, _element.setAttribute)(button, [(0, _a11y.A11Y_HIDDEN)(), (0, _a11y.A11Y_LABEL)(' ')]);
494
493
  (0, _element.setAttribute)(TH, [(0, _a11y.A11Y_HASPOPUP)('menu')]);
495
494
  }
496
495
 
@@ -15,8 +15,7 @@ import { ItemsFactory } from "../contextMenu/itemsFactory.mjs";
15
15
  import { Menu } from "../contextMenu/menu/index.mjs";
16
16
  import Hooks from "../../pluginHooks.mjs";
17
17
  import { COLUMN_LEFT, COLUMN_RIGHT, REMOVE_COLUMN, CLEAR_COLUMN, READ_ONLY, ALIGNMENT, SEPARATOR } from "../contextMenu/predefinedItems/index.mjs";
18
- import { COLUMN_HEADER_LABEL_OPEN_MENU } from "../../i18n/constants.mjs";
19
- import { A11Y_LABEL, A11Y_HASPOPUP } from "../../helpers/a11y.mjs";
18
+ import { A11Y_HASPOPUP, A11Y_HIDDEN, A11Y_LABEL } from "../../helpers/a11y.mjs";
20
19
  Hooks.getSingleton().register('afterDropdownMenuDefaultOptions');
21
20
  Hooks.getSingleton().register('beforeDropdownMenuShow');
22
21
  Hooks.getSingleton().register('afterDropdownMenuShow');
@@ -485,7 +484,7 @@ function _onAfterGetColHeader2(col, TH) {
485
484
  button.type = 'button';
486
485
  button.tabIndex = -1;
487
486
  if (this.hot.getSettings().ariaTags) {
488
- setAttribute(button, [A11Y_LABEL(this.hot.getTranslatedPhrase(COLUMN_HEADER_LABEL_OPEN_MENU))]);
487
+ setAttribute(button, [A11Y_HIDDEN(), A11Y_LABEL(' ')]);
489
488
  setAttribute(TH, [A11Y_HASPOPUP('menu')]);
490
489
  }
491
490
 
@@ -295,7 +295,16 @@ class Filters extends _base.BasePlugin {
295
295
  // A fake menu item that once focused allows escaping from the focus navigation (using Tab keys)
296
296
  // to the menu navigation using arrow keys.
297
297
  {
298
- focus: () => mainMenu.focus()
298
+ focus: () => {
299
+ const menuNavigator = mainMenu.getNavigator();
300
+ const lastSelectedMenuItem = _classPrivateFieldGet(this, _menuFocusNavigator).getLastMenuPage();
301
+ mainMenu.focus();
302
+ if (lastSelectedMenuItem > 0) {
303
+ menuNavigator.setCurrentPage(lastSelectedMenuItem);
304
+ } else {
305
+ menuNavigator.toFirstItem();
306
+ }
307
+ }
299
308
  }, ...Array.from(this.components).map(_ref => {
300
309
  let [, component] = _ref;
301
310
  return component.getElements();
@@ -289,7 +289,16 @@ export class Filters extends BasePlugin {
289
289
  // A fake menu item that once focused allows escaping from the focus navigation (using Tab keys)
290
290
  // to the menu navigation using arrow keys.
291
291
  {
292
- focus: () => mainMenu.focus()
292
+ focus: () => {
293
+ const menuNavigator = mainMenu.getNavigator();
294
+ const lastSelectedMenuItem = _classPrivateFieldGet(this, _menuFocusNavigator).getLastMenuPage();
295
+ mainMenu.focus();
296
+ if (lastSelectedMenuItem > 0) {
297
+ menuNavigator.setCurrentPage(lastSelectedMenuItem);
298
+ } else {
299
+ menuNavigator.toFirstItem();
300
+ }
301
+ }
293
302
  }, ...Array.from(this.components).map(_ref => {
294
303
  let [, component] = _ref;
295
304
  return component.getElements();
@@ -27,12 +27,17 @@ const SHORTCUTS_MENU_CONTEXT = 'filters';
27
27
  * @returns {Paginator}
28
28
  */
29
29
  function createMenuFocusController(mainMenu, menuItems) {
30
- const navigator = (0, _focusNavigator.createFocusNavigator)(menuItems);
30
+ /**
31
+ * @type {number} The last selected menu item (before clearing the the menu state after going
32
+ * into the focus mode triggered by the TAB or SHIFT+TAB keys).
33
+ */
34
+ let lastSelectedMenuItem = -1;
35
+ const focusNavigator = (0, _focusNavigator.createFocusNavigator)(menuItems);
31
36
  const updateNavigatorPosition = element => () => {
32
37
  if (mainMenu.isOpened()) {
33
38
  mainMenu.getKeyboardShortcutsCtrl().listen(SHORTCUTS_MENU_CONTEXT);
34
39
  }
35
- navigator.setCurrentPage(menuItems.indexOf(element));
40
+ focusNavigator.setCurrentPage(menuItems.indexOf(element));
36
41
  };
37
42
 
38
43
  // update navigator position (internal state) to element that was recently clicked or focused
@@ -45,7 +50,7 @@ function createMenuFocusController(mainMenu, menuItems) {
45
50
  });
46
51
  mainMenu.addLocalHook('afterSelectionChange', selectedItem => {
47
52
  if (!selectedItem.key.startsWith('filter_')) {
48
- navigator.clear();
53
+ focusNavigator.clear();
49
54
  }
50
55
  });
51
56
 
@@ -57,7 +62,7 @@ function createMenuFocusController(mainMenu, menuItems) {
57
62
  function addKeyboardShortcuts(menu) {
58
63
  const mainMenuShortcutsCtrl = mainMenu.getKeyboardShortcutsCtrl();
59
64
  const currentMenuShortcutsCtrl = menu.getKeyboardShortcutsCtrl();
60
- navigator.clear();
65
+ focusNavigator.clear();
61
66
  currentMenuShortcutsCtrl.addCustomShortcuts([{
62
67
  keys: [['Tab'], ['Shift', 'Tab']],
63
68
  forwardToContext: mainMenuShortcutsCtrl.getContext(SHORTCUTS_MENU_CONTEXT),
@@ -74,11 +79,15 @@ function createMenuFocusController(mainMenu, menuItems) {
74
79
  mainMenuShortcutsCtrl.addCustomShortcuts([{
75
80
  keys: [['Tab'], ['Shift', 'Tab']],
76
81
  callback: event => {
77
- mainMenu.getNavigator().clear();
82
+ const menuNavigator = mainMenu.getNavigator();
83
+ if (menuNavigator.getCurrentPage() > -1) {
84
+ lastSelectedMenuItem = menuNavigator.getCurrentPage();
85
+ }
86
+ menuNavigator.clear();
78
87
  if (event.shiftKey) {
79
- navigator.toPreviousItem();
88
+ focusNavigator.toPreviousItem();
80
89
  } else {
81
- navigator.toNextItem();
90
+ focusNavigator.toNextItem();
82
91
  }
83
92
  }
84
93
  }, {
@@ -90,7 +99,7 @@ function createMenuFocusController(mainMenu, menuItems) {
90
99
  keys: [['Enter'], ['Space']],
91
100
  preventDefault: false,
92
101
  callback: event => {
93
- const element = menuItems[navigator.getCurrentPage()];
102
+ const element = menuItems[focusNavigator.getCurrentPage()];
94
103
  if (element instanceof _select.SelectUI) {
95
104
  element.openOptions();
96
105
  event.preventDefault();
@@ -116,8 +125,18 @@ function createMenuFocusController(mainMenu, menuItems) {
116
125
  mainMenu.focus();
117
126
  mainMenu.getKeyboardShortcutsCtrl().listen(SHORTCUTS_MENU_CONTEXT);
118
127
  }
128
+
129
+ /**
130
+ * Retrieves the last selected menu item (before clearing the state after going into the focus mode).
131
+ *
132
+ * @returns {number} The last selected menu item.
133
+ */
134
+ function getLastMenuPage() {
135
+ return lastSelectedMenuItem;
136
+ }
119
137
  return {
120
- ...navigator,
121
- listen
138
+ ...focusNavigator,
139
+ listen,
140
+ getLastMenuPage
122
141
  };
123
142
  }
@@ -23,12 +23,17 @@ const SHORTCUTS_MENU_CONTEXT = 'filters';
23
23
  * @returns {Paginator}
24
24
  */
25
25
  export function createMenuFocusController(mainMenu, menuItems) {
26
- const navigator = createFocusNavigator(menuItems);
26
+ /**
27
+ * @type {number} The last selected menu item (before clearing the the menu state after going
28
+ * into the focus mode triggered by the TAB or SHIFT+TAB keys).
29
+ */
30
+ let lastSelectedMenuItem = -1;
31
+ const focusNavigator = createFocusNavigator(menuItems);
27
32
  const updateNavigatorPosition = element => () => {
28
33
  if (mainMenu.isOpened()) {
29
34
  mainMenu.getKeyboardShortcutsCtrl().listen(SHORTCUTS_MENU_CONTEXT);
30
35
  }
31
- navigator.setCurrentPage(menuItems.indexOf(element));
36
+ focusNavigator.setCurrentPage(menuItems.indexOf(element));
32
37
  };
33
38
 
34
39
  // update navigator position (internal state) to element that was recently clicked or focused
@@ -41,7 +46,7 @@ export function createMenuFocusController(mainMenu, menuItems) {
41
46
  });
42
47
  mainMenu.addLocalHook('afterSelectionChange', selectedItem => {
43
48
  if (!selectedItem.key.startsWith('filter_')) {
44
- navigator.clear();
49
+ focusNavigator.clear();
45
50
  }
46
51
  });
47
52
 
@@ -53,7 +58,7 @@ export function createMenuFocusController(mainMenu, menuItems) {
53
58
  function addKeyboardShortcuts(menu) {
54
59
  const mainMenuShortcutsCtrl = mainMenu.getKeyboardShortcutsCtrl();
55
60
  const currentMenuShortcutsCtrl = menu.getKeyboardShortcutsCtrl();
56
- navigator.clear();
61
+ focusNavigator.clear();
57
62
  currentMenuShortcutsCtrl.addCustomShortcuts([{
58
63
  keys: [['Tab'], ['Shift', 'Tab']],
59
64
  forwardToContext: mainMenuShortcutsCtrl.getContext(SHORTCUTS_MENU_CONTEXT),
@@ -70,11 +75,15 @@ export function createMenuFocusController(mainMenu, menuItems) {
70
75
  mainMenuShortcutsCtrl.addCustomShortcuts([{
71
76
  keys: [['Tab'], ['Shift', 'Tab']],
72
77
  callback: event => {
73
- mainMenu.getNavigator().clear();
78
+ const menuNavigator = mainMenu.getNavigator();
79
+ if (menuNavigator.getCurrentPage() > -1) {
80
+ lastSelectedMenuItem = menuNavigator.getCurrentPage();
81
+ }
82
+ menuNavigator.clear();
74
83
  if (event.shiftKey) {
75
- navigator.toPreviousItem();
84
+ focusNavigator.toPreviousItem();
76
85
  } else {
77
- navigator.toNextItem();
86
+ focusNavigator.toNextItem();
78
87
  }
79
88
  }
80
89
  }, {
@@ -86,7 +95,7 @@ export function createMenuFocusController(mainMenu, menuItems) {
86
95
  keys: [['Enter'], ['Space']],
87
96
  preventDefault: false,
88
97
  callback: event => {
89
- const element = menuItems[navigator.getCurrentPage()];
98
+ const element = menuItems[focusNavigator.getCurrentPage()];
90
99
  if (element instanceof SelectUI) {
91
100
  element.openOptions();
92
101
  event.preventDefault();
@@ -112,8 +121,18 @@ export function createMenuFocusController(mainMenu, menuItems) {
112
121
  mainMenu.focus();
113
122
  mainMenu.getKeyboardShortcutsCtrl().listen(SHORTCUTS_MENU_CONTEXT);
114
123
  }
124
+
125
+ /**
126
+ * Retrieves the last selected menu item (before clearing the state after going into the focus mode).
127
+ *
128
+ * @returns {number} The last selected menu item.
129
+ */
130
+ function getLastMenuPage() {
131
+ return lastSelectedMenuItem;
132
+ }
115
133
  return {
116
- ...navigator,
117
- listen
134
+ ...focusNavigator,
135
+ listen,
136
+ getLastMenuPage
118
137
  };
119
138
  }
@@ -63,8 +63,11 @@ class InputUI extends _base.BaseUI {
63
63
  */
64
64
  build() {
65
65
  super.build();
66
+ const icon = this.hot.rootDocument.createElement('div');
66
67
  _classPrivateFieldSet(this, _input, this._element.firstChild);
67
68
  (0, _element.addClass)(this._element, 'htUIInput');
69
+ (0, _element.addClass)(icon, 'htUIInputIcon');
70
+ this._element.appendChild(icon);
68
71
  this.update();
69
72
  }
70
73
 
@@ -60,8 +60,11 @@ export class InputUI extends BaseUI {
60
60
  */
61
61
  build() {
62
62
  super.build();
63
+ const icon = this.hot.rootDocument.createElement('div');
63
64
  _classPrivateFieldSet(this, _input, this._element.firstChild);
64
65
  addClass(this._element, 'htUIInput');
66
+ addClass(icon, 'htUIInputIcon');
67
+ this._element.appendChild(icon);
65
68
  this.update();
66
69
  }
67
70
 
@@ -14,8 +14,6 @@ var _pluginHooks = _interopRequireDefault(require("../../pluginHooks"));
14
14
  var _hideColumn = _interopRequireDefault(require("./contextMenuItem/hideColumn"));
15
15
  var _showColumn = _interopRequireDefault(require("./contextMenuItem/showColumn"));
16
16
  var _translations = require("../../translations");
17
- var _a11y = require("../../helpers/a11y");
18
- var _constants = require("../../i18n/constants");
19
17
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
20
18
  function _classPrivateMethodInitSpec(obj, privateSet) { _checkPrivateRedeclaration(obj, privateSet); privateSet.add(obj); }
21
19
  function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); }
@@ -32,8 +30,6 @@ _pluginHooks.default.getSingleton().register('beforeUnhideColumns');
32
30
  _pluginHooks.default.getSingleton().register('afterUnhideColumns');
33
31
  const PLUGIN_KEY = exports.PLUGIN_KEY = 'hiddenColumns';
34
32
  const PLUGIN_PRIORITY = exports.PLUGIN_PRIORITY = 310;
35
- const BEFORE_INDICATOR_CLASSNAME = 'beforeHiddenColumnIndicator';
36
- const AFTER_INDICATOR_CLASSNAME = 'afterHiddenColumnIndicator';
37
33
 
38
34
  /* eslint-disable jsdoc/require-description-complete-sentence */
39
35
 
@@ -143,7 +139,6 @@ const AFTER_INDICATOR_CLASSNAME = 'afterHiddenColumnIndicator';
143
139
  */
144
140
  var _settings = /*#__PURE__*/new WeakMap();
145
141
  var _hiddenColumnsMap = /*#__PURE__*/new WeakMap();
146
- var _clearIndicatorElements = /*#__PURE__*/new WeakSet();
147
142
  var _onModifyColWidth = /*#__PURE__*/new WeakSet();
148
143
  var _onAfterGetCellMeta = /*#__PURE__*/new WeakSet();
149
144
  var _onModifyCopyableRange = /*#__PURE__*/new WeakSet();
@@ -193,12 +188,6 @@ class HiddenColumns extends _base.BasePlugin {
193
188
  * @returns {number}
194
189
  */
195
190
  _classPrivateMethodInitSpec(this, _onModifyColWidth);
196
- /**
197
- * Remove the indicator elements from the provided column header element.
198
- *
199
- * @param {HTMLElement} TH Column header element.
200
- */
201
- _classPrivateMethodInitSpec(this, _clearIndicatorElements);
202
191
  /**
203
192
  * Cached plugin settings.
204
193
  *
@@ -288,15 +277,8 @@ class HiddenColumns extends _base.BasePlugin {
288
277
  * Disables the plugin functionality for this Handsontable instance.
289
278
  */
290
279
  disablePlugin() {
291
- const clearColHeader = (columnIndex, TH) => {
292
- _classPrivateMethodGet(this, _clearIndicatorElements, _clearIndicatorElements2).call(this, TH);
293
- };
294
280
  this.hot.columnIndexMapper.unregisterMap(this.pluginName);
295
281
  _classPrivateFieldSet(this, _settings, {});
296
- this.hot.addHook('afterGetColHeader', clearColHeader);
297
- this.hot.addHookOnce('afterViewRender', () => {
298
- this.hot.removeHook('afterGetColHeader', clearColHeader);
299
- });
300
282
  super.disablePlugin();
301
283
  this.resetCellsMeta();
302
284
  }
@@ -448,11 +430,6 @@ class HiddenColumns extends _base.BasePlugin {
448
430
  }
449
431
  }
450
432
  exports.HiddenColumns = HiddenColumns;
451
- function _clearIndicatorElements2(TH) {
452
- Array.from(TH.querySelectorAll(`.${AFTER_INDICATOR_CLASSNAME}, .${BEFORE_INDICATOR_CLASSNAME}`)).forEach(element => {
453
- element.remove();
454
- });
455
- }
456
433
  function _onModifyColWidth2(width, column) {
457
434
  // Hook is triggered internally only for the visible columns. Conditional will be handled for the API
458
435
  // calls of the `getColWidth` function on not visible indexes.
@@ -524,35 +501,14 @@ function _onModifyCopyableRange2(ranges) {
524
501
  return newRanges;
525
502
  }
526
503
  function _onAfterGetColHeader2(column, TH) {
527
- const areAriaTagsEnabled = this.hot.getSettings().ariaTags;
528
- const beforeHiddenColumnIndicatorElement = TH.querySelector('.beforeHiddenColumnIndicator');
529
- const afterHiddenColumnIndicatorElement = TH.querySelector('.afterHiddenColumnIndicator');
530
504
  if (!_classPrivateFieldGet(this, _settings).indicators || column < 0) {
531
- beforeHiddenColumnIndicatorElement === null || beforeHiddenColumnIndicatorElement === void 0 || beforeHiddenColumnIndicatorElement.remove();
532
- afterHiddenColumnIndicatorElement === null || afterHiddenColumnIndicatorElement === void 0 || afterHiddenColumnIndicatorElement.remove();
533
505
  return;
534
506
  }
535
507
  const classList = [];
536
508
  if (column >= 1 && this.isHidden(column - 1)) {
537
- if (!afterHiddenColumnIndicatorElement) {
538
- const attributesToAdd = areAriaTagsEnabled ? [(0, _a11y.A11Y_LABEL)(this.hot.getTranslatedPhrase(_constants.COLUMN_HEADER_LABEL_AFTER_HIDDEN_COLUMN))] : [];
539
- (0, _element.appendElement)(TH, {
540
- tagName: 'div',
541
- attributes: attributesToAdd,
542
- className: AFTER_INDICATOR_CLASSNAME
543
- });
544
- }
545
509
  classList.push('afterHiddenColumn');
546
510
  }
547
511
  if (column < this.hot.countCols() - 1 && this.isHidden(column + 1)) {
548
- if (!beforeHiddenColumnIndicatorElement) {
549
- const attributesToAdd = areAriaTagsEnabled ? [(0, _a11y.A11Y_LABEL)(this.hot.getTranslatedPhrase(_constants.COLUMN_HEADER_LABEL_BEFORE_HIDDEN_COLUMN))] : [];
550
- (0, _element.appendElement)(TH, {
551
- tagName: 'div',
552
- attributes: attributesToAdd,
553
- className: BEFORE_INDICATOR_CLASSNAME
554
- });
555
- }
556
512
  classList.push('beforeHiddenColumn');
557
513
  }
558
514
  (0, _element.addClass)(TH, classList);