handsontable 0.0.0-next-4b40c99-20241108 → 0.0.0-next-bb36dee-20241108

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


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

Files changed (109) hide show
  1. package/3rdparty/walkontable/src/calculator/index.js +1 -2
  2. package/3rdparty/walkontable/src/calculator/index.mjs +2 -2
  3. package/3rdparty/walkontable/src/calculator/viewportRows.js +3 -3
  4. package/3rdparty/walkontable/src/calculator/viewportRows.mjs +3 -3
  5. package/3rdparty/walkontable/src/core/_base.js +3 -0
  6. package/3rdparty/walkontable/src/core/_base.mjs +3 -0
  7. package/3rdparty/walkontable/src/core/clone.js +1 -0
  8. package/3rdparty/walkontable/src/core/clone.mjs +1 -0
  9. package/3rdparty/walkontable/src/core/core.js +2 -0
  10. package/3rdparty/walkontable/src/core/core.mjs +2 -0
  11. package/3rdparty/walkontable/src/facade/core.js +3 -0
  12. package/3rdparty/walkontable/src/facade/core.mjs +3 -0
  13. package/3rdparty/walkontable/src/index.js +0 -1
  14. package/3rdparty/walkontable/src/index.mjs +2 -2
  15. package/3rdparty/walkontable/src/overlay/_base.js +3 -1
  16. package/3rdparty/walkontable/src/overlay/_base.mjs +3 -1
  17. package/3rdparty/walkontable/src/overlay/bottom.js +2 -2
  18. package/3rdparty/walkontable/src/overlay/bottom.mjs +2 -2
  19. package/3rdparty/walkontable/src/overlay/top.js +1 -1
  20. package/3rdparty/walkontable/src/overlay/top.mjs +1 -1
  21. package/3rdparty/walkontable/src/renderer/index.js +4 -2
  22. package/3rdparty/walkontable/src/renderer/index.mjs +4 -2
  23. package/3rdparty/walkontable/src/renderer/table.js +12 -3
  24. package/3rdparty/walkontable/src/renderer/table.mjs +12 -3
  25. package/3rdparty/walkontable/src/settings.js +0 -2
  26. package/3rdparty/walkontable/src/settings.mjs +0 -2
  27. package/3rdparty/walkontable/src/table.js +15 -9
  28. package/3rdparty/walkontable/src/table.mjs +15 -9
  29. package/3rdparty/walkontable/src/types.js +1 -0
  30. package/3rdparty/walkontable/src/types.mjs +1 -0
  31. package/3rdparty/walkontable/src/utils/column.js +1 -1
  32. package/3rdparty/walkontable/src/utils/column.mjs +1 -1
  33. package/3rdparty/walkontable/src/utils/stylesHandler.js +272 -0
  34. package/3rdparty/walkontable/src/utils/stylesHandler.mjs +268 -0
  35. package/3rdparty/walkontable/src/viewport.js +1 -0
  36. package/3rdparty/walkontable/src/viewport.mjs +1 -0
  37. package/base.js +2 -2
  38. package/base.mjs +2 -2
  39. package/core/hooks/constants.js +8 -0
  40. package/core/hooks/constants.mjs +8 -0
  41. package/core/hooks/index.d.ts +1 -0
  42. package/core.d.ts +2 -0
  43. package/core.js +47 -0
  44. package/core.mjs +47 -0
  45. package/dataMap/metaManager/metaSchema.js +23 -3
  46. package/dataMap/metaManager/metaSchema.mjs +23 -3
  47. package/dist/handsontable.css +17 -9
  48. package/dist/handsontable.full.css +249 -240
  49. package/dist/handsontable.full.js +4521 -4217
  50. package/dist/handsontable.full.min.css +11 -9
  51. package/dist/handsontable.full.min.js +53 -53
  52. package/dist/handsontable.js +4228 -3918
  53. package/dist/handsontable.min.css +5 -4
  54. package/dist/handsontable.min.js +23 -23
  55. package/editors/autocompleteEditor/autocompleteEditor.js +1 -1
  56. package/editors/autocompleteEditor/autocompleteEditor.mjs +1 -1
  57. package/editors/baseEditor/baseEditor.js +1 -1
  58. package/editors/baseEditor/baseEditor.mjs +1 -1
  59. package/editors/dateEditor/dateEditor.js +7 -0
  60. package/editors/dateEditor/dateEditor.mjs +8 -1
  61. package/editors/handsontableEditor/handsontableEditor.js +5 -1
  62. package/editors/handsontableEditor/handsontableEditor.mjs +5 -1
  63. package/editors/selectEditor/selectEditor.js +20 -9
  64. package/editors/selectEditor/selectEditor.mjs +20 -9
  65. package/editors/textEditor/textEditor.js +4 -11
  66. package/editors/textEditor/textEditor.mjs +4 -11
  67. package/focusManager.js +5 -7
  68. package/focusManager.mjs +5 -7
  69. package/helpers/dom/element.js +32 -1
  70. package/helpers/dom/element.mjs +31 -1
  71. package/helpers/mixed.js +2 -2
  72. package/helpers/mixed.mjs +2 -2
  73. package/helpers/themes.js +17 -0
  74. package/helpers/themes.mjs +13 -0
  75. package/package.json +10 -3
  76. package/plugins/comments/commentEditor.js +9 -0
  77. package/plugins/comments/commentEditor.mjs +9 -0
  78. package/plugins/comments/comments.js +9 -0
  79. package/plugins/comments/comments.mjs +10 -1
  80. package/plugins/contextMenu/contextMenu.d.ts +2 -1
  81. package/plugins/contextMenu/menu/menu.js +7 -4
  82. package/plugins/contextMenu/menu/menu.mjs +7 -4
  83. package/plugins/copyPaste/copyPaste.d.ts +1 -0
  84. package/plugins/dropdownMenu/dropdownMenu.d.ts +2 -1
  85. package/plugins/filters/ui/multipleSelect.js +4 -0
  86. package/plugins/filters/ui/multipleSelect.mjs +4 -0
  87. package/plugins/manualRowMove/manualRowMove.js +1 -1
  88. package/plugins/manualRowMove/manualRowMove.mjs +1 -1
  89. package/plugins/manualRowResize/manualRowResize.js +1 -2
  90. package/plugins/manualRowResize/manualRowResize.mjs +2 -3
  91. package/plugins/mergeCells/mergeCells.js +1 -1
  92. package/plugins/mergeCells/mergeCells.mjs +1 -1
  93. package/plugins/nestedRows/ui/headers.js +7 -1
  94. package/plugins/nestedRows/ui/headers.mjs +7 -1
  95. package/plugins/stretchColumns/calculator.js +2 -1
  96. package/plugins/stretchColumns/calculator.mjs +3 -2
  97. package/settings.d.ts +1 -0
  98. package/styles/handsontable.css +2053 -0
  99. package/styles/handsontable.min.css +30 -0
  100. package/styles/ht-theme-horizon.css +571 -0
  101. package/styles/ht-theme-horizon.min.css +30 -0
  102. package/styles/ht-theme-main.css +575 -0
  103. package/styles/ht-theme-main.min.css +30 -0
  104. package/tableView.js +46 -0
  105. package/tableView.mjs +47 -1
  106. package/utils/autoResize.js +4 -1
  107. package/utils/autoResize.mjs +4 -1
  108. package/utils/ghostTable.js +5 -3
  109. package/utils/ghostTable.mjs +5 -3
