handsontable 16.1.1-next-895fbb8-20250923 → 16.2.0-next-216dbd0-20251112

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 (301) hide show
  1. package/3rdparty/walkontable/src/overlays.js +1 -1
  2. package/3rdparty/walkontable/src/overlays.mjs +1 -1
  3. package/3rdparty/walkontable/src/selection/border/border.js +19 -3
  4. package/3rdparty/walkontable/src/selection/border/border.mjs +19 -3
  5. package/CHANGELOG.md +40 -0
  6. package/base.js +2 -2
  7. package/base.mjs +2 -2
  8. package/core/coordsMapper/index.js +11 -0
  9. package/core/coordsMapper/index.mjs +1 -0
  10. package/core/hooks/bucket.js +7 -1
  11. package/core/hooks/bucket.mjs +7 -1
  12. package/core/hooks/constants.js +54 -0
  13. package/core/hooks/constants.mjs +54 -0
  14. package/core/hooks/index.d.ts +6 -0
  15. package/core/index.js +10 -4
  16. package/core/index.mjs +2 -1
  17. package/core.d.ts +3 -2
  18. package/core.js +67 -26
  19. package/core.mjs +56 -15
  20. package/dataMap/metaManager/metaSchema.js +197 -20
  21. package/dataMap/metaManager/metaSchema.mjs +197 -20
  22. package/dist/handsontable.css +175 -3
  23. package/dist/handsontable.full.css +175 -3
  24. package/dist/handsontable.full.js +10940 -8445
  25. package/dist/handsontable.full.min.css +5 -4
  26. package/dist/handsontable.full.min.js +193 -192
  27. package/dist/handsontable.js +6472 -4116
  28. package/dist/handsontable.min.css +4 -4
  29. package/dist/handsontable.min.js +43 -42
  30. package/dist/languages/all.js +168 -21
  31. package/dist/languages/all.min.js +1 -1
  32. package/dist/languages/ar-AR.js +8 -1
  33. package/dist/languages/ar-AR.min.js +1 -1
  34. package/dist/languages/cs-CZ.js +8 -1
  35. package/dist/languages/cs-CZ.min.js +1 -1
  36. package/dist/languages/de-CH.js +8 -1
  37. package/dist/languages/de-CH.min.js +1 -1
  38. package/dist/languages/de-DE.js +8 -1
  39. package/dist/languages/de-DE.min.js +1 -1
  40. package/dist/languages/en-US.js +8 -1
  41. package/dist/languages/en-US.min.js +1 -1
  42. package/dist/languages/es-MX.js +8 -1
  43. package/dist/languages/es-MX.min.js +1 -1
  44. package/dist/languages/fa-IR.js +8 -1
  45. package/dist/languages/fa-IR.min.js +1 -1
  46. package/dist/languages/fr-FR.js +8 -1
  47. package/dist/languages/fr-FR.min.js +1 -1
  48. package/dist/languages/hr-HR.js +8 -1
  49. package/dist/languages/hr-HR.min.js +1 -1
  50. package/dist/languages/it-IT.js +8 -1
  51. package/dist/languages/it-IT.min.js +1 -1
  52. package/dist/languages/ja-JP.js +8 -1
  53. package/dist/languages/ja-JP.min.js +1 -1
  54. package/dist/languages/ko-KR.js +8 -1
  55. package/dist/languages/ko-KR.min.js +1 -1
  56. package/dist/languages/lv-LV.js +8 -1
  57. package/dist/languages/lv-LV.min.js +1 -1
  58. package/dist/languages/nb-NO.js +8 -1
  59. package/dist/languages/nb-NO.min.js +1 -1
  60. package/dist/languages/nl-NL.js +8 -1
  61. package/dist/languages/nl-NL.min.js +1 -1
  62. package/dist/languages/pl-PL.js +8 -1
  63. package/dist/languages/pl-PL.min.js +1 -1
  64. package/dist/languages/pt-BR.js +8 -1
  65. package/dist/languages/pt-BR.min.js +1 -1
  66. package/dist/languages/ru-RU.js +8 -1
  67. package/dist/languages/ru-RU.min.js +1 -1
  68. package/dist/languages/sr-SP.js +8 -1
  69. package/dist/languages/sr-SP.min.js +1 -1
  70. package/dist/languages/zh-CN.js +8 -1
  71. package/dist/languages/zh-CN.min.js +1 -1
  72. package/dist/languages/zh-TW.js +8 -1
  73. package/dist/languages/zh-TW.min.js +1 -1
  74. package/editors/autocompleteEditor/autocompleteEditor.js +21 -1
  75. package/editors/autocompleteEditor/autocompleteEditor.mjs +22 -2
  76. package/focusManager/constants.js +25 -0
  77. package/focusManager/constants.mjs +22 -0
  78. package/focusManager/eventListener.js +107 -0
  79. package/focusManager/eventListener.mjs +103 -0
  80. package/{focusManager.d.ts → focusManager/grid.d.ts} +1 -1
  81. package/{focusManager.js → focusManager/grid.js} +48 -17
  82. package/{focusManager.mjs → focusManager/grid.mjs} +47 -16
  83. package/focusManager/index.d.ts +2 -0
  84. package/focusManager/index.js +20 -0
  85. package/focusManager/index.mjs +20 -0
  86. package/focusManager/scope.js +133 -0
  87. package/focusManager/scope.mjs +129 -0
  88. package/focusManager/scopeManager.d.ts +19 -0
  89. package/focusManager/scopeManager.js +268 -0
  90. package/focusManager/scopeManager.mjs +263 -0
  91. package/focusManager/scopes/grid.js +120 -0
  92. package/focusManager/scopes/grid.mjs +116 -0
  93. package/focusManager/scopes/index.js +13 -0
  94. package/focusManager/scopes/index.mjs +9 -0
  95. package/{utils → focusManager/utils}/focusDetector.js +21 -31
  96. package/{utils → focusManager/utils}/focusDetector.mjs +21 -31
  97. package/focusManager/utils/utils.js +95 -0
  98. package/focusManager/utils/utils.mjs +89 -0
  99. package/helpers/dom/element.js +1 -1
  100. package/helpers/dom/element.mjs +2 -2
  101. package/helpers/dom/event.js +1 -1
  102. package/helpers/dom/event.mjs +1 -1
  103. package/helpers/mixed.js +2 -65
  104. package/helpers/mixed.mjs +2 -63
  105. package/i18n/constants.js +10 -1
  106. package/i18n/constants.mjs +10 -1
  107. package/i18n/languages/ar-AR.js +8 -1
  108. package/i18n/languages/ar-AR.mjs +8 -1
  109. package/i18n/languages/cs-CZ.js +8 -1
  110. package/i18n/languages/cs-CZ.mjs +8 -1
  111. package/i18n/languages/de-CH.js +8 -1
  112. package/i18n/languages/de-CH.mjs +8 -1
  113. package/i18n/languages/de-DE.js +8 -1
  114. package/i18n/languages/de-DE.mjs +8 -1
  115. package/i18n/languages/en-US.js +8 -1
  116. package/i18n/languages/en-US.mjs +8 -1
  117. package/i18n/languages/es-MX.js +8 -1
  118. package/i18n/languages/es-MX.mjs +8 -1
  119. package/i18n/languages/fa-IR.js +8 -1
  120. package/i18n/languages/fa-IR.mjs +8 -1
  121. package/i18n/languages/fr-FR.js +8 -1
  122. package/i18n/languages/fr-FR.mjs +8 -1
  123. package/i18n/languages/hr-HR.js +8 -1
  124. package/i18n/languages/hr-HR.mjs +8 -1
  125. package/i18n/languages/it-IT.js +8 -1
  126. package/i18n/languages/it-IT.mjs +8 -1
  127. package/i18n/languages/ja-JP.js +8 -1
  128. package/i18n/languages/ja-JP.mjs +8 -1
  129. package/i18n/languages/ko-KR.js +8 -1
  130. package/i18n/languages/ko-KR.mjs +8 -1
  131. package/i18n/languages/lv-LV.js +8 -1
  132. package/i18n/languages/lv-LV.mjs +8 -1
  133. package/i18n/languages/nb-NO.js +8 -1
  134. package/i18n/languages/nb-NO.mjs +8 -1
  135. package/i18n/languages/nl-NL.js +8 -1
  136. package/i18n/languages/nl-NL.mjs +8 -1
  137. package/i18n/languages/pl-PL.js +8 -1
  138. package/i18n/languages/pl-PL.mjs +8 -1
  139. package/i18n/languages/pt-BR.js +8 -1
  140. package/i18n/languages/pt-BR.mjs +8 -1
  141. package/i18n/languages/ru-RU.js +8 -1
  142. package/i18n/languages/ru-RU.mjs +8 -1
  143. package/i18n/languages/sr-SP.js +8 -1
  144. package/i18n/languages/sr-SP.mjs +8 -1
  145. package/i18n/languages/zh-CN.js +8 -1
  146. package/i18n/languages/zh-CN.mjs +8 -1
  147. package/i18n/languages/zh-TW.js +8 -1
  148. package/i18n/languages/zh-TW.mjs +8 -1
  149. package/index.d.ts +9 -0
  150. package/languages/all.js +168 -21
  151. package/languages/ar-AR.js +8 -1
  152. package/languages/ar-AR.mjs +8 -1
  153. package/languages/cs-CZ.js +8 -1
  154. package/languages/cs-CZ.mjs +8 -1
  155. package/languages/de-CH.js +8 -1
  156. package/languages/de-CH.mjs +8 -1
  157. package/languages/de-DE.js +8 -1
  158. package/languages/de-DE.mjs +8 -1
  159. package/languages/en-US.js +8 -1
  160. package/languages/en-US.mjs +8 -1
  161. package/languages/es-MX.js +8 -1
  162. package/languages/es-MX.mjs +8 -1
  163. package/languages/fa-IR.js +8 -1
  164. package/languages/fa-IR.mjs +8 -1
  165. package/languages/fr-FR.js +8 -1
  166. package/languages/fr-FR.mjs +8 -1
  167. package/languages/hr-HR.js +8 -1
  168. package/languages/hr-HR.mjs +8 -1
  169. package/languages/index.js +168 -21
  170. package/languages/it-IT.js +8 -1
  171. package/languages/it-IT.mjs +8 -1
  172. package/languages/ja-JP.js +8 -1
  173. package/languages/ja-JP.mjs +8 -1
  174. package/languages/ko-KR.js +8 -1
  175. package/languages/ko-KR.mjs +8 -1
  176. package/languages/lv-LV.js +8 -1
  177. package/languages/lv-LV.mjs +8 -1
  178. package/languages/nb-NO.js +8 -1
  179. package/languages/nb-NO.mjs +8 -1
  180. package/languages/nl-NL.js +8 -1
  181. package/languages/nl-NL.mjs +8 -1
  182. package/languages/pl-PL.js +8 -1
  183. package/languages/pl-PL.mjs +8 -1
  184. package/languages/pt-BR.js +8 -1
  185. package/languages/pt-BR.mjs +8 -1
  186. package/languages/ru-RU.js +8 -1
  187. package/languages/ru-RU.mjs +8 -1
  188. package/languages/sr-SP.js +8 -1
  189. package/languages/sr-SP.mjs +8 -1
  190. package/languages/zh-CN.js +8 -1
  191. package/languages/zh-CN.mjs +8 -1
  192. package/languages/zh-TW.js +8 -1
  193. package/languages/zh-TW.mjs +8 -1
  194. package/package.json +25 -7
  195. package/plugins/autoRowSize/autoRowSize.js +8 -1
  196. package/plugins/autoRowSize/autoRowSize.mjs +8 -1
  197. package/plugins/base/base.js +36 -10
  198. package/plugins/base/base.mjs +36 -10
  199. package/plugins/columnSummary/columnSummary.d.ts +2 -2
  200. package/plugins/columnSummary/columnSummary.js +44 -10
  201. package/plugins/columnSummary/columnSummary.mjs +44 -10
  202. package/plugins/columnSummary/endpoints.js +15 -13
  203. package/plugins/columnSummary/endpoints.mjs +15 -13
  204. package/plugins/columnSummary/utils.js +31 -0
  205. package/plugins/columnSummary/utils.mjs +30 -0
  206. package/plugins/customBorders/customBorders.d.ts +1 -0
  207. package/plugins/customBorders/customBorders.js +32 -2
  208. package/plugins/customBorders/customBorders.mjs +32 -2
  209. package/plugins/dialog/constants.js +7 -0
  210. package/plugins/dialog/constants.mjs +4 -0
  211. package/plugins/dialog/dialog.d.ts +22 -2
  212. package/plugins/dialog/dialog.js +197 -81
  213. package/plugins/dialog/dialog.mjs +196 -81
  214. package/plugins/dialog/templates/base.js +60 -0
  215. package/plugins/dialog/templates/base.mjs +56 -0
  216. package/plugins/dialog/templates/confirm.js +106 -0
  217. package/plugins/dialog/templates/confirm.mjs +102 -0
  218. package/plugins/dialog/templates/index.js +6 -0
  219. package/plugins/dialog/templates/index.mjs +4 -0
  220. package/plugins/dialog/ui.js +125 -41
  221. package/plugins/dialog/ui.mjs +119 -35
  222. package/plugins/emptyDataState/emptyDataState.d.ts +24 -0
  223. package/plugins/emptyDataState/emptyDataState.js +526 -0
  224. package/plugins/emptyDataState/emptyDataState.mjs +521 -0
  225. package/plugins/emptyDataState/index.d.ts +1 -0
  226. package/plugins/emptyDataState/index.js +7 -0
  227. package/plugins/emptyDataState/index.mjs +1 -0
  228. package/plugins/emptyDataState/ui.js +282 -0
  229. package/plugins/emptyDataState/ui.mjs +278 -0
  230. package/plugins/filters/component/value.js +16 -1
  231. package/plugins/filters/component/value.mjs +16 -1
  232. package/plugins/filters/filters.d.ts +5 -1
  233. package/plugins/filters/filters.js +22 -1
  234. package/plugins/filters/filters.mjs +22 -1
  235. package/plugins/filters/ui/multipleSelect.js +90 -79
  236. package/plugins/filters/ui/multipleSelect.mjs +90 -79
  237. package/plugins/index.d.ts +3 -0
  238. package/plugins/index.js +3 -0
  239. package/plugins/index.mjs +3 -1
  240. package/plugins/mergeCells/utils.js +1 -5
  241. package/plugins/mergeCells/utils.mjs +1 -5
  242. package/plugins/pagination/pagination.js +37 -175
  243. package/plugins/pagination/pagination.mjs +37 -175
  244. package/plugins/pagination/strategies/autoPageSize.js +2 -2
  245. package/plugins/pagination/strategies/autoPageSize.mjs +2 -2
  246. package/plugins/pagination/ui.js +6 -10
  247. package/plugins/pagination/ui.mjs +7 -11
  248. package/plugins/stretchColumns/calculator.js +3 -1
  249. package/plugins/stretchColumns/calculator.mjs +3 -1
  250. package/plugins/undoRedo/undoRedo.js +16 -6
  251. package/plugins/undoRedo/undoRedo.mjs +16 -5
  252. package/renderers/checkboxRenderer/checkboxRenderer.js +12 -15
  253. package/renderers/checkboxRenderer/checkboxRenderer.mjs +12 -15
  254. package/selection/selection.js +1 -1
  255. package/selection/selection.mjs +1 -1
  256. package/settings.d.ts +3 -0
  257. package/shortcutContexts/commands/index.js +2 -1
  258. package/shortcutContexts/commands/index.mjs +2 -1
  259. package/shortcutContexts/commands/tabNavigation.js +51 -0
  260. package/shortcutContexts/commands/tabNavigation.mjs +48 -0
  261. package/shortcutContexts/constants.js +16 -1
  262. package/shortcutContexts/constants.mjs +16 -1
  263. package/shortcutContexts/editor.js +2 -2
  264. package/shortcutContexts/editor.mjs +3 -3
  265. package/shortcutContexts/grid.js +19 -3
  266. package/shortcutContexts/grid.mjs +20 -4
  267. package/shortcuts/manager.d.ts +1 -0
  268. package/shortcuts/manager.js +17 -2
  269. package/shortcuts/manager.mjs +17 -2
  270. package/styles/handsontable.css +192 -35
  271. package/styles/handsontable.min.css +3 -3
  272. package/styles/ht-icons-horizon.css +233 -0
  273. package/styles/ht-icons-horizon.min.css +30 -0
  274. package/styles/ht-icons-main.css +233 -0
  275. package/styles/ht-icons-main.min.css +30 -0
  276. package/styles/ht-theme-classic-no-icons.css +399 -0
  277. package/styles/ht-theme-classic-no-icons.min.css +30 -0
  278. package/styles/ht-theme-classic.css +308 -556
  279. package/styles/ht-theme-classic.min.css +3 -3
  280. package/styles/ht-theme-horizon-no-icons.css +405 -0
  281. package/styles/ht-theme-horizon-no-icons.min.css +30 -0
  282. package/styles/ht-theme-horizon.css +312 -556
  283. package/styles/ht-theme-horizon.min.css +3 -3
  284. package/styles/ht-theme-main-no-icons.css +396 -0
  285. package/styles/ht-theme-main-no-icons.min.css +30 -0
  286. package/styles/ht-theme-main.css +303 -556
  287. package/styles/ht-theme-main.min.css +3 -3
  288. package/tableView.js +23 -5
  289. package/tableView.mjs +23 -5
  290. package/utils/dataStructures/uniqueMap.js +10 -0
  291. package/utils/dataStructures/uniqueMap.mjs +10 -0
  292. package/utils/ghostTable.js +0 -3
  293. package/utils/ghostTable.mjs +0 -3
  294. package/utils/stylesHandler.js +19 -4
  295. package/utils/stylesHandler.mjs +19 -4
  296. package/core/focusCatcher/index.js +0 -131
  297. package/core/focusCatcher/index.mjs +0 -127
  298. package/core/focusCatcher/utils.js +0 -31
  299. package/core/focusCatcher/utils.mjs +0 -27
  300. package/plugins/pagination/focusController.js +0 -27
  301. package/plugins/pagination/focusController.mjs +0 -23
