handsontable 0.0.0-next-f86a877-20250819 → 0.0.0-next-fce5825-20250822

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 (73) hide show
  1. package/base.js +2 -2
  2. package/base.mjs +2 -2
  3. package/core/focusCatcher/index.js +37 -20
  4. package/core/focusCatcher/index.mjs +37 -20
  5. package/core/focusCatcher/utils.js +3 -64
  6. package/core/focusCatcher/utils.mjs +1 -60
  7. package/core/hooks/constants.js +58 -0
  8. package/core/hooks/constants.mjs +58 -0
  9. package/core/hooks/index.d.ts +7 -0
  10. package/core.js +13 -4
  11. package/core.mjs +13 -4
  12. package/dataMap/metaManager/metaSchema.js +95 -0
  13. package/dataMap/metaManager/metaSchema.mjs +95 -0
  14. package/dist/handsontable.css +103 -5
  15. package/dist/handsontable.full.css +103 -5
  16. package/dist/handsontable.full.js +1600 -282
  17. package/dist/handsontable.full.min.css +3 -3
  18. package/dist/handsontable.full.min.js +65 -65
  19. package/dist/handsontable.js +1600 -282
  20. package/dist/handsontable.min.css +3 -3
  21. package/dist/handsontable.min.js +27 -27
  22. package/editors/baseEditor/baseEditor.js +1 -0
  23. package/editors/baseEditor/baseEditor.mjs +1 -0
  24. package/helpers/a11y.js +5 -1
  25. package/helpers/a11y.mjs +3 -1
  26. package/helpers/mixed.js +64 -1
  27. package/helpers/mixed.mjs +62 -1
  28. package/index.d.ts +9 -0
  29. package/package.json +6 -1
  30. package/plugins/base/base.js +75 -14
  31. package/plugins/base/base.mjs +75 -14
  32. package/plugins/contextMenu/contextMenu.js +1 -0
  33. package/plugins/contextMenu/contextMenu.mjs +1 -0
  34. package/plugins/dialog/dialog.d.ts +23 -0
  35. package/plugins/dialog/dialog.js +469 -0
  36. package/plugins/dialog/dialog.mjs +465 -0
  37. package/plugins/dialog/index.d.ts +1 -0
  38. package/plugins/dialog/index.js +7 -0
  39. package/plugins/dialog/index.mjs +1 -0
  40. package/plugins/dialog/ui.js +240 -0
  41. package/plugins/dialog/ui.mjs +235 -0
  42. package/plugins/dropdownMenu/dropdownMenu.js +1 -0
  43. package/plugins/dropdownMenu/dropdownMenu.mjs +1 -0
  44. package/plugins/index.d.ts +3 -0
  45. package/plugins/index.js +3 -0
  46. package/plugins/index.mjs +3 -1
  47. package/plugins/pagination/focusController.js +27 -0
  48. package/plugins/pagination/focusController.mjs +23 -0
  49. package/plugins/pagination/pagination.js +165 -18
  50. package/plugins/pagination/pagination.mjs +165 -18
  51. package/plugins/pagination/ui.js +101 -62
  52. package/plugins/pagination/ui.mjs +102 -63
  53. package/selection/range.js +11 -0
  54. package/selection/range.mjs +11 -0
  55. package/selection/selection.js +63 -2
  56. package/selection/selection.mjs +63 -2
  57. package/selection/utils.js +2 -1
  58. package/selection/utils.mjs +2 -1
  59. package/settings.d.ts +2 -0
  60. package/shortcuts/context.js +4 -1
  61. package/shortcuts/context.mjs +4 -1
  62. package/shortcuts/manager.js +17 -3
  63. package/shortcuts/manager.mjs +17 -3
  64. package/styles/handsontable.css +106 -22
  65. package/styles/handsontable.min.css +3 -3
  66. package/styles/ht-theme-horizon.css +24 -6
  67. package/styles/ht-theme-horizon.min.css +3 -3
  68. package/styles/ht-theme-main.css +52 -34
  69. package/styles/ht-theme-main.min.css +3 -3
  70. package/tableView.js +7 -2
  71. package/tableView.mjs +7 -2
  72. package/{core/focusCatcher → utils}/focusDetector.js +29 -11
  73. package/{core/focusCatcher → utils}/focusDetector.mjs +29 -11
@@ -253,6 +253,7 @@ class BaseEditor {
253
253
  this.hot.removeHook('afterScroll', openEditor);
254
254
  openEditor();
255
255
  }
256
+ this.addHook('beforeDialogShow', () => this.cancelChanges());
256
257
  }
257
258
 
