handsontable 0.0.0-next-87b048b-20250409 → 0.0.0-next-ff10728-20250410

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

Potentially problematic release.


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

Files changed (106) hide show
  1. package/3rdparty/walkontable/src/cell/range.js +0 -14
  2. package/3rdparty/walkontable/src/cell/range.mjs +0 -14
  3. package/3rdparty/walkontable/src/renderer/rowHeaders.js +1 -4
  4. package/3rdparty/walkontable/src/renderer/rowHeaders.mjs +1 -4
  5. package/3rdparty/walkontable/src/selection/border/border.js +0 -5
  6. package/3rdparty/walkontable/src/selection/border/border.mjs +0 -5
  7. package/3rdparty/walkontable/src/table/mixin/stickyColumnsStart.js +4 -3
  8. package/3rdparty/walkontable/src/table/mixin/stickyColumnsStart.mjs +4 -3
  9. package/3rdparty/walkontable/src/table/mixin/stickyRowsBottom.js +10 -8
  10. package/3rdparty/walkontable/src/table/mixin/stickyRowsBottom.mjs +10 -8
  11. package/3rdparty/walkontable/src/table/mixin/stickyRowsTop.js +4 -3
  12. package/3rdparty/walkontable/src/table/mixin/stickyRowsTop.mjs +4 -3
  13. package/3rdparty/walkontable/src/table.js +2 -5
  14. package/3rdparty/walkontable/src/table.mjs +2 -5
  15. package/CHANGELOG.md +0 -39
  16. package/base.js +2 -2
  17. package/base.mjs +2 -2
  18. package/core/focusCatcher/focusDetector.js +1 -1
  19. package/core/focusCatcher/focusDetector.mjs +2 -2
  20. package/core/hooks/constants.js +0 -8
  21. package/core/hooks/constants.mjs +0 -8
  22. package/core/hooks/index.d.ts +0 -1
  23. package/core.d.ts +1 -0
  24. package/core.js +25 -32
  25. package/core.mjs +26 -33
  26. package/dataMap/dataMap.js +7 -0
  27. package/dataMap/dataMap.mjs +7 -0
  28. package/dataMap/metaManager/metaSchema.js +0 -1
  29. package/dataMap/metaManager/metaSchema.mjs +0 -1
  30. package/dist/handsontable.css +3 -3
  31. package/dist/handsontable.full.css +3 -3
  32. package/dist/handsontable.full.js +350 -437
  33. package/dist/handsontable.full.min.css +3 -3
  34. package/dist/handsontable.full.min.js +17 -17
  35. package/dist/handsontable.js +350 -437
  36. package/dist/handsontable.min.css +3 -3
  37. package/dist/handsontable.min.js +18 -18
  38. package/editorManager.js +7 -1
  39. package/editorManager.mjs +7 -1
  40. package/editors/autocompleteEditor/autocompleteEditor.js +4 -14
  41. package/editors/autocompleteEditor/autocompleteEditor.mjs +4 -14
  42. package/editors/textEditor/textEditor.js +1 -1
  43. package/editors/textEditor/textEditor.mjs +2 -2
  44. package/helpers/browser.js +1 -1
  45. package/helpers/browser.mjs +1 -1
  46. package/helpers/dom/element.js +2 -2
  47. package/helpers/dom/element.mjs +1 -1
  48. package/helpers/mixed.js +2 -2
  49. package/helpers/mixed.mjs +2 -2
  50. package/helpers/object.js +0 -3
  51. package/helpers/object.mjs +0 -3
  52. package/package.json +1 -1
  53. package/plugins/autoColumnSize/autoColumnSize.js +1 -1
  54. package/plugins/autoColumnSize/autoColumnSize.mjs +1 -1
  55. package/plugins/autoRowSize/autoRowSize.js +6 -1
  56. package/plugins/autoRowSize/autoRowSize.mjs +6 -1
  57. package/plugins/columnSorting/columnSorting.js +4 -0
  58. package/plugins/columnSorting/columnSorting.mjs +4 -0
  59. package/plugins/comments/comments.js +0 -1
  60. package/plugins/comments/comments.mjs +0 -1
  61. package/plugins/contextMenu/menu/defaultShortcutsList.js +2 -2
  62. package/plugins/contextMenu/menu/defaultShortcutsList.mjs +2 -2
  63. package/plugins/contextMenu/menu/menu.js +0 -1
  64. package/plugins/contextMenu/menu/menu.mjs +0 -1
  65. package/plugins/contextMenu/menu/positioner.js +2 -10
  66. package/plugins/contextMenu/menu/positioner.mjs +2 -10
  67. package/plugins/copyPaste/copyPaste.js +15 -12
  68. package/plugins/copyPaste/copyPaste.mjs +16 -13
  69. package/plugins/copyPaste/pasteEvent.js +0 -3
  70. package/plugins/copyPaste/pasteEvent.mjs +0 -3
  71. package/plugins/filters/filters.js +24 -25
  72. package/plugins/filters/filters.mjs +24 -25
  73. package/plugins/filters/ui/multipleSelect.js +1 -7
  74. package/plugins/filters/ui/multipleSelect.mjs +1 -7
  75. package/plugins/hiddenColumns/hiddenColumns.js +1 -1
  76. package/plugins/hiddenColumns/hiddenColumns.mjs +1 -1
  77. package/plugins/hiddenRows/hiddenRows.js +1 -1
  78. package/plugins/hiddenRows/hiddenRows.mjs +1 -1
  79. package/plugins/manualColumnResize/manualColumnResize.js +6 -4
  80. package/plugins/manualColumnResize/manualColumnResize.mjs +6 -4
  81. package/plugins/manualRowResize/manualRowResize.js +6 -4
  82. package/plugins/manualRowResize/manualRowResize.mjs +6 -4
  83. package/plugins/mergeCells/mergeCells.js +29 -8
  84. package/plugins/mergeCells/mergeCells.mjs +29 -8
  85. package/plugins/mergeCells/renderer.js +0 -15
  86. package/plugins/mergeCells/renderer.mjs +0 -15
  87. package/plugins/nestedRows/data/dataManager.js +2 -2
  88. package/plugins/nestedRows/data/dataManager.mjs +2 -2
  89. package/plugins/undoRedo/actions/removeColumn.js +14 -19
  90. package/plugins/undoRedo/actions/removeColumn.mjs +14 -19
  91. package/plugins/undoRedo/actions/removeRow.js +4 -12
  92. package/plugins/undoRedo/actions/removeRow.mjs +4 -12
  93. package/selection/selection.js +1 -3
  94. package/selection/selection.mjs +1 -3
  95. package/styles/handsontable.css +15 -14
  96. package/styles/handsontable.min.css +3 -3
  97. package/styles/ht-theme-horizon.css +2 -2
  98. package/styles/ht-theme-horizon.min.css +2 -2
  99. package/styles/ht-theme-main.css +2 -2
  100. package/styles/ht-theme-main.min.css +2 -2
  101. package/tableView.js +8 -5
  102. package/tableView.mjs +8 -5
  103. package/utils/ghostTable.js +0 -3
  104. package/utils/ghostTable.mjs +0 -3
  105. package/plugins/mergeCells/utils.js +0 -31
  106. package/plugins/mergeCells/utils.mjs +0 -27
