handsontable 0.0.0-next-ff10728-20250410 → 0.0.0-next-d9b3885-20250415

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 (122) hide show
  1. package/3rdparty/walkontable/src/cell/range.js +14 -0
  2. package/3rdparty/walkontable/src/cell/range.mjs +14 -0
  3. package/3rdparty/walkontable/src/renderer/rowHeaders.js +4 -1
  4. package/3rdparty/walkontable/src/renderer/rowHeaders.mjs +4 -1
  5. package/3rdparty/walkontable/src/selection/border/border.js +5 -0
  6. package/3rdparty/walkontable/src/selection/border/border.mjs +5 -0
  7. package/3rdparty/walkontable/src/table/mixin/stickyColumnsStart.js +3 -4
  8. package/3rdparty/walkontable/src/table/mixin/stickyColumnsStart.mjs +3 -4
  9. package/3rdparty/walkontable/src/table/mixin/stickyRowsBottom.js +8 -10
  10. package/3rdparty/walkontable/src/table/mixin/stickyRowsBottom.mjs +8 -10
  11. package/3rdparty/walkontable/src/table/mixin/stickyRowsTop.js +3 -4
  12. package/3rdparty/walkontable/src/table/mixin/stickyRowsTop.mjs +3 -4
  13. package/3rdparty/walkontable/src/table.js +5 -2
  14. package/3rdparty/walkontable/src/table.mjs +5 -2
  15. package/CHANGELOG.md +39 -0
  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 +266 -0
  21. package/core/hooks/constants.mjs +266 -0
  22. package/core/hooks/index.d.ts +1 -0
  23. package/core.d.ts +0 -1
  24. package/core.js +71 -25
  25. package/core.mjs +72 -26
  26. package/dataMap/dataMap.js +0 -7
  27. package/dataMap/dataMap.mjs +0 -7
  28. package/dataMap/metaManager/metaSchema.js +28 -0
  29. package/dataMap/metaManager/metaSchema.mjs +28 -0
  30. package/dist/handsontable.css +3 -3
  31. package/dist/handsontable.full.css +3 -3
  32. package/dist/handsontable.full.js +1375 -350
  33. package/dist/handsontable.full.min.css +3 -3
  34. package/dist/handsontable.full.min.js +17 -17
  35. package/dist/handsontable.js +1375 -350
  36. package/dist/handsontable.min.css +3 -3
  37. package/dist/handsontable.min.js +18 -18
  38. package/editorManager.js +1 -7
  39. package/editorManager.mjs +1 -7
  40. package/editors/autocompleteEditor/autocompleteEditor.js +14 -4
  41. package/editors/autocompleteEditor/autocompleteEditor.mjs +14 -4
  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 +3 -0
  51. package/helpers/object.mjs +3 -0
  52. package/package.json +1 -1
  53. package/plugins/autoColumnSize/autoColumnSize.js +48 -1
  54. package/plugins/autoColumnSize/autoColumnSize.mjs +48 -1
  55. package/plugins/autoRowSize/autoRowSize.js +46 -6
  56. package/plugins/autoRowSize/autoRowSize.mjs +46 -6
  57. package/plugins/bindRowsWithHeaders/bindRowsWithHeaders.js +13 -0
  58. package/plugins/bindRowsWithHeaders/bindRowsWithHeaders.mjs +13 -0
  59. package/plugins/collapsibleColumns/collapsibleColumns.js +31 -0
  60. package/plugins/collapsibleColumns/collapsibleColumns.mjs +31 -0
  61. package/plugins/columnSorting/columnSorting.js +0 -4
  62. package/plugins/columnSorting/columnSorting.mjs +0 -4
  63. package/plugins/columnSummary/columnSummary.js +33 -0
  64. package/plugins/columnSummary/columnSummary.mjs +33 -0
  65. package/plugins/comments/comments.js +54 -0
  66. package/plugins/comments/comments.mjs +54 -0
  67. package/plugins/contextMenu/menu/defaultShortcutsList.js +2 -2
  68. package/plugins/contextMenu/menu/defaultShortcutsList.mjs +2 -2
  69. package/plugins/contextMenu/menu/menu.js +1 -0
  70. package/plugins/contextMenu/menu/menu.mjs +1 -0
  71. package/plugins/contextMenu/menu/positioner.js +10 -2
  72. package/plugins/contextMenu/menu/positioner.mjs +10 -2
  73. package/plugins/copyPaste/copyPaste.js +12 -15
  74. package/plugins/copyPaste/copyPaste.mjs +13 -16
  75. package/plugins/copyPaste/pasteEvent.js +3 -0
  76. package/plugins/copyPaste/pasteEvent.mjs +3 -0
  77. package/plugins/dropdownMenu/dropdownMenu.js +15 -0
  78. package/plugins/dropdownMenu/dropdownMenu.mjs +15 -0
  79. package/plugins/exportFile/exportFile.js +58 -0
  80. package/plugins/exportFile/exportFile.mjs +58 -0
  81. package/plugins/filters/filters.js +99 -24
  82. package/plugins/filters/filters.mjs +99 -24
  83. package/plugins/filters/ui/multipleSelect.js +7 -1
  84. package/plugins/filters/ui/multipleSelect.mjs +7 -1
  85. package/plugins/hiddenColumns/hiddenColumns.js +65 -1
  86. package/plugins/hiddenColumns/hiddenColumns.mjs +65 -1
  87. package/plugins/hiddenRows/hiddenRows.js +65 -1
  88. package/plugins/hiddenRows/hiddenRows.mjs +65 -1
  89. package/plugins/manualColumnResize/manualColumnResize.js +4 -6
  90. package/plugins/manualColumnResize/manualColumnResize.mjs +4 -6
  91. package/plugins/manualRowResize/manualRowResize.js +4 -6
  92. package/plugins/manualRowResize/manualRowResize.mjs +4 -6
  93. package/plugins/mergeCells/mergeCells.js +26 -29
  94. package/plugins/mergeCells/mergeCells.mjs +26 -29
  95. package/plugins/mergeCells/renderer.js +15 -0
  96. package/plugins/mergeCells/renderer.mjs +15 -0
  97. package/plugins/mergeCells/utils.js +31 -0
  98. package/plugins/mergeCells/utils.mjs +27 -0
  99. package/plugins/nestedHeaders/nestedHeaders.js +25 -0
  100. package/plugins/nestedHeaders/nestedHeaders.mjs +25 -0
  101. package/plugins/nestedRows/data/dataManager.js +2 -2
  102. package/plugins/nestedRows/data/dataManager.mjs +2 -2
  103. package/plugins/stretchColumns/stretchColumns.js +13 -0
  104. package/plugins/stretchColumns/stretchColumns.mjs +13 -0
  105. package/plugins/trimRows/trimRows.js +61 -0
  106. package/plugins/trimRows/trimRows.mjs +61 -0
  107. package/plugins/undoRedo/actions/removeColumn.js +19 -14
  108. package/plugins/undoRedo/actions/removeColumn.mjs +19 -14
  109. package/plugins/undoRedo/actions/removeRow.js +12 -4
  110. package/plugins/undoRedo/actions/removeRow.mjs +12 -4
  111. package/selection/selection.js +3 -1
  112. package/selection/selection.mjs +3 -1
  113. package/styles/handsontable.css +14 -15
  114. package/styles/handsontable.min.css +3 -3
  115. package/styles/ht-theme-horizon.css +2 -2
  116. package/styles/ht-theme-horizon.min.css +2 -2
  117. package/styles/ht-theme-main.css +2 -2
  118. package/styles/ht-theme-main.min.css +2 -2
  119. package/tableView.js +5 -8
  120. package/tableView.mjs +5 -8
  121. package/utils/ghostTable.js +3 -0
  122. package/utils/ghostTable.mjs +3 -0
