handsontable 0.0.0-next-4ad1863-20241122 → 0.0.0-next-fd9f817-20241125

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 (104) 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 +17 -9
  28. package/3rdparty/walkontable/src/table.mjs +17 -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 +287 -0
  34. package/3rdparty/walkontable/src/utils/stylesHandler.mjs +283 -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 +9 -0
  40. package/core/hooks/constants.mjs +9 -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 +4547 -4210
  50. package/dist/handsontable.full.min.css +11 -9
  51. package/dist/handsontable.full.min.js +53 -53
  52. package/dist/handsontable.js +4254 -3911
  53. package/dist/handsontable.min.css +5 -4
  54. package/dist/handsontable.min.js +24 -24
  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 +9 -0
  60. package/editors/dateEditor/dateEditor.mjs +10 -1
  61. package/editors/handsontableEditor/handsontableEditor.js +7 -1
  62. package/editors/handsontableEditor/handsontableEditor.mjs +7 -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/helpers/dom/element.js +32 -1
  68. package/helpers/dom/element.mjs +31 -1
  69. package/helpers/mixed.js +2 -2
  70. package/helpers/mixed.mjs +2 -2
  71. package/helpers/themes.js +17 -0
  72. package/helpers/themes.mjs +13 -0
  73. package/package.json +10 -3
  74. package/plugins/comments/commentEditor.js +9 -0
  75. package/plugins/comments/commentEditor.mjs +9 -0
  76. package/plugins/comments/comments.js +14 -0
  77. package/plugins/comments/comments.mjs +15 -1
  78. package/plugins/contextMenu/menu/menu.js +9 -4
  79. package/plugins/contextMenu/menu/menu.mjs +9 -4
  80. package/plugins/filters/ui/multipleSelect.js +6 -0
  81. package/plugins/filters/ui/multipleSelect.mjs +6 -0
  82. package/plugins/manualRowMove/manualRowMove.js +1 -1
  83. package/plugins/manualRowMove/manualRowMove.mjs +1 -1
  84. package/plugins/manualRowResize/manualRowResize.js +1 -2
  85. package/plugins/manualRowResize/manualRowResize.mjs +2 -3
  86. package/plugins/mergeCells/mergeCells.js +1 -1
  87. package/plugins/mergeCells/mergeCells.mjs +1 -1
  88. package/plugins/nestedRows/ui/headers.js +7 -1
  89. package/plugins/nestedRows/ui/headers.mjs +7 -1
  90. package/plugins/stretchColumns/calculator.js +2 -1
  91. package/plugins/stretchColumns/calculator.mjs +3 -2
  92. package/settings.d.ts +1 -0
  93. package/styles/handsontable.css +2187 -0
  94. package/styles/handsontable.min.css +30 -0
  95. package/styles/ht-theme-horizon.css +607 -0
  96. package/styles/ht-theme-horizon.min.css +30 -0
  97. package/styles/ht-theme-main.css +613 -0
  98. package/styles/ht-theme-main.min.css +30 -0
  99. package/tableView.js +46 -0
  100. package/tableView.mjs +47 -1
  101. package/utils/autoResize.js +4 -1
  102. package/utils/autoResize.mjs +4 -1
  103. package/utils/ghostTable.js +5 -3
  104. 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,12 @@ class DateEditor extends _textEditor.TextEditor {
52
52
  this.parentDestroyed = true;
53
53
  this.destroyElements();
54
54
  });
55
+ this.hot.addHook('afterSetTheme', (themeName, firstRun) => {
56
+ if (!firstRun) {
57
+ (0, _element.removeClass)(this.datePicker, /ht-theme-.*/g);
58
+ (0, _element.addClass)(this.datePicker, themeName);
59
+ }
60
+ });
55
61
  }
56
62
 
57
63
  /**
@@ -67,6 +73,9 @@ class DateEditor extends _textEditor.TextEditor {
67
73
  this.datePickerStyle.zIndex = 9999;
68
74
  this.datePicker.setAttribute('dir', this.hot.isRtl() ? 'rtl' : 'ltr');
69
75
  (0, _element.addClass)(this.datePicker, 'htDatepickerHolder');
76
+ const themeClassName = this.hot.getCurrentThemeName();
77
+ (0, _element.removeClass)(this.datePicker, /ht-theme-.*/g);
78
+ (0, _element.addClass)(this.datePicker, themeClassName);
70
79
  this.hot.rootDocument.body.appendChild(this.datePicker);
71
80
 
72
81
  /**
@@ -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,12 @@ export class DateEditor extends TextEditor {
48
48
  this.parentDestroyed = true;
49
49
  this.destroyElements();
50
50
  });
51
+ this.hot.addHook('afterSetTheme', (themeName, firstRun) => {
52
+ if (!firstRun) {
53
+ removeClass(this.datePicker, /ht-theme-.*/g);
54
+ addClass(this.datePicker, themeName);
55
+ }
56
+ });
51
57
  }
52
58
 
53
59
  /**
@@ -63,6 +69,9 @@ export class DateEditor extends TextEditor {
63
69
  this.datePickerStyle.zIndex = 9999;
64
70
  this.datePicker.setAttribute('dir', this.hot.isRtl() ? 'rtl' : 'ltr');
65
71
  addClass(this.datePicker, 'htDatepickerHolder');
72
+ const themeClassName = this.hot.getCurrentThemeName();
73
+ removeClass(this.datePicker, /ht-theme-.*/g);
74
+ addClass(this.datePicker, themeClassName);
66
75
  this.hot.rootDocument.body.appendChild(this.datePicker);