258
259
  /**
@@ -249,6 +249,7 @@ export class BaseEditor {
249
249
  this.hot.removeHook('afterScroll', openEditor);
250
250
  openEditor();
251
251
  }
252
+ this.addHook('beforeDialogShow', () => this.cancelChanges());
252
253
  }
253
254
 
254
255
  /**
package/helpers/a11y.js CHANGED
@@ -33,6 +33,8 @@ const A11Y_OPTION = () => ['role', 'option'];
33
33
  exports.A11Y_OPTION = A11Y_OPTION;
34
34
  const A11Y_CHECKBOX = () => ['role', 'checkbox'];
35
35
  exports.A11Y_CHECKBOX = A11Y_CHECKBOX;
36
+ const A11Y_DIALOG = () => ['role', 'dialog'];
37
+ exports.A11Y_DIALOG = A11Y_DIALOG;
36
38
  const A11Y_SCOPE_COL = () => ['scope', 'col'];
37
39
  exports.A11Y_SCOPE_COL = A11Y_SCOPE_COL;
38
40
  const A11Y_SCOPE_ROW = () => ['scope', 'row'];
@@ -85,4 +87,6 @@ exports.A11Y_RELEVANT = A11Y_RELEVANT;
85
87
  const A11Y_SETSIZE = val => ['aria-setsize', val];
86
88
  exports.A11Y_SETSIZE = A11Y_SETSIZE;
87
89
  const A11Y_POSINSET = val => ['aria-posinset', val];
88
- exports.A11Y_POSINSET = A11Y_POSINSET;
90
+ exports.A11Y_POSINSET = A11Y_POSINSET;
91
+ const A11Y_MODAL = () => ['aria-modal', 'true'];
92
+ exports.A11Y_MODAL = A11Y_MODAL;
package/helpers/a11y.mjs CHANGED
@@ -14,6 +14,7 @@ export const A11Y_COMBOBOX = () => ['role', 'combobox'];
14
14
  export const A11Y_LISTBOX = () => ['role', 'listbox'];
15
15
  export const A11Y_OPTION = () => ['role', 'option'];
16
16
  export const A11Y_CHECKBOX = () => ['role', 'checkbox'];
17
+ export const A11Y_DIALOG = () => ['role', 'dialog'];
17
18
  export const A11Y_SCOPE_COL = () => ['scope', 'col'];
18
19
  export const A11Y_SCOPE_ROW = () => ['scope', 'row'];
19
20
  export const A11Y_TEXT = () => ['type', 'text'];
@@ -41,4 +42,5 @@ export const A11Y_ACTIVEDESCENDANT = val => ['aria-activedescendant', val];
41
42
  export const A11Y_LIVE = val => ['aria-live', val];
42
43
  export const A11Y_RELEVANT = val => ['aria-relevant', val];
43
44
  export const A11Y_SETSIZE = val => ['aria-setsize', val];
44
- export const A11Y_POSINSET = val => ['aria-posinset', val];
45
+ export const A11Y_POSINSET = val => ['aria-posinset', val];
46
+ export const A11Y_MODAL = () => ['aria-modal', 'true'];
package/helpers/mixed.js CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  exports.__esModule = true;
4
4
  exports._injectProductInfo = _injectProductInfo;
5
+ exports.getMostBottomEndPosition = getMostBottomEndPosition;
6
+ exports.getMostTopStartPosition = getMostTopStartPosition;
5
7
  exports.isDefined = isDefined;
6
8
  exports.isEmpty = isEmpty;
7
9
  exports.isRegExp = isRegExp;
@@ -134,7 +136,7 @@ const domMessages = {
134
136
  function _injectProductInfo(key, element) {
135
137
  const hasValidType = !isEmpty(key);
136
138
  const isNonCommercial = typeof key === 'string' && key.toLowerCase() === 'non-commercial-and-evaluation';
137
- const hotVersion = "0.0.0-next-f86a877-20250819";
139
+ const hotVersion = "0.0.0-next-fce5825-20250822";
138
140
  let keyValidityDate;
139
141
  let consoleMessageState = 'invalid';
140
142
  let domMessageState = 'invalid';
@@ -208,4 +210,65 @@ function _checkKeySchema(v) {
208
210
  }
209
211
  return p === z;
210
212
  }
213
+
214
+ /**
215
+ * Gets the coordinates of the most top-start cell or header (depends on the table settings and its size).
216
+ *
217
+ * @param {Core} hot The Handsontable instance.
218
+ * @returns {CellCoords|null}
219
+ */
220
+ function getMostTopStartPosition(hot) {
221
+ const {
222
+ rowIndexMapper,
223
+ columnIndexMapper
224
+ } = hot;
225
+ const {
226
+ navigableHeaders
227
+ } = hot.getSettings();
228
+ let topRow = navigableHeaders && hot.countColHeaders() > 0 ? -hot.countColHeaders() : 0;
229
+ let startColumn = navigableHeaders && hot.countRowHeaders() > 0 ? -hot.countRowHeaders() : 0;
230
+ if (topRow === 0) {
231
+ topRow = rowIndexMapper.getVisualFromRenderableIndex(topRow);
232
+ }
233
+ if (startColumn === 0) {
234
+ startColumn = columnIndexMapper.getVisualFromRenderableIndex(startColumn);
235
+ }
236
+ if (topRow === null || startColumn === null) {
237
+ return null;
238
+ }
239
+ return hot._createCellCoords(topRow, startColumn);
240
+ }
241
+
242
+ /**
243
+ * Gets the coordinates of the most bottom-end cell or header (depends on the table settings and its size).
244
+ *
245
+ * @param {Core} hot The Handsontable instance.
246
+ * @returns {CellCoords|null}
247
+ */
248
+ function getMostBottomEndPosition(hot) {
249
+ var _rowIndexMapper$getVi, _columnIndexMapper$ge;
250
+ const {
251
+ rowIndexMapper,
252
+ columnIndexMapper
253
+ } = hot;
254
+ const {
255
+ navigableHeaders
256
+ } = hot.getSettings();
257
+ let bottomRow = rowIndexMapper.getRenderableIndexesLength() - 1;
258
+ let endColumn = columnIndexMapper.getRenderableIndexesLength() - 1;
259
+ if (bottomRow < 0) {
260
+ if (!navigableHeaders || hot.countColHeaders() === 0) {
261
+ return null;
262
+ }
263
+ bottomRow = -1;
264
+ }
265
+ if (endColumn < 0) {
266
+ if (!navigableHeaders || hot.countColHeaders() === 0) {
267
+ return null;
268
+ }
269
+ endColumn = -1;
270
+ }
271
+ return hot._createCellCoords((_rowIndexMapper$getVi = rowIndexMapper.getVisualFromRenderableIndex(bottomRow)) !== null && _rowIndexMapper$getVi !== void 0 ? _rowIndexMapper$getVi : bottomRow, (_columnIndexMapper$ge = columnIndexMapper.getVisualFromRenderableIndex(endColumn)) !== null && _columnIndexMapper$ge !== void 0 ? _columnIndexMapper$ge : endColumn);
272
+ }
273
+
211
274
  /* eslint-enable */