package/core.js CHANGED
@@ -84,6 +84,12 @@ const deprecationWarns = new Set();
84
84
  * by using React's `ref` feature (read more on the [Instance methods](@/guides/getting-started/react-methods/react-methods.md) page).
85
85
  * :::
86
86
  *
87
+ * ::: only-for angular
88
+ * To use these methods, associate a Handsontable instance with your instance
89
+ * of the [`HotTable` component](@/guides/getting-started/installation/installation.md#5-use-the-hottable-component),
90
+ * by using `@ViewChild` decorator (read more on the [Instance access](@/guides/getting-started/angular-hot-instance/angular-hot-instance.md) page).
91
+ * :::
92
+ *
87
93
  * ## How to call a method
88
94
  *
89
95
  * ::: only-for javascript
@@ -114,6 +120,39 @@ const deprecationWarns = new Set();
114
120
  * ```
115
121
  * :::
116
122
  *
123
+ * ::: only-for angular
124
+ * ```ts
125
+ * import { Component, ViewChild, AfterViewInit } from "@angular/core";
126
+ * import {
127
+ * GridSettings,
128
+ * HotTableComponent,
129
+ * HotTableModule,
130
+ * } from "@handsontable/angular-wrapper";
131
+ *
132
+ * `@Component`({
133
+ * standalone: true,
134
+ * imports: [HotTableModule],
135
+ * template: ` <div class="ht-theme-main">
136
+ * <hot-table [settings]="gridSettings" />
137
+ * </div>`,
138
+ * })
139
+ * export class ExampleComponent implements AfterViewInit {
140
+ * `@ViewChild`(HotTableComponent, { static: false })
141
+ * readonly hotTable!: HotTableComponent;
142
+ *
143
+ * readonly gridSettings = <GridSettings>{
144
+ * columns: [{}],
145
+ * };
146
+ *
147
+ * ngAfterViewInit(): void {
148
+ * // Access the Handsontable instance
149
+ * // Call a method
150
+ * this.hotTable?.hotInstance?.setDataAtCell(0, 0, "new value");
151
+ * }
152
+ * }
153
+ * ```
154
+ * :::
155
+ *
117
156
  * @param {HTMLElement} rootElement The element to which the Handsontable instance is injected.
118
157
  * @param {object} userSettings The user defined options.
119
158
  * @param {boolean} [rootInstanceSymbol=false] Indicates if the instance is root of all later instances created.
@@ -231,7 +270,6 @@ function Core(rootElement, userSettings) {
231
270
  const globalMeta = metaManager.getGlobalMeta();
232
271
  const pluginsRegistry = (0, _uniqueMap.createUniqueMap)();
233
272
  this.container = this.rootDocument.createElement('div');
234
- this.renderCall = false;
235
273
  rootElement.insertBefore(this.container, rootElement.firstChild);
236
274
  if ((0, _rootInstance.isRootInstance)(this)) {
237
275
  (0, _mixed._injectProductInfo)(userSettings.licenseKey, rootElement);
@@ -263,6 +301,9 @@ function Core(rootElement, userSettings) {
263
301
  this.rowIndexMapper.addLocalHook('indexesSequenceChange', source => {
264
302
  instance.runHooks('afterRowSequenceChange', source);
265
303
  });
304
+ eventManager.addEventListener(this.rootDocument.documentElement, 'compositionstart', event => {
305
+ instance.runHooks('beforeCompositionStart', event);
306
+ });
266
307
  dataSource = new _dataSource.default(instance);
267
308
  if (!this.rootElement.id || this.rootElement.id.substring(0, 3) === 'ht_') {
268
309
  this.rootElement.id = this.guid; // if root element does not have an id, assign a random id
@@ -342,6 +383,7 @@ function Core(rootElement, userSettings) {
342
383
  let {
343
384
  hiddenIndexesChanged
344
385
  } = _ref;
386
+ this.forceFullRender = true;
345
387
  if (hiddenIndexesChanged) {
346
388
  this.selection.commit();
347
389
  }
@@ -625,13 +667,6 @@ function Core(rootElement, userSettings) {
625
667
  }
626
668
  }
627
669
  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
670
  const fixedRowsTop = tableMeta.fixedRowsTop;
636
671
  if (fixedRowsTop >= calcIndex + 1) {
637
672
  tableMeta.fixedRowsTop -= Math.min(groupAmount, fixedRowsTop - calcIndex);
@@ -640,6 +675,13 @@ function Core(rootElement, userSettings) {
640
675
  if (fixedRowsBottom && calcIndex >= totalRows - fixedRowsBottom) {
641
676
  tableMeta.fixedRowsBottom -= Math.min(groupAmount, fixedRowsBottom);
642
677
  }
678
+ if (totalRows === 0) {
679
+ selection.deselect();
680
+ } else if (source === 'ContextMenu.removeRow') {
681
+ selection.refresh();
682
+ } else {
683
+ selection.shiftRows(groupIndex, -groupAmount);
684
+ }
643
685
  offset += groupAmount;
644
686
  });
645
687
  };
@@ -1049,8 +1091,7 @@ function Core(rootElement, userSettings) {
1049
1091
  (0, _index.installFocusCatcher)(instance);
1050
1092
  }
1051
1093
  instance.runHooks('init');
1052
- this.forceFullRender = true; // used when data was changed
1053
- this.view.render();
1094
+ this.render();
1054
1095
 
1055
1096
  // Run the logic only if it's the table's initialization and the root element is not visible.
1056
1097
  if (!!firstRun && instance.rootElement.offsetParent === null) {
@@ -1223,13 +1264,11 @@ function Core(rootElement, userSettings) {
1223
1264
  datamap.set(changes[i][0], changes[i][1], changes[i][3]);
1224
1265
  }
1225
1266
  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
1267
  if (hasChanges) {
1229
1268
  grid.adjustRowsAndCols();
1230
1269
  instance.runHooks('beforeChangeRender', changes, source);
1231
1270
  editorManager.closeEditor();
1232
- instance.view.render();
1271
+ instance.render();
1233
1272
  editorManager.prepareEditor();
1234
1273
  instance.view.adjustElementsSize();
1235
1274
  instance.runHooks('afterChange', changes, source || 'edit');
@@ -1238,7 +1277,7 @@ function Core(rootElement, userSettings) {
1238
1277
  activeEditor.refreshValue();
1239
1278
  }
1240
1279
  } else {
1241
- instance.view.render();
1280
+ instance.render();
1242
1281
  }
1243
1282
  }
1244
1283
 
@@ -1388,9 +1427,22 @@ function Core(rootElement, userSettings) {
1388
1427
  ...tableMeta
1389
1428
  };
1390
1429
  }
1391
- if (cellProperties.type === 'numeric' && typeof newValue === 'string' && (0, _number.isNumericLike)(newValue)) {
1430
+ const {
1431
+ type,
1432
+ checkedTemplate,
1433
+ uncheckedTemplate
1434
+ } = cellProperties;
1435
+ if (type === 'numeric' && typeof newValue === 'string' && (0, _number.isNumericLike)(newValue)) {
1392
1436
  filteredChanges[i][3] = getParsedNumber(newValue);
1393
1437
  }
1438
+ if (type === 'checkbox') {
1439
+ const stringifiedValue = (0, _mixed.stringify)(newValue);
1440
+ const isChecked = stringifiedValue === (0, _mixed.stringify)(checkedTemplate);
1441
+ const isUnchecked = stringifiedValue === (0, _mixed.stringify)(uncheckedTemplate);
1442
+ if (isChecked || isUnchecked) {
1443
+ filteredChanges[i][3] = isChecked ? checkedTemplate : uncheckedTemplate;
1444
+ }
1445
+ }
1394
1446
  }
1395
1447
  return filteredChanges;
1396
1448
  }
@@ -1792,11 +1844,7 @@ function Core(rootElement, userSettings) {
1792
1844
  const nextValue = this.renderSuspendedCounter - 1;
1793
1845
  this.renderSuspendedCounter = Math.max(nextValue, 0);
1794
1846
  if (!this.isRenderSuspended() && nextValue === this.renderSuspendedCounter) {
1795
- if (this.renderCall) {
1796
- this.render();
1797
- } else {
1798
- instance.view.render();
1799
- }
1847
+ instance.view.render();
1800
1848
  }
1801
1849
  };
1802
1850
 
@@ -1812,9 +1860,8 @@ function Core(rootElement, userSettings) {
1812
1860
  */
1813
1861
  this.render = function () {
1814
1862
  if (this.view) {
1815
- this.renderCall = true;
1816
- this.forceFullRender = true; // used when data was changed or when all cells need to be re-rendered
1817
-
1863
+ // used when data was changed or when all cells need to be re-rendered (slow render)
1864
+ this.forceFullRender = true;
1818
1865
  if (!this.isRenderSuspended()) {
1819
1866
  instance.view.render();
1820
1867
  }
@@ -2427,8 +2474,7 @@ function Core(rootElement, userSettings) {
2427
2474
  }
2428
2475
  grid.adjustRowsAndCols();
2429
2476
  if (instance.view && !firstRun) {
2430
- instance.forceFullRender = true; // used when data was changed
2431
- instance.view.render();
2477
+ instance.render();
2432
2478
  instance.view._wt.wtOverlays.adjustElementsSize();
2433
2479
  }
2434
2480
  if (!init && instance.view && (currentHeight === '' || height === '' || height === undefined) && currentHeight !== height) {
package/core.mjs CHANGED
@@ -14,7 +14,7 @@ import "core-js/modules/esnext.iterator.map.js";
14
14
  import "core-js/modules/web.immediate.js";
15
15
  import { addClass, empty, observeVisibilityChangeOnce, removeClass } from "./helpers/dom/element.mjs";
16
16
  import { isFunction } from "./helpers/function.mjs";
17
- import { isDefined, isUndefined, isRegExp, _injectProductInfo, isEmpty } from "./helpers/mixed.mjs";
17
+ import { isDefined, isUndefined, isRegExp, _injectProductInfo, isEmpty, stringify } from "./helpers/mixed.mjs";
18
18
  import { isMobileBrowser, isIpadOS } from "./helpers/browser.mjs";
19
19
  import EditorManager from "./editorManager.mjs";
20
20
  import EventManager from "./eventManager.mjs";
@@ -79,6 +79,12 @@ const deprecationWarns = new Set();
79
79
  * by using React's `ref` feature (read more on the [Instance methods](@/guides/getting-started/react-methods/react-methods.md) page).
80
80
  * :::
81
81
  *
82
+ * ::: only-for angular
83
+ * To use these methods, associate a Handsontable instance with your instance
84
+ * of the [`HotTable` component](@/guides/getting-started/installation/installation.md#5-use-the-hottable-component),
85
+ * by using `@ViewChild` decorator (read more on the [Instance access](@/guides/getting-started/angular-hot-instance/angular-hot-instance.md) page).
86
+ * :::
87
+ *
82
88
  * ## How to call a method
83
89
  *
84
90
  * ::: only-for javascript
@@ -109,6 +115,39 @@ const deprecationWarns = new Set();
109
115
  * ```
110
116
  * :::
111
117
  *
118
+ * ::: only-for angular
119
+ * ```ts
120
+ * import { Component, ViewChild, AfterViewInit } from "@angular/core";
121
+ * import {
122
+ * GridSettings,
123
+ * HotTableComponent,
124
+ * HotTableModule,
125
+ * } from "@handsontable/angular-wrapper";
126
+ *
127
+ * `@Component`({
128
+ * standalone: true,
129
+ * imports: [HotTableModule],
130
+ * template: ` <div class="ht-theme-main">
131
+ * <hot-table [settings]="gridSettings" />
132
+ * </div>`,
133
+ * })
134
+ * export class ExampleComponent implements AfterViewInit {
135
+ * `@ViewChild`(HotTableComponent, { static: false })
136
+ * readonly hotTable!: HotTableComponent;
137
+ *
138
+ * readonly gridSettings = <GridSettings>{
139
+ * columns: [{}],
140
+ * };
141
+ *
142
+ * ngAfterViewInit(): void {
143
+ * // Access the Handsontable instance
144
+ * // Call a method
145
+ * this.hotTable?.hotInstance?.setDataAtCell(0, 0, "new value");
146
+ * }
147
+ * }
148
+ * ```
149
+ * :::
150
+ *
112
151
  * @param {HTMLElement} rootElement The element to which the Handsontable instance is injected.
113
152
  * @param {object} userSettings The user defined options.
114
153
  * @param {boolean} [rootInstanceSymbol=false] Indicates if the instance is root of all later instances created.
@@ -226,7 +265,6 @@ export default function Core(rootElement, userSettings) {
226
265
  const globalMeta = metaManager.getGlobalMeta();
227
266
  const pluginsRegistry = createUniqueMap();
228
267
  this.container = this.rootDocument.createElement('div');
229
- this.renderCall = false;
230
268
  rootElement.insertBefore(this.container, rootElement.firstChild);
231
269
  if (isRootInstance(this)) {
232
270
  _injectProductInfo(userSettings.licenseKey, rootElement);
@@ -258,6 +296,9 @@ export default function Core(rootElement, userSettings) {
258
296
  this.rowIndexMapper.addLocalHook('indexesSequenceChange', source => {
259
297
  instance.runHooks('afterRowSequenceChange', source);
260
298
  });
299
+ eventManager.addEventListener(this.rootDocument.documentElement, 'compositionstart', event => {
300
+ instance.runHooks('beforeCompositionStart', event);
301
+ });
261
302
  dataSource = new DataSource(instance);
262
303
  if (!this.rootElement.id || this.rootElement.id.substring(0, 3) === 'ht_') {
263
304
  this.rootElement.id = this.guid; // if root element does not have an id, assign a random id
@@ -337,6 +378,7 @@ export default function Core(rootElement, userSettings) {
337
378
  let {
338
379
  hiddenIndexesChanged
339
380
  } = _ref;
381
+ this.forceFullRender = true;
340
382
  if (hiddenIndexesChanged) {
341
383
  this.selection.commit();
342
384
  }
@@ -620,13 +662,6 @@ export default function Core(rootElement, userSettings) {
620
662
  }
621
663
  }
622
664
  const totalRows = instance.countRows();
623
- if (totalRows === 0) {
624
- selection.deselect();
625
- } else if (source === 'ContextMenu.removeRow') {
626
- selection.refresh();
627
- } else {
628
- selection.shiftRows(groupIndex, -groupAmount);
629
- }
630
665
  const fixedRowsTop = tableMeta.fixedRowsTop;
631
666
  if (fixedRowsTop >= calcIndex + 1) {
632
667
  tableMeta.fixedRowsTop -= Math.min(groupAmount, fixedRowsTop - calcIndex);
@@ -635,6 +670,13 @@ export default function Core(rootElement, userSettings) {
635
670
  if (fixedRowsBottom && calcIndex >= totalRows - fixedRowsBottom) {
636
671
  tableMeta.fixedRowsBottom -= Math.min(groupAmount, fixedRowsBottom);
637
672
  }
673
+ if (totalRows === 0) {
674
+ selection.deselect();
675
+ } else if (source === 'ContextMenu.removeRow') {
676
+ selection.refresh();
677
+ } else {
678
+ selection.shiftRows(groupIndex, -groupAmount);
679
+ }
638
680
  offset += groupAmount;
639
681
  });
640
682
  };
@@ -1044,8 +1086,7 @@ export default function Core(rootElement, userSettings) {
1044
1086
  installFocusCatcher(instance);
1045
1087
  }
1046
1088
  instance.runHooks('init');
1047
- this.forceFullRender = true; // used when data was changed
1048
- this.view.render();
1089
+ this.render();
1049
1090
 
1050
1091
  // Run the logic only if it's the table's initialization and the root element is not visible.
1051
1092
  if (!!firstRun && instance.rootElement.offsetParent === null) {
@@ -1218,13 +1259,11 @@ export default function Core(rootElement, userSettings) {
1218
1259
  datamap.set(changes[i][0], changes[i][1], changes[i][3]);
1219
1260
  }
1220
1261
  const hasChanges = changes.length > 0;
1221
- instance.forceFullRender = true; // used when data was changed or when all cells need to be re-rendered
1222
-
1223
1262
  if (hasChanges) {
1224
1263
  grid.adjustRowsAndCols();
1225
1264
  instance.runHooks('beforeChangeRender', changes, source);
1226
1265
  editorManager.closeEditor();
1227
- instance.view.render();
1266
+ instance.render();
1228
1267
  editorManager.prepareEditor();
1229
1268
  instance.view.adjustElementsSize();
1230
1269
  instance.runHooks('afterChange', changes, source || 'edit');
@@ -1233,7 +1272,7 @@ export default function Core(rootElement, userSettings) {
1233
1272
  activeEditor.refreshValue();
1234
1273
  }
1235
1274
  } else {
1236
- instance.view.render();
1275
+ instance.render();
1237
1276
  }
1238
1277
  }
1239
1278
 
@@ -1383,9 +1422,22 @@ export default function Core(rootElement, userSettings) {
1383
1422
  ...tableMeta
1384
1423
  };
1385
1424
  }
1386
- if (cellProperties.type === 'numeric' && typeof newValue === 'string' && isNumericLike(newValue)) {
1425
+ const {
1426
+ type,
1427
+ checkedTemplate,
1428
+ uncheckedTemplate
1429
+ } = cellProperties;
1430
+ if (type === 'numeric' && typeof newValue === 'string' && isNumericLike(newValue)) {
1387
1431
  filteredChanges[i][3] = getParsedNumber(newValue);
1388
1432
  }
1433
+ if (type === 'checkbox') {
1434
+ const stringifiedValue = stringify(newValue);
1435
+ const isChecked = stringifiedValue === stringify(checkedTemplate);
1436
+ const isUnchecked = stringifiedValue === stringify(uncheckedTemplate);
1437
+ if (isChecked || isUnchecked) {
1438
+ filteredChanges[i][3] = isChecked ? checkedTemplate : uncheckedTemplate;
1439
+ }
1440
+ }
1389
1441
  }
1390
1442
  return filteredChanges;
1391
1443
  }
@@ -1787,11 +1839,7 @@ export default function Core(rootElement, userSettings) {
1787
1839
  const nextValue = this.renderSuspendedCounter - 1;
1788
1840
  this.renderSuspendedCounter = Math.max(nextValue, 0);
1789
1841
  if (!this.isRenderSuspended() && nextValue === this.renderSuspendedCounter) {
1790
- if (this.renderCall) {
1791
- this.render();
1792
- } else {
1793
- instance.view.render();
1794
- }
1842
+ instance.view.render();
1795
1843
  }
1796
1844
  };
1797
1845
 
@@ -1807,9 +1855,8 @@ export default function Core(rootElement, userSettings) {
1807
1855
  */
1808
1856
  this.render = function () {
1809
1857
  if (this.view) {
1810
- this.renderCall = true;
1811
- this.forceFullRender = true; // used when data was changed or when all cells need to be re-rendered
1812
-
1858
+ // used when data was changed or when all cells need to be re-rendered (slow render)
1859
+ this.forceFullRender = true;
1813
1860
  if (!this.isRenderSuspended()) {
1814
1861
  instance.view.render();
1815
1862
  }
@@ -2422,8 +2469,7 @@ export default function Core(rootElement, userSettings) {
2422
2469
  }
2423
2470
  grid.adjustRowsAndCols();
2424
2471
  if (instance.view && !firstRun) {
2425
- instance.forceFullRender = true; // used when data was changed
2426
- instance.view.render();
2472
+ instance.render();
2427
2473
  instance.view._wt.wtOverlays.adjustElementsSize();
2428
2474
  }
2429
2475
  if (!init && instance.view && (currentHeight === '' || height === '' || height === undefined) && currentHeight !== height) {
@@ -357,8 +357,6 @@ class DataMap {
357
357
  }
358
358
  }
359
359
  this.hot.runHooks('afterCreateRow', newVisualRowIndex, numberOfCreatedRows, source);
360
- this.hot.forceFullRender = true; // used when data was changed
361
-
362
360
  return {
363
361
  delta: numberOfCreatedRows,
364
362
  startPhysicalIndex: physicalRowIndex
@@ -444,8 +442,6 @@ class DataMap {
444
442
  }
445
443
  const newVisualColumnIndex = this.hot.toVisualColumn(startPhysicalIndex);
446
444
  this.hot.runHooks('afterCreateCol', newVisualColumnIndex, numberOfCreatedCols, source);
447
- this.hot.forceFullRender = true; // used when data was changed
448
-
449
445
  this.refreshDuckSchema();
450
446
  return {
451
447
  delta: numberOfCreatedCols,
@@ -492,8 +488,6 @@ class DataMap {
492
488
  this.metaManager.removeRow(rowPhysicalIndex, 1);
493
489
  });
494
490
  this.hot.runHooks('afterRemoveRow', rowIndex, numberOfRemovedIndexes, removedPhysicalIndexes, source);
495
- this.hot.forceFullRender = true; // used when data was changed
496
-
497
491
  return true;
498
492
  }
499
493
 
@@ -553,7 +547,6 @@ class DataMap {
553
547
  }
554
548
  }
555
549
  this.hot.runHooks('afterRemoveCol', columnIndex, amount, removedPhysicalIndexes, source);
556
- this.hot.forceFullRender = true; // used when data was changed
557
550
  this.refreshDuckSchema();
558
551
  return true;
559
552
  }
@@ -353,8 +353,6 @@ class DataMap {
353
353
  }
354
354
  }
355
355
  this.hot.runHooks('afterCreateRow', newVisualRowIndex, numberOfCreatedRows, source);
356
- this.hot.forceFullRender = true; // used when data was changed
357
-
358
356
  return {
359
357
  delta: numberOfCreatedRows,
360
358
  startPhysicalIndex: physicalRowIndex
@@ -440,8 +438,6 @@ class DataMap {
440
438
  }
441
439
  const newVisualColumnIndex = this.hot.toVisualColumn(startPhysicalIndex);
442
440
  this.hot.runHooks('afterCreateCol', newVisualColumnIndex, numberOfCreatedCols, source);
443
- this.hot.forceFullRender = true; // used when data was changed
444
-
445
441
  this.refreshDuckSchema();
446
442
  return {
447
443
  delta: numberOfCreatedCols,
@@ -488,8 +484,6 @@ class DataMap {
488
484
  this.metaManager.removeRow(rowPhysicalIndex, 1);
489
485
  });
490
486
  this.hot.runHooks('afterRemoveRow', rowIndex, numberOfRemovedIndexes, removedPhysicalIndexes, source);
491
- this.hot.forceFullRender = true; // used when data was changed
492
-
493
487
  return true;
494
488
  }
495
489
 
@@ -549,7 +543,6 @@ class DataMap {
549
543
  }
550
544
  }
551
545
  this.hot.runHooks('afterRemoveCol', columnIndex, amount, removedPhysicalIndexes, source);
552
- this.hot.forceFullRender = true; // used when data was changed
553
546
  this.refreshDuckSchema();
554
547
  return true;
555
548
  }