@@ -379,7 +379,7 @@ class AutocompleteEditor extends _handsontableEditor.HandsontableEditor {
379
379
  let lastRowHeight = 0;
380
380
  let height = null;
381
381
  do {
382
- lastRowHeight = this.htEditor.getRowHeight(i) || this.htEditor.view._wt.getSetting('defaultRowHeight');
382
+ lastRowHeight = this.htEditor.getRowHeight(i) || this.htEditor.view.getDefaultRowHeight();
383
383
  tempHeight += lastRowHeight;
384
384
  i += 1;
385
385
  } while (tempHeight < spaceAvailable);
@@ -376,7 +376,7 @@ export class AutocompleteEditor extends HandsontableEditor {
376
376
  let lastRowHeight = 0;
377
377
  let height = null;
378
378
  do {
379
- lastRowHeight = this.htEditor.getRowHeight(i) || this.htEditor.view._wt.getSetting('defaultRowHeight');
379
+ lastRowHeight = this.htEditor.getRowHeight(i) || this.htEditor.view.getDefaultRowHeight();
380
380
  tempHeight += lastRowHeight;
381
381
  i += 1;
382
382
  } while (tempHeight < spaceAvailable);
@@ -492,7 +492,7 @@ class BaseEditor {
492
492
  const actualVerticalScrollbarWidth = (0, _element.hasVerticalScrollbar)(scrollableContainerTop) ? scrollbarWidth : 0;
493
493
  const actualHorizontalScrollbarWidth = (0, _element.hasHorizontalScrollbar)(scrollableContainerLeft) ? scrollbarWidth : 0;
494
494
  const maxWidth = this.hot.view.maximumVisibleElementWidth(cellStartOffset) - actualVerticalScrollbarWidth + inlineStartBorderCompensation;
495
- const maxHeight = Math.max(this.hot.view.maximumVisibleElementHeight(cellTopOffset) - actualHorizontalScrollbarWidth + topBorderCompensation, 23);
495
+ const maxHeight = Math.max(this.hot.view.maximumVisibleElementHeight(cellTopOffset) - actualHorizontalScrollbarWidth + topBorderCompensation, this.hot.view.getDefaultRowHeight());
496
496
  return {
497
497
  top: topPos,
498
498
  start: inlineStartPos,
@@ -488,7 +488,7 @@ export class BaseEditor {
488
488
  const actualVerticalScrollbarWidth = hasVerticalScrollbar(scrollableContainerTop) ? scrollbarWidth : 0;
489
489
  const actualHorizontalScrollbarWidth = hasHorizontalScrollbar(scrollableContainerLeft) ? scrollbarWidth : 0;
490
490
  const maxWidth = this.hot.view.maximumVisibleElementWidth(cellStartOffset) - actualVerticalScrollbarWidth + inlineStartBorderCompensation;
491
- const maxHeight = Math.max(this.hot.view.maximumVisibleElementHeight(cellTopOffset) - actualHorizontalScrollbarWidth + topBorderCompensation, 23);
491
+ const maxHeight = Math.max(this.hot.view.maximumVisibleElementHeight(cellTopOffset) - actualHorizontalScrollbarWidth + topBorderCompensation, this.hot.view.getDefaultRowHeight());
492
492
  return {
493
493
  top: topPos,
494
494
  start: inlineStartPos,
@@ -52,6 +52,10 @@ class DateEditor extends _textEditor.TextEditor {
52
52
  this.parentDestroyed = true;
53
53
  this.destroyElements();
54
54
  });
55
+ this.hot.addHook('afterSetTheme', themeName => {
56
+ (0, _element.removeClass)(this.datePicker, /ht-theme-.*/g);
57
+ (0, _element.addClass)(this.datePicker, themeName);
58
+ });
55
59
  }
56
60
 
57
61
  /**
@@ -67,6 +71,9 @@ class DateEditor extends _textEditor.TextEditor {
67
71
  this.datePickerStyle.zIndex = 9999;
68
72
  this.datePicker.setAttribute('dir', this.hot.isRtl() ? 'rtl' : 'ltr');
69
73
  (0, _element.addClass)(this.datePicker, 'htDatepickerHolder');
74
+ const themeClassName = this.hot.getCurrentThemeName();
75
+ (0, _element.removeClass)(this.datePicker, /ht-theme-.*/g);
76
+ (0, _element.addClass)(this.datePicker, themeClassName);
70
77
  this.hot.rootDocument.body.appendChild(this.datePicker);
71
78
 
72
79
  /**
@@ -6,7 +6,7 @@ import moment from 'moment';
6
6
  import Pikaday from '@handsontable/pikaday';
7
7
  import { EDITOR_STATE } from "../baseEditor/index.mjs";
8
8
  import { TextEditor } from "../textEditor/index.mjs";
9
- import { addClass, hasClass, outerHeight, outerWidth } from "../../helpers/dom/element.mjs";
9
+ import { addClass, removeClass, hasClass, outerHeight, outerWidth } from "../../helpers/dom/element.mjs";
10
10
  import { deepExtend } from "../../helpers/object.mjs";
11
11
  import { isFunctionKey } from "../../helpers/unicode.mjs";
12
12
  export const EDITOR_TYPE = 'date';
@@ -48,6 +48,10 @@ export class DateEditor extends TextEditor {
48
48
  this.parentDestroyed = true;
49
49
  this.destroyElements();
50
50
  });
51
+ this.hot.addHook('afterSetTheme', themeName => {
52
+ removeClass(this.datePicker, /ht-theme-.*/g);
53
+ addClass(this.datePicker, themeName);
54
+ });
51
55
  }