package/helpers/mixed.mjs CHANGED
@@ -124,7 +124,7 @@ const domMessages = {
124
124
  export function _injectProductInfo(key, element) {
125
125
  const hasValidType = !isEmpty(key);
126
126
  const isNonCommercial = typeof key === 'string' && key.toLowerCase() === 'non-commercial-and-evaluation';
127
- const hotVersion = "0.0.0-next-f86a877-20250819";
127
+ const hotVersion = "0.0.0-next-fce5825-20250822";
128
128
  let keyValidityDate;
129
129
  let consoleMessageState = 'invalid';
130
130
  let domMessageState = 'invalid';
@@ -198,4 +198,65 @@ function _checkKeySchema(v) {
198
198
  }
199
199
  return p === z;
200
200
  }
201
+
202
+ /**
203
+ * Gets the coordinates of the most top-start cell or header (depends on the table settings and its size).
204
+ *
205
+ * @param {Core} hot The Handsontable instance.
206
+ * @returns {CellCoords|null}
207
+ */
208
+ export function getMostTopStartPosition(hot) {
209
+ const {
210
+ rowIndexMapper,
211
+ columnIndexMapper
212
+ } = hot;
213
+ const {
214
+ navigableHeaders
215
+ } = hot.getSettings();
216
+ let topRow = navigableHeaders && hot.countColHeaders() > 0 ? -hot.countColHeaders() : 0;
217
+ let startColumn = navigableHeaders && hot.countRowHeaders() > 0 ? -hot.countRowHeaders() : 0;
218
+ if (topRow === 0) {
219
+ topRow = rowIndexMapper.getVisualFromRenderableIndex(topRow);
220
+ }
221
+ if (startColumn === 0) {
222
+ startColumn = columnIndexMapper.getVisualFromRenderableIndex(startColumn);
223
+ }
224
+ if (topRow === null || startColumn === null) {
225
+ return null;
226
+ }
227
+ return hot._createCellCoords(topRow, startColumn);
228
+ }
229
+
230
+ /**
231
+ * Gets the coordinates of the most bottom-end cell or header (depends on the table settings and its size).
232
+ *
233
+ * @param {Core} hot The Handsontable instance.
234
+ * @returns {CellCoords|null}
235
+ */
236
+ export function getMostBottomEndPosition(hot) {
237
+ var _rowIndexMapper$getVi, _columnIndexMapper$ge;
238
+ const {
239
+ rowIndexMapper,
240
+ columnIndexMapper
241
+ } = hot;
242
+ const {
243
+ navigableHeaders
244
+ } = hot.getSettings();
245
+ let bottomRow = rowIndexMapper.getRenderableIndexesLength() - 1;
246
+ let endColumn = columnIndexMapper.getRenderableIndexesLength() - 1;
247
+ if (bottomRow < 0) {
248
+ if (!navigableHeaders || hot.countColHeaders() === 0) {
249
+ return null;
250
+ }
251
+ bottomRow = -1;
252
+ }
253
+ if (endColumn < 0) {
254
+ if (!navigableHeaders || hot.countColHeaders() === 0) {
255
+ return null;
256
+ }
257
+ endColumn = -1;
258
+ }
259
+ return hot._createCellCoords((_rowIndexMapper$getVi = rowIndexMapper.getVisualFromRenderableIndex(bottomRow)) !== null && _rowIndexMapper$getVi !== void 0 ? _rowIndexMapper$getVi : bottomRow, (_columnIndexMapper$ge = columnIndexMapper.getVisualFromRenderableIndex(endColumn)) !== null && _columnIndexMapper$ge !== void 0 ? _columnIndexMapper$ge : endColumn);
260
+ }
261
+
201
262
  /* eslint-enable */
package/index.d.ts CHANGED
@@ -235,6 +235,10 @@ import {
235
235
  TrimRows as _TrimRows,
236
236
  Settings as TrimRowsSettings,
237
237
  } from './plugins/trimRows';
238
+ import {
239
+ Dialog as _Dialog,
240
+ Settings as DialogSettings,
241
+ } from './plugins/dialog';
238
242
  import {
239
243
  UndoRedo as _UndoRedo,
240
244
  Settings as UndoRedoSettings,
@@ -389,6 +393,7 @@ declare namespace Handsontable {
389
393
  export class Search extends _Search {}
390
394
  export class TouchScroll extends _TouchScroll {}
391
395
  export class TrimRows extends _TrimRows {}
396
+ export class Dialog extends _Dialog {}
392
397
  export class UndoRedo extends _UndoRedo {}
393
398
 
394
399
  export namespace AutoColumnSize {
@@ -547,6 +552,10 @@ declare namespace Handsontable {
547
552
  export { TrimRowsSettings as Settings };
548
553
  }
549
554
 
555
+ export namespace Dialog {
556
+ export { DialogSettings as Settings };
557
+ }
558
+
550
559
  export namespace UndoRedo {
551
560
  export { UndoRedoSettings as Settings };
552
561
  }
package/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "url": "https://github.com/handsontable/handsontable/issues"
11
11
  },
12
12
  "author": "Handsoncode <hello@handsontable.com>",
13
- "version": "0.0.0-next-f86a877-20250819",
13
+ "version": "0.0.0-next-fce5825-20250822",
14
14
  "main": "index",
15
15
  "module": "index.mjs",
16
16
  "jsnext:main": "index.mjs",
@@ -388,6 +388,11 @@
388
388
  "require": "./plugins/customBorders/index.js",
389
389
  "import": "./plugins/customBorders/index.mjs"
390
390
  },
391
+ "./plugins/dialog": {
392
+ "types": "./plugins/dialog/index.d.ts",
393
+ "require": "./plugins/dialog/index.js",
394
+ "import": "./plugins/dialog/index.mjs"
395
+ },
391
396
  "./plugins/dragToScroll": {
392
397
  "types": "./plugins/dragToScroll/index.d.ts",
393
398
  "require": "./plugins/dragToScroll/index.js",
@@ -13,13 +13,15 @@ var _registry3 = require("../../editors/registry");
13
13
  var _registry4 = require("../../renderers/registry");
14
14
  var _registry5 = require("../../validators/registry");
15
15
  var _eventManager = _interopRequireDefault(require("../../eventManager"));
16
+ var _console = require("../../helpers/console");
16
17
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
17
18
  function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); }
18
- function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
19
- function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
20
19
  function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
21
20
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
22
21
  function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
22
+ function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
23
+ function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
24
+ function _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }
23
25
  function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }
24
26
  function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
25
27
  const DEPS_TYPE_CHECKERS = new Map([['plugin', _registry.hasPlugin], ['cell-type', _registry2.hasCellType], ['editor', _registry3.hasEditor], ['renderer', _registry4.hasRenderer], ['validator', _registry5.hasValidator]]);
@@ -32,6 +34,7 @@ let initializedPlugins = null;
32
34
  * @util
33
35
  * @property {Core} hot Handsontable instance.
34
36
  */
37
+ var _pluginSettings = /*#__PURE__*/new WeakMap();
35
38
  var _hooks = /*#__PURE__*/new WeakMap();
36
39
  var _BasePlugin_brand = /*#__PURE__*/new WeakSet();
37
40
  class BasePlugin {
@@ -62,9 +65,18 @@ class BasePlugin {
62
65
  }
63
66
 
64
67
  /**
65
- * The instance of the {@link EventManager} class.
68
+ * Validators for plugin settings.
69
+ *
70
+ * @type {Function|object|null}
71
+ */
72
+ static get SETTINGS_VALIDATORS() {
73
+ return null;
74
+ }
75
+
76
+ /**
77
+ * Plugin settings.
66
78
  *
67
- * @type {EventManager}
79
+ * @type {object|null}
68
80
  */
69
81
 
70
82
  /**
@@ -81,6 +93,12 @@ class BasePlugin {
81
93
  * @returns {boolean}
82
94
  */
83
95
  _classPrivateMethodInitSpec(this, _BasePlugin_brand);
96
+ _classPrivateFieldInitSpec(this, _pluginSettings, null);
97
+ /**
98
+ * The instance of the {@link EventManager} class.
99
+ *
100
+ * @type {EventManager}
101
+ */
84
102
  _defineProperty(this, "eventManager", new _eventManager.default(this));
85
103
  /**
86
104
  * @type {string}
@@ -121,6 +139,7 @@ class BasePlugin {
121
139
  }
122
140
  init() {
123
141
  this.pluginName = this.hot.getPluginName(this);
142
+ this.updatePluginSettings(this.hot.getSettings()[this.constructor.PLUGIN_KEY]);
124
143
  const pluginDeps = this.constructor.PLUGIN_DEPS;
125
144
  const deps = Array.isArray(pluginDeps) ? pluginDeps : [];
126
145
  if (deps.length > 0) {
@@ -188,25 +207,65 @@ class BasePlugin {
188
207
  * @returns {*}
189
208
  */
190
209
  getSetting(settingName) {
191
- const pluginSettings = this.hot.getSettings()[this.constructor.PLUGIN_KEY];
192
210
  if (settingName === undefined) {
193
- return pluginSettings;
211
+ return _classPrivateFieldGet(_pluginSettings, this);
194
212
  }
195
213
  const defaultSettings = this.constructor.DEFAULT_SETTINGS;
196
- if ((Array.isArray(pluginSettings) || (0, _object.isObject)(pluginSettings)) && defaultSettings[defaultMainSettingSymbol] === settingName) {
197
- var _pluginSettings$setti;
198
- if (Array.isArray(pluginSettings)) {
199
- return pluginSettings;
214
+ if ((Array.isArray(_classPrivateFieldGet(_pluginSettings, this)) || (0, _object.isObject)(_classPrivateFieldGet(_pluginSettings, this))) && defaultSettings[defaultMainSettingSymbol] === settingName) {
215
+ var _classPrivateFieldGet2;
216
+ if (Array.isArray(_classPrivateFieldGet(_pluginSettings, this))) {
217
+ return _classPrivateFieldGet(_pluginSettings, this);
200
218
  }
201
- return (_pluginSettings$setti = pluginSettings[settingName]) !== null && _pluginSettings$setti !== void 0 ? _pluginSettings$setti : defaultSettings[settingName];
219
+ return (_classPrivateFieldGet2 = _classPrivateFieldGet(_pluginSettings, this)[settingName]) !== null && _classPrivateFieldGet2 !== void 0 ? _classPrivateFieldGet2 : defaultSettings[settingName];
202
220
  }
203
- if ((0, _object.isObject)(pluginSettings)) {
204
- var _pluginSettings$setti2;
205
- return (_pluginSettings$setti2 = pluginSettings[settingName]) !== null && _pluginSettings$setti2 !== void 0 ? _pluginSettings$setti2 : defaultSettings[settingName];
221
+ if ((0, _object.isObject)(_classPrivateFieldGet(_pluginSettings, this))) {
222
+ var _classPrivateFieldGet3;
223
+ return (_classPrivateFieldGet3 = _classPrivateFieldGet(_pluginSettings, this)[settingName]) !== null && _classPrivateFieldGet3 !== void 0 ? _classPrivateFieldGet3 : defaultSettings[settingName];
206
224
  }
207
225
  return defaultSettings[settingName];
208
226
  }
209
227
 
228
+ /**
229
+ * Update plugin settings.
230
+ *
231
+ * @param {*} newSettings New settings.
232
+ * @returns {object} Updated settings object.
233
+ */
234
+ updatePluginSettings(newSettings) {
235
+ const settingsValidators = this.constructor.SETTINGS_VALIDATORS;
236
+ if (settingsValidators && typeof settingsValidators === 'function' && typeof newSettings !== 'object') {
237
+ const isValid = settingsValidators(newSettings);
238
+ if (isValid === false) {
239
+ (0, _console.warn)(`${this.pluginName} Plugin: option is not valid and it will be ignored.`);
240
+ return;
241
+ }
242
+ _classPrivateFieldSet(_pluginSettings, this, newSettings);
243
+ return _classPrivateFieldGet(_pluginSettings, this);
244
+ }
245
+ if (settingsValidators && typeof settingsValidators === 'object' && typeof newSettings === 'object') {
246
+ if (_classPrivateFieldGet(_pluginSettings, this) === null || typeof _classPrivateFieldGet(_pluginSettings, this) !== 'object') {
247
+ _classPrivateFieldSet(_pluginSettings, this, {
248
+ ...this.constructor.DEFAULT_SETTINGS
249
+ });
250
+ }
251
+ Object.keys(settingsValidators).forEach(key => {
252
+ if (!(key in newSettings)) {
253
+ return;
254
+ }
255
+ const validator = settingsValidators[key];
256
+ const isValid = validator ? validator(newSettings[key]) : true;
257
+ if (isValid === false) {
258
+ (0, _console.warn)(`${this.pluginName} Plugin: "${key}" option is not valid and it will be ignored.`);
259
+ return;
260
+ }
261
+ _classPrivateFieldGet(_pluginSettings, this)[key] = newSettings[key];
262
+ });
263
+ return _classPrivateFieldGet(_pluginSettings, this);
264
+ }
265
+ _classPrivateFieldSet(_pluginSettings, this, newSettings);
266
+ return newSettings;
267
+ }
268
+
210
269
  /**
211
270
  * Add listener to plugin hooks system.
212
271
  *
@@ -284,6 +343,7 @@ class BasePlugin {
284
343
  this.enablePlugin();
285
344
  }
286
345
  if (this.enabled && this.isEnabled() && relevantToSettings) {
346
+ this.updatePluginSettings(newSettings[this.constructor.PLUGIN_KEY]);
287
347
  this.updatePlugin(newSettings);
288
348
  }
289
349
  }
@@ -301,6 +361,7 @@ class BasePlugin {
301
361
  */
302
362
  destroy() {
303
363
  var _this$eventManager2;
364
+ _classPrivateFieldSet(_pluginSettings, this, null);
304
365
  (_this$eventManager2 = this.eventManager) === null || _this$eventManager2 === void 0 || _this$eventManager2.destroy();
305
366
  this.clearHooks();
306
367
  (0, _object.objectEach)(this, (value, property) => {
@@ -3,11 +3,12 @@ import "core-js/modules/es.array.push.js";
3
3
  import "core-js/modules/esnext.iterator.constructor.js";
4
4
  import "core-js/modules/esnext.iterator.for-each.js";
5
5
  function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); }
6
- function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
7
- function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
8
6
  function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
9
7
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
10
8
  function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
9
+ function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
10
+ function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
11
+ function _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }
11
12
  function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }
12
13
  function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
13
14
  import { defineGetter, objectEach, isObject } from "../../helpers/object.mjs";
@@ -18,6 +19,7 @@ import { hasEditor } from "../../editors/registry.mjs";
18
19
  import { hasRenderer } from "../../renderers/registry.mjs";
19
20
  import { hasValidator } from "../../validators/registry.mjs";
20
21
  import EventManager from "../../eventManager.mjs";
22
+ import { warn } from "../../helpers/console.mjs";
21
23
  const DEPS_TYPE_CHECKERS = new Map([['plugin', hasPlugin], ['cell-type', hasCellType], ['editor', hasEditor], ['renderer', hasRenderer], ['validator', hasValidator]]);
22
24
  export const defaultMainSettingSymbol = Symbol('mainSetting');
23
25
  export const PLUGIN_KEY = 'base';
@@ -28,6 +30,7 @@ let initializedPlugins = null;
28
30
  * @util
29
31
  * @property {Core} hot Handsontable instance.
30
32
  */
33
+ var _pluginSettings = /*#__PURE__*/new WeakMap();
31
34
  var _hooks = /*#__PURE__*/new WeakMap();
32
35
  var _BasePlugin_brand = /*#__PURE__*/new WeakSet();
33
36
  export class BasePlugin {
@@ -58,9 +61,18 @@ export class BasePlugin {
58
61
  }
59
62
 
60
63
  /**
61
- * The instance of the {@link EventManager} class.
64
+ * Validators for plugin settings.
65
+ *
66
+ * @type {Function|object|null}
67
+ */
68
+ static get SETTINGS_VALIDATORS() {
69
+ return null;
70
+ }
71
+
72
+ /**
73
+ * Plugin settings.
62
74
  *
63
- * @type {EventManager}
75
+ * @type {object|null}
64
76
  */
65
77
 
66
78
  /**
@@ -77,6 +89,12 @@ export class BasePlugin {
77
89
  * @returns {boolean}
78
90
  */
79
91
  _classPrivateMethodInitSpec(this, _BasePlugin_brand);
92
+ _classPrivateFieldInitSpec(this, _pluginSettings, null);
93
+ /**
94
+ * The instance of the {@link EventManager} class.
95
+ *
96
+ * @type {EventManager}
97
+ */
80
98
  _defineProperty(this, "eventManager", new EventManager(this));
81
99
  /**
82
100
  * @type {string}
@@ -117,6 +135,7 @@ export class BasePlugin {
117
135
  }
118
136
  init() {
119
137
  this.pluginName = this.hot.getPluginName(this);
138
+ this.updatePluginSettings(this.hot.getSettings()[this.constructor.PLUGIN_KEY]);
120
139
  const pluginDeps = this.constructor.PLUGIN_DEPS;
121
140
  const deps = Array.isArray(pluginDeps) ? pluginDeps : [];
122
141
  if (deps.length > 0) {
@@ -184,25 +203,65 @@ export class BasePlugin {
184
203
  * @returns {*}
185
204
  */
186
205
  getSetting(settingName) {
187
- const pluginSettings = this.hot.getSettings()[this.constructor.PLUGIN_KEY];
188
206
  if (settingName === undefined) {
189
- return pluginSettings;
207
+ return _classPrivateFieldGet(_pluginSettings, this);
190
208
  }
191
209
  const defaultSettings = this.constructor.DEFAULT_SETTINGS;
192
- if ((Array.isArray(pluginSettings) || isObject(pluginSettings)) && defaultSettings[defaultMainSettingSymbol] === settingName) {
193
- var _pluginSettings$setti;
194
- if (Array.isArray(pluginSettings)) {
195
- return pluginSettings;
210
+ if ((Array.isArray(_classPrivateFieldGet(_pluginSettings, this)) || isObject(_classPrivateFieldGet(_pluginSettings, this))) && defaultSettings[defaultMainSettingSymbol] === settingName) {
211
+ var _classPrivateFieldGet2;
212
+ if (Array.isArray(_classPrivateFieldGet(_pluginSettings, this))) {
213
+ return _classPrivateFieldGet(_pluginSettings, this);
196
214
  }
197
- return (_pluginSettings$setti = pluginSettings[settingName]) !== null && _pluginSettings$setti !== void 0 ? _pluginSettings$setti : defaultSettings[settingName];
215
+ return (_classPrivateFieldGet2 = _classPrivateFieldGet(_pluginSettings, this)[settingName]) !== null && _classPrivateFieldGet2 !== void 0 ? _classPrivateFieldGet2 : defaultSettings[settingName];
198
216
  }
199
- if (isObject(pluginSettings)) {
200
- var _pluginSettings$setti2;
201
- return (_pluginSettings$setti2 = pluginSettings[settingName]) !== null && _pluginSettings$setti2 !== void 0 ? _pluginSettings$setti2 : defaultSettings[settingName];
217
+ if (isObject(_classPrivateFieldGet(_pluginSettings, this))) {
218
+ var _classPrivateFieldGet3;
219
+ return (_classPrivateFieldGet3 = _classPrivateFieldGet(_pluginSettings, this)[settingName]) !== null && _classPrivateFieldGet3 !== void 0 ? _classPrivateFieldGet3 : defaultSettings[settingName];
202
220
  }
203
221
  return defaultSettings[settingName];
204
222
  }
205
223
 
224
+ /**
225
+ * Update plugin settings.
226
+ *
227
+ * @param {*} newSettings New settings.
228
+ * @returns {object} Updated settings object.
229
+ */
230
+ updatePluginSettings(newSettings) {
231
+ const settingsValidators = this.constructor.SETTINGS_VALIDATORS;
232
+ if (settingsValidators && typeof settingsValidators === 'function' && typeof newSettings !== 'object') {
233
+ const isValid = settingsValidators(newSettings);
234
+ if (isValid === false) {
235
+ warn(`${this.pluginName} Plugin: option is not valid and it will be ignored.`);
236
+ return;
237
+ }
238
+ _classPrivateFieldSet(_pluginSettings, this, newSettings);
239
+ return _classPrivateFieldGet(_pluginSettings, this);
240
+ }
241
+ if (settingsValidators && typeof settingsValidators === 'object' && typeof newSettings === 'object') {
242
+ if (_classPrivateFieldGet(_pluginSettings, this) === null || typeof _classPrivateFieldGet(_pluginSettings, this) !== 'object') {
243
+ _classPrivateFieldSet(_pluginSettings, this, {
244
+ ...this.constructor.DEFAULT_SETTINGS
245
+ });
246
+ }
247
+ Object.keys(settingsValidators).forEach(key => {
248
+ if (!(key in newSettings)) {
249
+ return;
250
+ }
251
+ const validator = settingsValidators[key];
252
+ const isValid = validator ? validator(newSettings[key]) : true;
253
+ if (isValid === false) {
254
+ warn(`${this.pluginName} Plugin: "${key}" option is not valid and it will be ignored.`);
255
+ return;
256
+ }
257
+ _classPrivateFieldGet(_pluginSettings, this)[key] = newSettings[key];
258
+ });
259
+ return _classPrivateFieldGet(_pluginSettings, this);
260
+ }
261
+ _classPrivateFieldSet(_pluginSettings, this, newSettings);
262
+ return newSettings;
263
+ }
264
+
206
265
  /**
207
266
  * Add listener to plugin hooks system.
208
267
  *
@@ -280,6 +339,7 @@ export class BasePlugin {
280
339
  this.enablePlugin();
281
340
  }
282
341
  if (this.enabled && this.isEnabled() && relevantToSettings) {
342
+ this.updatePluginSettings(newSettings[this.constructor.PLUGIN_KEY]);
283
343
  this.updatePlugin(newSettings);
284
344
  }
285
345
  }
@@ -297,6 +357,7 @@ export class BasePlugin {
297
357
  */
298
358
  destroy() {
299
359
  var _this$eventManager2;
360
+ _classPrivateFieldSet(_pluginSettings, this, null);
300
361
  (_this$eventManager2 = this.eventManager) === null || _this$eventManager2 === void 0 || _this$eventManager2.destroy();
301
362
  this.clearHooks();
302
363
  objectEach(this, (value, property) => {
@@ -138,6 +138,7 @@ class ContextMenu extends _base.BasePlugin {
138
138
  return _this.executeCommand.call(_this, ...params);
139
139
  });
140
140
  this.addHook('afterOnCellContextMenu', event => _assertClassBrand(_ContextMenu_brand, this, _onAfterOnCellContextMenu).call(this, event));
141
+ this.addHook('beforeDialogShow', () => this.close());
141
142
  this.registerShortcuts();
142
143
  super.enablePlugin();
143
144
  }
@@ -135,6 +135,7 @@ export class ContextMenu extends BasePlugin {
135
135
  return _this.executeCommand.call(_this, ...params);
136
136
  });
137
137
  this.addHook('afterOnCellContextMenu', event => _assertClassBrand(_ContextMenu_brand, this, _onAfterOnCellContextMenu).call(this, event));
138
+ this.addHook('beforeDialogShow', () => this.close());
138
139
  this.registerShortcuts();
139
140
  super.enablePlugin();
140
141
  }
@@ -0,0 +1,23 @@
1
+ import Core from '../../core';
2
+ import { BasePlugin } from '../base';
3
+
4
+ export interface DialogConfig {
5
+ content?: string | HTMLElement;
6
+ customClassName?: string;
7
+ background?: 'solid' | 'semi-transparent';
8
+ contentBackground?: boolean;
9
+ contentDirections?: 'row' | 'row-reverse' | 'column' | 'column-reverse';
10
+ animation?: boolean;
11
+ closable?: boolean;
12
+ }
13
+
14
+ export type Settings = boolean | DialogConfig;
15
+
16
+ export class Dialog extends BasePlugin {
17
+
18
+ constructor(hotInstance: Core);
19
+ isVisible(): boolean;
20
+ show(config?: DialogConfig): void;
21
+ hide(): void;
22
+ update(config: DialogConfig): void;
23
+ }