67
76
 
68
77
  /**
@@ -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,11 @@ class HandsontableEditor extends _textEditor.TextEditor {
186
187
  this.htEditor.destroy();
187
188
  }
188
189
  });
190
+ this.hot.addHook('afterSetTheme', (themeName, firstRun) => {
191
+ if (!firstRun) {
192
+ this.htEditor.useTheme(themeName);
193
+ }
194
+ });
189
195
  }
190
196
 
191
197
  /**
@@ -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,11 @@ export class HandsontableEditor extends TextEditor {
183
184
  this.htEditor.destroy();
184
185
  }
185
186
  });
187
+ this.hot.addHook('afterSetTheme', (themeName, firstRun) => {
188
+ if (!firstRun) {
189
+ this.htEditor.useTheme(themeName);
190
+ }
191
+ });
186
192
  }
187
193
 
188
194
  /**
@@ -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
 
@@ -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-4ad1863-20241122";
137
+ const hotVersion = "0.0.0-next-fd9f817-20241125";
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-4ad1863-20241122";
127
+ const hotVersion = "0.0.0-next-fd9f817-20241125";
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-4ad1863-20241122",
13
+ "version": "0.0.0-next-fd9f817-20241125",
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
  */
@@ -234,6 +234,12 @@ class Comments extends _base.BasePlugin {
234
234
  this.addHook('afterScroll', () => _assertClassBrand(_Comments_brand, this, _onAfterScroll).call(this));
235
235
  this.addHook('afterBeginEditing', () => this.hide());
236
236
  this.addHook('afterDocumentKeyDown', event => _assertClassBrand(_Comments_brand, this, _onAfterDocumentKeyDown).call(this, event));
237
+ this.addHook('afterSetTheme', function () {
238
+ for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
239
+ args[_key2] = arguments[_key2];
240
+ }
241
+ return _assertClassBrand(_Comments_brand, _this, _updateEditorThemeClassName).call(_this, ...args);
242
+ });
237
243
  _classPrivateFieldGet(_displaySwitch, this).addLocalHook('hide', () => this.hide());
238
244
  _classPrivateFieldGet(_displaySwitch, this).addLocalHook('show', (row, col) => this.showAtCell(row, col));
239
245
  this.registerShortcuts();
@@ -788,4 +794,12 @@ function _onAfterScroll() {
788
794
  if (!_classPrivateFieldGet(_preventEditorHiding, this)) {
789
795
  this.hide();
790
796
  }
797
+ }
798
+ /**
799
+ * Updates the editor theme class name.
800
+ */
801
+ function _updateEditorThemeClassName() {
802
+ const editorElement = _classPrivateFieldGet(_editor, this).getEditorElement();
803
+ (0, _element.removeClass)(editorElement, /ht-theme-.*/g);
804
+ (0, _element.addClass)(editorElement, this.hot.getCurrentThemeName());
791
805
  }
@@ -9,7 +9,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
9
9
  function _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }
10
10
  function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }
11
11
  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"); }
12
- import { addClass, closest, isChildOf, hasClass, outerHeight } from "../../helpers/dom/element.mjs";
12
+ import { addClass, removeClass, closest, isChildOf, hasClass, outerHeight } from "../../helpers/dom/element.mjs";
13
13
  import { stopImmediatePropagation } from "../../helpers/dom/event.mjs";
14
14
  import { deepClone, deepExtend } from "../../helpers/object.mjs";
15
15
  import { BasePlugin } from "../base/index.mjs";
@@ -230,6 +230,12 @@ export class Comments extends BasePlugin {
230
230
  this.addHook('afterScroll', () => _assertClassBrand(_Comments_brand, this, _onAfterScroll).call(this));
231
231
  this.addHook('afterBeginEditing', () => this.hide());
232
232
  this.addHook('afterDocumentKeyDown', event => _assertClassBrand(_Comments_brand, this, _onAfterDocumentKeyDown).call(this, event));
233
+ this.addHook('afterSetTheme', function () {
234
+ for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
235
+ args[_key2] = arguments[_key2];
236
+ }
237
+ return _assertClassBrand(_Comments_brand, _this, _updateEditorThemeClassName).call(_this, ...args);
238
+ });
233
239
  _classPrivateFieldGet(_displaySwitch, this).addLocalHook('hide', () => this.hide());
234
240
  _classPrivateFieldGet(_displaySwitch, this).addLocalHook('show', (row, col) => this.showAtCell(row, col));
235
241
  this.registerShortcuts();
@@ -783,4 +789,12 @@ function _onAfterScroll() {
783
789
  if (!_classPrivateFieldGet(_preventEditorHiding, this)) {
784
790
  this.hide();
785
791
  }
792
+ }
793
+ /**
794
+ * Updates the editor theme class name.
795
+ */
796
+ function _updateEditorThemeClassName() {
797
+ const editorElement = _classPrivateFieldGet(_editor, this).getEditorElement();
798
+ removeClass(editorElement, /ht-theme-.*/g);
799
+ addClass(editorElement, this.hot.getCurrentThemeName());
786
800
  }