@@ -83,6 +83,33 @@ var _object = require("../../helpers/object");
83
83
  * ```
84
84
  * :::
85
85
  *
86
+ * ::: only-for angular
87
+ * ```ts
88
+ * settings = {
89
+ * data: [
90
+ * ["A1", "B1", "C1", "D1", "E1"],
91
+ * ["A2", "B2", "C2", "D2", "E2"],
92
+ * ["A3", "B3", "C3", "D3", "E3"],
93
+ * ["A4", "B4", "C4", "D4", "E4"],
94
+ * ["A5", "B5", "C5", "D5", "E5"],
95
+ * ],
96
+ * width: 400,
97
+ * height: 300,
98
+ * colHeaders: true,
99
+ * rowHeaders: true,
100
+ * customBorders: true,
101
+ * dropdownMenu: true,
102
+ * multiColumnSorting: true,
103
+ * filters: true,
104
+ * manualRowMove: true,
105
+ * };
106
+ * ```
107
+ *
108
+ * ```html
109
+ * <hot-table [settings]="settings" />
110
+ * ```
111
+ * :::
112
+ *
86
113
  * Depending on your needs, you can apply [configuration options](@/api/options.md) to different elements of your grid:
87
114
  * - [The entire grid](@/guides/getting-started/configuration-options/configuration-options.md#set-grid-options)
88
115
  * - [Individual columns](@/guides/getting-started/configuration-options/configuration-options.md#set-column-options)
@@ -2649,6 +2676,7 @@ var _default = () => {
2649
2676
  * | `'de-CH'` | German - Switzerland |
2650
2677
  * | `'de-DE'` | German - Germany |
2651
2678
  * | `'es-MX'` | Spanish - Mexico |
2679
+ * | `'fa-IR'` | Persian - Iran |
2652
2680
  * | `'fr-FR'` | French - France |
2653
2681
  * | `'hr-HR'` | Croatian - Croatia |
2654
2682
  * | `'it-IT'` | Italian - Italy |
@@ -80,6 +80,33 @@ import { isObjectEqual } from "../../helpers/object.mjs";
80
80
  * ```
