handsontable 0.0.0-next-ff10728-20250410 → 0.0.0-next-9410a76-20250416
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.
- package/3rdparty/walkontable/src/cell/range.js +14 -0
- package/3rdparty/walkontable/src/cell/range.mjs +14 -0
- package/3rdparty/walkontable/src/renderer/rowHeaders.js +4 -1
- package/3rdparty/walkontable/src/renderer/rowHeaders.mjs +4 -1
- package/3rdparty/walkontable/src/selection/border/border.js +5 -0
- package/3rdparty/walkontable/src/selection/border/border.mjs +5 -0
- package/3rdparty/walkontable/src/table/mixin/stickyColumnsStart.js +3 -4
- package/3rdparty/walkontable/src/table/mixin/stickyColumnsStart.mjs +3 -4
- package/3rdparty/walkontable/src/table/mixin/stickyRowsBottom.js +8 -10
- package/3rdparty/walkontable/src/table/mixin/stickyRowsBottom.mjs +8 -10
- package/3rdparty/walkontable/src/table/mixin/stickyRowsTop.js +3 -4
- package/3rdparty/walkontable/src/table/mixin/stickyRowsTop.mjs +3 -4
- package/3rdparty/walkontable/src/table.js +5 -2
- package/3rdparty/walkontable/src/table.mjs +5 -2
- package/CHANGELOG.md +39 -0
- package/base.js +2 -2
- package/base.mjs +2 -2
- package/core/focusCatcher/focusDetector.js +1 -1
- package/core/focusCatcher/focusDetector.mjs +2 -2
- package/core/hooks/constants.js +8 -0
- package/core/hooks/constants.mjs +8 -0
- package/core/hooks/index.d.ts +1 -0
- package/core.d.ts +0 -1
- package/core.js +32 -25
- package/core.mjs +33 -26
- package/dataMap/dataMap.js +0 -7
- package/dataMap/dataMap.mjs +0 -7
- package/dataMap/metaManager/metaSchema.js +1 -0
- package/dataMap/metaManager/metaSchema.mjs +1 -0
- package/dist/handsontable.css +3 -3
- package/dist/handsontable.full.css +3 -3
- package/dist/handsontable.full.js +437 -350
- package/dist/handsontable.full.min.css +3 -3
- package/dist/handsontable.full.min.js +17 -17
- package/dist/handsontable.js +437 -350
- package/dist/handsontable.min.css +3 -3
- package/dist/handsontable.min.js +18 -18
- package/editorManager.js +1 -7
- package/editorManager.mjs +1 -7
- package/editors/autocompleteEditor/autocompleteEditor.js +14 -4
- package/editors/autocompleteEditor/autocompleteEditor.mjs +14 -4
- package/editors/textEditor/textEditor.js +1 -1
- package/editors/textEditor/textEditor.mjs +2 -2
- package/helpers/browser.js +1 -1
- package/helpers/browser.mjs +1 -1
- package/helpers/dom/element.js +2 -2
- package/helpers/dom/element.mjs +1 -1
- package/helpers/mixed.js +2 -2
- package/helpers/mixed.mjs +2 -2
- package/helpers/object.js +3 -0
- package/helpers/object.mjs +3 -0
- package/package.json +1 -1
- package/plugins/autoColumnSize/autoColumnSize.js +1 -1
- package/plugins/autoColumnSize/autoColumnSize.mjs +1 -1
- package/plugins/autoRowSize/autoRowSize.js +1 -6
- package/plugins/autoRowSize/autoRowSize.mjs +1 -6
- package/plugins/columnSorting/columnSorting.js +0 -4
- package/plugins/columnSorting/columnSorting.mjs +0 -4
- package/plugins/comments/comments.js +1 -0
- package/plugins/comments/comments.mjs +1 -0
- package/plugins/contextMenu/menu/defaultShortcutsList.js +2 -2
- package/plugins/contextMenu/menu/defaultShortcutsList.mjs +2 -2
- package/plugins/contextMenu/menu/menu.js +1 -0
- package/plugins/contextMenu/menu/menu.mjs +1 -0
- package/plugins/contextMenu/menu/positioner.js +10 -2
- package/plugins/contextMenu/menu/positioner.mjs +10 -2
- package/plugins/copyPaste/copyPaste.js +12 -15
- package/plugins/copyPaste/copyPaste.mjs +13 -16
- package/plugins/copyPaste/pasteEvent.js +3 -0
- package/plugins/copyPaste/pasteEvent.mjs +3 -0
- package/plugins/filters/filters.js +25 -24
- package/plugins/filters/filters.mjs +25 -24
- package/plugins/filters/ui/multipleSelect.js +7 -1
- package/plugins/filters/ui/multipleSelect.mjs +7 -1
- package/plugins/hiddenColumns/hiddenColumns.js +1 -1
- package/plugins/hiddenColumns/hiddenColumns.mjs +1 -1
- package/plugins/hiddenRows/hiddenRows.js +1 -1
- package/plugins/hiddenRows/hiddenRows.mjs +1 -1
- package/plugins/manualColumnResize/manualColumnResize.js +4 -6
- package/plugins/manualColumnResize/manualColumnResize.mjs +4 -6
- package/plugins/manualRowResize/manualRowResize.js +4 -6
- package/plugins/manualRowResize/manualRowResize.mjs +4 -6
- package/plugins/mergeCells/mergeCells.js +8 -29
- package/plugins/mergeCells/mergeCells.mjs +8 -29
- package/plugins/mergeCells/renderer.js +15 -0
- package/plugins/mergeCells/renderer.mjs +15 -0
- package/plugins/mergeCells/utils.js +31 -0
- package/plugins/mergeCells/utils.mjs +27 -0
- package/plugins/nestedRows/data/dataManager.js +2 -2
- package/plugins/nestedRows/data/dataManager.mjs +2 -2
- package/plugins/undoRedo/actions/removeColumn.js +19 -14
- package/plugins/undoRedo/actions/removeColumn.mjs +19 -14
- package/plugins/undoRedo/actions/removeRow.js +12 -4
- package/plugins/undoRedo/actions/removeRow.mjs +12 -4
- package/selection/selection.js +3 -1
- package/selection/selection.mjs +3 -1
- package/styles/handsontable.css +14 -15
- package/styles/handsontable.min.css +3 -3
- package/styles/ht-theme-horizon.css +2 -2
- package/styles/ht-theme-horizon.min.css +2 -2
- package/styles/ht-theme-main.css +2 -2
- package/styles/ht-theme-main.min.css +2 -2
- package/tableView.js +5 -8
- package/tableView.mjs +5 -8
- package/utils/ghostTable.js +3 -0
- package/utils/ghostTable.mjs +3 -0
|
@@ -105,6 +105,20 @@ 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
|
+
|
|
108
122
|
/**
|
|
109
123
|
* Checks if the coordinates in your `CellRange` instance are valid
|
|
110
124
|
* in the context of given table parameters.
|
|
@@ -101,6 +101,20 @@ 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
|
+
|
|
104
118
|
/**
|
|
105
119
|
* Checks if the coordinates in your `CellRange` instance are valid
|
|
106
120
|
* in the context of given table parameters.
|
|
@@ -74,7 +74,10 @@ 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
|
-
|
|
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--) {
|
|
78
81
|
orderView.render();
|
|
79
82
|
const TH = orderView.getCurrentNode();
|
|
80
83
|
TH.className = '';
|
|
@@ -71,7 +71,10 @@ 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
|
-
|
|
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--) {
|
|
75
78
|
orderView.render();
|
|
76
79
|
const TH = orderView.getCurrentNode();
|
|
77
80
|
TH.className = '';
|
|
@@ -352,6 +352,11 @@ 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
|
+
}
|
|
355
360
|
let fromTD;
|
|
356
361
|
if (isMultiple) {
|
|
357
362
|
fromColumn = Math.max(fromColumn, firstRenderedColumn);
|
|
@@ -349,6 +349,11 @@ 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
|
+
}
|
|
352
357
|
let fromTD;
|
|
353
358
|
if (isMultiple) {
|
|
354
359
|
fromColumn = Math.max(fromColumn, firstRenderedColumn);
|
|
@@ -20,8 +20,8 @@ const stickyColumnsStart = {
|
|
|
20
20
|
* @this Table
|
|
21
21
|
*/
|
|
22
22
|
getFirstRenderedColumn() {
|
|
23
|
-
const
|
|
24
|
-
if (
|
|
23
|
+
const allStickyColumns = this.getRenderedColumnsCount();
|
|
24
|
+
if (allStickyColumns === 0) {
|
|
25
25
|
return -1;
|
|
26
26
|
}
|
|
27
27
|
return 0;
|
|
@@ -82,8 +82,7 @@ const stickyColumnsStart = {
|
|
|
82
82
|
* @this Table
|
|
83
83
|
*/
|
|
84
84
|
getRenderedColumnsCount() {
|
|
85
|
-
|
|
86
|
-
return Math.min(this.wtSettings.getSetting('fixedColumnsStart'), totalColumns);
|
|
85
|
+
return Math.min(this.wtSettings.getSetting('totalColumns'), this.wtSettings.getSetting('fixedColumnsStart'));
|
|
87
86
|
},
|
|
88
87
|
/**
|
|
89
88
|
* 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
|
|
21
|
-
if (
|
|
20
|
+
const allStickyColumns = this.getRenderedColumnsCount();
|
|
21
|
+
if (allStickyColumns === 0) {
|
|
22
22
|
return -1;
|
|
23
23
|
}
|
|
24
24
|
return 0;
|
|
@@ -79,8 +79,7 @@ const stickyColumnsStart = {
|
|
|
79
79
|
* @this Table
|
|
80
80
|
*/
|
|
81
81
|
getRenderedColumnsCount() {
|
|
82
|
-
|
|
83
|
-
return Math.min(this.wtSettings.getSetting('fixedColumnsStart'), totalColumns);
|
|
82
|
+
return Math.min(this.wtSettings.getSetting('totalColumns'), this.wtSettings.getSetting('fixedColumnsStart'));
|
|
84
83
|
},
|
|
85
84
|
/**
|
|
86
85
|
* Get the number of fully visible columns in the viewport.
|
|
@@ -20,16 +20,11 @@ const stickyRowsBottom = {
|
|
|
20
20
|
* @this Table
|
|
21
21
|
*/
|
|
22
22
|
getFirstRenderedRow() {
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
const index = totalRows - fixedRowsBottom;
|
|
26
|
-
if (totalRows === 0 || fixedRowsBottom === 0) {
|
|
23
|
+
const allStickyRows = this.getRenderedRowsCount();
|
|
24
|
+
if (allStickyRows === 0) {
|
|
27
25
|
return -1;
|
|
28
26
|
}
|
|
29
|
-
|
|
30
|
-
return 0;
|
|
31
|
-
}
|
|
32
|
-
return index;
|
|
27
|
+
return this.wtSettings.getSetting('totalRows') - allStickyRows;
|
|
33
28
|
},
|
|
34
29
|
/**
|
|
35
30
|
* Get the source index of the first row fully visible in the viewport. If no rows are fully visible, returns an error code: -1.
|
|
@@ -58,6 +53,10 @@ const stickyRowsBottom = {
|
|
|
58
53
|
* @this Table
|
|
59
54
|
*/
|
|
60
55
|
getLastRenderedRow() {
|
|
56
|
+
const allStickyRows = this.getRenderedRowsCount();
|
|
57
|
+
if (allStickyRows === 0) {
|
|
58
|
+
return -1;
|
|
59
|
+
}
|
|
61
60
|
return this.wtSettings.getSetting('totalRows') - 1;
|
|
62
61
|
},
|
|
63
62
|
/**
|
|
@@ -87,8 +86,7 @@ const stickyRowsBottom = {
|
|
|
87
86
|
* @this Table
|
|
88
87
|
*/
|
|
89
88
|
getRenderedRowsCount() {
|
|
90
|
-
|
|
91
|
-
return Math.min(this.wtSettings.getSetting('fixedRowsBottom'), totalRows);
|
|
89
|
+
return Math.min(this.wtSettings.getSetting('totalRows'), this.wtSettings.getSetting('fixedRowsBottom'));
|
|
92
90
|
},
|
|
93
91
|
/**
|
|
94
92
|
* Get the number of fully visible rows in the viewport.
|
|
@@ -17,16 +17,11 @@ const stickyRowsBottom = {
|
|
|
17
17
|
* @this Table
|
|
18
18
|
*/
|
|
19
19
|
getFirstRenderedRow() {
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
const index = totalRows - fixedRowsBottom;
|
|
23
|
-
if (totalRows === 0 || fixedRowsBottom === 0) {
|
|
20
|
+
const allStickyRows = this.getRenderedRowsCount();
|
|
21
|
+
if (allStickyRows === 0) {
|
|
24
22
|
return -1;
|
|
25
23
|
}
|
|
26
|
-
|
|
27
|
-
return 0;
|
|
28
|
-
}
|
|
29
|
-
return index;
|
|
24
|
+
return this.wtSettings.getSetting('totalRows') - allStickyRows;
|
|
30
25
|
},
|
|
31
26
|
/**
|
|
32
27
|
* Get the source index of the first row fully visible in the viewport. If no rows are fully visible, returns an error code: -1.
|
|
@@ -55,6 +50,10 @@ const stickyRowsBottom = {
|
|
|
55
50
|
* @this Table
|
|
56
51
|
*/
|
|
57
52
|
getLastRenderedRow() {
|
|
53
|
+
const allStickyRows = this.getRenderedRowsCount();
|
|
54
|
+
if (allStickyRows === 0) {
|
|
55
|
+
return -1;
|
|
56
|
+
}
|
|
58
57
|
return this.wtSettings.getSetting('totalRows') - 1;
|
|
59
58
|
},
|
|
60
59
|
/**
|
|
@@ -84,8 +83,7 @@ const stickyRowsBottom = {
|
|
|
84
83
|
* @this Table
|
|
85
84
|
*/
|
|
86
85
|
getRenderedRowsCount() {
|
|
87
|
-
|
|
88
|
-
return Math.min(this.wtSettings.getSetting('fixedRowsBottom'), totalRows);
|
|
86
|
+
return Math.min(this.wtSettings.getSetting('totalRows'), this.wtSettings.getSetting('fixedRowsBottom'));
|
|
89
87
|
},
|
|
90
88
|
/**
|
|
91
89
|
* 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
|
|
24
|
-
if (
|
|
23
|
+
const allStickyRows = this.getRenderedRowsCount();
|
|
24
|
+
if (allStickyRows === 0) {
|
|
25
25
|
return -1;
|
|
26
26
|
}
|
|
27
27
|
return 0;
|
|
@@ -82,8 +82,7 @@ const stickyRowsTop = {
|
|
|
82
82
|
* @this Table
|
|
83
83
|
*/
|
|
84
84
|
getRenderedRowsCount() {
|
|
85
|
-
|
|
86
|
-
return Math.min(this.wtSettings.getSetting('fixedRowsTop'), totalRows);
|
|
85
|
+
return Math.min(this.wtSettings.getSetting('totalRows'), this.wtSettings.getSetting('fixedRowsTop'));
|
|
87
86
|
},
|
|
88
87
|
/**
|
|
89
88
|
* 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
|
|
21
|
-
if (
|
|
20
|
+
const allStickyRows = this.getRenderedRowsCount();
|
|
21
|
+
if (allStickyRows === 0) {
|
|
22
22
|
return -1;
|
|
23
23
|
}
|
|
24
24
|
return 0;
|
|
@@ -79,8 +79,7 @@ const stickyRowsTop = {
|
|
|
79
79
|
* @this Table
|
|
80
80
|
*/
|
|
81
81
|
getRenderedRowsCount() {
|
|
82
|
-
|
|
83
|
-
return Math.min(this.wtSettings.getSetting('fixedRowsTop'), totalRows);
|
|
82
|
+
return Math.min(this.wtSettings.getSetting('totalRows'), this.wtSettings.getSetting('fixedRowsTop'));
|
|
84
83
|
},
|
|
85
84
|
/**
|
|
86
85
|
* 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 =
|
|
283
|
-
const startColumn =
|
|
282
|
+
const startRow = Math.max(this.getFirstRenderedRow(), 0);
|
|
283
|
+
const startColumn = Math.max(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,6 +598,9 @@ class Table {
|
|
|
598
598
|
return null;
|
|
599
599
|
}
|
|
600
600
|
const TR = cellElement.parentNode;
|
|
601
|
+
if (!TR) {
|
|
602
|
+
return null;
|
|
603
|
+
}
|
|
601
604
|
const CONTAINER = TR.parentNode;
|
|
602
605
|
let row = (0, _element.index)(TR);
|
|
603
606
|
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 =
|
|
279
|
-
const startColumn =
|
|
278
|
+
const startRow = Math.max(this.getFirstRenderedRow(), 0);
|
|
279
|
+
const startColumn = Math.max(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,6 +594,9 @@ class Table {
|
|
|
594
594
|
return null;
|
|
595
595
|
}
|
|
596
596
|
const TR = cellElement.parentNode;
|
|
597
|
+
if (!TR) {
|
|
598
|
+
return null;
|
|
599
|
+
}
|
|
597
600
|
const CONTAINER = TR.parentNode;
|
|
598
601
|
let row = index(TR);
|
|
599
602
|
let col = cellElement.cellIndex;
|
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,45 @@ 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
|
+
|
|
12
51
|
## [15.1.0] - 2025-02-20
|
|
13
52
|
|
|
14
53
|
### 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 = "
|
|
49
|
-
Handsontable.version = "0.0.0-next-
|
|
48
|
+
Handsontable.buildDate = "16/04/2025 06:18:04";
|
|
49
|
+
Handsontable.version = "0.0.0-next-9410a76-20250416";
|
|
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 = "
|
|
39
|
-
Handsontable.version = "0.0.0-next-
|
|
38
|
+
Handsontable.buildDate = "16/04/2025 06:18:10";
|
|
39
|
+
Handsontable.version = "0.0.0-next-9410a76-20250416";
|
|
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.
|
|
61
|
+
(0, _element.setAttribute)(input, [(0, _a11y.A11Y_LABEL)('Focus catcher')]);
|
|
62
62
|
}
|
|
63
63
|
return input;
|
|
64
64
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { setAttribute } from "../../helpers/dom/element.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { A11Y_LABEL } 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, [
|
|
57
|
+
setAttribute(input, [A11Y_LABEL('Focus catcher')]);
|
|
58
58
|
}
|
|
59
59
|
return input;
|
|
60
60
|
}
|
package/core/hooks/constants.js
CHANGED
|
@@ -336,6 +336,14 @@ 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',
|
|
339
347
|
/**
|
|
340
348
|
* Fired after getting the cell settings.
|
|
341
349
|
*
|
package/core/hooks/constants.mjs
CHANGED
|
@@ -333,6 +333,14 @@ 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',
|
|
336
344
|
/**
|
|
337
345
|
* Fired after getting the cell settings.
|
|
338
346
|
*
|
package/core/hooks/index.d.ts
CHANGED
|
@@ -167,6 +167,7 @@ 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;
|
|
170
171
|
beforeContextMenuSetItems?: (menuItems: ContextMenuMenuItemConfig[]) => void;
|
|
171
172
|
beforeContextMenuShow?: (context: ContextMenu) => void;
|
|
172
173
|
beforeCopy?: (data: CellValue[][], coords: RangeType[], copiedHeadersCount: { columnHeadersCount: number }) => void | boolean;
|
package/core.d.ts
CHANGED
|
@@ -140,7 +140,6 @@ 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;
|
|
144
143
|
resumeExecution(): void;
|
|
145
144
|
resumeRender(): void;
|
|
146
145
|
rootDocument: Document;
|
package/core.js
CHANGED
|
@@ -231,7 +231,6 @@ 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;
|
|
235
234
|
rootElement.insertBefore(this.container, rootElement.firstChild);
|
|
236
235
|
if ((0, _rootInstance.isRootInstance)(this)) {
|
|
237
236
|
(0, _mixed._injectProductInfo)(userSettings.licenseKey, rootElement);
|
|
@@ -263,6 +262,9 @@ function Core(rootElement, userSettings) {
|
|
|
263
262
|
this.rowIndexMapper.addLocalHook('indexesSequenceChange', source => {
|
|
264
263
|
instance.runHooks('afterRowSequenceChange', source);
|
|
265
264
|
});
|
|
265
|
+
eventManager.addEventListener(this.rootDocument.documentElement, 'compositionstart', event => {
|
|
266
|
+
instance.runHooks('beforeCompositionStart', event);
|
|
267
|
+
});
|
|
266
268
|
dataSource = new _dataSource.default(instance);
|
|
267
269
|
if (!this.rootElement.id || this.rootElement.id.substring(0, 3) === 'ht_') {
|
|
268
270
|
this.rootElement.id = this.guid; // if root element does not have an id, assign a random id
|
|
@@ -342,6 +344,7 @@ function Core(rootElement, userSettings) {
|
|
|
342
344
|
let {
|
|
343
345
|
hiddenIndexesChanged
|
|
344
346
|
} = _ref;
|
|
347
|
+
this.forceFullRender = true;
|
|
345
348
|
if (hiddenIndexesChanged) {
|
|
346
349
|
this.selection.commit();
|
|
347
350
|
}
|
|
@@ -625,13 +628,6 @@ function Core(rootElement, userSettings) {
|
|
|
625
628
|
}
|
|
626
629
|
}
|
|
627
630
|
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
|
-
}
|
|
635
631
|
const fixedRowsTop = tableMeta.fixedRowsTop;
|
|
636
632
|
if (fixedRowsTop >= calcIndex + 1) {
|
|
637
633
|
tableMeta.fixedRowsTop -= Math.min(groupAmount, fixedRowsTop - calcIndex);
|
|
@@ -640,6 +636,13 @@ function Core(rootElement, userSettings) {
|
|
|
640
636
|
if (fixedRowsBottom && calcIndex >= totalRows - fixedRowsBottom) {
|
|
641
637
|
tableMeta.fixedRowsBottom -= Math.min(groupAmount, fixedRowsBottom);
|
|
642
638
|
}
|
|
639
|
+
if (totalRows === 0) {
|
|
640
|
+
selection.deselect();
|
|
641
|
+
} else if (source === 'ContextMenu.removeRow') {
|
|
642
|
+
selection.refresh();
|
|
643
|
+
} else {
|
|
644
|
+
selection.shiftRows(groupIndex, -groupAmount);
|
|
645
|
+
}
|
|
643
646
|
offset += groupAmount;
|
|
644
647
|
});
|
|
645
648
|
};
|
|
@@ -1049,8 +1052,7 @@ function Core(rootElement, userSettings) {
|
|
|
1049
1052
|
(0, _index.installFocusCatcher)(instance);
|
|
1050
1053
|
}
|
|
1051
1054
|
instance.runHooks('init');
|
|
1052
|
-
this.
|
|
1053
|
-
this.view.render();
|
|
1055
|
+
this.render();
|
|
1054
1056
|
|
|
1055
1057
|
// Run the logic only if it's the table's initialization and the root element is not visible.
|
|
1056
1058
|
if (!!firstRun && instance.rootElement.offsetParent === null) {
|
|
@@ -1223,13 +1225,11 @@ function Core(rootElement, userSettings) {
|
|
|
1223
1225
|
datamap.set(changes[i][0], changes[i][1], changes[i][3]);
|
|
1224
1226
|
}
|
|
1225
1227
|
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.
|
|
1232
|
+
instance.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.
|
|
1241
|
+
instance.render();
|
|
1242
1242
|
}
|
|
1243
1243
|
}
|
|
1244
1244
|
|
|
@@ -1388,9 +1388,22 @@ function Core(rootElement, userSettings) {
|
|
|
1388
1388
|
...tableMeta
|
|
1389
1389
|
};
|
|
1390
1390
|
}
|
|
1391
|
-
|
|
1391
|
+
const {
|
|
1392
|
+
type,
|
|
1393
|
+
checkedTemplate,
|
|
1394
|
+
uncheckedTemplate
|
|
1395
|
+
} = cellProperties;
|
|
1396
|
+
if (type === 'numeric' && typeof newValue === 'string' && (0, _number.isNumericLike)(newValue)) {
|
|
1392
1397
|
filteredChanges[i][3] = getParsedNumber(newValue);
|
|
1393
1398
|
}
|
|
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
|
+
}
|
|
1394
1407
|
}
|
|
1395
1408
|
return filteredChanges;
|
|
1396
1409
|
}
|
|
@@ -1792,11 +1805,7 @@ function Core(rootElement, userSettings) {
|
|
|
1792
1805
|
const nextValue = this.renderSuspendedCounter - 1;
|
|
1793
1806
|
this.renderSuspendedCounter = Math.max(nextValue, 0);
|
|
1794
1807
|
if (!this.isRenderSuspended() && nextValue === this.renderSuspendedCounter) {
|
|
1795
|
-
|
|
1796
|
-
this.render();
|
|
1797
|
-
} else {
|
|
1798
|
-
instance.view.render();
|
|
1799
|
-
}
|
|
1808
|
+
instance.view.render();
|
|
1800
1809
|
}
|
|
1801
1810
|
};
|
|
1802
1811
|
|
|
@@ -1812,9 +1821,8 @@ function Core(rootElement, userSettings) {
|
|
|
1812
1821
|
*/
|
|
1813
1822
|
this.render = function () {
|
|
1814
1823
|
if (this.view) {
|
|
1815
|
-
|
|
1816
|
-
this.forceFullRender = true;
|
|
1817
|
-
|
|
1824
|
+
// used when data was changed or when all cells need to be re-rendered (slow render)
|
|
1825
|
+
this.forceFullRender = true;
|
|
1818
1826
|
if (!this.isRenderSuspended()) {
|
|
1819
1827
|
instance.view.render();
|
|
1820
1828
|
}
|
|
@@ -2427,8 +2435,7 @@ function Core(rootElement, userSettings) {
|
|
|
2427
2435
|
}
|
|
2428
2436
|
grid.adjustRowsAndCols();
|
|
2429
2437
|
if (instance.view && !firstRun) {
|
|
2430
|
-
instance.
|
|
2431
|
-
instance.view.render();
|
|
2438
|
+
instance.render();
|
|
2432
2439
|
instance.view._wt.wtOverlays.adjustElementsSize();
|
|
2433
2440
|
}
|
|
2434
2441
|
if (!init && instance.view && (currentHeight === '' || height === '' || height === undefined) && currentHeight !== height) {
|