@@ -42,7 +42,7 @@ export class AutoPageSizeStrategy {
42
42
  const viewportSize = viewportSizeProvider();
43
43
  const pages = [];
44
44
  let startIndex = 0;
45
- let totalSize = 1; // 1px border compensation for the first row
45
+ let totalSize = 0;
46
46
  let pageSize = 0;
47
47
  for (let index = 0; index < itemSizes.length; index++) {
48
48
  const itemSize = itemSizes[index];
@@ -53,7 +53,7 @@ export class AutoPageSizeStrategy {
53
53
  pageSize
54
54
  });
55
55
  startIndex = index;
56
- totalSize = 1; // 1px border compensation for the first row
56
+ totalSize = 0;
57
57
  pageSize = 0;
58
58
  }
59
59
  totalSize += itemSize;
@@ -149,6 +149,7 @@ class PaginationUI {
149
149
  } = elements.refs;
150
150
  _classPrivateFieldSet(_refs, this, elements.refs);
151
151
  container.setAttribute('dir', _classPrivateFieldGet(_isRtl, this) ? 'rtl' : 'ltr');
152
+ container.tabIndex = -1;
152
153
  const isDisabled = event => event.currentTarget.disabled;
153
154
  const addClickListener = (eventName, element, callback) => {
154
155
  element.addEventListener(eventName, event => {
@@ -158,14 +159,9 @@ class PaginationUI {
158
159
  });
159
160
  };
160
161
  addClickListener('click', first, () => this.runLocalHooks('firstPageClick'));
161
- addClickListener('focus', first, () => this.runLocalHooks('focus', first));
162
162
  addClickListener('click', prev, () => this.runLocalHooks('prevPageClick'));
163
- addClickListener('focus', prev, () => this.runLocalHooks('focus', prev));
164
163
  addClickListener('click', next, () => this.runLocalHooks('nextPageClick'));
165
- addClickListener('focus', next, () => this.runLocalHooks('focus', next));
166
164
  addClickListener('click', last, () => this.runLocalHooks('lastPageClick'));
167
- addClickListener('focus', last, () => this.runLocalHooks('focus', last));
168
- addClickListener('focus', pageSizeSelect, () => this.runLocalHooks('focus', pageSizeSelect));
169
165
  pageSizeSelect.addEventListener('change', () => {
170
166
  const value = pageSizeSelect.value === 'auto' ? 'auto' : Number.parseInt(pageSizeSelect.value, 10);
171
167
  this.runLocalHooks('pageSizeChange', value);
@@ -314,7 +310,7 @@ class PaginationUI {
314
310
  pageSizeSelect.textContent = '';
315
311
  pageSizeLabel.textContent = `${pageSizeLabelText}:`;
316
312
  (0, _element.setAttribute)(pageNavSection, [...[(0, _a11y.A11Y_LABEL)(_classPrivateFieldGet(_phraseTranslator, this).call(this, C.PAGINATION_SECTION))]]);
317
- (0, _element.setAttribute)(pageSizeSelect, [...[(0, _a11y.A11Y_LABEL)(_classPrivateFieldGet(_phraseTranslator, this).call(this, C.PAGINATION_PAGE_SIZE_SECTION))], ...[(0, _a11y.A11Y_TABINDEX)(-1)]]);
313
+ (0, _element.setAttribute)(pageSizeSelect, [...[(0, _a11y.A11Y_LABEL)(_classPrivateFieldGet(_phraseTranslator, this).call(this, C.PAGINATION_PAGE_SIZE_SECTION))]]);
318
314
  _classPrivateFieldGet(_a11yAnnouncer, this).call(this, navLabelText);
319
315
  this.refreshBorderState();
320
316
  pageSizeList.forEach(pageSizeItem => {
@@ -359,10 +355,10 @@ class PaginationUI {
359
355
  }
360
356
  }
361
357
  }
362
- (0, _element.setAttribute)(first, [...[(0, _a11y.A11Y_LABEL)(_classPrivateFieldGet(_phraseTranslator, this).call(this, C.PAGINATION_FIRST_PAGE))], ...[(0, _a11y.A11Y_DISABLED)(isFirstPage)], ...[(0, _a11y.A11Y_TABINDEX)(-1)]]);
363
- (0, _element.setAttribute)(prev, [...[(0, _a11y.A11Y_LABEL)(_classPrivateFieldGet(_phraseTranslator, this).call(this, C.PAGINATION_PREV_PAGE))], ...[(0, _a11y.A11Y_DISABLED)(isFirstPage)], ...[(0, _a11y.A11Y_TABINDEX)(-1)]]);
364
- (0, _element.setAttribute)(next, [...[(0, _a11y.A11Y_LABEL)(_classPrivateFieldGet(_phraseTranslator, this).call(this, C.PAGINATION_NEXT_PAGE))], ...[(0, _a11y.A11Y_DISABLED)(isLastPage)], ...[(0, _a11y.A11Y_TABINDEX)(-1)]]);
365
- (0, _element.setAttribute)(last, [...[(0, _a11y.A11Y_LABEL)(_classPrivateFieldGet(_phraseTranslator, this).call(this, C.PAGINATION_LAST_PAGE))], ...[(0, _a11y.A11Y_DISABLED)(isLastPage)], ...[(0, _a11y.A11Y_TABINDEX)(-1)]]);
358
+ (0, _element.setAttribute)(first, [...[(0, _a11y.A11Y_LABEL)(_classPrivateFieldGet(_phraseTranslator, this).call(this, C.PAGINATION_FIRST_PAGE))], ...[(0, _a11y.A11Y_DISABLED)(isFirstPage)]]);
359
+ (0, _element.setAttribute)(prev, [...[(0, _a11y.A11Y_LABEL)(_classPrivateFieldGet(_phraseTranslator, this).call(this, C.PAGINATION_PREV_PAGE))], ...[(0, _a11y.A11Y_DISABLED)(isFirstPage)]]);
360
+ (0, _element.setAttribute)(next, [...[(0, _a11y.A11Y_LABEL)(_classPrivateFieldGet(_phraseTranslator, this).call(this, C.PAGINATION_NEXT_PAGE))], ...[(0, _a11y.A11Y_DISABLED)(isLastPage)]]);
361
+ (0, _element.setAttribute)(last, [...[(0, _a11y.A11Y_LABEL)(_classPrivateFieldGet(_phraseTranslator, this).call(this, C.PAGINATION_LAST_PAGE))], ...[(0, _a11y.A11Y_DISABLED)(isLastPage)]]);
366
362
  return this;
367
363
  }
368
364
 
@@ -12,7 +12,7 @@ import { mixin } from "../../helpers/object.mjs";
12
12
  import localHooks from "../../mixins/localHooks.mjs";
13
13
  import * as C from "../../i18n/constants.mjs";
14
14
  import { addClass, removeClass, setAttribute } from "../../helpers/dom/element.mjs";
15
- import { A11Y_DISABLED, A11Y_LABEL, A11Y_TABINDEX } from "../../helpers/a11y.mjs";
15
+ import { A11Y_DISABLED, A11Y_LABEL } from "../../helpers/a11y.mjs";
16
16
  const TEMPLATE = `
17
17
  <div data-ref="container" class="ht-pagination handsontable">
18
18
  <div class="ht-pagination__inner">
@@ -144,6 +144,7 @@ export class PaginationUI {
144
144
  } = elements.refs;
145
145
  _classPrivateFieldSet(_refs, this, elements.refs);
146
146
  container.setAttribute('dir', _classPrivateFieldGet(_isRtl, this) ? 'rtl' : 'ltr');
147
+ container.tabIndex = -1;
147
148
  const isDisabled = event => event.currentTarget.disabled;
148
149
  const addClickListener = (eventName, element, callback) => {
149
150
  element.addEventListener(eventName, event => {
@@ -153,14 +154,9 @@ export class PaginationUI {
153
154
  });
154
155
  };
155
156
  addClickListener('click', first, () => this.runLocalHooks('firstPageClick'));
156
- addClickListener('focus', first, () => this.runLocalHooks('focus', first));
157
157
  addClickListener('click', prev, () => this.runLocalHooks('prevPageClick'));
158
- addClickListener('focus', prev, () => this.runLocalHooks('focus', prev));
159
158
  addClickListener('click', next, () => this.runLocalHooks('nextPageClick'));
160
- addClickListener('focus', next, () => this.runLocalHooks('focus', next));
161
159
  addClickListener('click', last, () => this.runLocalHooks('lastPageClick'));
162
- addClickListener('focus', last, () => this.runLocalHooks('focus', last));
163
- addClickListener('focus', pageSizeSelect, () => this.runLocalHooks('focus', pageSizeSelect));
164
160
  pageSizeSelect.addEventListener('change', () => {
165
161
  const value = pageSizeSelect.value === 'auto' ? 'auto' : Number.parseInt(pageSizeSelect.value, 10);
166
162
  this.runLocalHooks('pageSizeChange', value);
@@ -309,7 +305,7 @@ export class PaginationUI {
309
305
  pageSizeSelect.textContent = '';
310
306
  pageSizeLabel.textContent = `${pageSizeLabelText}:`;
311
307
  setAttribute(pageNavSection, [...[A11Y_LABEL(_classPrivateFieldGet(_phraseTranslator, this).call(this, C.PAGINATION_SECTION))]]);
312
- setAttribute(pageSizeSelect, [...[A11Y_LABEL(_classPrivateFieldGet(_phraseTranslator, this).call(this, C.PAGINATION_PAGE_SIZE_SECTION))], ...[A11Y_TABINDEX(-1)]]);
308
+ setAttribute(pageSizeSelect, [...[A11Y_LABEL(_classPrivateFieldGet(_phraseTranslator, this).call(this, C.PAGINATION_PAGE_SIZE_SECTION))]]);
313
309
  _classPrivateFieldGet(_a11yAnnouncer, this).call(this, navLabelText);
314
310
  this.refreshBorderState();
315
311
  pageSizeList.forEach(pageSizeItem => {
@@ -354,10 +350,10 @@ export class PaginationUI {
354
350
  }
355
351
  }
356
352
  }
357
- setAttribute(first, [...[A11Y_LABEL(_classPrivateFieldGet(_phraseTranslator, this).call(this, C.PAGINATION_FIRST_PAGE))], ...[A11Y_DISABLED(isFirstPage)], ...[A11Y_TABINDEX(-1)]]);
358
- setAttribute(prev, [...[A11Y_LABEL(_classPrivateFieldGet(_phraseTranslator, this).call(this, C.PAGINATION_PREV_PAGE))], ...[A11Y_DISABLED(isFirstPage)], ...[A11Y_TABINDEX(-1)]]);
359
- setAttribute(next, [...[A11Y_LABEL(_classPrivateFieldGet(_phraseTranslator, this).call(this, C.PAGINATION_NEXT_PAGE))], ...[A11Y_DISABLED(isLastPage)], ...[A11Y_TABINDEX(-1)]]);
360
- setAttribute(last, [...[A11Y_LABEL(_classPrivateFieldGet(_phraseTranslator, this).call(this, C.PAGINATION_LAST_PAGE))], ...[A11Y_DISABLED(isLastPage)], ...[A11Y_TABINDEX(-1)]]);
353
+ setAttribute(first, [...[A11Y_LABEL(_classPrivateFieldGet(_phraseTranslator, this).call(this, C.PAGINATION_FIRST_PAGE))], ...[A11Y_DISABLED(isFirstPage)]]);
354
+ setAttribute(prev, [...[A11Y_LABEL(_classPrivateFieldGet(_phraseTranslator, this).call(this, C.PAGINATION_PREV_PAGE))], ...[A11Y_DISABLED(isFirstPage)]]);
355
+ setAttribute(next, [...[A11Y_LABEL(_classPrivateFieldGet(_phraseTranslator, this).call(this, C.PAGINATION_NEXT_PAGE))], ...[A11Y_DISABLED(isLastPage)]]);
356
+ setAttribute(last, [...[A11Y_LABEL(_classPrivateFieldGet(_phraseTranslator, this).call(this, C.PAGINATION_LAST_PAGE))], ...[A11Y_DISABLED(isLastPage)]]);
361
357
  return this;
362
358
  }
363
359
 
@@ -129,6 +129,8 @@ function _willVerticalScrollAppear() {
129
129
  const viewportHeight = view.getViewportHeight();
130
130
  const totalRows = _classPrivateFieldGet(_hot, this).countRows();
131
131
  const defaultRowHeight = stylesHandler.getDefaultRowHeight();
132
+ const isLegacyTheme = stylesHandler.isClassicTheme();
133
+ const firstRowBorderCompensation = row => isLegacyTheme && row === 0 ? 1 : 0;
132
134
  let totalHeight = 0;
133
135
  let hasVerticalScroll = false;
134
136
  for (let row = 0; row < totalRows; row++) {
@@ -137,7 +139,7 @@ function _willVerticalScrollAppear() {
137
139
  // eslint-disable-next-line no-continue
138
140
  continue;
139
141
  }
140
- totalHeight += ((_classPrivateFieldGet2 = _classPrivateFieldGet(_hot, this).getRowHeight(row)) !== null && _classPrivateFieldGet2 !== void 0 ? _classPrivateFieldGet2 : defaultRowHeight) + (row === 0 ? 1 : 0);
142
+ totalHeight += ((_classPrivateFieldGet2 = _classPrivateFieldGet(_hot, this).getRowHeight(row)) !== null && _classPrivateFieldGet2 !== void 0 ? _classPrivateFieldGet2 : defaultRowHeight) + firstRowBorderCompensation(row);
141
143
  if (totalHeight > viewportHeight) {
142
144
  hasVerticalScroll = true;
143
145
  break;
@@ -125,6 +125,8 @@ function _willVerticalScrollAppear() {
125
125
  const viewportHeight = view.getViewportHeight();
126
126
  const totalRows = _classPrivateFieldGet(_hot, this).countRows();
127
127
  const defaultRowHeight = stylesHandler.getDefaultRowHeight();
128
+ const isLegacyTheme = stylesHandler.isClassicTheme();
129
+ const firstRowBorderCompensation = row => isLegacyTheme && row === 0 ? 1 : 0;
128
130
  let totalHeight = 0;
129
131
  let hasVerticalScroll = false;
130
132
  for (let row = 0; row < totalRows; row++) {
@@ -133,7 +135,7 @@ function _willVerticalScrollAppear() {
133
135
  // eslint-disable-next-line no-continue
134
136
  continue;
135
137
  }
136
- totalHeight += ((_classPrivateFieldGet2 = _classPrivateFieldGet(_hot, this).getRowHeight(row)) !== null && _classPrivateFieldGet2 !== void 0 ? _classPrivateFieldGet2 : defaultRowHeight) + (row === 0 ? 1 : 0);
138
+ totalHeight += ((_classPrivateFieldGet2 = _classPrivateFieldGet(_hot, this).getRowHeight(row)) !== null && _classPrivateFieldGet2 !== void 0 ? _classPrivateFieldGet2 : defaultRowHeight) + firstRowBorderCompensation(row);
137
139
  if (totalHeight > viewportHeight) {
138
140
  hasVerticalScroll = true;
139
141
  break;
@@ -21,7 +21,7 @@ function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("C
21
21
  function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
22
22
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
23
23
  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); }
24
- function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
24
+ function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); } /* eslint-disable jsdoc/require-description-complete-sentence */
25
25
  const SHORTCUTS_GROUP = 'undoRedo';
26
26
  const PLUGIN_KEY = exports.PLUGIN_KEY = 'undoRedo';
27
27
  const PLUGIN_PRIORITY = exports.PLUGIN_PRIORITY = 1000;
@@ -322,7 +322,9 @@ function _exposeAPIToCore() {
322
322
  };
323
323
 
324
324
  /**
325
- * {@link UndoRedo#undo}.
325
+ * ::: warning
326
+ * This method is deprecated and it will be removed from the Core API in the future. Please use the method from the [`UndoRedo`](@/api/undoRedo.md#undo-2) plugin.
327
+ * :::
326
328
  *
327
329
  * @alias undo
328
330
  * @memberof! Core#
@@ -332,7 +334,9 @@ function _exposeAPIToCore() {
332
334
  this.undo();
333
335
  };
334
336
  /**
335
- * {@link UndoRedo#redo}.
337
+ * ::: warning
338
+ * This method is deprecated and it will be removed from the Core API in the future. Please use the method from the [`UndoRedo`](@/api/undoRedo.md#redo) plugin.
339
+ * :::
336
340
  *
337
341
  * @alias redo
338
342
  * @memberof! Core#
@@ -342,7 +346,9 @@ function _exposeAPIToCore() {
342
346
  this.redo();
343
347
  };
344
348
  /**
345
- * {@link UndoRedo#isUndoAvailable}.
349
+ * ::: warning
350
+ * This method is deprecated and it will be removed from the Core API in the future. Please use the method from the [`UndoRedo`](@/api/undoRedo.md#isundoavailable) plugin.
351
+ * :::
346
352
  *
347
353
  * @alias isUndoAvailable
348
354
  * @memberof! Core#
@@ -353,7 +359,9 @@ function _exposeAPIToCore() {
353
359
  return this.isUndoAvailable();
354
360
  };
355
361
  /**
356
- * {@link UndoRedo#isRedoAvailable}.
362
+ * ::: warning
363
+ * This method is deprecated and it will be removed from the Core API in the future. Please use the method from the [`UndoRedo`](@/api/undoRedo.md#isredoavailable) plugin.
364
+ * :::
357
365
  *
358
366
  * @alias isRedoAvailable
359
367
  * @memberof! Core#
@@ -364,7 +372,9 @@ function _exposeAPIToCore() {
364
372
  return this.isRedoAvailable();
365
373
  };
366
374
  /**
367
- * {@link UndoRedo#clear}.
375
+ * ::: warning
376
+ * This method is deprecated and it will be removed from the Core API in the future. Please use the method from the [`UndoRedo`](@/api/undoRedo.md#clear) plugin.
377
+ * :::
368
378
  *
369
379
  * @alias clearUndo
370
380
  * @memberof! Core#
@@ -13,6 +13,7 @@ import "core-js/modules/es.set.is-subset-of.v2.js";
13
13
  import "core-js/modules/es.set.is-superset-of.v2.js";
14
14
  import "core-js/modules/es.set.symmetric-difference.v2.js";
15
15
  import "core-js/modules/es.set.union.v2.js";
16
+ /* eslint-disable jsdoc/require-description-complete-sentence */
16
17
  import { BasePlugin } from "../base/index.mjs";
17
18
  import { Hooks } from "../../core/hooks/index.mjs";
18
19
  import { deepClone } from "../../helpers/object.mjs";
@@ -318,7 +319,9 @@ function _exposeAPIToCore() {
318
319
  };
319
320
 
320
321
  /**
321
- * {@link UndoRedo#undo}.
322
+ * ::: warning
323
+ * This method is deprecated and it will be removed from the Core API in the future. Please use the method from the [`UndoRedo`](@/api/undoRedo.md#undo-2) plugin.
324
+ * :::
322
325
  *
323
326
  * @alias undo
324
327
  * @memberof! Core#
@@ -328,7 +331,9 @@ function _exposeAPIToCore() {
328
331
  this.undo();
329
332
  };
330
333
  /**
331
- * {@link UndoRedo#redo}.
334
+ * ::: warning
335
+ * This method is deprecated and it will be removed from the Core API in the future. Please use the method from the [`UndoRedo`](@/api/undoRedo.md#redo) plugin.
336
+ * :::
332
337
  *
333
338
  * @alias redo
334
339
  * @memberof! Core#
@@ -338,7 +343,9 @@ function _exposeAPIToCore() {
338
343
  this.redo();
339
344
  };
340
345
  /**
341
- * {@link UndoRedo#isUndoAvailable}.
346
+ * ::: warning
347
+ * This method is deprecated and it will be removed from the Core API in the future. Please use the method from the [`UndoRedo`](@/api/undoRedo.md#isundoavailable) plugin.
348
+ * :::
342
349
  *
343
350
  * @alias isUndoAvailable
344
351
  * @memberof! Core#
@@ -349,7 +356,9 @@ function _exposeAPIToCore() {
349
356
  return this.isUndoAvailable();
350
357
  };
351
358
  /**
352
- * {@link UndoRedo#isRedoAvailable}.
359
+ * ::: warning
360
+ * This method is deprecated and it will be removed from the Core API in the future. Please use the method from the [`UndoRedo`](@/api/undoRedo.md#isredoavailable) plugin.
361
+ * :::
353
362
  *
354
363
  * @alias isRedoAvailable
355
364
  * @memberof! Core#
@@ -360,7 +369,9 @@ function _exposeAPIToCore() {
360
369
  return this.isRedoAvailable();
361
370
  };
362
371
  /**
363
- * {@link UndoRedo#clear}.
372
+ * ::: warning
373
+ * This method is deprecated and it will be removed from the Core API in the future. Please use the method from the [`UndoRedo`](@/api/undoRedo.md#clear) plugin.
374
+ * :::
364
375
  *
365
376
  * @alias clearUndo
366
377
  * @memberof! Core#
@@ -30,24 +30,21 @@ _hooks.Hooks.getSingleton().add('modifyAutoColumnSizeSeed', function (bundleSeed
30
30
  column,
31
31
  prop
32
32
  } = cellMeta;
33
- if (type !== RENDERER_TYPE) {
33
+ if (type !== RENDERER_TYPE || !label) {
34
34
  return;
35
35
  }
36
- if (label) {
37
- const {
38
- value: labelValue,
39
- property: labelProperty
40
- } = label;
41
- let labelText = cellValue;
42
- if (labelValue) {
43
- labelText = typeof labelValue === 'function' ? labelValue(row, column, prop, cellValue) : labelValue;
44
- } else if (labelProperty) {
45
- const labelData = this.getDataAtRowProp(row, labelProperty);
46
- labelText = labelData !== null ? labelData : cellValue;
47
- }
48
- bundleSeed = labelText;
36
+ const {
37
+ value: labelValue,
38
+ property: labelProperty
39
+ } = label;
40
+ let labelText = cellValue;
41
+ if (labelValue) {
42
+ labelText = typeof labelValue === 'function' ? labelValue(row, column, prop, cellValue) : labelValue;
43
+ } else if (labelProperty) {
44
+ const labelData = this.getDataAtRowProp(row, labelProperty);
45
+ labelText = labelData !== null ? labelData : cellValue;
49
46
  }
50
- return bundleSeed;
47
+ return `${(0, _mixed.stringify)(labelText).length}`;
51
48
  });
52
49
  /**
53
50
  * Checkbox renderer.
@@ -25,24 +25,21 @@ Hooks.getSingleton().add('modifyAutoColumnSizeSeed', function (bundleSeed, cellM
25
25
  column,
26
26
  prop
27
27
  } = cellMeta;
28
- if (type !== RENDERER_TYPE) {
28
+ if (type !== RENDERER_TYPE || !label) {
29
29
  return;
30
30
  }
31
- if (label) {
32
- const {
33
- value: labelValue,
34
- property: labelProperty
35
- } = label;
36
- let labelText = cellValue;
37
- if (labelValue) {
38
- labelText = typeof labelValue === 'function' ? labelValue(row, column, prop, cellValue) : labelValue;
39
- } else if (labelProperty) {
40
- const labelData = this.getDataAtRowProp(row, labelProperty);
41
- labelText = labelData !== null ? labelData : cellValue;
42
- }
43
- bundleSeed = labelText;
31
+ const {
32
+ value: labelValue,
33
+ property: labelProperty
34
+ } = label;
35
+ let labelText = cellValue;
36
+ if (labelValue) {
37
+ labelText = typeof labelValue === 'function' ? labelValue(row, column, prop, cellValue) : labelValue;
38
+ } else if (labelProperty) {
39
+ const labelData = this.getDataAtRowProp(row, labelProperty);
40
+ labelText = labelData !== null ? labelData : cellValue;
44
41
  }
45
- return bundleSeed;
42
+ return `${stringify(labelText).length}`;
46
43
  });
47
44
  /**
48
45
  * Checkbox renderer.
@@ -1168,7 +1168,7 @@ class Selection {
1168
1168
  }
1169
1169
  this.selectedRange.clear();
1170
1170
  this.highlight.clear();
1171
- this.inProgress = true;
1171
+ this.inProgress = false;
1172
1172
  _classPrivateFieldSet(_disableHeadersHighlight, this, disableHeadersHighlight);
1173
1173
  this.selectedByRowHeader = new Set(selectedByRowHeader);
1174
1174
  this.selectedByColumnHeader = new Set(selectedByColumnHeader);
@@ -1163,7 +1163,7 @@ class Selection {
1163
1163
  }
1164
1164
  this.selectedRange.clear();
1165
1165
  this.highlight.clear();
1166
- this.inProgress = true;
1166
+ this.inProgress = false;
1167
1167
  _classPrivateFieldSet(_disableHeadersHighlight, this, disableHeadersHighlight);
1168
1168
  this.selectedByRowHeader = new Set(selectedByRowHeader);
1169
1169
  this.selectedByColumnHeader = new Set(selectedByColumnHeader);
package/settings.d.ts CHANGED
@@ -43,6 +43,7 @@ import { Settings as SearchSettings } from './plugins/search';
43
43
  import { Settings as TrimRowsSettings } from './plugins/trimRows';
44
44
  import { Settings as DialogSettings } from './plugins/dialog';
45
45
  import { Settings as LoadingSettings } from './plugins/loading';
46
+ import { Settings as EmptyDataStateSettings } from './plugins/emptyDataState';
46
47
  import { Settings as UndoRedoSettings } from './plugins/undoRedo';
47
48
  import { EditorType, BaseEditor } from './editors';
48
49
  import { RendererType } from './renderers';
@@ -181,6 +182,7 @@ export interface GridSettings extends Events {
181
182
  maxRows?: number;
182
183
  mergeCells?: MergeCellsSettings;
183
184
  minCols?: number;
185
+ minRowHeights?: number | string | number[] | string[] | undefined[] | Array<number | string | undefined> | ((index: number) => string | number | undefined);
184
186
  minRows?: number;
185
187
  minSpareCols?: number;
186
188
  minSpareRows?: number;
@@ -229,6 +231,7 @@ export interface GridSettings extends Events {
229
231
  uncheckedTemplate?: boolean | string | number;
230
232
  dialog?: DialogSettings;
231
233
  loading?: LoadingSettings;
234
+ emptyDataState?: EmptyDataStateSettings;
232
235
  undo?: UndoRedoSettings;
233
236
  validator?: BaseValidator | RegExp | ValidatorType | string;
234
237
  valueGetter?: (this: Core, value: CellValue, row: number, column: number, cellProperties: CellProperties) => CellValue;
@@ -10,7 +10,8 @@ var _scrollToFocusedCell = require("./scrollToFocusedCell");
10
10
  var _selectAllCells = require("./selectAllCells");
11
11
  var _selectAllCellsAndHeaders = require("./selectAllCellsAndHeaders");
12
12
  var _populateSelectedCellsData = require("./populateSelectedCellsData");
13
- const allCommands = [...(0, _editor.getAllCommands)(), ...(0, _extendCellsSelection.getAllCommands)(), ...(0, _moveCellSelection.getAllCommands)(), _emptySelectedCells.command, _scrollToFocusedCell.command, _selectAllCells.command, _selectAllCellsAndHeaders.command, _populateSelectedCellsData.command];
13
+ var _tabNavigation = require("./tabNavigation");
14
+ const allCommands = [...(0, _editor.getAllCommands)(), ...(0, _extendCellsSelection.getAllCommands)(), ...(0, _moveCellSelection.getAllCommands)(), _emptySelectedCells.command, _scrollToFocusedCell.command, _selectAllCells.command, _selectAllCellsAndHeaders.command, _populateSelectedCellsData.command, _tabNavigation.command];
14
15
 
15
16
  /**
16
17
  * Prepares and creates an object with all available commands to trigger.
@@ -6,7 +6,8 @@ import { command as scrollToFocusedCell } from "./scrollToFocusedCell.mjs";
6
6
  import { command as selectAllCells } from "./selectAllCells.mjs";
7
7
  import { command as selectAllCellsAndHeaders } from "./selectAllCellsAndHeaders.mjs";
8
8
  import { command as populateSelectedCellsData } from "./populateSelectedCellsData.mjs";
9
- const allCommands = [...getAllEditorCommands(), ...getAllSelectionExtendCommands(), ...getAllSelectionMoveCommands(), emptySelectedCells, scrollToFocusedCell, selectAllCells, selectAllCellsAndHeaders, populateSelectedCellsData];
9
+ import { command as tabNavigation } from "./tabNavigation.mjs";
10
+ const allCommands = [...getAllEditorCommands(), ...getAllSelectionExtendCommands(), ...getAllSelectionMoveCommands(), emptySelectedCells, scrollToFocusedCell, selectAllCells, selectAllCellsAndHeaders, populateSelectedCellsData, tabNavigation];
10
11
 
11
12
  /**
12
13
  * Prepares and creates an object with all available commands to trigger.
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ const command = exports.command = {
5
+ name: 'tabNavigation',
6
+ callback(hot) {
7
+ const rowWrapState = {
8
+ wrapped: false,
9
+ flipped: false
10
+ };
11
+ let isTabOrShiftTabPressed = false;
12
+ let preventViewportScroll = false;
13
+ hot.addHook('afterSelection', (row, column, row2, column2, preventScrolling) => {
14
+ if (isTabOrShiftTabPressed && (rowWrapState.wrapped && rowWrapState.flipped || preventViewportScroll)) {
15
+ preventViewportScroll = false;
16
+ preventScrolling.value = true;
17
+ }
18
+ });
19
+ hot.addHook('beforeRowWrap', (interruptedByAutoInsertMode, newCoords, isFlipped) => {
20
+ rowWrapState.wrapped = true;
21
+ rowWrapState.flipped = isFlipped;
22
+ });
23
+ return {
24
+ before() {
25
+ const {
26
+ tabNavigation
27
+ } = hot.getSettings();
28
+ isTabOrShiftTabPressed = true;
29
+ if (!tabNavigation) {
30
+ preventViewportScroll = true;
31
+ }
32
+ },
33
+ after(event) {
34
+ const {
35
+ tabNavigation,
36
+ autoWrapRow
37
+ } = hot.getSettings();
38
+ isTabOrShiftTabPressed = false;
39
+ if (!tabNavigation || !hot.selection.isSelected() || autoWrapRow && rowWrapState.wrapped && rowWrapState.flipped || !autoWrapRow && rowWrapState.wrapped) {
40
+ rowWrapState.wrapped = false;
41
+ rowWrapState.flipped = false;
42
+ hot.deselectCell();
43
+ return false;
44
+ }
45
+
46
+ // if the selection is still within the table's range then prevent default action
47
+ event.preventDefault();
48
+ }
49
+ };
50
+ }
51
+ };
@@ -0,0 +1,48 @@
1
+ export const command = {
2
+ name: 'tabNavigation',
3
+ callback(hot) {
4
+ const rowWrapState = {
5
+ wrapped: false,
6
+ flipped: false
7
+ };
8
+ let isTabOrShiftTabPressed = false;
9
+ let preventViewportScroll = false;
10
+ hot.addHook('afterSelection', (row, column, row2, column2, preventScrolling) => {
11
+ if (isTabOrShiftTabPressed && (rowWrapState.wrapped && rowWrapState.flipped || preventViewportScroll)) {
12
+ preventViewportScroll = false;
13
+ preventScrolling.value = true;
14
+ }
15
+ });
16
+ hot.addHook('beforeRowWrap', (interruptedByAutoInsertMode, newCoords, isFlipped) => {
17
+ rowWrapState.wrapped = true;
18
+ rowWrapState.flipped = isFlipped;
19
+ });
20
+ return {
21
+ before() {
22
+ const {
23
+ tabNavigation
24
+ } = hot.getSettings();
25
+ isTabOrShiftTabPressed = true;
26
+ if (!tabNavigation) {
27
+ preventViewportScroll = true;
28
+ }
29
+ },
30
+ after(event) {
31
+ const {
32
+ tabNavigation,
33
+ autoWrapRow
34
+ } = hot.getSettings();
35
+ isTabOrShiftTabPressed = false;
36
+ if (!tabNavigation || !hot.selection.isSelected() || autoWrapRow && rowWrapState.wrapped && rowWrapState.flipped || !autoWrapRow && rowWrapState.wrapped) {
37
+ rowWrapState.wrapped = false;
38
+ rowWrapState.flipped = false;
39
+ hot.deselectCell();
40
+ return false;
41
+ }
42
+
43
+ // if the selection is still within the table's range then prevent default action
44
+ event.preventDefault();
45
+ }
46
+ };
47
+ }
48
+ };
@@ -1,11 +1,26 @@
1
1
  "use strict";
2
2
 
3
3
  exports.__esModule = true;
4
+ /* eslint-disable jsdoc/require-description-complete-sentence */
4
5
  /**
5
6
  * Group name for keyboard shortcuts that are active when the cell is selected.
6
7
  */
7
8
  const GRID_GROUP = exports.GRID_GROUP = 'gridDefault';
9
+ /**
10
+ * Scope name for the grid.
11
+ */
12
+ const GRID_SCOPE = exports.GRID_SCOPE = 'grid';
13
+ /**
14
+ * A special group that is used to group keyboard shortcuts that listen to tab navigation events only to
15
+ * handle the tab navigation logic and proper focus movement between the grid and other UI elements
16
+ * provided by the plugin (e.g. dialog or pagination).
17
+ */
18
+ const GRID_TAB_NAVIGATION_GROUP = exports.GRID_TAB_NAVIGATION_GROUP = 'grid.tabNavigation';
8
19
  /**
9
20
  * Group name for keyboard shortcuts that are active when the cell editor is active.
10
21
  */
11
- const EDITOR_EDIT_GROUP = exports.EDITOR_EDIT_GROUP = 'editorManager.handlingEditor';
22
+ const EDITOR_EDIT_GROUP = exports.EDITOR_EDIT_GROUP = 'editorManager.handlingEditor';
23
+ /**
24
+ * Scope name for the editor.
25
+ */
26
+ const EDITOR_SCOPE = exports.EDITOR_SCOPE = 'editor';
@@ -1,8 +1,23 @@
1
+ /* eslint-disable jsdoc/require-description-complete-sentence */
1
2
  /**
2
3
  * Group name for keyboard shortcuts that are active when the cell is selected.
3
4
  */
4
5
  export const GRID_GROUP = 'gridDefault';
6
+ /**
7
+ * Scope name for the grid.
8
+ */
9
+ export const GRID_SCOPE = 'grid';
10
+ /**
11
+ * A special group that is used to group keyboard shortcuts that listen to tab navigation events only to
12
+ * handle the tab navigation logic and proper focus movement between the grid and other UI elements
13
+ * provided by the plugin (e.g. dialog or pagination).
14
+ */
15
+ export const GRID_TAB_NAVIGATION_GROUP = 'grid.tabNavigation';
5
16
  /**
6
17
  * Group name for keyboard shortcuts that are active when the cell editor is active.
7
18
  */
8
- export const EDITOR_EDIT_GROUP = 'editorManager.handlingEditor';
19
+ export const EDITOR_EDIT_GROUP = 'editorManager.handlingEditor';
20
+ /**
21
+ * Scope name for the editor.
22
+ */
23
+ export const EDITOR_SCOPE = 'editor';
@@ -10,7 +10,7 @@ var _commands = require("./commands");
10
10
  * @param {Handsontable} hot The Handsontable instance.
11
11
  */
12
12
  function shortcutsEditorContext(hot) {
13
- const context = hot.getShortcutManager().addContext('editor');
13
+ const context = hot.getShortcutManager().addContext(_constants.EDITOR_SCOPE);
14
14
  const commandsPool = (0, _commands.createKeyboardShortcutCommandsPool)(hot);
15
15
  const config = {
16
16
  group: _constants.EDITOR_EDIT_GROUP
@@ -24,7 +24,7 @@ function shortcutsEditorContext(hot) {
24
24
  callback: (event, keys) => commandsPool.editorCloseAndSaveByEnter(event, keys)
25
25
  }, {
26
26
  keys: [['Tab'], ['Tab', 'Shift'], ['PageDown'], ['PageUp']],
27
- forwardToContext: hot.getShortcutManager().getContext('grid'),
27
+ forwardToContext: hot.getShortcutManager().getContext(_constants.GRID_SCOPE),
28
28
  callback: (event, keys) => commandsPool.editorCloseAndSave(event, keys)
29
29
  }, {
30
30
  keys: [['ArrowDown'], ['ArrowUp'], ['ArrowLeft'], ['ArrowRight']],
@@ -1,4 +1,4 @@
1
- import { EDITOR_EDIT_GROUP } from "./constants.mjs";
1
+ import { EDITOR_EDIT_GROUP, EDITOR_SCOPE, GRID_SCOPE } from "./constants.mjs";
2
2
  import { createKeyboardShortcutCommandsPool } from "./commands/index.mjs";
3
3
  /**
4
4
  * The context that defines a base shortcut list available for cells editors.
@@ -6,7 +6,7 @@ import { createKeyboardShortcutCommandsPool } from "./commands/index.mjs";
6
6
  * @param {Handsontable} hot The Handsontable instance.
7
7
  */
8
8
  export function shortcutsEditorContext(hot) {
9
- const context = hot.getShortcutManager().addContext('editor');
9
+ const context = hot.getShortcutManager().addContext(EDITOR_SCOPE);
10
10
  const commandsPool = createKeyboardShortcutCommandsPool(hot);
11
11
  const config = {
12
12
  group: EDITOR_EDIT_GROUP
@@ -20,7 +20,7 @@ export function shortcutsEditorContext(hot) {
20
20
  callback: (event, keys) => commandsPool.editorCloseAndSaveByEnter(event, keys)
21
21
  }, {
22
22
  keys: [['Tab'], ['Tab', 'Shift'], ['PageDown'], ['PageUp']],
23
- forwardToContext: hot.getShortcutManager().getContext('grid'),
23
+ forwardToContext: hot.getShortcutManager().getContext(GRID_SCOPE),
24
24
  callback: (event, keys) => commandsPool.editorCloseAndSave(event, keys)
25
25
  }, {
26
26
  keys: [['ArrowDown'], ['ArrowUp'], ['ArrowLeft'], ['ArrowRight']],