81
81
  * :::
82
82
  *
83
+ * ::: only-for angular
84
+ * ```ts
85
+ * settings = {
86
+ * data: [
87
+ * ["A1", "B1", "C1", "D1", "E1"],
88
+ * ["A2", "B2", "C2", "D2", "E2"],
89
+ * ["A3", "B3", "C3", "D3", "E3"],
90
+ * ["A4", "B4", "C4", "D4", "E4"],
91
+ * ["A5", "B5", "C5", "D5", "E5"],
92
+ * ],
93
+ * width: 400,
94
+ * height: 300,
95
+ * colHeaders: true,
96
+ * rowHeaders: true,
97
+ * customBorders: true,
98
+ * dropdownMenu: true,
99
+ * multiColumnSorting: true,
100
+ * filters: true,
101
+ * manualRowMove: true,
102
+ * };
103
+ * ```
104
+ *
105
+ * ```html
106
+ * <hot-table [settings]="settings" />
107
+ * ```
108
+ * :::
109
+ *
83
110
  * Depending on your needs, you can apply [configuration options](@/api/options.md) to different elements of your grid:
84
111
  * - [The entire grid](@/guides/getting-started/configuration-options/configuration-options.md#set-grid-options)
85
112
  * - [Individual columns](@/guides/getting-started/configuration-options/configuration-options.md#set-column-options)
@@ -2646,6 +2673,7 @@ export default () => {
2646
2673
  * | `'de-CH'` | German - Switzerland |
2647
2674
  * | `'de-DE'` | German - Germany |
2648
2675
  * | `'es-MX'` | Spanish - Mexico |
2676
+ * | `'fa-IR'` | Persian - Iran |
2649
2677
  * | `'fr-FR'` | French - France |
2650
2678
  * | `'hr-HR'` | Croatian - Croatia |
2651
2679
  * | `'it-IT'` | Italian - Italy |
@@ -25,8 +25,8 @@
25
25
  * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER ARISING FROM
26
26
  * USE OR INABILITY TO USE THIS SOFTWARE.
27
27
  *
28
- * Version: 0.0.0-next-ff10728-20250410
29
- * Release date: 20/02/2025 (built at 10/04/2025 06:44:13)
28
+ * Version: 0.0.0-next-d9b3885-20250415
29
+ * Release date: 19/03/2025 (built at 15/04/2025 10:07:06)
30
30
  */
31
31
  /**
32
32
  * Fix for bootstrap styles
@@ -1458,7 +1458,7 @@ textarea.HandsontableCopyPaste {
1458
1458
  }
1459
1459
 
1460
1460
  .htUIMultipleSelect .ht_master .wtHolder {
1461
- overflow-y: scroll;
1461
+ overflow: auto;
1462
1462
  }
1463
1463
 
1464
1464
  .handsontable .htFiltersActive .changeType {
@@ -25,8 +25,8 @@
25
25
  * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER ARISING FROM
26
26
  * USE OR INABILITY TO USE THIS SOFTWARE.
27
27
  *
28
- * Version: 0.0.0-next-ff10728-20250410
29
- * Release date: 20/02/2025 (built at 10/04/2025 06:44:13)
28
+ * Version: 0.0.0-next-d9b3885-20250415
29
+ * Release date: 19/03/2025 (built at 15/04/2025 10:07:06)
30
30
  */
31
31
  /**
32
32
  * Fix for bootstrap styles
@@ -1458,7 +1458,7 @@ textarea.HandsontableCopyPaste {
1458
1458
  }
1459
1459
 
1460
1460
  .htUIMultipleSelect .ht_master .wtHolder {
1461
- overflow-y: scroll;
1461
+ overflow: auto;
1462
1462
  }
1463
1463
 
1464
1464
  .handsontable .htFiltersActive .changeType {