@@ -105,20 +105,6 @@ class CellRange {
105
105
  return this;
106
106
  }
107
107
 
108
- /**
109
- * Normalizes the coordinates in your `CellRange` instance to the nearest valid position.
110
- *
111
- * Coordinates that point to headers (negative values) are normalized to `0`.
112
- *
113
- * @returns {CellRange}
114
- */
115
- normalize() {
116
- this.highlight.normalize();
117
- this.from.normalize();
118
- this.to.normalize();
119
- return this;
120
- }
121
-
122
108
  /**
123
109
  * Checks if the coordinates in your `CellRange` instance are valid
124
110
  * in the context of given table parameters.
@@ -101,20 +101,6 @@ class CellRange {
101
101
  return this;
102
102
  }
103
103
 
104
- /**
105
- * Normalizes the coordinates in your `CellRange` instance to the nearest valid position.
106
- *
107
- * Coordinates that point to headers (negative values) are normalized to `0`.
108
- *
109
- * @returns {CellRange}
110
- */
111
- normalize() {
112
- this.highlight.normalize();
113
- this.from.normalize();
114
- this.to.normalize();
115
- return this;
116
- }
117
-
118
104
  /**
119
105
  * Checks if the coordinates in your `CellRange` instance are valid
120
106
  * in the context of given table parameters.
@@ -74,10 +74,7 @@ class RowHeadersRenderer extends _base.BaseRenderer {
74
74
  const orderView = this.obtainOrderView(TR);
75
75
  const cellsView = cells.obtainOrderView(TR);
76
76
  orderView.appendView(cellsView).setSize(rowHeadersCount).setOffset(0).start();
77
-
78
- // Reading the row header renderers in reverse because of how the Eco Renderers handle rendering
79
- // (prepending the nodes when rendering row headers).
80
- for (let visibleColumnIndex = rowHeadersCount - 1; visibleColumnIndex >= 0; visibleColumnIndex--) {
77
+ for (let visibleColumnIndex = 0; visibleColumnIndex < rowHeadersCount; visibleColumnIndex++) {
81
78
  orderView.render();
82
79
  const TH = orderView.getCurrentNode();
83
80
  TH.className = '';
@@ -71,10 +71,7 @@ export class RowHeadersRenderer extends BaseRenderer {
71
71
  const orderView = this.obtainOrderView(TR);
72
72
  const cellsView = cells.obtainOrderView(TR);
73
73
  orderView.appendView(cellsView).setSize(rowHeadersCount).setOffset(0).start();
74
-
75
- // Reading the row header renderers in reverse because of how the Eco Renderers handle rendering
76
- // (prepending the nodes when rendering row headers).
77
- for (let visibleColumnIndex = rowHeadersCount - 1; visibleColumnIndex >= 0; visibleColumnIndex--) {
74
+ for (let visibleColumnIndex = 0; visibleColumnIndex < rowHeadersCount; visibleColumnIndex++) {
78
75
  orderView.render();
79
76
  const TH = orderView.getCurrentNode();
80
77
  TH.className = '';
@@ -352,11 +352,6 @@ class Border {
352
352
  const lastRenderedRow = wtTable.getLastRenderedRow();
353
353
  const firstRenderedColumn = wtTable.getFirstRenderedColumn();
354
354
  const lastRenderedColumn = wtTable.getLastRenderedColumn();
355
- if (firstRenderedColumn < 0 && lastRenderedColumn < 0 || firstRenderedRow < 0 && lastRenderedRow < 0) {
356
- // ...also when overlays have rendered only headers skip it
357
- this.disappear();
358
- return;
359
- }
360
355
  let fromTD;
361
356
  if (isMultiple) {
362
357
  fromColumn = Math.max(fromColumn, firstRenderedColumn);
@@ -349,11 +349,6 @@ class Border {
349
349
  const lastRenderedRow = wtTable.getLastRenderedRow();
350
350
  const firstRenderedColumn = wtTable.getFirstRenderedColumn();
351
351
  const lastRenderedColumn = wtTable.getLastRenderedColumn();
352
- if (firstRenderedColumn < 0 && lastRenderedColumn < 0 || firstRenderedRow < 0 && lastRenderedRow < 0) {
353
- // ...also when overlays have rendered only headers skip it
354
- this.disappear();
355
- return;
356
- }
357
352
  let fromTD;
358
353
  if (isMultiple) {
359
354
  fromColumn = Math.max(fromColumn, firstRenderedColumn);
@@ -20,8 +20,8 @@ const stickyColumnsStart = {
20
20
  * @this Table
21
21
  */