52
56
 
53
57
  /**
@@ -63,6 +67,9 @@ export class DateEditor extends TextEditor {
63
67
  this.datePickerStyle.zIndex = 9999;
64
68
  this.datePicker.setAttribute('dir', this.hot.isRtl() ? 'rtl' : 'ltr');
65
69
  addClass(this.datePicker, 'htDatepickerHolder');
70
+ const themeClassName = this.hot.getCurrentThemeName();
71
+ removeClass(this.datePicker, /ht-theme-.*/g);
72
+ addClass(this.datePicker, themeClassName);
66
73
  this.hot.rootDocument.body.appendChild(this.datePicker);
67
74
 
68
75
  /**
@@ -89,6 +89,7 @@ class HandsontableEditor extends _textEditor.TextEditor {
89
89
  autoWrapCol: false,
90
90
  autoWrapRow: false,
91
91
  ariaTags: false,
92
+ themeName: this.hot.getCurrentThemeName(),
92
93
  afterOnCellMouseDown(_, coords) {
93
94
  const sourceValue = this.getSourceData(coords.row, coords.col);
94
95
 
@@ -162,7 +163,7 @@ class HandsontableEditor extends _textEditor.TextEditor {
162
163
  * @returns {number}
163
164
  */
164
165
  getHeight() {
165
- return this.htEditor.view.getTableHeight();
166
+ return this.htEditor.view.getTableHeight() + 1;
166
167
  }
167
168
 
168
169
  /**
@@ -186,6 +187,9 @@ class HandsontableEditor extends _textEditor.TextEditor {
186
187
  this.htEditor.destroy();
187
188
  }
188
189
  });
190
+ this.hot.addHook('afterSetTheme', themeName => {
191
+ this.htEditor.useTheme(themeName);
192
+ });
189
193
  }
190
194
 
191
195
  /**
@@ -86,6 +86,7 @@ export class HandsontableEditor extends TextEditor {
86
86
  autoWrapCol: false,
87
87
  autoWrapRow: false,
88
88
  ariaTags: false,
89
+ themeName: this.hot.getCurrentThemeName(),
89
90
  afterOnCellMouseDown(_, coords) {
90
91
  const sourceValue = this.getSourceData(coords.row, coords.col);
91
92
 
@@ -159,7 +160,7 @@ export class HandsontableEditor extends TextEditor {
159
160
  * @returns {number}
160
161
  */
161
162
  getHeight() {
162
- return this.htEditor.view.getTableHeight();
163
+ return this.htEditor.view.getTableHeight() + 1;
163
164
  }
164
165
 
165
166
  /**
@@ -183,6 +184,9 @@ export class HandsontableEditor extends TextEditor {
183
184
  this.htEditor.destroy();
184
185
  }
185
186
  });
187
+ this.hot.addHook('afterSetTheme', themeName => {
188
+ this.htEditor.useTheme(themeName);
189
+ });
186
190
  }
187
191
 
188
192
  /**
@@ -4,6 +4,7 @@ exports.__esModule = true;
4
4
  var _baseEditor = require("../baseEditor");
5
5
  var _element = require("../../helpers/dom/element");
6
6
  var _object = require("../../helpers/object");
7
+ var _a11y = require("../../helpers/a11y");
7
8
  const EDITOR_VISIBLE_CLASS_NAME = 'ht_editor_visible';
8
9
  const SHORTCUTS_GROUP = 'selectEditor';
9
10
  const EDITOR_TYPE = exports.EDITOR_TYPE = 'select';
@@ -21,11 +22,21 @@ class SelectEditor extends _baseEditor.BaseEditor {
21
22
  * Initializes editor instance, DOM Element and mount hooks.
22
23
  */
