handsontable 17.0.0 → 17.0.1-rc2
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.
- package/3rdparty/walkontable/src/overlays.js +3 -3
- package/3rdparty/walkontable/src/overlays.mjs +3 -3
- package/3rdparty/walkontable/src/selection/border/border.js +26 -15
- package/3rdparty/walkontable/src/selection/border/border.mjs +26 -15
- package/3rdparty/walkontable/src/selection/manager.js +12 -0
- package/3rdparty/walkontable/src/selection/manager.mjs +12 -0
- package/CHANGELOG.md +21 -2
- package/base.js +2 -2
- package/base.mjs +2 -2
- package/core.d.ts +5 -0
- package/core.js +10 -2
- package/core.mjs +10 -2
- package/dataMap/metaManager/metaSchema.js +2 -2
- package/dataMap/metaManager/metaSchema.mjs +2 -2
- package/dist/handsontable.full.js +594 -225
- package/dist/handsontable.full.min.js +75 -75
- package/dist/handsontable.js +579 -221
- package/dist/handsontable.min.js +29 -29
- package/dist/languages/all.min.js +1 -1
- package/dist/languages/ar-AR.min.js +1 -1
- package/dist/languages/cs-CZ.min.js +1 -1
- package/dist/languages/de-CH.min.js +1 -1
- package/dist/languages/de-DE.min.js +1 -1
- package/dist/languages/en-US.min.js +1 -1
- package/dist/languages/es-MX.min.js +1 -1
- package/dist/languages/fa-IR.min.js +1 -1
- package/dist/languages/fr-FR.min.js +1 -1
- package/dist/languages/hr-HR.min.js +1 -1
- package/dist/languages/it-IT.min.js +1 -1
- package/dist/languages/ja-JP.min.js +1 -1
- package/dist/languages/ko-KR.min.js +1 -1
- package/dist/languages/lv-LV.min.js +1 -1
- package/dist/languages/nb-NO.min.js +1 -1
- package/dist/languages/nl-NL.min.js +1 -1
- package/dist/languages/pl-PL.min.js +1 -1
- package/dist/languages/pt-BR.min.js +1 -1
- package/dist/languages/ru-RU.min.js +1 -1
- package/dist/languages/sr-SP.min.js +1 -1
- package/dist/languages/zh-CN.min.js +1 -1
- package/dist/languages/zh-TW.min.js +1 -1
- package/dist/themes/classic.js +2 -2
- package/dist/themes/classic.min.js +3 -3
- package/dist/themes/horizon.js +2 -2
- package/dist/themes/horizon.min.js +3 -3
- package/dist/themes/main.js +4 -4
- package/dist/themes/main.min.js +3 -3
- package/dist/themes/static/variables/colors/ant.js +2 -2
- package/dist/themes/static/variables/colors/ant.min.js +3 -3
- package/dist/themes/static/variables/colors/classic.js +2 -2
- package/dist/themes/static/variables/colors/classic.min.js +3 -3
- package/dist/themes/static/variables/colors/horizon.js +2 -2
- package/dist/themes/static/variables/colors/horizon.min.js +3 -3
- package/dist/themes/static/variables/colors/main.js +2 -2
- package/dist/themes/static/variables/colors/main.min.js +3 -3
- package/dist/themes/static/variables/colors/material.js +2 -2
- package/dist/themes/static/variables/colors/material.min.js +3 -3
- package/dist/themes/static/variables/colors/shadcn.js +2 -2
- package/dist/themes/static/variables/colors/shadcn.min.js +3 -3
- package/dist/themes/static/variables/density.js +2 -2
- package/dist/themes/static/variables/density.min.js +3 -3
- package/dist/themes/static/variables/helpers/iconsMap.js +2 -2
- package/dist/themes/static/variables/helpers/iconsMap.min.js +3 -3
- package/dist/themes/static/variables/icons/horizon.js +2 -2
- package/dist/themes/static/variables/icons/horizon.min.js +3 -3
- package/dist/themes/static/variables/icons/main.js +2 -2
- package/dist/themes/static/variables/icons/main.min.js +3 -3
- package/dist/themes/static/variables/sizing.js +2 -2
- package/dist/themes/static/variables/sizing.min.js +3 -3
- package/dist/themes/static/variables/tokens/classic.js +2 -2
- package/dist/themes/static/variables/tokens/classic.min.js +3 -3
- package/dist/themes/static/variables/tokens/horizon.js +2 -2
- package/dist/themes/static/variables/tokens/horizon.min.js +3 -3
- package/dist/themes/static/variables/tokens/main.js +4 -4
- package/dist/themes/static/variables/tokens/main.min.js +3 -3
- package/editors/baseEditor/baseEditor.js +17 -23
- package/editors/baseEditor/baseEditor.mjs +17 -23
- package/editors/dateEditor/dateEditor.js +28 -4
- package/editors/dateEditor/dateEditor.mjs +28 -4
- package/helpers/browser.d.ts +1 -0
- package/helpers/browser.js +19 -1
- package/helpers/browser.mjs +18 -1
- package/helpers/dom/element.js +42 -26
- package/helpers/dom/element.mjs +43 -27
- package/helpers/mixed.js +6 -6
- package/helpers/mixed.mjs +6 -6
- package/package.json +1 -1
- package/plugins/exportFile/exportFile.js +60 -21
- package/plugins/exportFile/exportFile.mjs +60 -21
- package/plugins/formulas/formulas.js +3 -5
- package/plugins/formulas/formulas.mjs +3 -5
- package/plugins/nestedHeaders/nestedHeaders.js +22 -2
- package/plugins/nestedHeaders/nestedHeaders.mjs +22 -2
- package/plugins/nestedHeaders/utils/ghostTable.js +162 -57
- package/plugins/nestedHeaders/utils/ghostTable.mjs +162 -57
- package/plugins/nestedRows/nestedRows.js +55 -27
- package/plugins/nestedRows/nestedRows.mjs +55 -27
- package/plugins/undoRedo/actions/dataChange.js +11 -6
- package/plugins/undoRedo/actions/dataChange.mjs +11 -6
- package/plugins/undoRedo/undoRedo.js +3 -1
- package/plugins/undoRedo/undoRedo.mjs +3 -1
- package/styles/handsontable.css +27 -10
- package/styles/handsontable.min.css +3 -3
- package/styles/handsontableStyles.js +1 -1
- package/styles/handsontableStyles.mjs +1 -1
- package/styles/ht-icons-horizon.min.css +2 -2
- package/styles/ht-icons-main.min.css +2 -2
- package/styles/ht-theme-classic-no-icons.min.css +2 -2
- package/styles/ht-theme-classic.min.css +2 -2
- package/styles/ht-theme-horizon-no-icons.min.css +2 -2
- package/styles/ht-theme-horizon.min.css +2 -2
- package/styles/ht-theme-main-no-icons.css +2 -2
- package/styles/ht-theme-main-no-icons.min.css +3 -3
- package/styles/ht-theme-main.css +2 -2
- package/styles/ht-theme-main.min.css +3 -3
- package/tableView.js +5 -0
- package/tableView.mjs +5 -0
- package/themes/static/variables/tokens/main.js +2 -2
- package/themes/static/variables/tokens/main.mjs +2 -2
- package/utils/parseTable.js +86 -13
- package/utils/parseTable.mjs +85 -13
|
@@ -462,13 +462,13 @@ class Overlays {
|
|
|
462
462
|
}
|
|
463
463
|
const topHolder = this.topOverlay.clone.wtTable.holder; // todo rethink
|
|
464
464
|
const leftHolder = this.inlineStartOverlay.clone.wtTable.holder; // todo rethink
|
|
465
|
-
|
|
465
|
+
const preventOverflow = this.wtSettings.getSetting('preventOverflow');
|
|
466
466
|
let scrollX = this.scrollableElement.scrollLeft;
|
|
467
467
|
let scrollY = this.scrollableElement.scrollTop;
|
|
468
|
-
if (this.wot.wtViewport.isHorizontallyScrollableByWindow()) {
|
|
468
|
+
if (this.wot.wtViewport.isHorizontallyScrollableByWindow() && (typeof preventOverflow === 'boolean' && preventOverflow || preventOverflow !== 'horizontal')) {
|
|
469
469
|
scrollX = this.scrollableElement.scrollX;
|
|
470
470
|
}
|
|
471
|
-
if (this.wot.wtViewport.isVerticallyScrollableByWindow()) {
|
|
471
|
+
if (this.wot.wtViewport.isVerticallyScrollableByWindow() && (typeof preventOverflow === 'boolean' && preventOverflow || preventOverflow !== 'vertical')) {
|
|
472
472
|
scrollY = this.scrollableElement.scrollY;
|
|
473
473
|
}
|
|
474
474
|
this.horizontalScrolling = this.lastScrollX !== scrollX;
|
|
@@ -459,13 +459,13 @@ class Overlays {
|
|
|
459
459
|
}
|
|
460
460
|
const topHolder = this.topOverlay.clone.wtTable.holder; // todo rethink
|
|
461
461
|
const leftHolder = this.inlineStartOverlay.clone.wtTable.holder; // todo rethink
|
|
462
|
-
|
|
462
|
+
const preventOverflow = this.wtSettings.getSetting('preventOverflow');
|
|
463
463
|
let scrollX = this.scrollableElement.scrollLeft;
|
|
464
464
|
let scrollY = this.scrollableElement.scrollTop;
|
|
465
|
-
if (this.wot.wtViewport.isHorizontallyScrollableByWindow()) {
|
|
465
|
+
if (this.wot.wtViewport.isHorizontallyScrollableByWindow() && (typeof preventOverflow === 'boolean' && preventOverflow || preventOverflow !== 'horizontal')) {
|
|
466
466
|
scrollX = this.scrollableElement.scrollX;
|
|
467
467
|
}
|
|
468
|
-
if (this.wot.wtViewport.isVerticallyScrollableByWindow()) {
|
|
468
|
+
if (this.wot.wtViewport.isVerticallyScrollableByWindow() && (typeof preventOverflow === 'boolean' && preventOverflow || preventOverflow !== 'vertical')) {
|
|
469
469
|
scrollY = this.scrollableElement.scrollY;
|
|
470
470
|
}
|
|
471
471
|
this.horizontalScrolling = this.lastScrollX !== scrollX;
|
|
@@ -206,24 +206,16 @@ class Border {
|
|
|
206
206
|
* Create multiple selector handler for mobile devices.
|
|
207
207
|
*/
|
|
208
208
|
createMultipleSelectorHandles() {
|
|
209
|
+
const hitAreaWidth = 40;
|
|
209
210
|
const {
|
|
210
|
-
rootDocument
|
|
211
|
-
wtSettings
|
|
211
|
+
rootDocument
|
|
212
212
|
} = this.wot;
|
|
213
|
-
const stylesHandler = wtSettings.getSetting('stylesHandler');
|
|
214
|
-
const cellMobileHandleSize = stylesHandler.getCSSVariableValue('cell-mobile-handle-size');
|
|
215
|
-
const cellMobileHandleBorderRadius = stylesHandler.getCSSVariableValue('cell-mobile-handle-border-radius');
|
|
216
|
-
const cellMobileHandleBackgroundColor = stylesHandler.getCSSVariableValue('cell-mobile-handle-background-color');
|
|
217
|
-
const cellMobileHandleBackgroundOpacity = stylesHandler.getCSSVariableValue('cell-mobile-handle-background-opacity');
|
|
218
|
-
const cellMobileHandleBorderWidth = stylesHandler.getCSSVariableValue('cell-mobile-handle-border-width');
|
|
219
|
-
const cellMobileHandleBorderColor = stylesHandler.getCSSVariableValue('cell-mobile-handle-border-color');
|
|
220
213
|
this.selectionHandles = {
|
|
221
214
|
top: rootDocument.createElement('DIV'),
|
|
222
215
|
topHitArea: rootDocument.createElement('DIV'),
|
|
223
216
|
bottom: rootDocument.createElement('DIV'),
|
|
224
217
|
bottomHitArea: rootDocument.createElement('DIV')
|
|
225
218
|
};
|
|
226
|
-
const hitAreaWidth = 40;
|
|
227
219
|
this.selectionHandles.top.className = 'topSelectionHandle topLeftSelectionHandle';
|
|
228
220
|
this.selectionHandles.topHitArea.className = 'topSelectionHandle-HitArea topLeftSelectionHandle-HitArea';
|
|
229
221
|
this.selectionHandles.bottom.className = 'bottomSelectionHandle bottomRightSelectionHandle';
|
|
@@ -244,23 +236,42 @@ class Border {
|
|
|
244
236
|
this.selectionHandles.styles.bottomHitArea[key] = value;
|
|
245
237
|
this.selectionHandles.styles.topHitArea[key] = value;
|
|
246
238
|
});
|
|
239
|
+
this.updateMultipleSelectorHandlesStyles();
|
|
240
|
+
this.main.appendChild(this.selectionHandles.top);
|
|
241
|
+
this.main.appendChild(this.selectionHandles.bottom);
|
|
242
|
+
this.main.appendChild(this.selectionHandles.topHitArea);
|
|
243
|
+
this.main.appendChild(this.selectionHandles.bottomHitArea);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Updates the multiple selector handle styles from the current theme after a theme change.
|
|
248
|
+
* Rereads CSS variables and applies them to existing handle elements.
|
|
249
|
+
*/
|
|
250
|
+
updateMultipleSelectorHandlesStyles() {
|
|
251
|
+
if (!this.selectionHandles) {
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
const wtSettings = this.wot.wtSettings;
|
|
255
|
+
const stylesHandler = wtSettings.getSetting('stylesHandler');
|
|
256
|
+
const cellMobileHandleSize = stylesHandler.getCSSVariableValue('cell-mobile-handle-size');
|
|
257
|
+
const cellMobileHandleBorderRadius = stylesHandler.getCSSVariableValue('cell-mobile-handle-border-radius');
|
|
258
|
+
const cellMobileHandleBackgroundColor = stylesHandler.getCSSVariableValue('cell-mobile-handle-background-color');
|
|
259
|
+
const cellMobileHandleBackgroundOpacity = stylesHandler.getCSSVariableValue('cell-mobile-handle-background-opacity');
|
|
260
|
+
const cellMobileHandleBorderWidth = stylesHandler.getCSSVariableValue('cell-mobile-handle-border-width');
|
|
261
|
+
const cellMobileHandleBorderColor = stylesHandler.getCSSVariableValue('cell-mobile-handle-border-color');
|
|
247
262
|
const handleStyle = {
|
|
248
263
|
position: 'absolute',
|
|
249
264
|
height: `${cellMobileHandleSize}px`,
|
|
250
265
|
width: `${cellMobileHandleSize}px`,
|
|
251
266
|
'border-radius': `${cellMobileHandleBorderRadius}px`,
|
|
252
267
|
// eslint-disable-next-line max-len
|
|
253
|
-
background: `color-mix(in srgb, ${cellMobileHandleBackgroundColor} ${cellMobileHandleBackgroundOpacity}
|
|
268
|
+
background: `color-mix(in srgb, ${cellMobileHandleBackgroundColor} ${cellMobileHandleBackgroundOpacity}%, transparent)`,
|
|
254
269
|
border: `${cellMobileHandleBorderWidth}px solid ${cellMobileHandleBorderColor}`
|
|
255
270
|
};
|
|
256
271
|
(0, _object.objectEach)(handleStyle, (value, key) => {
|
|
257
272
|
this.selectionHandles.styles.bottom[key] = value;
|
|
258
273
|
this.selectionHandles.styles.top[key] = value;
|
|
259
274
|
});
|
|
260
|
-
this.main.appendChild(this.selectionHandles.top);
|
|
261
|
-
this.main.appendChild(this.selectionHandles.bottom);
|
|
262
|
-
this.main.appendChild(this.selectionHandles.topHitArea);
|
|
263
|
-
this.main.appendChild(this.selectionHandles.bottomHitArea);
|
|
264
275
|
}
|
|
265
276
|
|
|
266
277
|
/**
|
|
@@ -203,24 +203,16 @@ class Border {
|
|
|
203
203
|
* Create multiple selector handler for mobile devices.
|
|
204
204
|
*/
|
|
205
205
|
createMultipleSelectorHandles() {
|
|
206
|
+
const hitAreaWidth = 40;
|
|
206
207
|
const {
|
|
207
|
-
rootDocument
|
|
208
|
-
wtSettings
|
|
208
|
+
rootDocument
|
|
209
209
|
} = this.wot;
|
|
210
|
-
const stylesHandler = wtSettings.getSetting('stylesHandler');
|
|
211
|
-
const cellMobileHandleSize = stylesHandler.getCSSVariableValue('cell-mobile-handle-size');
|
|
212
|
-
const cellMobileHandleBorderRadius = stylesHandler.getCSSVariableValue('cell-mobile-handle-border-radius');
|
|
213
|
-
const cellMobileHandleBackgroundColor = stylesHandler.getCSSVariableValue('cell-mobile-handle-background-color');
|
|
214
|
-
const cellMobileHandleBackgroundOpacity = stylesHandler.getCSSVariableValue('cell-mobile-handle-background-opacity');
|
|
215
|
-
const cellMobileHandleBorderWidth = stylesHandler.getCSSVariableValue('cell-mobile-handle-border-width');
|
|
216
|
-
const cellMobileHandleBorderColor = stylesHandler.getCSSVariableValue('cell-mobile-handle-border-color');
|
|
217
210
|
this.selectionHandles = {
|
|
218
211
|
top: rootDocument.createElement('DIV'),
|
|
219
212
|
topHitArea: rootDocument.createElement('DIV'),
|
|
220
213
|
bottom: rootDocument.createElement('DIV'),
|
|
221
214
|
bottomHitArea: rootDocument.createElement('DIV')
|
|
222
215
|
};
|
|
223
|
-
const hitAreaWidth = 40;
|
|
224
216
|
this.selectionHandles.top.className = 'topSelectionHandle topLeftSelectionHandle';
|
|
225
217
|
this.selectionHandles.topHitArea.className = 'topSelectionHandle-HitArea topLeftSelectionHandle-HitArea';
|
|
226
218
|
this.selectionHandles.bottom.className = 'bottomSelectionHandle bottomRightSelectionHandle';
|
|
@@ -241,23 +233,42 @@ class Border {
|
|
|
241
233
|
this.selectionHandles.styles.bottomHitArea[key] = value;
|
|
242
234
|
this.selectionHandles.styles.topHitArea[key] = value;
|
|
243
235
|
});
|
|
236
|
+
this.updateMultipleSelectorHandlesStyles();
|
|
237
|
+
this.main.appendChild(this.selectionHandles.top);
|
|
238
|
+
this.main.appendChild(this.selectionHandles.bottom);
|
|
239
|
+
this.main.appendChild(this.selectionHandles.topHitArea);
|
|
240
|
+
this.main.appendChild(this.selectionHandles.bottomHitArea);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Updates the multiple selector handle styles from the current theme after a theme change.
|
|
245
|
+
* Rereads CSS variables and applies them to existing handle elements.
|
|
246
|
+
*/
|
|
247
|
+
updateMultipleSelectorHandlesStyles() {
|
|
248
|
+
if (!this.selectionHandles) {
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
const wtSettings = this.wot.wtSettings;
|
|
252
|
+
const stylesHandler = wtSettings.getSetting('stylesHandler');
|
|
253
|
+
const cellMobileHandleSize = stylesHandler.getCSSVariableValue('cell-mobile-handle-size');
|
|
254
|
+
const cellMobileHandleBorderRadius = stylesHandler.getCSSVariableValue('cell-mobile-handle-border-radius');
|
|
255
|
+
const cellMobileHandleBackgroundColor = stylesHandler.getCSSVariableValue('cell-mobile-handle-background-color');
|
|
256
|
+
const cellMobileHandleBackgroundOpacity = stylesHandler.getCSSVariableValue('cell-mobile-handle-background-opacity');
|
|
257
|
+
const cellMobileHandleBorderWidth = stylesHandler.getCSSVariableValue('cell-mobile-handle-border-width');
|
|
258
|
+
const cellMobileHandleBorderColor = stylesHandler.getCSSVariableValue('cell-mobile-handle-border-color');
|
|
244
259
|
const handleStyle = {
|
|
245
260
|
position: 'absolute',
|
|
246
261
|
height: `${cellMobileHandleSize}px`,
|
|
247
262
|
width: `${cellMobileHandleSize}px`,
|
|
248
263
|
'border-radius': `${cellMobileHandleBorderRadius}px`,
|
|
249
264
|
// eslint-disable-next-line max-len
|
|
250
|
-
background: `color-mix(in srgb, ${cellMobileHandleBackgroundColor} ${cellMobileHandleBackgroundOpacity}
|
|
265
|
+
background: `color-mix(in srgb, ${cellMobileHandleBackgroundColor} ${cellMobileHandleBackgroundOpacity}%, transparent)`,
|
|
251
266
|
border: `${cellMobileHandleBorderWidth}px solid ${cellMobileHandleBorderColor}`
|
|
252
267
|
};
|
|
253
268
|
objectEach(handleStyle, (value, key) => {
|
|
254
269
|
this.selectionHandles.styles.bottom[key] = value;
|
|
255
270
|
this.selectionHandles.styles.top[key] = value;
|
|
256
271
|
});
|
|
257
|
-
this.main.appendChild(this.selectionHandles.top);
|
|
258
|
-
this.main.appendChild(this.selectionHandles.bottom);
|
|
259
|
-
this.main.appendChild(this.selectionHandles.topHitArea);
|
|
260
|
-
this.main.appendChild(this.selectionHandles.bottomHitArea);
|
|
261
272
|
}
|
|
262
273
|
|
|
263
274
|
/**
|
|
@@ -151,6 +151,18 @@ class SelectionManager {
|
|
|
151
151
|
_classPrivateFieldGet(_selectionBorders, this).delete(selection);
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
+
/**
|
|
155
|
+
* Refreshes the multiple selector handle styles on all border instances after a theme change.
|
|
156
|
+
*/
|
|
157
|
+
refreshAllBorderHandleStyles() {
|
|
158
|
+
_classPrivateFieldGet(_selectionBorders, this).forEach(bordersMap => {
|
|
159
|
+
bordersMap.forEach(border => {
|
|
160
|
+
var _border$updateMultipl;
|
|
161
|
+
(_border$updateMultipl = border.updateMultipleSelectorHandlesStyles) === null || _border$updateMultipl === void 0 || _border$updateMultipl.call(border);
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
154
166
|
/**
|
|
155
167
|
* Renders all the selections (add CSS classes to cells and draw borders).
|
|
156
168
|
*
|
|
@@ -147,6 +147,18 @@ export class SelectionManager {
|
|
|
147
147
|
_classPrivateFieldGet(_selectionBorders, this).delete(selection);
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
+
/**
|
|
151
|
+
* Refreshes the multiple selector handle styles on all border instances after a theme change.
|
|
152
|
+
*/
|
|
153
|
+
refreshAllBorderHandleStyles() {
|
|
154
|
+
_classPrivateFieldGet(_selectionBorders, this).forEach(bordersMap => {
|
|
155
|
+
bordersMap.forEach(border => {
|
|
156
|
+
var _border$updateMultipl;
|
|
157
|
+
(_border$updateMultipl = border.updateMultipleSelectorHandlesStyles) === null || _border$updateMultipl === void 0 || _border$updateMultipl.call(border);
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
150
162
|
/**
|
|
151
163
|
* Renders all the selections (add CSS classes to cells and draw borders).
|
|
152
164
|
*
|
package/CHANGELOG.md
CHANGED
|
@@ -9,7 +9,26 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
9
9
|
|
|
10
10
|
<!-- UNVERSIONED -->
|
|
11
11
|
|
|
12
|
-
## [17.0.
|
|
12
|
+
## [17.0.1-rc1] - 2026-03-19
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
- Fix UndoRedo crash when nullified changes [#12000](https://github.com/handsontable/handsontable/pull/12000)
|
|
16
|
+
- Fix UndoRedo beforeChange order [#12001](https://github.com/handsontable/handsontable/pull/12001)
|
|
17
|
+
- Fixed a bug where the editor does not receive the user inputs [#12042](https://github.com/handsontable/handsontable/pull/12042)
|
|
18
|
+
- Fixed scrollbar width calcualtion on Safari >=26. [#12047](https://github.com/handsontable/handsontable/pull/12047)
|
|
19
|
+
- Added missing typings for Core [#12048](https://github.com/handsontable/handsontable/pull/12048)
|
|
20
|
+
- Fixed rounded corners that may be applied in incorrect use cases [#12052](https://github.com/handsontable/handsontable/pull/12052)
|
|
21
|
+
- Fixed undo/redo stack desync with formulas engine [#12056](https://github.com/handsontable/handsontable/pull/12056)
|
|
22
|
+
- Fixed column width calculation for collapsed columns [#12059](https://github.com/handsontable/handsontable/pull/12059)
|
|
23
|
+
- Fixed and issue with table backround overflow [#12063](https://github.com/handsontable/handsontable/pull/12063)
|
|
24
|
+
- Fixed column header misalignment when nestedRow is enabled [#12081](https://github.com/handsontable/handsontable/pull/12081)
|
|
25
|
+
- Fixed an issue with mobile select handles styles [#12083](https://github.com/handsontable/handsontable/pull/12083)
|
|
26
|
+
- Improved clipboard processing after paste [#12084](https://github.com/handsontable/handsontable/pull/12084)
|
|
27
|
+
- Fixed an issue with scrolling issue that occurs when preventOverflow is enabled [#12086](https://github.com/handsontable/handsontable/pull/12086)
|
|
28
|
+
- Fixed date picker positioning near viewport edges [#12087](https://github.com/handsontable/handsontable/pull/12087)
|
|
29
|
+
- Fixed an issue with main theme hover on menu icon background color [#12159](https://github.com/handsontable/handsontable/pull/12159)
|
|
30
|
+
|
|
31
|
+
## [17.0.0] - 2026-03-09
|
|
13
32
|
|
|
14
33
|
### Added
|
|
15
34
|
- **Breaking change**: Added the Theme API. [#11950](https://github.com/handsontable/handsontable/pull/11950)
|
|
@@ -34,7 +53,7 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
34
53
|
- Deprecated **moment.js** for date parsing and display. Replace it with the `Intl.DateTimeFormat` API. [Migration guide](https://handsontable.com/docs/javascript-data-grid/migration-from-16.2-to-17.0#_4-migrate-from-moment-js-format-to-intl-datetimeformat)
|
|
35
54
|
- Deprecated **DOMPurify** as a built-in XSS sanitizer. Use the new `sanitizer` option or convert content to plain text. [Migration guide](https://handsontable.com/docs/javascript-data-grid/migration-from-16.2-to-17.0#_5-migrate-from-built-in-dompurify-to-the-sanitizer-option)
|
|
36
55
|
- Deprecated **core-js** polyfills for ECMAScript features. [Migration guide](https://handsontable.com/docs/javascript-data-grid/migration-from-16.2-to-17.0#_6-core-js-dependency-removed)
|
|
37
|
-
- Deprecated bundling **HyperFormula** as a Handsontable dependency. Starting from version 18.0, install and import it separately, then pass it to the Formulas plugin with `licenseKey: 'internal-use'`. [Formula calculation](https://handsontable.com/docs/javascript-data-grid/formula-calculation)
|
|
56
|
+
- Deprecated bundling **HyperFormula** as a Handsontable dependency. Starting from version 18.0, install and import it separately, then pass it to the Formulas plugin with `licenseKey: 'internal-use-in-handsontable'`. [Formula calculation](https://handsontable.com/docs/javascript-data-grid/formula-calculation)
|
|
38
57
|
|
|
39
58
|
### Removed
|
|
40
59
|
- **Breaking change**: Removed deprecated wrapper packages for Angular, React, and Vue, the `PersistentState` plugin, and the legacy undo/redo methods. [#12015](https://github.com/handsontable/handsontable/pull/12015)
|
package/base.js
CHANGED
|
@@ -49,8 +49,8 @@ Handsontable.hooks = _hooks.Hooks.getSingleton();
|
|
|
49
49
|
Handsontable.CellCoords = _src.CellCoords;
|
|
50
50
|
Handsontable.CellRange = _src.CellRange;
|
|
51
51
|
Handsontable.packageName = 'handsontable';
|
|
52
|
-
Handsontable.buildDate = "
|
|
53
|
-
Handsontable.version = "17.0.
|
|
52
|
+
Handsontable.buildDate = "23/03/2026 11:47:53";
|
|
53
|
+
Handsontable.version = "17.0.1-rc2";
|
|
54
54
|
Handsontable.languages = {
|
|
55
55
|
dictionaryKeys: _registry.dictionaryKeys,
|
|
56
56
|
getLanguageDictionary: _registry.getLanguageDictionary,
|
package/base.mjs
CHANGED
|
@@ -39,8 +39,8 @@ Handsontable.hooks = Hooks.getSingleton();
|
|
|
39
39
|
Handsontable.CellCoords = CellCoords;
|
|
40
40
|
Handsontable.CellRange = CellRange;
|
|
41
41
|
Handsontable.packageName = 'handsontable';
|
|
42
|
-
Handsontable.buildDate = "
|
|
43
|
-
Handsontable.version = "17.0.
|
|
42
|
+
Handsontable.buildDate = "23/03/2026 11:48:00";
|
|
43
|
+
Handsontable.version = "17.0.1-rc2";
|
|
44
44
|
Handsontable.languages = {
|
|
45
45
|
dictionaryKeys,
|
|
46
46
|
getLanguageDictionary,
|
package/core.d.ts
CHANGED
|
@@ -121,6 +121,7 @@ export default class Core {
|
|
|
121
121
|
getTableHeight(): number;
|
|
122
122
|
getTranslatedPhrase(dictionaryKey: string, extraArguments: any): string | null;
|
|
123
123
|
getValue(): CellValue;
|
|
124
|
+
guid: string;
|
|
124
125
|
hasColHeaders(): boolean;
|
|
125
126
|
hasHook(key: keyof Events): boolean;
|
|
126
127
|
hasRowHeaders(): boolean;
|
|
@@ -145,9 +146,13 @@ export default class Core {
|
|
|
145
146
|
render(): void;
|
|
146
147
|
resumeExecution(): void;
|
|
147
148
|
resumeRender(): void;
|
|
149
|
+
rootContainer: HTMLElement;
|
|
148
150
|
rootDocument: Document;
|
|
149
151
|
rootElement: HTMLElement;
|
|
152
|
+
rootGridElement: HTMLElement;
|
|
153
|
+
rootPortalElement: HTMLElement;
|
|
150
154
|
rootWindow: Window;
|
|
155
|
+
rootWrapperElement: HTMLElement;
|
|
151
156
|
rowIndexMapper: IndexMapper;
|
|
152
157
|
runHooks(key: keyof Events, p1?: any, p2?: any, p3?: any, p4?: any, p5?: any, p6?: any): any;
|
|
153
158
|
scrollViewportTo(options: { row?: number, col?: number, verticalSnap?: 'top' | 'bottom', horizontalSnap?: 'start' | 'end', considerHiddenIndexes?: boolean }, callback?: () => void): boolean;
|
package/core.js
CHANGED
|
@@ -325,6 +325,7 @@ function Core(rootContainer, userSettings) {
|
|
|
325
325
|
rootDocument: instance.rootDocument,
|
|
326
326
|
onThemeChange: themeName => {
|
|
327
327
|
if ((0, _rootInstance.isRootInstance)(this)) {
|
|
328
|
+
var _this$view;
|
|
328
329
|
(0, _element.removeClass)(this.rootWrapperElement, /ht-theme-.*/g);
|
|
329
330
|
(0, _element.removeClass)(this.rootPortalElement, /ht-theme-.*/g);
|
|
330
331
|
if (themeName) {
|
|
@@ -334,6 +335,7 @@ function Core(rootContainer, userSettings) {
|
|
|
334
335
|
(0, _console.warn)(`The "${themeName}" theme is enabled, but its stylesheets are missing` + ' or not imported correctly. Import the correct CSS files in order to use that theme.');
|
|
335
336
|
}
|
|
336
337
|
}
|
|
338
|
+
(_this$view = this.view) === null || _this$view === void 0 || (_this$view = _this$view._wt) === null || _this$view === void 0 || (_this$view = _this$view.selectionManager) === null || _this$view === void 0 || _this$view.refreshAllBorderHandleStyles();
|
|
337
339
|
}
|
|
338
340
|
},
|
|
339
341
|
injectCoreCss: typeof (userSettings === null || userSettings === void 0 ? void 0 : userSettings.injectCoreCss) === 'boolean' ? userSettings.injectCoreCss : true
|
|
@@ -1211,7 +1213,7 @@ function Core(rootContainer, userSettings) {
|
|
|
1211
1213
|
focusGridManager.init();
|
|
1212
1214
|
if ((0, _rootInstance.isRootInstance)(this)) {
|
|
1213
1215
|
(0, _a11yAnnouncer.install)(instance.rootPortalElement);
|
|
1214
|
-
(0, _mixed._injectProductInfo)(mergedUserSettings.licenseKey, this.rootWrapperElement, "
|
|
1216
|
+
(0, _mixed._injectProductInfo)(mergedUserSettings.licenseKey, this.rootWrapperElement, "23/03/2026");
|
|
1215
1217
|
}
|
|
1216
1218
|
instance.runHooks('init');
|
|
1217
1219
|
this.render();
|
|
@@ -2616,7 +2618,13 @@ function Core(rootContainer, userSettings) {
|
|
|
2616
2618
|
initializeThemeManager(settings.theme);
|
|
2617
2619
|
instance.useTheme(instance.themeManager.getClassName());
|
|
2618
2620
|
} else {
|
|
2619
|
-
|
|
2621
|
+
let themeObject;
|
|
2622
|
+
if (typeof settings.theme.getThemeConfig !== 'function') {
|
|
2623
|
+
themeObject = (0, _themes2.registerTheme)(settings.theme);
|
|
2624
|
+
} else {
|
|
2625
|
+
themeObject = settings.theme;
|
|
2626
|
+
}
|
|
2627
|
+
instance.themeManager.update(themeObject);
|
|
2620
2628
|
instance.useTheme(instance.themeManager.getClassName());
|
|
2621
2629
|
}
|
|
2622
2630
|
}
|
package/core.mjs
CHANGED
|
@@ -320,6 +320,7 @@ export default function Core(rootContainer, userSettings) {
|
|
|
320
320
|
rootDocument: instance.rootDocument,
|
|
321
321
|
onThemeChange: themeName => {
|
|
322
322
|
if (isRootInstance(this)) {
|
|
323
|
+
var _this$view;
|
|
323
324
|
removeClass(this.rootWrapperElement, /ht-theme-.*/g);
|
|
324
325
|
removeClass(this.rootPortalElement, /ht-theme-.*/g);
|
|
325
326
|
if (themeName) {
|
|
@@ -329,6 +330,7 @@ export default function Core(rootContainer, userSettings) {
|
|
|
329
330
|
warn(`The "${themeName}" theme is enabled, but its stylesheets are missing` + ' or not imported correctly. Import the correct CSS files in order to use that theme.');
|
|
330
331
|
}
|
|
331
332
|
}
|
|
333
|
+
(_this$view = this.view) === null || _this$view === void 0 || (_this$view = _this$view._wt) === null || _this$view === void 0 || (_this$view = _this$view.selectionManager) === null || _this$view === void 0 || _this$view.refreshAllBorderHandleStyles();
|
|
332
334
|
}
|
|
333
335
|
},
|
|
334
336
|
injectCoreCss: typeof (userSettings === null || userSettings === void 0 ? void 0 : userSettings.injectCoreCss) === 'boolean' ? userSettings.injectCoreCss : true
|
|
@@ -1206,7 +1208,7 @@ export default function Core(rootContainer, userSettings) {
|
|
|
1206
1208
|
focusGridManager.init();
|
|
1207
1209
|
if (isRootInstance(this)) {
|
|
1208
1210
|
installAccessibilityAnnouncer(instance.rootPortalElement);
|
|
1209
|
-
_injectProductInfo(mergedUserSettings.licenseKey, this.rootWrapperElement, "
|
|
1211
|
+
_injectProductInfo(mergedUserSettings.licenseKey, this.rootWrapperElement, "23/03/2026");
|
|
1210
1212
|
}
|
|
1211
1213
|
instance.runHooks('init');
|
|
1212
1214
|
this.render();
|
|
@@ -2611,7 +2613,13 @@ export default function Core(rootContainer, userSettings) {
|
|
|
2611
2613
|
initializeThemeManager(settings.theme);
|
|
2612
2614
|
instance.useTheme(instance.themeManager.getClassName());
|
|
2613
2615
|
} else {
|
|
2614
|
-
|
|
2616
|
+
let themeObject;
|
|
2617
|
+
if (typeof settings.theme.getThemeConfig !== 'function') {
|
|
2618
|
+
themeObject = registerTheme(settings.theme);
|
|
2619
|
+
} else {
|
|
2620
|
+
themeObject = settings.theme;
|
|
2621
|
+
}
|
|
2622
|
+
instance.themeManager.update(themeObject);
|
|
2615
2623
|
instance.useTheme(instance.themeManager.getClassName());
|
|
2616
2624
|
}
|
|
2617
2625
|
}
|
|
@@ -4953,7 +4953,7 @@ var _default = () => {
|
|
|
4953
4953
|
* @description
|
|
4954
4954
|
* The `skipColumnOnPaste` option determines whether you can paste data into a given column.
|
|
4955
4955
|
*
|
|
4956
|
-
* You can only apply the `skipColumnOnPaste` option to an entire column, using the [`columns`](#columns) option.
|
|
4956
|
+
* You can only apply the `skipColumnOnPaste` option to an entire column, using the [`columns`](#columns) option. This option is not supported for the global table level settings.
|
|
4957
4957
|
*
|
|
4958
4958
|
* You can set the `skipColumnOnPaste` option to one of the following:
|
|
4959
4959
|
*
|
|
@@ -4986,7 +4986,7 @@ var _default = () => {
|
|
|
4986
4986
|
*
|
|
4987
4987
|
* The `skipRowOnPaste` option determines whether you can paste data into a given row.
|
|
4988
4988
|
*
|
|
4989
|
-
* You can only apply the `skipRowOnPaste` option to an entire row, using the [`cells`](#cells) option.
|
|
4989
|
+
* You can only apply the `skipRowOnPaste` option to an entire row, using the [`cells`](#cells) option. This option is not supported for the global table level settings.
|
|
4990
4990
|
*
|
|
4991
4991
|
* You can set the `skipRowOnPaste` option to one of the following:
|
|
4992
4992
|
*
|
|
@@ -4950,7 +4950,7 @@ export default () => {
|
|
|
4950
4950
|
* @description
|
|
4951
4951
|
* The `skipColumnOnPaste` option determines whether you can paste data into a given column.
|
|
4952
4952
|
*
|
|
4953
|
-
* You can only apply the `skipColumnOnPaste` option to an entire column, using the [`columns`](#columns) option.
|
|
4953
|
+
* You can only apply the `skipColumnOnPaste` option to an entire column, using the [`columns`](#columns) option. This option is not supported for the global table level settings.
|
|
4954
4954
|
*
|
|
4955
4955
|
* You can set the `skipColumnOnPaste` option to one of the following:
|
|
4956
4956
|
*
|
|
@@ -4983,7 +4983,7 @@ export default () => {
|
|
|
4983
4983
|
*
|
|
4984
4984
|
* The `skipRowOnPaste` option determines whether you can paste data into a given row.
|
|
4985
4985
|
*
|
|
4986
|
-
* You can only apply the `skipRowOnPaste` option to an entire row, using the [`cells`](#cells) option.
|
|
4986
|
+
* You can only apply the `skipRowOnPaste` option to an entire row, using the [`cells`](#cells) option. This option is not supported for the global table level settings.
|
|
4987
4987
|
*
|
|
4988
4988
|
* You can set the `skipRowOnPaste` option to one of the following:
|
|
4989
4989
|
*
|