22
22
  getFirstRenderedColumn() {
23
- const allStickyColumns = this.getRenderedColumnsCount();
24
- if (allStickyColumns === 0) {
23
+ const totalColumns = this.wtSettings.getSetting('totalColumns');
24
+ if (totalColumns === 0) {
25
25
  return -1;
26
26
  }
27
27
  return 0;
@@ -82,7 +82,8 @@ const stickyColumnsStart = {
82
82
  * @this Table
83
83
  */
84
84
  getRenderedColumnsCount() {
85
- return Math.min(this.wtSettings.getSetting('totalColumns'), this.wtSettings.getSetting('fixedColumnsStart'));
85
+ const totalColumns = this.wtSettings.getSetting('totalColumns');
86
+ return Math.min(this.wtSettings.getSetting('fixedColumnsStart'), totalColumns);
86
87
  },
87
88
  /**
88
89
  * Get the number of fully visible columns in the viewport.
@@ -17,8 +17,8 @@ const stickyColumnsStart = {
17
17
  * @this Table
18
18
  */
19
19
  getFirstRenderedColumn() {
20
- const allStickyColumns = this.getRenderedColumnsCount();
21
- if (allStickyColumns === 0) {
20
+ const totalColumns = this.wtSettings.getSetting('totalColumns');
21
+ if (totalColumns === 0) {
22
22
  return -1;
23
23
  }
24
24
  return 0;
@@ -79,7 +79,8 @@ const stickyColumnsStart = {
79
79
  * @this Table
80
80
  */
81
81
  getRenderedColumnsCount() {
82
- return Math.min(this.wtSettings.getSetting('totalColumns'), this.wtSettings.getSetting('fixedColumnsStart'));
82
+ const totalColumns = this.wtSettings.getSetting('totalColumns');
83
+ return Math.min(this.wtSettings.getSetting('fixedColumnsStart'), totalColumns);
83
84
  },
84
85
  /**
85
86
  * Get the number of fully visible columns in the viewport.
@@ -20,11 +20,16 @@ const stickyRowsBottom = {
20
20
  * @this Table
21
21
  */
22
22
  getFirstRenderedRow() {
23
- const allStickyRows = this.getRenderedRowsCount();
24
- if (allStickyRows === 0) {
23
+ const totalRows = this.wtSettings.getSetting('totalRows');
24
+ const fixedRowsBottom = this.wtSettings.getSetting('fixedRowsBottom');
25
+ const index = totalRows - fixedRowsBottom;
26
+ if (totalRows === 0 || fixedRowsBottom === 0) {
25
27
  return -1;
26
28
  }
27
- return this.wtSettings.getSetting('totalRows') - allStickyRows;
29
+ if (index < 0) {
30
+ return 0;
31
+ }
32
+ return index;
28
33
  },
29
34
  /**
30
35
  * Get the source index of the first row fully visible in the viewport. If no rows are fully visible, returns an error code: -1.
@@ -53,10 +58,6 @@ const stickyRowsBottom = {
53
58
  * @this Table
54
59
  */
55
60
  getLastRenderedRow() {
56
- const allStickyRows = this.getRenderedRowsCount();
57
- if (allStickyRows === 0) {
58
- return -1;
59
- }
60
61
  return this.wtSettings.getSetting('totalRows') - 1;
61
62
  },
62
63
  /**
@@ -86,7 +87,8 @@ const stickyRowsBottom = {
86
87
  * @this Table
87
88
  */
88
89
  getRenderedRowsCount() {
89
- return Math.min(this.wtSettings.getSetting('totalRows'), this.wtSettings.getSetting('fixedRowsBottom'));
90
+ const totalRows = this.wtSettings.getSetting('totalRows');
91
+ return Math.min(this.wtSettings.getSetting('fixedRowsBottom'), totalRows);
90
92
  },
91
93
  /**
92
94
  * Get the number of fully visible rows in the viewport.
@@ -17,11 +17,16 @@ const stickyRowsBottom = {
17
17
  * @this Table
18
18
  */
19
19
  getFirstRenderedRow() {
20
- const allStickyRows = this.getRenderedRowsCount();
21
- if (allStickyRows === 0) {
20
+ const totalRows = this.wtSettings.getSetting('totalRows');
21
+ const fixedRowsBottom = this.wtSettings.getSetting('fixedRowsBottom');
22
+ const index = totalRows - fixedRowsBottom;
23
+ if (totalRows === 0 || fixedRowsBottom === 0) {
22
24
  return -1;
23
25
  }
24
- return this.wtSettings.getSetting('totalRows') - allStickyRows;
26
+ if (index < 0) {
27
+ return 0;
28
+ }
29
+ return index;
25
30
  },
26
31
  /**
27
32
  * Get the source index of the first row fully visible in the viewport. If no rows are fully visible, returns an error code: -1.
@@ -50,10 +55,6 @@ const stickyRowsBottom = {
50
55
  * @this Table
51
56
  */
52
57
  getLastRenderedRow() {
53
- const allStickyRows = this.getRenderedRowsCount();
54
- if (allStickyRows === 0) {
55
- return -1;
56
- }
57
58
  return this.wtSettings.getSetting('totalRows') - 1;
58
59
  },
59
60
  /**
@@ -83,7 +84,8 @@ const stickyRowsBottom = {
83
84
  * @this Table
84
85
  */
85
86
  getRenderedRowsCount() {
86
- return Math.min(this.wtSettings.getSetting('totalRows'), this.wtSettings.getSetting('fixedRowsBottom'));
87
+ const totalRows = this.wtSettings.getSetting('totalRows');
88
+ return Math.min(this.wtSettings.getSetting('fixedRowsBottom'), totalRows);
87
89
  },
88
90
  /**
89
91
  * Get the number of fully visible rows in the viewport.
@@ -20,8 +20,8 @@ const stickyRowsTop = {
20
20
  * @this Table
21
21
  */
22
22
  getFirstRenderedRow() {
23
- const allStickyRows = this.getRenderedRowsCount();
24
- if (allStickyRows === 0) {
23
+ const totalRows = this.wtSettings.getSetting('totalRows');
24
+ if (totalRows === 0) {
25
25
  return -1;
26
26
  }
27
27
  return 0;
@@ -82,7 +82,8 @@ const stickyRowsTop = {
82
82
  * @this Table
83
83
  */
84
84
  getRenderedRowsCount() {
85
- return Math.min(this.wtSettings.getSetting('totalRows'), this.wtSettings.getSetting('fixedRowsTop'));
85
+ const totalRows = this.wtSettings.getSetting('totalRows');
86
+ return Math.min(this.wtSettings.getSetting('fixedRowsTop'), totalRows);
86
87
  },
87
88
  /**
88
89
  * Get the number of fully visible rows in the viewport.
@@ -17,8 +17,8 @@ const stickyRowsTop = {
17
17
  * @this Table
18
18
  */
19
19
  getFirstRenderedRow() {
20
- const allStickyRows = this.getRenderedRowsCount();
21
- if (allStickyRows === 0) {
20
+ const totalRows = this.wtSettings.getSetting('totalRows');
21
+ if (totalRows === 0) {
22
22
  return -1;
23
23
  }
24
24
  return 0;
@@ -79,7 +79,8 @@ const stickyRowsTop = {
79
79
  * @this Table
80
80
  */
81
81
  getRenderedRowsCount() {
82
- return Math.min(this.wtSettings.getSetting('totalRows'), this.wtSettings.getSetting('fixedRowsTop'));
82
+ const totalRows = this.wtSettings.getSetting('totalRows');
83
+ return Math.min(this.wtSettings.getSetting('fixedRowsTop'), totalRows);
83
84
  },
84
85
  /**
85
86
  * Get the number of fully visible rows in the viewport.
@@ -279,8 +279,8 @@ class Table {
279
279
  } else {
280
280
  this.tableOffset = this.dataAccessObject.parentTableOffset;
281
281
  }
282
- const startRow = Math.max(this.getFirstRenderedRow(), 0);
283
- const startColumn = Math.max(this.getFirstRenderedColumn(), 0);
282
+ const startRow = totalRows > 0 ? this.getFirstRenderedRow() : 0;
283
+ const startColumn = totalColumns > 0 ? this.getFirstRenderedColumn() : 0;
284
284
  this.rowFilter = new _row.default(startRow, totalRows, columnHeadersCount);
285
285
  this.columnFilter = new _column.default(startColumn, totalColumns, rowHeadersCount);
286
286
  let performRedraw = true;
@@ -598,9 +598,6 @@ class Table {
598
598
  return null;
599
599
  }
600
600
  const TR = cellElement.parentNode;
601
- if (!TR) {
602
- return null;
603
- }
604
601
  const CONTAINER = TR.parentNode;
605
602
  let row = (0, _element.index)(TR);
606
603
  let col = cellElement.cellIndex;
@@ -275,8 +275,8 @@ class Table {
275
275
  } else {
276
276
  this.tableOffset = this.dataAccessObject.parentTableOffset;
277
277
  }
278
- const startRow = Math.max(this.getFirstRenderedRow(), 0);
279
- const startColumn = Math.max(this.getFirstRenderedColumn(), 0);
278
+ const startRow = totalRows > 0 ? this.getFirstRenderedRow() : 0;
279
+ const startColumn = totalColumns > 0 ? this.getFirstRenderedColumn() : 0;
280
280
  this.rowFilter = new RowFilter(startRow, totalRows, columnHeadersCount);
281
281
  this.columnFilter = new ColumnFilter(startColumn, totalColumns, rowHeadersCount);
282
282
  let performRedraw = true;
@@ -594,9 +594,6 @@ class Table {
594
594
  return null;
595
595
  }
596
596
  const TR = cellElement.parentNode;
597
- if (!TR) {
598
- return null;
599
- }
600
597
  const CONTAINER = TR.parentNode;
601
598
  let row = index(TR);
602
599
  let col = cellElement.cellIndex;
package/CHANGELOG.md CHANGED
@@ -9,45 +9,6 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
9
9
 
10
10
  <!-- UNVERSIONED -->
11
11
 
12
- ## [15.2.0] - 2025-03-19
13
-
14
- ### Added
15
- - Added the Farsi translation. [#11388](https://github.com/handsontable/handsontable/pull/11388)
16
- - Added support for class names passed as an array for the numeric cell renderer. [#11420](https://github.com/handsontable/handsontable/pull/11420)
17
- - Updated the Italian translation for the new Context Menu labels. [#11436](https://github.com/handsontable/handsontable/pull/11436)
18
- - Updated the Serbian translation for the new Context Menu labels. [#11437](https://github.com/handsontable/handsontable/pull/11437)
19
- - Added the mobile cell handle CSS variables to the themes. [#11479](https://github.com/handsontable/handsontable/pull/11479)
20
- - Improved the execution flow of the Filters plugin and added two new methods (`importConditions` and `exportConditions`). [#11488](https://github.com/handsontable/handsontable/pull/11488)
21
-
22
- ### Changed
23
- - Sped up the rendering performance for themes. [#11443](https://github.com/handsontable/handsontable/pull/11443)
24
- - Improved the table UI behavior after removing all rows and/or columns. [#11477](https://github.com/handsontable/handsontable/pull/11477)
25
- - Reverted the removal of `actionType` class field for UndoRedo actions. [#11495](https://github.com/handsontable/handsontable/pull/11495)
26
-
27
- ### Removed
28
- - Removed the broken, unsupported and undocumented `rendererTemplate` Text Renderer option. [#11424](https://github.com/handsontable/handsontable/pull/11424)
29
-
30
- ### Fixed
31
- - Fixed the default (fallback) date format for the Date editor. [#11419](https://github.com/handsontable/handsontable/pull/11419)
32
- - Fixed the Context Menu's items' state rendering. [#11422](https://github.com/handsontable/handsontable/pull/11422)
33
- - Corrected the checkbox visibility in the no-theme variant. [#11427](https://github.com/handsontable/handsontable/pull/11427)
34
- - Fixed problems with the cell content reading with `imeFastEdit` enabled. [#11442](https://github.com/handsontable/handsontable/pull/11442)
35
- - Fixed `hasVerticalScroll` and `hasHorizontalScroll` methods. [#11455](https://github.com/handsontable/handsontable/pull/11455)
36
- - Fixed the editor border radius on mobile devices. [#11457](https://github.com/handsontable/handsontable/pull/11457)
37
- - Fixed the wrong height of the first row. [#11458](https://github.com/handsontable/handsontable/pull/11458)
38
- - Fixed the single cell selection inside iframes. [#11460](https://github.com/handsontable/handsontable/pull/11460)
39
- - Fixed an issue with row header misalignment. [#11465](https://github.com/handsontable/handsontable/pull/11465)
40
- - Improved the Autocomplete/Dropdown Editor list behavior. [#11469](https://github.com/handsontable/handsontable/pull/11469)
41
- - Fixed a problem with horizontal scrollbar in the Autocomplete dropdown. [#11473](https://github.com/handsontable/handsontable/pull/11473)
42
- - Fixed the merged cells height for custom row heights. [#11478](https://github.com/handsontable/handsontable/pull/11478)
43
- - Fixed a problem with the Comments editor not flipping direction when overlapping the window's scrollbars. [#11481](https://github.com/handsontable/handsontable/pull/11481)
44
- - Fixed a problem with the focus trap during `Shift` + `Tab` navigation. [#11483](https://github.com/handsontable/handsontable/pull/11483)
45
- - Fixed an issue with the Context Menu opening on Classic theme. [#11486](https://github.com/handsontable/handsontable/pull/11486)
46
- - Fixed a problem with `rowHeights` when the provided value was lower than the default/minimal row height. [#11487](https://github.com/handsontable/handsontable/pull/11487)
47
- - Fixed an issue with the data source modification for row values passed as strings. [#11491](https://github.com/handsontable/handsontable/pull/11491)
48
- - Fixed the conflicts between ColumnSorting and MultiColumnSorting plugins. [#11492](https://github.com/handsontable/handsontable/pull/11492)
49
- - Fixed copy, cut an paste actions on tables with a selection reaching outside of the rendered viewport. [#11504](https://github.com/handsontable/handsontable/pull/11504)
50
-
51
12
  ## [15.1.0] - 2025-02-20
52
13
 
53
14
  ### Added
package/base.js CHANGED
@@ -45,8 +45,8 @@ Handsontable.hooks = _hooks.Hooks.getSingleton();
45
45
  Handsontable.CellCoords = _src.CellCoords;
46
46
  Handsontable.CellRange = _src.CellRange;
47
47
  Handsontable.packageName = 'handsontable';
48
- Handsontable.buildDate = "09/04/2025 06:00:42";
49
- Handsontable.version = "0.0.0-next-87b048b-20250409";
48
+ Handsontable.buildDate = "10/04/2025 06:43:46";
49
+ Handsontable.version = "0.0.0-next-ff10728-20250410";
50
50
  Handsontable.languages = {
51
51
  dictionaryKeys: _registry.dictionaryKeys,
52
52
  getLanguageDictionary: _registry.getLanguageDictionary,
package/base.mjs CHANGED
@@ -35,8 +35,8 @@ Handsontable.hooks = Hooks.getSingleton();
35
35
  Handsontable.CellCoords = CellCoords;
36
36
  Handsontable.CellRange = CellRange;
37
37
  Handsontable.packageName = 'handsontable';
38
- Handsontable.buildDate = "09/04/2025 06:00:48";
39
- Handsontable.version = "0.0.0-next-87b048b-20250409";
38
+ Handsontable.buildDate = "10/04/2025 06:43:52";
39
+ Handsontable.version = "0.0.0-next-ff10728-20250410";
40
40
  Handsontable.languages = {
41
41
  dictionaryKeys,
42
42
  getLanguageDictionary,
@@ -58,7 +58,7 @@ function createInputElement(hot) {
58
58
  input.name = '__htFocusCatcher';
59
59
  input.classList.add('htFocusCatcher');
60
60
  if (hot.getSettings().ariaTags) {
61
- (0, _element.setAttribute)(input, [(0, _a11y.A11Y_LABEL)('Focus catcher')]);
61
+ (0, _element.setAttribute)(input, [(0, _a11y.A11Y_PRESENTATION)(), (0, _a11y.A11Y_HIDDEN)()]);
62
62
  }
63
63
  return input;
64
64
  }
@@ -1,5 +1,5 @@
1
1
  import { setAttribute } from "../../helpers/dom/element.mjs";
2
- import { A11Y_LABEL } from "../../helpers/a11y.mjs";
2
+ import { A11Y_PRESENTATION, A11Y_HIDDEN } from "../../helpers/a11y.mjs";
3
3
  /**
4
4
  * Installs a focus detector module. The module appends two input elements into the DOM side by side.
5
5
  * When the first input is focused, then it means that a user entered to the component using the TAB key
@@ -54,7 +54,7 @@ function createInputElement(hot) {
54
54
  input.name = '__htFocusCatcher';
55
55
  input.classList.add('htFocusCatcher');
56
56
  if (hot.getSettings().ariaTags) {
57
- setAttribute(input, [A11Y_LABEL('Focus catcher')]);
57
+ setAttribute(input, [A11Y_PRESENTATION(), A11Y_HIDDEN()]);
58
58
  }
59
59
  return input;
60
60
  }
@@ -336,14 +336,6 @@ const REGISTERED_HOOKS = exports.REGISTERED_HOOKS = [/* eslint-disable jsdoc/req
336
336
  * @returns {string[]|undefined} Can return an `Array` of `String`s. Each of these strings will act like class names to be removed from all the cells in the table.
337
337
  */
338
338
  'beforeRemoveCellClassNames',
339
- /**
340
- * Hook fired after `compositionstart` event is handled.
341
- *
342
- * @event Hooks#beforeCompositionStart
343
- * @since 15.3.0
344
- * @param {Event} event A native `composition` event object.
345
- */
346
- 'beforeCompositionStart',
347
339
  /**
348
340
  * Fired after getting the cell settings.
349
341
  *
@@ -333,14 +333,6 @@ export const REGISTERED_HOOKS = [/* eslint-disable jsdoc/require-description-com
333
333
  * @returns {string[]|undefined} Can return an `Array` of `String`s. Each of these strings will act like class names to be removed from all the cells in the table.
334
334
  */
335
335
  'beforeRemoveCellClassNames',
336
- /**
337
- * Hook fired after `compositionstart` event is handled.
338
- *
339
- * @event Hooks#beforeCompositionStart
340
- * @since 15.3.0
341
- * @param {Event} event A native `composition` event object.
342
- */
343
- 'beforeCompositionStart',
344
336
  /**
345
337
  * Fired after getting the cell settings.
346
338
  *
@@ -167,7 +167,6 @@ export interface Events {
167
167
  beforeColumnSort?: (currentSortConfig: ColumnSortingConfig[], destinationSortConfigs: ColumnSortingConfig[]) => void | boolean;
168
168
  beforeColumnWrap?: (isActionInterrupted: { value: boolean }, newCoords: CellCoords, isColumnFlipped: boolean) => void;
169
169
  beforeColumnUnfreeze?: (columnIndex: number, isUnfreezingPerformed: boolean) => void | boolean;
170
- beforeCompositionStart?: (event: CompositionEvent) => void;
171
170
  beforeContextMenuSetItems?: (menuItems: ContextMenuMenuItemConfig[]) => void;
172
171
  beforeContextMenuShow?: (context: ContextMenu) => void;
173
172
  beforeCopy?: (data: CellValue[][], coords: RangeType[], copiedHeadersCount: { columnHeadersCount: number }) => void | boolean;
package/core.d.ts CHANGED
@@ -140,6 +140,7 @@ export default class Core {
140
140
  removeCellMeta(row: number, column: number, key: (keyof CellMeta) | string): void;
141
141
  removeHook<K extends keyof Events>(key: K, callback: Events[K]): void;
142
142
  render(): void;
143
+ renderCall: boolean;
143
144
  resumeExecution(): void;
144
145
  resumeRender(): void;
145
146
  rootDocument: Document;
package/core.js CHANGED
@@ -231,6 +231,7 @@ function Core(rootElement, userSettings) {
231
231
  const globalMeta = metaManager.getGlobalMeta();
232
232
  const pluginsRegistry = (0, _uniqueMap.createUniqueMap)();
233
233
  this.container = this.rootDocument.createElement('div');
234
+ this.renderCall = false;
234
235
  rootElement.insertBefore(this.container, rootElement.firstChild);
235
236
  if ((0, _rootInstance.isRootInstance)(this)) {
236
237
  (0, _mixed._injectProductInfo)(userSettings.licenseKey, rootElement);
@@ -262,9 +263,6 @@ function Core(rootElement, userSettings) {
262
263
  this.rowIndexMapper.addLocalHook('indexesSequenceChange', source => {
263
264
  instance.runHooks('afterRowSequenceChange', source);
264
265
  });
265
- eventManager.addEventListener(this.rootDocument.documentElement, 'compositionstart', event => {
266
- instance.runHooks('beforeCompositionStart', event);
267
- });
268
266
  dataSource = new _dataSource.default(instance);
269
267
  if (!this.rootElement.id || this.rootElement.id.substring(0, 3) === 'ht_') {
270
268
  this.rootElement.id = this.guid; // if root element does not have an id, assign a random id
@@ -344,7 +342,6 @@ function Core(rootElement, userSettings) {
344
342
  let {
345
343
  hiddenIndexesChanged
346
344
  } = _ref;
347
- this.forceFullRender = true;
348
345
  if (hiddenIndexesChanged) {
349
346
  this.selection.commit();
350
347
  }
@@ -628,6 +625,13 @@ function Core(rootElement, userSettings) {
628
625
  }
629
626
  }
630
627
  const totalRows = instance.countRows();
628
+ if (totalRows === 0) {
629
+ selection.deselect();
630
+ } else if (source === 'ContextMenu.removeRow') {
631
+ selection.refresh();
632
+ } else {
633
+ selection.shiftRows(groupIndex, -groupAmount);
634
+ }
631
635
  const fixedRowsTop = tableMeta.fixedRowsTop;
632
636
  if (fixedRowsTop >= calcIndex + 1) {
633
637
  tableMeta.fixedRowsTop -= Math.min(groupAmount, fixedRowsTop - calcIndex);
@@ -636,13 +640,6 @@ function Core(rootElement, userSettings) {
636
640
  if (fixedRowsBottom && calcIndex >= totalRows - fixedRowsBottom) {
637
641
  tableMeta.fixedRowsBottom -= Math.min(groupAmount, fixedRowsBottom);
638
642
  }
639
- if (totalRows === 0) {
640
- selection.deselect();
641
- } else if (source === 'ContextMenu.removeRow') {
642
- selection.refresh();
643
- } else {
644
- selection.shiftRows(groupIndex, -groupAmount);
645
- }
646
643
  offset += groupAmount;
647
644
  });
648
645
  };
@@ -1052,7 +1049,8 @@ function Core(rootElement, userSettings) {
1052
1049
  (0, _index.installFocusCatcher)(instance);
1053
1050
  }
1054
1051
  instance.runHooks('init');
1055
- this.render();
1052
+ this.forceFullRender = true; // used when data was changed
1053
+ this.view.render();
1056
1054
 
1057
1055
  // Run the logic only if it's the table's initialization and the root element is not visible.
1058
1056
  if (!!firstRun && instance.rootElement.offsetParent === null) {
@@ -1225,11 +1223,13 @@ function Core(rootElement, userSettings) {
1225
1223
  datamap.set(changes[i][0], changes[i][1], changes[i][3]);
1226
1224
  }
1227
1225
  const hasChanges = changes.length > 0;
1226
+ instance.forceFullRender = true; // used when data was changed or when all cells need to be re-rendered
1227
+
1228
1228
  if (hasChanges) {
1229
1229
  grid.adjustRowsAndCols();
1230
1230
  instance.runHooks('beforeChangeRender', changes, source);
1231
1231
  editorManager.closeEditor();
1232
- instance.render();
1232
+ instance.view.render();
1233
1233
  editorManager.prepareEditor();
1234
1234
  instance.view.adjustElementsSize();
1235
1235
  instance.runHooks('afterChange', changes, source || 'edit');
@@ -1238,7 +1238,7 @@ function Core(rootElement, userSettings) {
1238
1238
  activeEditor.refreshValue();
1239
1239
  }
1240
1240
  } else {
1241
- instance.render();
1241
+ instance.view.render();
1242
1242
  }
1243
1243
  }
1244
1244
 
@@ -1388,22 +1388,9 @@ function Core(rootElement, userSettings) {
1388
1388
  ...tableMeta
1389
1389
  };
1390
1390
  }
1391
- const {
1392
- type,
1393
- checkedTemplate,
1394
- uncheckedTemplate
1395
- } = cellProperties;
1396
- if (type === 'numeric' && typeof newValue === 'string' && (0, _number.isNumericLike)(newValue)) {
1391
+ if (cellProperties.type === 'numeric' && typeof newValue === 'string' && (0, _number.isNumericLike)(newValue)) {
1397
1392
  filteredChanges[i][3] = getParsedNumber(newValue);
1398
1393
  }
1399
- if (type === 'checkbox') {
1400
- const stringifiedValue = (0, _mixed.stringify)(newValue);
1401
- const isChecked = stringifiedValue === (0, _mixed.stringify)(checkedTemplate);
1402
- const isUnchecked = stringifiedValue === (0, _mixed.stringify)(uncheckedTemplate);
1403
- if (isChecked || isUnchecked) {
1404
- filteredChanges[i][3] = isChecked ? checkedTemplate : uncheckedTemplate;
1405
- }
1406
- }
1407
1394
  }
1408
1395
  return filteredChanges;
1409
1396
  }
@@ -1805,7 +1792,11 @@ function Core(rootElement, userSettings) {
1805
1792
  const nextValue = this.renderSuspendedCounter - 1;
1806
1793
  this.renderSuspendedCounter = Math.max(nextValue, 0);
1807
1794
  if (!this.isRenderSuspended() && nextValue === this.renderSuspendedCounter) {
1808
- instance.view.render();
1795
+ if (this.renderCall) {
1796
+ this.render();
1797
+ } else {
1798
+ instance.view.render();
1799
+ }
1809
1800
  }
1810
1801
  };
1811
1802
 
@@ -1821,8 +1812,9 @@ function Core(rootElement, userSettings) {
1821
1812
  */
1822
1813
  this.render = function () {
1823
1814
  if (this.view) {
1824
- // used when data was changed or when all cells need to be re-rendered (slow render)
1825
- this.forceFullRender = true;
1815
+ this.renderCall = true;
1816
+ this.forceFullRender = true; // used when data was changed or when all cells need to be re-rendered
1817
+
1826
1818
  if (!this.isRenderSuspended()) {
1827
1819
  instance.view.render();
1828
1820
  }
@@ -2435,7 +2427,8 @@ function Core(rootElement, userSettings) {
2435
2427
  }
2436
2428
  grid.adjustRowsAndCols();
2437
2429
  if (instance.view && !firstRun) {
2438
- instance.render();
2430
+ instance.forceFullRender = true; // used when data was changed
2431
+ instance.view.render();
2439
2432
  instance.view._wt.wtOverlays.adjustElementsSize();
2440
2433
  }
2441
2434
  if (!init && instance.view && (currentHeight === '' || height === '' || height === undefined) && currentHeight !== height) {