23
24
  init() {
25
+ this.selectWrapper = this.hot.rootDocument.createElement('div');
24
26
  this.select = this.hot.rootDocument.createElement('select');
25
27
  this.select.setAttribute('data-hot-input', 'true');
26
- this.select.style.display = 'none';
27
- (0, _element.addClass)(this.select, 'htSelectEditor');
28
- this.hot.rootElement.appendChild(this.select);
28
+ this.selectWrapper.style.display = 'none';
29
+ const ARROW = this.hot.rootDocument.createElement('DIV');
30
+ const isAriaEnabled = this.hot.getSettings().ariaTags;
31
+ ARROW.className = 'htAutocompleteArrow';
32
+ if (isAriaEnabled) {
33
+ ARROW.setAttribute(...(0, _a11y.A11Y_HIDDEN)());
34
+ }
35
+ ARROW.appendChild(this.hot.rootDocument.createTextNode(String.fromCharCode(9660)));
36
+ (0, _element.addClass)(this.selectWrapper, 'htSelectEditor');
37
+ this.selectWrapper.appendChild(this.select);
38
+ this.selectWrapper.insertBefore(ARROW, this.selectWrapper.firstChild);
39
+ this.hot.rootElement.appendChild(this.selectWrapper);
29
40
  this.registerHooks();
30
41
  }
31
42
 
@@ -53,7 +64,7 @@ class SelectEditor extends _baseEditor.BaseEditor {
53
64
  open() {
54
65
  this._opened = true;
55
66
  this.refreshDimensions();
56
- this.select.style.display = '';
67
+ this.selectWrapper.style.display = '';
57
68
  const shortcutManager = this.hot.getShortcutManager();
58
69
  shortcutManager.setActiveContextName('editor');
59
70
  this.registerShortcuts();
@@ -64,9 +75,9 @@ class SelectEditor extends _baseEditor.BaseEditor {
64
75
  */
65
76
  close() {
66
77
  this._opened = false;
67
- this.select.style.display = 'none';
68
- if ((0, _element.hasClass)(this.select, EDITOR_VISIBLE_CLASS_NAME)) {
69
- (0, _element.removeClass)(this.select, EDITOR_VISIBLE_CLASS_NAME);
78
+ this.selectWrapper.style.display = 'none';
79
+ if ((0, _element.hasClass)(this.selectWrapper, EDITOR_VISIBLE_CLASS_NAME)) {
80
+ (0, _element.removeClass)(this.selectWrapper, EDITOR_VISIBLE_CLASS_NAME);
70
81
  }
71
82
  this.unregisterShortcuts();
72
83
  this.clearHooks();
@@ -172,13 +183,13 @@ class SelectEditor extends _baseEditor.BaseEditor {
172
183
  width,
173
184
  height
174
185
  } = this.getEditedCellRect();
175
- const selectStyle = this.select.style;
186
+ const selectStyle = this.selectWrapper.style;
176
187
  selectStyle.height = `${height}px`;
177
188
  selectStyle.width = `${width}px`;
178
189
  selectStyle.top = `${top}px`;
179
190
  selectStyle[this.hot.isRtl() ? 'right' : 'left'] = `${start}px`;
180
191
  selectStyle.margin = '0px';
181
- (0, _element.addClass)(this.select, EDITOR_VISIBLE_CLASS_NAME);
192
+ (0, _element.addClass)(this.selectWrapper, EDITOR_VISIBLE_CLASS_NAME);
182
193
  }
183
194
 
184
195
  /**
@@ -1,6 +1,7 @@
1
1
  import { BaseEditor, EDITOR_STATE } from "../baseEditor/index.mjs";
2
2
  import { addClass, empty, fastInnerHTML, hasClass, removeClass } from "../../helpers/dom/element.mjs";
3
3
  import { objectEach } from "../../helpers/object.mjs";
4
+ import { A11Y_HIDDEN } from "../../helpers/a11y.mjs";
4
5
  const EDITOR_VISIBLE_CLASS_NAME = 'ht_editor_visible';
5
6
  const SHORTCUTS_GROUP = 'selectEditor';
6
7
  export const EDITOR_TYPE = 'select';
@@ -18,11 +19,21 @@ export class SelectEditor extends BaseEditor {
18
19
  * Initializes editor instance, DOM Element and mount hooks.
19
20
  */
20
21
  init() {
22
+ this.selectWrapper = this.hot.rootDocument.createElement('div');
21
23
  this.select = this.hot.rootDocument.createElement('select');
22
24
  this.select.setAttribute('data-hot-input', 'true');
23
- this.select.style.display = 'none';
24
- addClass(this.select, 'htSelectEditor');
25
- this.hot.rootElement.appendChild(this.select);
25
+ this.selectWrapper.style.display = 'none';
26
+ const ARROW = this.hot.rootDocument.createElement('DIV');
27
+ const isAriaEnabled = this.hot.getSettings().ariaTags;
28
+ ARROW.className = 'htAutocompleteArrow';
29
+ if (isAriaEnabled) {
30
+ ARROW.setAttribute(...A11Y_HIDDEN());
31
+ }
32
+ ARROW.appendChild(this.hot.rootDocument.createTextNode(String.fromCharCode(9660)));
33
+ addClass(this.selectWrapper, 'htSelectEditor');
34
+ this.selectWrapper.appendChild(this.select);
35
+ this.selectWrapper.insertBefore(ARROW, this.selectWrapper.firstChild);
36
+ this.hot.rootElement.appendChild(this.selectWrapper);
26
37
  this.registerHooks();
27
38
  }
28
39
 
@@ -50,7 +61,7 @@ export class SelectEditor extends BaseEditor {
50
61
  open() {
51
62
  this._opened = true;
52
63
  this.refreshDimensions();
53
- this.select.style.display = '';
64
+ this.selectWrapper.style.display = '';
54
65
  const shortcutManager = this.hot.getShortcutManager();
55
66
  shortcutManager.setActiveContextName('editor');
56
67
  this.registerShortcuts();
@@ -61,9 +72,9 @@ export class SelectEditor extends BaseEditor {
61
72
  */
62
73
  close() {
63
74
  this._opened = false;
64
- this.select.style.display = 'none';
65
- if (hasClass(this.select, EDITOR_VISIBLE_CLASS_NAME)) {
66
- removeClass(this.select, EDITOR_VISIBLE_CLASS_NAME);
75
+ this.selectWrapper.style.display = 'none';
76
+ if (hasClass(this.selectWrapper, EDITOR_VISIBLE_CLASS_NAME)) {
77
+ removeClass(this.selectWrapper, EDITOR_VISIBLE_CLASS_NAME);
67
78
  }
68
79
  this.unregisterShortcuts();
69
80
  this.clearHooks();
@@ -169,13 +180,13 @@ export class SelectEditor extends BaseEditor {
169
180
  width,
170
181
  height
171
182
  } = this.getEditedCellRect();
172
- const selectStyle = this.select.style;
183
+ const selectStyle = this.selectWrapper.style;
173
184
  selectStyle.height = `${height}px`;
174
185
  selectStyle.width = `${width}px`;
175
186
  selectStyle.top = `${top}px`;
176
187
  selectStyle[this.hot.isRtl() ? 'right' : 'left'] = `${start}px`;
177
188
  selectStyle.margin = '0px';
178
- addClass(this.select, EDITOR_VISIBLE_CLASS_NAME);
189
+ addClass(this.selectWrapper, EDITOR_VISIBLE_CLASS_NAME);
179
190
  }
180
191
 
181
192
  /**
@@ -309,19 +309,12 @@ class TextEditor extends _baseEditor.BaseEditor {
309
309
  this.TEXTAREA.style.fontSize = cellComputedStyle.fontSize;
310
310
  this.TEXTAREA.style.fontFamily = cellComputedStyle.fontFamily;
311
311
  this.TEXTAREA.style.backgroundColor = this.TD.style.backgroundColor;
312
- const textareaComputedStyle = this.hot.rootWindow.getComputedStyle(this.TEXTAREA);
313
- const horizontalPadding = parseInt(textareaComputedStyle.paddingLeft, 10) + parseInt(textareaComputedStyle.paddingRight, 10);
314
- const verticalPadding = parseInt(textareaComputedStyle.paddingTop, 10) + parseInt(textareaComputedStyle.paddingBottom, 10);
315
- const finalWidth = width - horizontalPadding;
316
- const finalHeight = height - verticalPadding;
317
- const finalMaxWidth = maxWidth - horizontalPadding;
318
- const finalMaxHeight = maxHeight - verticalPadding;
319
312
  this.autoResize.init(this.TEXTAREA, {
320
- minWidth: Math.min(finalWidth, finalMaxWidth),
321
- minHeight: Math.min(finalHeight, finalMaxHeight),
313
+ minWidth: Math.min(width, maxWidth),
314
+ minHeight: Math.min(height, maxHeight),
322
315
  // TEXTAREA should never be wider than visible part of the viewport (should not cover the scrollbar)
323
- maxWidth: finalMaxWidth,
324
- maxHeight: finalMaxHeight
316
+ maxWidth,
317
+ maxHeight
325
318
  }, true);
326
319
  }
327
320
 
@@ -305,19 +305,12 @@ export class TextEditor extends BaseEditor {
305
305
  this.TEXTAREA.style.fontSize = cellComputedStyle.fontSize;
306
306
  this.TEXTAREA.style.fontFamily = cellComputedStyle.fontFamily;
307
307
  this.TEXTAREA.style.backgroundColor = this.TD.style.backgroundColor;
308
- const textareaComputedStyle = this.hot.rootWindow.getComputedStyle(this.TEXTAREA);
309
- const horizontalPadding = parseInt(textareaComputedStyle.paddingLeft, 10) + parseInt(textareaComputedStyle.paddingRight, 10);
310
- const verticalPadding = parseInt(textareaComputedStyle.paddingTop, 10) + parseInt(textareaComputedStyle.paddingBottom, 10);
311
- const finalWidth = width - horizontalPadding;
312
- const finalHeight = height - verticalPadding;
313
- const finalMaxWidth = maxWidth - horizontalPadding;
314
- const finalMaxHeight = maxHeight - verticalPadding;
315
308
  this.autoResize.init(this.TEXTAREA, {
316
- minWidth: Math.min(finalWidth, finalMaxWidth),
317
- minHeight: Math.min(finalHeight, finalMaxHeight),
309
+ minWidth: Math.min(width, maxWidth),
310
+ minHeight: Math.min(height, maxHeight),
318
311
  // TEXTAREA should never be wider than visible part of the viewport (should not cover the scrollbar)
319
- maxWidth: finalMaxWidth,
320
- maxHeight: finalMaxHeight
312
+ maxWidth,
313
+ maxHeight
321
314
  }, true);
322
315
  }
323
316
 
package/focusManager.js CHANGED
@@ -163,12 +163,11 @@ class FocusManager {
163
163
  * @returns {HTMLTextAreaElement|HTMLElement|undefined}
164
164
  */
165
165
  getRefocusElement() {
166
+ var _classPrivateFieldGet2;
166
167
  if (typeof _classPrivateFieldGet(_refocusElementGetter, this) === 'function') {
167
168
  return _classPrivateFieldGet(_refocusElementGetter, this).call(this);
168
- } else {
169
- var _classPrivateFieldGet2;
170
- return (_classPrivateFieldGet2 = _classPrivateFieldGet(_hot, this).getActiveEditor()) === null || _classPrivateFieldGet2 === void 0 ? void 0 : _classPrivateFieldGet2.TEXTAREA;
171
169
  }
170
+ return (_classPrivateFieldGet2 = _classPrivateFieldGet(_hot, this).getActiveEditor()) === null || _classPrivateFieldGet2 === void 0 ? void 0 : _classPrivateFieldGet2.TEXTAREA;
172
171
  }
173
172
 
174
173
  /**
@@ -209,13 +208,12 @@ class FocusManager {
209
208
  refocusToEditorTextarea() {
210
209
  var _classPrivateFieldGet5;
211
210
  let delay = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _classPrivateFieldGet(_refocusDelay, this);
212
- const refocusElement = this.getRefocusElement();
213
-
214
211
  // Re-focus on the editor's `TEXTAREA` element (or a predefined element) if the `imeFastEdit` option is enabled.
215
- if (_classPrivateFieldGet(_hot, this).getSettings().imeFastEdit && !((_classPrivateFieldGet5 = _classPrivateFieldGet(_hot, this).getActiveEditor()) !== null && _classPrivateFieldGet5 !== void 0 && _classPrivateFieldGet5.isOpened()) && !!refocusElement) {
212
+ if (_classPrivateFieldGet(_hot, this).getSettings().imeFastEdit && !((_classPrivateFieldGet5 = _classPrivateFieldGet(_hot, this).getActiveEditor()) !== null && _classPrivateFieldGet5 !== void 0 && _classPrivateFieldGet5.isOpened())) {
216
213
  if (!_classPrivateFieldGet(_debouncedSelect, this).has(delay)) {
217
214
  _classPrivateFieldGet(_debouncedSelect, this).set(delay, (0, _function.debounce)(() => {
218
- refocusElement.select();
215
+ var _this$getRefocusEleme;
216
+ (_this$getRefocusEleme = this.getRefocusElement()) === null || _this$getRefocusEleme === void 0 || _this$getRefocusEleme.select();
219
217
  }, delay));
220
218
  }
221
219
  _classPrivateFieldGet(_debouncedSelect, this).get(delay)();
package/focusManager.mjs CHANGED
@@ -160,12 +160,11 @@ export class FocusManager {
160
160
  * @returns {HTMLTextAreaElement|HTMLElement|undefined}
161
161
  */
162
162
  getRefocusElement() {
163
+ var _classPrivateFieldGet2;
163
164
  if (typeof _classPrivateFieldGet(_refocusElementGetter, this) === 'function') {
164
165
  return _classPrivateFieldGet(_refocusElementGetter, this).call(this);
165
- } else {
166
- var _classPrivateFieldGet2;
167
- return (_classPrivateFieldGet2 = _classPrivateFieldGet(_hot, this).getActiveEditor()) === null || _classPrivateFieldGet2 === void 0 ? void 0 : _classPrivateFieldGet2.TEXTAREA;
168
166
  }
167
+ return (_classPrivateFieldGet2 = _classPrivateFieldGet(_hot, this).getActiveEditor()) === null || _classPrivateFieldGet2 === void 0 ? void 0 : _classPrivateFieldGet2.TEXTAREA;
169
168
  }
170
169
 
171
170
  /**
@@ -206,13 +205,12 @@ export class FocusManager {
206
205
  refocusToEditorTextarea() {
207
206
  var _classPrivateFieldGet5;
208
207
  let delay = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _classPrivateFieldGet(_refocusDelay, this);
209
- const refocusElement = this.getRefocusElement();
210
-
211
208
  // Re-focus on the editor's `TEXTAREA` element (or a predefined element) if the `imeFastEdit` option is enabled.
212
- if (_classPrivateFieldGet(_hot, this).getSettings().imeFastEdit && !((_classPrivateFieldGet5 = _classPrivateFieldGet(_hot, this).getActiveEditor()) !== null && _classPrivateFieldGet5 !== void 0 && _classPrivateFieldGet5.isOpened()) && !!refocusElement) {
209
+ if (_classPrivateFieldGet(_hot, this).getSettings().imeFastEdit && !((_classPrivateFieldGet5 = _classPrivateFieldGet(_hot, this).getActiveEditor()) !== null && _classPrivateFieldGet5 !== void 0 && _classPrivateFieldGet5.isOpened())) {
213
210
  if (!_classPrivateFieldGet(_debouncedSelect, this).has(delay)) {
214
211
  _classPrivateFieldGet(_debouncedSelect, this).set(delay, debounce(() => {
215
- refocusElement.select();
212
+ var _this$getRefocusEleme;
213
+ (_this$getRefocusEleme = this.getRefocusElement()) === null || _this$getRefocusEleme === void 0 || _this$getRefocusEleme.select();
216
214
  }, delay));
217
215
  }
218
216
  _classPrivateFieldGet(_debouncedSelect, this).get(delay)();
@@ -9,6 +9,7 @@ exports.closestDown = closestDown;
9
9
  exports.empty = empty;
10
10
  exports.fastInnerHTML = fastInnerHTML;
11
11
  exports.fastInnerText = fastInnerText;
12
+ exports.findFirstParentWithClass = findFirstParentWithClass;
12
13
  exports.getCaretPosition = getCaretPosition;
13
14
  exports.getCssTransform = getCssTransform;
14
15
  exports.getFrameElement = getFrameElement;
@@ -197,6 +198,36 @@ function closestDown(element, nodes, until) {
197
198
  return length ? matched[length - 1] : null;
198
199
  }
199
200
 
201
+ /**
202
+ * Traverses up the DOM tree from the given element and finds parent elements that have a specified class name
203
+ * or match a provided class name regular expression.
204
+ *
205
+ * @param {HTMLElement} element - The element from which to start traversing.
206
+ * @param {string|RegExp} className - The class name or class name regular expression to check.
207
+ * @returns {{element: HTMLElement, classNames: string[]}} - Returns an object containing the matched parent element and an array of matched class names.
208
+ */
209
+ function findFirstParentWithClass(element, className) {
210
+ const matched = {
211
+ element: undefined,
212
+ classNames: []
213
+ };
214
+ let elementToCheck = element;
215
+ while (elementToCheck !== null && elementToCheck !== element.ownerDocument.documentElement && !matched.element) {
216
+ if (typeof className === 'string' && elementToCheck.classList.contains(className)) {
217
+ matched.element = elementToCheck;
218
+ matched.classNames.push(className);
219
+ } else if (className instanceof RegExp) {
220
+ const matchingClasses = Array.from(elementToCheck.classList).filter(cls => className.test(cls));
221
+ if (matchingClasses.length) {
222
+ matched.element = elementToCheck;
223
+ matched.classNames.push(...matchingClasses);
224
+ }
225
+ }
226
+ elementToCheck = elementToCheck.parentElement;
227
+ }
228
+ return matched;
229
+ }
230
+
200
231
  /**
201
232
  * Goes up the DOM tree and checks if element is child of another element.
202
233
  *
@@ -334,7 +365,7 @@ function addClass(element, className) {
334
365
  * Remove class name from an element.
335
366
  *
336
367
  * @param {HTMLElement} element An element to process.
337
- * @param {string|Array<string|RegExp>} className Class name as string or array of strings.
368
+ * @param {string|RegExp|Array<string|RegExp>} className Class name as string or array of strings.
338
369
  */
339
370
  function removeClass(element, className) {
340
371
  if (typeof className === 'string') {
@@ -138,6 +138,36 @@ export function closestDown(element, nodes, until) {
138
138
  return length ? matched[length - 1] : null;
139
139
  }
140
140
 
141
+ /**
142
+ * Traverses up the DOM tree from the given element and finds parent elements that have a specified class name
143
+ * or match a provided class name regular expression.
144
+ *
145
+ * @param {HTMLElement} element - The element from which to start traversing.
146
+ * @param {string|RegExp} className - The class name or class name regular expression to check.
147
+ * @returns {{element: HTMLElement, classNames: string[]}} - Returns an object containing the matched parent element and an array of matched class names.
148
+ */
149
+ export function findFirstParentWithClass(element, className) {
150
+ const matched = {
151
+ element: undefined,
152
+ classNames: []
153
+ };
154
+ let elementToCheck = element;
155
+ while (elementToCheck !== null && elementToCheck !== element.ownerDocument.documentElement && !matched.element) {
156
+ if (typeof className === 'string' && elementToCheck.classList.contains(className)) {
157
+ matched.element = elementToCheck;
158
+ matched.classNames.push(className);
159
+ } else if (className instanceof RegExp) {
160
+ const matchingClasses = Array.from(elementToCheck.classList).filter(cls => className.test(cls));
161
+ if (matchingClasses.length) {
162
+ matched.element = elementToCheck;
163
+ matched.classNames.push(...matchingClasses);
164
+ }
165
+ }
166
+ elementToCheck = elementToCheck.parentElement;
167
+ }
168
+ return matched;
169
+ }
170
+
141
171
  /**
142
172
  * Goes up the DOM tree and checks if element is child of another element.
143
173
  *
@@ -275,7 +305,7 @@ export function addClass(element, className) {
275
305
  * Remove class name from an element.
276
306
  *
277
307
  * @param {HTMLElement} element An element to process.
278
- * @param {string|Array<string|RegExp>} className Class name as string or array of strings.
308
+ * @param {string|RegExp|Array<string|RegExp>} className Class name as string or array of strings.
279
309
  */
280
310
  export function removeClass(element, className) {
281
311
  if (typeof className === 'string') {
package/helpers/mixed.js CHANGED
@@ -134,7 +134,7 @@ const domMessages = {
134
134
  function _injectProductInfo(key, element) {
135
135
  const hasValidType = !isEmpty(key);
136
136
  const isNonCommercial = typeof key === 'string' && key.toLowerCase() === 'non-commercial-and-evaluation';
137
- const hotVersion = "0.0.0-next-4b40c99-20241108";
137
+ const hotVersion = "0.0.0-next-bb36dee-20241108";
138
138
  let keyValidityDate;
139
139
  let consoleMessageState = 'invalid';
140
140
  let domMessageState = 'invalid';
@@ -188,7 +188,7 @@ function _injectProductInfo(key, element) {
188
188
  });
189
189
  if (message) {
190
190
  const messageNode = document.createElement('div');
191
- messageNode.className = 'hot-display-license-info';
191
+ messageNode.className = 'handsontable hot-display-license-info';
192
192
  messageNode.innerHTML = domMessages[domMessageState]({
193
193
  keyValidityDate,
194
194
  hotVersion
package/helpers/mixed.mjs CHANGED
@@ -124,7 +124,7 @@ const domMessages = {
124
124
  export function _injectProductInfo(key, element) {
125
125
  const hasValidType = !isEmpty(key);
126
126
  const isNonCommercial = typeof key === 'string' && key.toLowerCase() === 'non-commercial-and-evaluation';
127
- const hotVersion = "0.0.0-next-4b40c99-20241108";
127
+ const hotVersion = "0.0.0-next-bb36dee-20241108";
128
128
  let keyValidityDate;
129
129
  let consoleMessageState = 'invalid';
130
130
  let domMessageState = 'invalid';
@@ -178,7 +178,7 @@ export function _injectProductInfo(key, element) {
178
178
  });
179
179
  if (message) {
180
180
  const messageNode = document.createElement('div');
181
- messageNode.className = 'hot-display-license-info';
181
+ messageNode.className = 'handsontable hot-display-license-info';
182
182
  messageNode.innerHTML = domMessages[domMessageState]({
183
183
  keyValidityDate,
184
184
  hotVersion
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.getThemeClassName = getThemeClassName;
5
+ var _element = require("./dom/element");
6
+ /**
7
+ * Retrieves the theme class name from the closest parent element that matches the specified regex pattern.
8
+ *
9
+ * @param {HTMLElement} rootElement - The root element from which to start searching for the theme class.
10
+ * @returns {string} - The theme class name regex.
11
+ */
12
+ function getThemeClassName(rootElement) {
13
+ const {
14
+ classNames
15
+ } = (0, _element.findFirstParentWithClass)(rootElement, /ht-theme-[a-zA-Z0-9_-]+/);
16
+ return classNames.pop();
17
+ }
@@ -0,0 +1,13 @@
1
+ import { findFirstParentWithClass } from "./dom/element.mjs";
2
+ /**
3
+ * Retrieves the theme class name from the closest parent element that matches the specified regex pattern.
4
+ *
5
+ * @param {HTMLElement} rootElement - The root element from which to start searching for the theme class.
6
+ * @returns {string} - The theme class name regex.
7
+ */
8
+ export function getThemeClassName(rootElement) {
9
+ const {
10
+ classNames
11
+ } = findFirstParentWithClass(rootElement, /ht-theme-[a-zA-Z0-9_-]+/);
12
+ return classNames.pop();
13
+ }
package/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "url": "https://github.com/handsontable/handsontable/issues"
11
11
  },
12
12
  "author": "Handsoncode <hello@handsontable.com>",
13
- "version": "0.0.0-next-4b40c99-20241108",
13
+ "version": "0.0.0-next-bb36dee-20241108",
14
14
  "main": "index",
15
15
  "module": "index.mjs",
16
16
  "jsnext:main": "index.mjs",
@@ -48,7 +48,6 @@
48
48
  "@babel/register": "^7.8.3",
49
49
  "@babel/runtime": "^7.11.2",
50
50
  "@babel/types": "^7.12.12",
51
- "@typescript-eslint/eslint-plugin": "^4.33.0",
52
51
  "babel-jest": "^26.6.3",
53
52
  "babel-loader": "^8.0.4",
54
53
  "babel-plugin-forbidden-imports": "^0.1.2",
@@ -92,8 +91,10 @@
92
91
  "string-replace-loader": "^3.1.0",
93
92
  "stylelint": "^16.3.1",
94
93
  "typescript": "3.8.2",
94
+ "@typescript-eslint/eslint-plugin": "^4.33.0",
95
95
  "webpack": "^5.88.1",
96
- "webpack-cli": "^5.1.4"
96
+ "webpack-cli": "^5.1.4",
97
+ "webpack-remove-empty-scripts": "^1.0.4"
97
98
  },
98
99
  "optionalDependencies": {
99
100
  "hyperformula": "^2.6.2"
@@ -770,6 +771,12 @@
770
771
  "./dist/languages/zh-CN.min.js": "./dist/languages/zh-CN.min.js",
771
772
  "./dist/languages/zh-TW.js": "./dist/languages/zh-TW.js",
772
773
  "./dist/languages/zh-TW.min.js": "./dist/languages/zh-TW.min.js",
774
+ "./styles/handsontable.css": "./styles/handsontable.css",
775
+ "./styles/handsontable.min.css": "./styles/handsontable.min.css",
776
+ "./styles/ht-theme-horizon.css": "./styles/ht-theme-horizon.css",
777
+ "./styles/ht-theme-horizon.min.css": "./styles/ht-theme-horizon.min.css",
778
+ "./styles/ht-theme-main.css": "./styles/ht-theme-main.css",
779
+ "./styles/ht-theme-main.min.css": "./styles/ht-theme-main.min.css",
773
780
  ".": {
774
781
  "types": "./index.d.ts",
775
782
  "import": "./index.mjs",
@@ -241,6 +241,15 @@ class CommentEditor {
241
241
  return _classPrivateFieldGet(_editor, this).querySelector(`.${CommentEditor.CLASS_INPUT}`);
242
242
  }
243
243
 
244
+ /**
245
+ * Get the editor element.
246
+ *
247
+ * @returns {HTMLElement} The editor element.
248
+ */
249
+ getEditorElement() {
250
+ return _classPrivateFieldGet(_editor, this);
251
+ }
252
+
244
253
  /**
245
254
  * Destroy the comments editor.
246
255
  */
@@ -237,6 +237,15 @@ class CommentEditor {
237
237
  return _classPrivateFieldGet(_editor, this).querySelector(`.${CommentEditor.CLASS_INPUT}`);
238
238
  }
239
239
 
240
+ /**
241
+ * Get the editor element.
242
+ *
243
+ * @returns {HTMLElement} The editor element.
244
+ */
245
+ getEditorElement() {
246
+ return _classPrivateFieldGet(_editor, this);
247
+ }
248
+
240
249
  /**
241
250
  * Destroy the comments editor.
242
251
  */