@keenthemes/ktui 1.2.5 → 1.2.7

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.
Files changed (196) hide show
  1. package/README.md +14 -5
  2. package/dist/ktui.js +1538 -786
  3. package/dist/ktui.min.js +1 -1
  4. package/dist/ktui.min.js.map +1 -1
  5. package/dist/styles.css +85 -5
  6. package/lib/cjs/components/datatable/datatable-checkbox.d.ts +37 -1
  7. package/lib/cjs/components/datatable/datatable-checkbox.d.ts.map +1 -1
  8. package/lib/cjs/components/datatable/datatable-checkbox.js +143 -156
  9. package/lib/cjs/components/datatable/datatable-checkbox.js.map +1 -1
  10. package/lib/cjs/components/datatable/datatable-column-utils.d.ts +30 -0
  11. package/lib/cjs/components/datatable/datatable-column-utils.d.ts.map +1 -0
  12. package/lib/cjs/components/datatable/datatable-column-utils.js +42 -0
  13. package/lib/cjs/components/datatable/datatable-column-utils.js.map +1 -0
  14. package/lib/cjs/components/datatable/datatable-contracts.d.ts +2 -4
  15. package/lib/cjs/components/datatable/datatable-contracts.d.ts.map +1 -1
  16. package/lib/cjs/components/datatable/datatable-defaults.d.ts +20 -0
  17. package/lib/cjs/components/datatable/datatable-defaults.d.ts.map +1 -0
  18. package/lib/cjs/components/datatable/datatable-defaults.js +193 -0
  19. package/lib/cjs/components/datatable/datatable-defaults.js.map +1 -0
  20. package/lib/cjs/components/datatable/datatable-layout-plugin.d.ts +7 -0
  21. package/lib/cjs/components/datatable/datatable-layout-plugin.d.ts.map +1 -0
  22. package/lib/cjs/components/datatable/datatable-layout-plugin.js +338 -0
  23. package/lib/cjs/components/datatable/datatable-layout-plugin.js.map +1 -0
  24. package/lib/cjs/components/datatable/datatable-local-provider.d.ts +2 -2
  25. package/lib/cjs/components/datatable/datatable-local-provider.d.ts.map +1 -1
  26. package/lib/cjs/components/datatable/datatable-local-provider.js +85 -27
  27. package/lib/cjs/components/datatable/datatable-local-provider.js.map +1 -1
  28. package/lib/cjs/components/datatable/datatable-pagination-renderer.d.ts.map +1 -1
  29. package/lib/cjs/components/datatable/datatable-pagination-renderer.js +13 -13
  30. package/lib/cjs/components/datatable/datatable-pagination-renderer.js.map +1 -1
  31. package/lib/cjs/components/datatable/datatable-registry.d.ts +18 -0
  32. package/lib/cjs/components/datatable/datatable-registry.d.ts.map +1 -0
  33. package/lib/cjs/components/datatable/datatable-registry.js +66 -0
  34. package/lib/cjs/components/datatable/datatable-registry.js.map +1 -0
  35. package/lib/cjs/components/datatable/datatable-remote-provider.d.ts.map +1 -1
  36. package/lib/cjs/components/datatable/datatable-remote-provider.js +1 -2
  37. package/lib/cjs/components/datatable/datatable-remote-provider.js.map +1 -1
  38. package/lib/cjs/components/datatable/datatable-search-handler.d.ts +10 -0
  39. package/lib/cjs/components/datatable/datatable-search-handler.d.ts.map +1 -0
  40. package/lib/cjs/components/datatable/datatable-search-handler.js +65 -0
  41. package/lib/cjs/components/datatable/datatable-search-handler.js.map +1 -0
  42. package/lib/cjs/components/datatable/datatable-sort.d.ts +31 -4
  43. package/lib/cjs/components/datatable/datatable-sort.d.ts.map +1 -1
  44. package/lib/cjs/components/datatable/datatable-sort.js +86 -58
  45. package/lib/cjs/components/datatable/datatable-sort.js.map +1 -1
  46. package/lib/cjs/components/datatable/datatable-spinner.d.ts +30 -0
  47. package/lib/cjs/components/datatable/datatable-spinner.d.ts.map +1 -0
  48. package/lib/cjs/components/datatable/datatable-spinner.js +54 -0
  49. package/lib/cjs/components/datatable/datatable-spinner.js.map +1 -0
  50. package/lib/cjs/components/datatable/datatable-state-persistence.d.ts +19 -0
  51. package/lib/cjs/components/datatable/datatable-state-persistence.d.ts.map +1 -0
  52. package/lib/cjs/components/datatable/datatable-state-persistence.js +59 -0
  53. package/lib/cjs/components/datatable/datatable-state-persistence.js.map +1 -0
  54. package/lib/cjs/components/datatable/datatable-table-renderer.d.ts +2 -0
  55. package/lib/cjs/components/datatable/datatable-table-renderer.d.ts.map +1 -1
  56. package/lib/cjs/components/datatable/datatable-table-renderer.js +75 -16
  57. package/lib/cjs/components/datatable/datatable-table-renderer.js.map +1 -1
  58. package/lib/cjs/components/datatable/datatable-utils.d.ts +10 -0
  59. package/lib/cjs/components/datatable/datatable-utils.d.ts.map +1 -0
  60. package/lib/cjs/components/datatable/datatable-utils.js +15 -0
  61. package/lib/cjs/components/datatable/datatable-utils.js.map +1 -0
  62. package/lib/cjs/components/datatable/datatable.d.ts +35 -34
  63. package/lib/cjs/components/datatable/datatable.d.ts.map +1 -1
  64. package/lib/cjs/components/datatable/datatable.js +233 -497
  65. package/lib/cjs/components/datatable/datatable.js.map +1 -1
  66. package/lib/cjs/components/datatable/index.d.ts +1 -1
  67. package/lib/cjs/components/datatable/index.d.ts.map +1 -1
  68. package/lib/cjs/components/datatable/types.d.ts +127 -11
  69. package/lib/cjs/components/datatable/types.d.ts.map +1 -1
  70. package/lib/cjs/index.d.ts +1 -1
  71. package/lib/cjs/index.d.ts.map +1 -1
  72. package/lib/cjs/index.js +6 -0
  73. package/lib/cjs/index.js.map +1 -1
  74. package/lib/esm/components/datatable/datatable-checkbox.d.ts +37 -1
  75. package/lib/esm/components/datatable/datatable-checkbox.d.ts.map +1 -1
  76. package/lib/esm/components/datatable/datatable-checkbox.js +142 -155
  77. package/lib/esm/components/datatable/datatable-checkbox.js.map +1 -1
  78. package/lib/esm/components/datatable/datatable-column-utils.d.ts +30 -0
  79. package/lib/esm/components/datatable/datatable-column-utils.d.ts.map +1 -0
  80. package/lib/esm/components/datatable/datatable-column-utils.js +38 -0
  81. package/lib/esm/components/datatable/datatable-column-utils.js.map +1 -0
  82. package/lib/esm/components/datatable/datatable-contracts.d.ts +2 -4
  83. package/lib/esm/components/datatable/datatable-contracts.d.ts.map +1 -1
  84. package/lib/esm/components/datatable/datatable-defaults.d.ts +20 -0
  85. package/lib/esm/components/datatable/datatable-defaults.d.ts.map +1 -0
  86. package/lib/esm/components/datatable/datatable-defaults.js +190 -0
  87. package/lib/esm/components/datatable/datatable-defaults.js.map +1 -0
  88. package/lib/esm/components/datatable/datatable-layout-plugin.d.ts +7 -0
  89. package/lib/esm/components/datatable/datatable-layout-plugin.d.ts.map +1 -0
  90. package/lib/esm/components/datatable/datatable-layout-plugin.js +334 -0
  91. package/lib/esm/components/datatable/datatable-layout-plugin.js.map +1 -0
  92. package/lib/esm/components/datatable/datatable-local-provider.d.ts +2 -2
  93. package/lib/esm/components/datatable/datatable-local-provider.d.ts.map +1 -1
  94. package/lib/esm/components/datatable/datatable-local-provider.js +85 -27
  95. package/lib/esm/components/datatable/datatable-local-provider.js.map +1 -1
  96. package/lib/esm/components/datatable/datatable-pagination-renderer.d.ts.map +1 -1
  97. package/lib/esm/components/datatable/datatable-pagination-renderer.js +13 -13
  98. package/lib/esm/components/datatable/datatable-pagination-renderer.js.map +1 -1
  99. package/lib/esm/components/datatable/datatable-registry.d.ts +18 -0
  100. package/lib/esm/components/datatable/datatable-registry.d.ts.map +1 -0
  101. package/lib/esm/components/datatable/datatable-registry.js +63 -0
  102. package/lib/esm/components/datatable/datatable-registry.js.map +1 -0
  103. package/lib/esm/components/datatable/datatable-remote-provider.d.ts.map +1 -1
  104. package/lib/esm/components/datatable/datatable-remote-provider.js +1 -2
  105. package/lib/esm/components/datatable/datatable-remote-provider.js.map +1 -1
  106. package/lib/esm/components/datatable/datatable-search-handler.d.ts +10 -0
  107. package/lib/esm/components/datatable/datatable-search-handler.d.ts.map +1 -0
  108. package/lib/esm/components/datatable/datatable-search-handler.js +62 -0
  109. package/lib/esm/components/datatable/datatable-search-handler.js.map +1 -0
  110. package/lib/esm/components/datatable/datatable-sort.d.ts +31 -4
  111. package/lib/esm/components/datatable/datatable-sort.d.ts.map +1 -1
  112. package/lib/esm/components/datatable/datatable-sort.js +85 -57
  113. package/lib/esm/components/datatable/datatable-sort.js.map +1 -1
  114. package/lib/esm/components/datatable/datatable-spinner.d.ts +30 -0
  115. package/lib/esm/components/datatable/datatable-spinner.d.ts.map +1 -0
  116. package/lib/esm/components/datatable/datatable-spinner.js +51 -0
  117. package/lib/esm/components/datatable/datatable-spinner.js.map +1 -0
  118. package/lib/esm/components/datatable/datatable-state-persistence.d.ts +19 -0
  119. package/lib/esm/components/datatable/datatable-state-persistence.d.ts.map +1 -0
  120. package/lib/esm/components/datatable/datatable-state-persistence.js +55 -0
  121. package/lib/esm/components/datatable/datatable-state-persistence.js.map +1 -0
  122. package/lib/esm/components/datatable/datatable-table-renderer.d.ts +2 -0
  123. package/lib/esm/components/datatable/datatable-table-renderer.d.ts.map +1 -1
  124. package/lib/esm/components/datatable/datatable-table-renderer.js +75 -16
  125. package/lib/esm/components/datatable/datatable-table-renderer.js.map +1 -1
  126. package/lib/esm/components/datatable/datatable-utils.d.ts +10 -0
  127. package/lib/esm/components/datatable/datatable-utils.d.ts.map +1 -0
  128. package/lib/esm/components/datatable/datatable-utils.js +12 -0
  129. package/lib/esm/components/datatable/datatable-utils.js.map +1 -0
  130. package/lib/esm/components/datatable/datatable.d.ts +35 -34
  131. package/lib/esm/components/datatable/datatable.d.ts.map +1 -1
  132. package/lib/esm/components/datatable/datatable.js +235 -499
  133. package/lib/esm/components/datatable/datatable.js.map +1 -1
  134. package/lib/esm/components/datatable/index.d.ts +1 -1
  135. package/lib/esm/components/datatable/index.d.ts.map +1 -1
  136. package/lib/esm/components/datatable/types.d.ts +127 -11
  137. package/lib/esm/components/datatable/types.d.ts.map +1 -1
  138. package/lib/esm/index.d.ts +1 -1
  139. package/lib/esm/index.d.ts.map +1 -1
  140. package/lib/esm/index.js +6 -0
  141. package/lib/esm/index.js.map +1 -1
  142. package/package.json +5 -1
  143. package/skills/ktui/SKILL.md +711 -0
  144. package/skills/ktui-datatable/SKILL.md +302 -0
  145. package/skills/ktui-install/SKILL.md +150 -0
  146. package/skills/ktui-select/SKILL.md +271 -0
  147. package/src/components/__tests__/component.test.ts +347 -0
  148. package/src/components/collapse/collapse.css +2 -2
  149. package/src/components/datatable/__tests__/architecture-boundaries.test.ts +56 -8
  150. package/src/components/datatable/__tests__/currency-sort.test.ts +25 -28
  151. package/src/components/datatable/__tests__/datatable-checkbox.test.ts +527 -0
  152. package/src/components/datatable/__tests__/datatable-column-utils.test.ts +117 -0
  153. package/src/components/datatable/__tests__/datatable-defaults.test.ts +57 -0
  154. package/src/components/datatable/__tests__/datatable-finalize-extended.test.ts +361 -0
  155. package/src/components/datatable/__tests__/datatable-fixed-layout.test.ts +427 -0
  156. package/src/components/datatable/__tests__/datatable-improvements.test.ts +484 -0
  157. package/src/components/datatable/__tests__/datatable-pagination-extended.test.ts +508 -0
  158. package/src/components/datatable/__tests__/datatable-public-api.test.ts +269 -0
  159. package/src/components/datatable/__tests__/datatable-registry.test.ts +172 -0
  160. package/src/components/datatable/__tests__/datatable-remote-provider.test.ts +468 -0
  161. package/src/components/datatable/__tests__/datatable-search-handler.test.ts +124 -0
  162. package/src/components/datatable/__tests__/datatable-sort-extended.test.ts +417 -0
  163. package/src/components/datatable/__tests__/datatable-spinner.test.ts +95 -0
  164. package/src/components/datatable/__tests__/datatable-table-renderer-extended.test.ts +425 -0
  165. package/src/components/datatable/__tests__/datatable-types.test.ts +117 -0
  166. package/src/components/datatable/__tests__/datatable-utils.test.ts +52 -0
  167. package/src/components/datatable/__tests__/locked-layout.test.ts +257 -0
  168. package/src/components/datatable/__tests__/multi-row-headers.test.ts +7 -7
  169. package/src/components/datatable/__tests__/pagination-reset.test.ts +147 -6
  170. package/src/components/datatable/__tests__/race-conditions.test.ts +11 -11
  171. package/src/components/datatable/__tests__/setup.ts +12 -4
  172. package/src/components/datatable/datatable-checkbox.ts +139 -143
  173. package/src/components/datatable/datatable-column-utils.ts +63 -0
  174. package/src/components/datatable/datatable-contracts.ts +2 -3
  175. package/src/components/datatable/datatable-defaults.ts +204 -0
  176. package/src/components/datatable/datatable-layout-plugin.ts +459 -0
  177. package/src/components/datatable/datatable-local-provider.ts +106 -35
  178. package/src/components/datatable/datatable-pagination-renderer.ts +13 -15
  179. package/src/components/datatable/datatable-registry.ts +89 -0
  180. package/src/components/datatable/datatable-remote-provider.ts +1 -3
  181. package/src/components/datatable/datatable-search-handler.ts +97 -0
  182. package/src/components/datatable/datatable-sort.ts +111 -66
  183. package/src/components/datatable/datatable-spinner.ts +103 -0
  184. package/src/components/datatable/datatable-state-persistence.ts +67 -0
  185. package/src/components/datatable/datatable-table-renderer.ts +81 -18
  186. package/src/components/datatable/datatable-utils.ts +12 -0
  187. package/src/components/datatable/datatable.css +98 -0
  188. package/src/components/datatable/datatable.ts +288 -583
  189. package/src/components/datatable/index.ts +8 -0
  190. package/src/components/datatable/types.ts +157 -23
  191. package/src/helpers/__tests__/dom.test.ts +776 -0
  192. package/src/helpers/__tests__/utils.test.ts +332 -0
  193. package/src/index.ts +15 -0
  194. package/skills/ktui-components/SKILL.md +0 -41
  195. package/skills/ktui-theming/SKILL.md +0 -50
  196. package/src/components/datatable/datatable-event-adapter.ts +0 -21
package/dist/ktui.js CHANGED
@@ -5253,85 +5253,77 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
5253
5253
  return to.concat(ar || Array.prototype.slice.call(from));
5254
5254
  };
5255
5255
  Object.defineProperty(exports, "__esModule", ({ value: true }));
5256
- exports.createCheckboxHandler = createCheckboxHandler;
5256
+ exports.KTDataTableCheckboxHandler = void 0;
5257
5257
  var event_handler_1 = __webpack_require__(/*! ../../helpers/event-handler */ "./src/helpers/event-handler.ts");
5258
- // Main function to create checkbox logic for a datatable instance
5259
- function createCheckboxHandler(element, config, fireEvent) {
5260
- var _a;
5261
- var headerChecked = false;
5262
- var headerCheckElement = null;
5263
- var targetElements = null;
5264
- // Default: preserve selection across all pages
5265
- var preserveSelection = ((_a = config.checkbox) === null || _a === void 0 ? void 0 : _a.preserveSelection) !== false;
5266
- function ensureState() {
5267
- var state = config._state;
5268
- if (!state) {
5269
- state = {};
5270
- config._state = state;
5271
- }
5272
- return state;
5273
- }
5274
- // Helper: get selectedRows from state, always as string[]
5275
- function getSelectedRows() {
5276
- var state = ensureState();
5277
- if (!Array.isArray(state.selectedRows))
5278
- state.selectedRows = [];
5279
- return state.selectedRows.map(String);
5280
- }
5281
- // Helper: set selectedRows in state
5282
- function setSelectedRows(rows) {
5283
- var state = ensureState();
5284
- state.selectedRows = Array.from(new Set(rows.map(String)));
5258
+ var KTDataTableCheckboxHandler = /** @class */ (function () {
5259
+ function KTDataTableCheckboxHandler(element, config, fireEvent, deps) {
5260
+ var _this = this;
5261
+ var _a;
5262
+ this._headerChecked = false;
5263
+ this._headerCheckElement = null;
5264
+ this._targetElements = null;
5265
+ this._delegatedEventId = null;
5266
+ this._checkboxListener = function (event) {
5267
+ _this._checkboxToggle(event);
5268
+ };
5269
+ this._element = element;
5270
+ this._config = config;
5271
+ this._fireEvent = fireEvent;
5272
+ this._deps = deps;
5273
+ this._preserveSelection = ((_a = config.checkbox) === null || _a === void 0 ? void 0 : _a.preserveSelection) !== false;
5285
5274
  }
5286
- // Helper: get all visible row IDs (values)
5287
- function getVisibleRowIds() {
5288
- if (!targetElements)
5275
+ KTDataTableCheckboxHandler.prototype._getSelectedRows = function () {
5276
+ var rows = this._deps.getState().selectedRows;
5277
+ return Array.isArray(rows) ? rows.map(String) : [];
5278
+ };
5279
+ KTDataTableCheckboxHandler.prototype._setSelectedRows = function (rows) {
5280
+ this._deps.setSelectedRows(Array.from(new Set(rows.map(String))));
5281
+ };
5282
+ KTDataTableCheckboxHandler.prototype._getVisibleRowIds = function () {
5283
+ if (!this._targetElements)
5289
5284
  return [];
5290
- return Array.from(targetElements)
5285
+ return Array.from(this._targetElements)
5291
5286
  .map(function (el) { return el.value; })
5292
5287
  .filter(function (v) { return v != null && v !== ''; });
5293
- }
5294
- // Listener for header checkbox
5295
- var checkboxListener = function (event) {
5296
- checkboxToggle(event);
5297
5288
  };
5298
- function init() {
5299
- var attrs = config.attributes;
5289
+ KTDataTableCheckboxHandler.prototype.init = function () {
5290
+ var attrs = this._config.attributes;
5300
5291
  if (!(attrs === null || attrs === void 0 ? void 0 : attrs.check) || !attrs.checkbox) {
5301
5292
  return;
5302
5293
  }
5303
- headerCheckElement = element.querySelector(attrs.check);
5304
- if (!headerCheckElement)
5294
+ this._headerCheckElement =
5295
+ this._element.querySelector(attrs.check);
5296
+ if (!this._headerCheckElement)
5305
5297
  return;
5306
- headerChecked = headerCheckElement.checked;
5307
- targetElements = element.querySelectorAll(attrs.checkbox);
5308
- checkboxHandler();
5309
- reapplyCheckedStates();
5310
- updateHeaderCheckboxState();
5311
- }
5312
- function checkboxHandler() {
5298
+ this._headerChecked = this._headerCheckElement.checked;
5299
+ this._targetElements =
5300
+ this._element.querySelectorAll(attrs.checkbox);
5301
+ this._checkboxHandler();
5302
+ this._reapplyCheckedStates();
5303
+ this._updateHeaderCheckboxState();
5304
+ };
5305
+ KTDataTableCheckboxHandler.prototype._checkboxHandler = function () {
5306
+ var _this = this;
5313
5307
  var _a;
5314
- if (!headerCheckElement)
5308
+ if (!this._headerCheckElement)
5315
5309
  return;
5316
- var rowCheckboxSelector = (_a = config.attributes) === null || _a === void 0 ? void 0 : _a.checkbox;
5310
+ var rowCheckboxSelector = (_a = this._config.attributes) === null || _a === void 0 ? void 0 : _a.checkbox;
5317
5311
  if (!rowCheckboxSelector)
5318
5312
  return;
5319
- headerCheckElement.addEventListener('click', checkboxListener);
5320
- event_handler_1.default.on(document.body, rowCheckboxSelector, 'input', (function (event) {
5313
+ this._headerCheckElement.addEventListener('click', this._checkboxListener);
5314
+ this._delegatedEventId = event_handler_1.default.on(this._element, rowCheckboxSelector, 'input', (function (event) {
5321
5315
  if (event)
5322
- handleRowCheckboxChange(event);
5316
+ _this._handleRowCheckboxChange(event);
5323
5317
  }));
5324
- }
5325
- // When a row checkbox is changed
5326
- function handleRowCheckboxChange(event) {
5318
+ };
5319
+ KTDataTableCheckboxHandler.prototype._handleRowCheckboxChange = function (event) {
5327
5320
  var input = event.target;
5328
5321
  if (!input)
5329
5322
  return;
5330
5323
  var value = input.value;
5331
- var selectedRows = getSelectedRows();
5324
+ var selectedRows = this._getSelectedRows();
5332
5325
  var wasChecked = selectedRows.includes(value);
5333
5326
  var isNowChecked = input.checked;
5334
- // Update state first
5335
5327
  if (isNowChecked) {
5336
5328
  if (!wasChecked)
5337
5329
  selectedRows.push(value);
@@ -5339,160 +5331,408 @@ function createCheckboxHandler(element, config, fireEvent) {
5339
5331
  else {
5340
5332
  selectedRows = selectedRows.filter(function (v) { return v !== value; });
5341
5333
  }
5342
- setSelectedRows(selectedRows);
5343
- updateHeaderCheckboxState();
5344
- // Fire specific checked/unchecked events after state is updated
5334
+ this._setSelectedRows(selectedRows);
5335
+ this._updateHeaderCheckboxState();
5345
5336
  if (isNowChecked && !wasChecked) {
5346
- fireEvent('checked');
5337
+ this._fireEvent('checked', { value: value });
5347
5338
  }
5348
5339
  else if (!isNowChecked && wasChecked) {
5349
- fireEvent('unchecked');
5340
+ this._fireEvent('unchecked', { value: value });
5350
5341
  }
5351
- // Always fire changed event for backward compatibility
5352
- fireEvent('changed');
5353
- }
5354
- // When the header checkbox is toggled
5355
- function checkboxToggle(_event) {
5356
- var checked = !isChecked();
5357
- // Update state first, then fire events
5358
- change(checked);
5359
- // Fire checked/unchecked events after state is updated
5342
+ this._fireEvent('changed');
5343
+ };
5344
+ KTDataTableCheckboxHandler.prototype._checkboxToggle = function (_event) {
5345
+ var checked = !this.isChecked();
5346
+ this._change(checked);
5360
5347
  var eventType = checked ? 'checked' : 'unchecked';
5361
- fireEvent(eventType);
5362
- }
5363
- // Change all visible checkboxes and update selectedRows
5364
- function change(checked) {
5348
+ this._fireEvent(eventType);
5349
+ };
5350
+ KTDataTableCheckboxHandler.prototype._change = function (checked) {
5365
5351
  var payload = { cancel: false };
5366
- fireEvent('change', payload);
5352
+ this._fireEvent('change', payload);
5367
5353
  if (payload.cancel === true)
5368
5354
  return;
5369
- headerChecked = checked;
5370
- if (headerCheckElement)
5371
- headerCheckElement.checked = checked;
5372
- if (targetElements) {
5373
- var visibleIds_1 = getVisibleRowIds();
5374
- var selectedRows = getSelectedRows();
5355
+ this._headerChecked = checked;
5356
+ if (this._headerCheckElement)
5357
+ this._headerCheckElement.checked = checked;
5358
+ if (this._targetElements) {
5359
+ var visibleIds_1 = this._getVisibleRowIds();
5360
+ var selectedRows = this._getSelectedRows();
5375
5361
  if (checked) {
5376
- // Add all visible IDs to selectedRows
5377
- selectedRows = preserveSelection
5362
+ selectedRows = this._preserveSelection
5378
5363
  ? Array.from(new Set(__spreadArray(__spreadArray([], selectedRows, true), visibleIds_1, true)))
5379
5364
  : visibleIds_1;
5380
5365
  }
5381
5366
  else {
5382
- // Remove all visible IDs from selectedRows
5383
- selectedRows = preserveSelection
5367
+ selectedRows = this._preserveSelection
5384
5368
  ? selectedRows.filter(function (v) { return !visibleIds_1.includes(v); })
5385
5369
  : [];
5386
5370
  }
5387
- setSelectedRows(selectedRows);
5388
- // Update visible checkboxes
5389
- targetElements.forEach(function (element) {
5371
+ this._setSelectedRows(selectedRows);
5372
+ this._targetElements.forEach(function (element) {
5390
5373
  if (element) {
5391
5374
  element.checked = checked;
5392
5375
  }
5393
5376
  });
5394
5377
  }
5395
- updateHeaderCheckboxState();
5396
- fireEvent('changed');
5397
- }
5398
- // Reapply checked state to visible checkboxes based on selectedRows
5399
- function reapplyCheckedStates() {
5400
- var selectedRows = getSelectedRows();
5401
- if (!targetElements)
5378
+ this._updateHeaderCheckboxState();
5379
+ this._fireEvent('changed');
5380
+ };
5381
+ KTDataTableCheckboxHandler.prototype._reapplyCheckedStates = function () {
5382
+ var _this = this;
5383
+ var selectedRows = this._getSelectedRows();
5384
+ if (!this._targetElements)
5402
5385
  return;
5403
- targetElements.forEach(function (element) {
5386
+ this._targetElements.forEach(function (element) {
5404
5387
  var _a;
5405
5388
  if (!element)
5406
5389
  return;
5407
5390
  var value = element.value;
5408
5391
  element.checked = selectedRows.includes(value);
5409
- // Update row class
5410
5392
  var row = element.closest('tr');
5411
- if (row && ((_a = config.checkbox) === null || _a === void 0 ? void 0 : _a.checkedClass)) {
5393
+ if (row && ((_a = _this._config.checkbox) === null || _a === void 0 ? void 0 : _a.checkedClass)) {
5412
5394
  if (element.checked) {
5413
- row.classList.add(config.checkbox.checkedClass);
5395
+ row.classList.add(_this._config.checkbox.checkedClass);
5414
5396
  }
5415
5397
  else {
5416
- row.classList.remove(config.checkbox.checkedClass);
5398
+ row.classList.remove(_this._config.checkbox.checkedClass);
5417
5399
  }
5418
5400
  }
5419
5401
  });
5420
- }
5421
- // Update header checkbox state (checked/indeterminate/unchecked)
5422
- function updateHeaderCheckboxState() {
5423
- if (!headerCheckElement || !targetElements)
5402
+ };
5403
+ KTDataTableCheckboxHandler.prototype._updateHeaderCheckboxState = function () {
5404
+ if (!this._headerCheckElement || !this._targetElements)
5424
5405
  return;
5425
- var total = targetElements.length;
5406
+ var total = this._targetElements.length;
5426
5407
  var checked = 0;
5427
5408
  for (var i = 0; i < total; i++) {
5428
- if (targetElements[i].checked)
5409
+ if (this._targetElements[i].checked)
5429
5410
  checked++;
5430
5411
  }
5431
5412
  if (checked === 0) {
5432
- headerCheckElement.indeterminate = false;
5433
- headerCheckElement.checked = false;
5434
- headerChecked = false;
5413
+ this._headerCheckElement.indeterminate = false;
5414
+ this._headerCheckElement.checked = false;
5415
+ this._headerChecked = false;
5435
5416
  }
5436
5417
  else if (checked > 0 && checked < total) {
5437
- headerCheckElement.indeterminate = true;
5438
- headerCheckElement.checked = false;
5439
- headerChecked = false;
5418
+ this._headerCheckElement.indeterminate = true;
5419
+ this._headerCheckElement.checked = false;
5420
+ this._headerChecked = false;
5440
5421
  }
5441
5422
  else if (checked === total) {
5442
- headerCheckElement.indeterminate = false;
5443
- headerCheckElement.checked = true;
5444
- headerChecked = true;
5423
+ this._headerCheckElement.indeterminate = false;
5424
+ this._headerCheckElement.checked = true;
5425
+ this._headerChecked = true;
5445
5426
  }
5446
- }
5447
- // Fix: isChecked() implementation
5448
- function isChecked() {
5449
- return headerChecked;
5450
- }
5451
- function getChecked() {
5452
- return getSelectedRows();
5453
- }
5454
- function check() {
5455
- change(true);
5456
- reapplyCheckedStates();
5457
- updateHeaderCheckboxState();
5458
- }
5459
- function uncheck() {
5460
- change(false);
5461
- reapplyCheckedStates();
5462
- updateHeaderCheckboxState();
5463
- }
5464
- function toggle() {
5465
- checkboxToggle();
5466
- reapplyCheckedStates();
5467
- updateHeaderCheckboxState();
5468
- }
5469
- function updateState() {
5427
+ };
5428
+ KTDataTableCheckboxHandler.prototype.isChecked = function () {
5429
+ return this._headerChecked;
5430
+ };
5431
+ KTDataTableCheckboxHandler.prototype.getChecked = function () {
5432
+ return this._getSelectedRows();
5433
+ };
5434
+ KTDataTableCheckboxHandler.prototype.check = function () {
5435
+ this._change(true);
5436
+ this._reapplyCheckedStates();
5437
+ this._updateHeaderCheckboxState();
5438
+ };
5439
+ KTDataTableCheckboxHandler.prototype.uncheck = function () {
5440
+ this._change(false);
5441
+ this._reapplyCheckedStates();
5442
+ this._updateHeaderCheckboxState();
5443
+ };
5444
+ KTDataTableCheckboxHandler.prototype.toggle = function () {
5445
+ this._checkboxToggle();
5446
+ this._reapplyCheckedStates();
5447
+ this._updateHeaderCheckboxState();
5448
+ };
5449
+ KTDataTableCheckboxHandler.prototype.updateState = function () {
5470
5450
  var _a;
5471
- var rowCheckSel = (_a = config.attributes) === null || _a === void 0 ? void 0 : _a.checkbox;
5451
+ var rowCheckSel = (_a = this._config.attributes) === null || _a === void 0 ? void 0 : _a.checkbox;
5472
5452
  if (!rowCheckSel) {
5473
5453
  return;
5474
5454
  }
5475
- targetElements = element.querySelectorAll(rowCheckSel);
5476
- reapplyCheckedStates();
5477
- updateHeaderCheckboxState();
5478
- }
5479
- return {
5480
- init: init,
5481
- check: check,
5482
- uncheck: uncheck,
5483
- toggle: toggle,
5484
- isChecked: isChecked,
5485
- getChecked: getChecked,
5486
- updateState: updateState,
5455
+ this._targetElements =
5456
+ this._element.querySelectorAll(rowCheckSel);
5457
+ this._reapplyCheckedStates();
5458
+ this._updateHeaderCheckboxState();
5459
+ };
5460
+ KTDataTableCheckboxHandler.prototype.dispose = function () {
5461
+ var _a;
5462
+ if (this._headerCheckElement) {
5463
+ this._headerCheckElement.removeEventListener('click', this._checkboxListener);
5464
+ }
5465
+ var rowCheckboxSelector = (_a = this._config.attributes) === null || _a === void 0 ? void 0 : _a.checkbox;
5466
+ if (this._delegatedEventId && rowCheckboxSelector) {
5467
+ event_handler_1.default.off(this._element, 'input', this._delegatedEventId);
5468
+ this._delegatedEventId = null;
5469
+ }
5470
+ this._headerCheckElement = null;
5471
+ this._targetElements = null;
5487
5472
  };
5473
+ return KTDataTableCheckboxHandler;
5474
+ }());
5475
+ exports.KTDataTableCheckboxHandler = KTDataTableCheckboxHandler;
5476
+
5477
+
5478
+ /***/ }),
5479
+
5480
+ /***/ "./src/components/datatable/datatable-column-utils.ts":
5481
+ /*!************************************************************!*\
5482
+ !*** ./src/components/datatable/datatable-column-utils.ts ***!
5483
+ \************************************************************/
5484
+ /***/ (function(__unused_webpack_module, exports) {
5485
+
5486
+
5487
+ /**
5488
+ * KTUI - Free & Open-Source Tailwind UI Components by Keenthemes
5489
+ * Copyright 2025 by Keenthemes Inc
5490
+ */
5491
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
5492
+ exports.resolveColumns = resolveColumns;
5493
+ exports.getLogicalColumnCount = getLogicalColumnCount;
5494
+ /**
5495
+ * Resolve column headers from a thead element.
5496
+ * Returns both the raw th list and the typed (data-kt-datatable-column) subset.
5497
+ * When some ths lack the attribute, columnsByIndex falls back to all ths by index.
5498
+ */
5499
+ function resolveColumns(theadElement) {
5500
+ var allThs = theadElement
5501
+ ? Array.from(theadElement.querySelectorAll('th'))
5502
+ : [];
5503
+ var typedThs = allThs.filter(function (th) {
5504
+ return th.hasAttribute('data-kt-datatable-column');
5505
+ });
5506
+ var columnsByIndex = typedThs.length > 0 ? typedThs : allThs;
5507
+ return { allThs: allThs, typedThs: typedThs, columnsByIndex: columnsByIndex };
5488
5508
  }
5509
+ /**
5510
+ * Get the logical column count: number of data columns.
5511
+ * Prefers originalData keys, falls back to first tbody row td count,
5512
+ * then to resolved columns from thead.
5513
+ */
5514
+ function getLogicalColumnCount(theadElement, tbodyElement, originalData) {
5515
+ if (originalData && originalData.length > 0) {
5516
+ return Object.keys(originalData[0]).length;
5517
+ }
5518
+ if (tbodyElement) {
5519
+ var firstRow = tbodyElement.querySelector('tr');
5520
+ if (firstRow) {
5521
+ return firstRow.querySelectorAll('td').length;
5522
+ }
5523
+ }
5524
+ var columnsByIndex = resolveColumns(theadElement).columnsByIndex;
5525
+ return columnsByIndex.length;
5526
+ }
5527
+
5528
+
5529
+ /***/ }),
5530
+
5531
+ /***/ "./src/components/datatable/datatable-defaults.ts":
5532
+ /*!********************************************************!*\
5533
+ !*** ./src/components/datatable/datatable-defaults.ts ***!
5534
+ \********************************************************/
5535
+ /***/ (function(__unused_webpack_module, exports) {
5536
+
5537
+
5538
+ /**
5539
+ * KTUI - Free & Open-Source Tailwind UI Components by Keenthemes
5540
+ * Copyright 2025 by Keenthemes Inc
5541
+ */
5542
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
5543
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
5544
+ if (ar || !(i in from)) {
5545
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
5546
+ ar[i] = from[i];
5547
+ }
5548
+ }
5549
+ return to.concat(ar || Array.prototype.slice.call(from));
5550
+ };
5551
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
5552
+ exports.DATATABLE_DEFAULTS = exports.DEFAULT_PAGE_MORE_LIMIT = exports.DEFAULT_SEARCH_DELAY = exports.DEFAULT_PAGE_SIZES = void 0;
5553
+ /** Default page size options shown in the size selector */
5554
+ exports.DEFAULT_PAGE_SIZES = [5, 10, 20, 30, 50];
5555
+ /** Default debounce delay (ms) for search input */
5556
+ exports.DEFAULT_SEARCH_DELAY = 500;
5557
+ /** Default maximum visible page buttons before showing '...' */
5558
+ exports.DEFAULT_PAGE_MORE_LIMIT = 3;
5559
+ /**
5560
+ * Default configuration for KTDataTable.
5561
+ * Extracted from _initDefaultConfig() for separation of concerns.
5562
+ * Note: sort.callback and search.callback are NOT included here because
5563
+ * they require instance context (this._sortHandler). They are added
5564
+ * in datatable.ts _initDefaultConfig().
5565
+ */
5566
+ exports.DATATABLE_DEFAULTS = {
5567
+ /**
5568
+ * HTTP method for server-side API call
5569
+ */
5570
+ requestMethod: 'GET',
5571
+ /**
5572
+ * Custom HTTP headers for the API request
5573
+ */
5574
+ requestHeaders: {
5575
+ 'Content-Type': 'application/x-www-form-urlencoded',
5576
+ },
5577
+ /**
5578
+ * Pagination info template
5579
+ */
5580
+ info: '{start}-{end} of {total}',
5581
+ /**
5582
+ * Info text when there is no data
5583
+ */
5584
+ infoEmpty: 'No records found',
5585
+ /**
5586
+ * Available page sizes
5587
+ */
5588
+ pageSizes: __spreadArray([], exports.DEFAULT_PAGE_SIZES, true),
5589
+ /**
5590
+ * Default page size
5591
+ */
5592
+ pageSize: 10,
5593
+ /**
5594
+ * Enable or disable pagination more button
5595
+ */
5596
+ pageMore: true,
5597
+ /**
5598
+ * Maximum number of pages before enabling pagination more button
5599
+ */
5600
+ pageMoreLimit: 3,
5601
+ /**
5602
+ * Pagination button templates
5603
+ */
5604
+ pagination: {
5605
+ number: {
5606
+ /**
5607
+ * CSS classes to be added to the pagination button
5608
+ */
5609
+ class: 'kt-datatable-pagination-button',
5610
+ /**
5611
+ * Text to be displayed in the pagination button
5612
+ */
5613
+ text: '{page}',
5614
+ },
5615
+ previous: {
5616
+ /**
5617
+ * CSS classes to be added to the previous pagination button
5618
+ */
5619
+ class: 'kt-datatable-pagination-button kt-datatable-pagination-prev',
5620
+ /**
5621
+ * Text to be displayed in the previous pagination button
5622
+ */
5623
+ text: "\n\t\t\t\t<svg class=\"rtl:transform rtl:rotate-180 size-3.5 shrink-0\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n\t\t\t\t\t<path d=\"M8.86501 16.7882V12.8481H21.1459C21.3724 12.8481 21.5897 12.7581 21.7498 12.5979C21.91 12.4378 22 12.2205 22 11.994C22 11.7675 21.91 11.5503 21.7498 11.3901C21.5897 11.2299 21.3724 11.1399 21.1459 11.1399H8.86501V7.2112C8.86628 7.10375 8.83517 6.9984 8.77573 6.90887C8.7163 6.81934 8.63129 6.74978 8.53177 6.70923C8.43225 6.66869 8.32283 6.65904 8.21775 6.68155C8.11267 6.70405 8.0168 6.75766 7.94262 6.83541L2.15981 11.6182C2.1092 11.668 2.06901 11.7274 2.04157 11.7929C2.01413 11.8584 2 11.9287 2 11.9997C2 12.0707 2.01413 12.141 2.04157 12.2065C2.06901 12.272 2.1092 12.3314 2.15981 12.3812L7.94262 17.164C8.0168 17.2417 8.11267 17.2953 8.21775 17.3178C8.32283 17.3403 8.43225 17.3307 8.53177 17.2902C8.63129 17.2496 8.7163 17.18 8.77573 17.0905C8.83517 17.001 8.86628 16.8956 8.86501 16.7882Z\" fill=\"currentColor\"/>\n\t\t\t\t</svg>\n\t\t\t",
5624
+ },
5625
+ next: {
5626
+ /**
5627
+ * CSS classes to be added to the next pagination button
5628
+ */
5629
+ class: 'kt-datatable-pagination-button kt-datatable-pagination-next',
5630
+ /**
5631
+ * Text to be displayed in the next pagination button
5632
+ */
5633
+ text: "\n\t\t\t\t<svg class=\"rtl:transform rtl:rotate-180 size-3.5 shrink-0\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n\t\t\t\t\t<path d=\"M15.135 7.21144V11.1516H2.85407C2.62756 11.1516 2.41032 11.2415 2.25015 11.4017C2.08998 11.5619 2 11.7791 2 12.0056C2 12.2321 2.08998 12.4494 2.25015 12.6096C2.41032 12.7697 2.62756 12.8597 2.85407 12.8597H15.135V16.7884C15.1337 16.8959 15.1648 17.0012 15.2243 17.0908C15.2837 17.1803 15.3687 17.2499 15.4682 17.2904C15.5677 17.3309 15.6772 17.3406 15.7822 17.3181C15.8873 17.2956 15.9832 17.242 16.0574 17.1642L21.8402 12.3814C21.8908 12.3316 21.931 12.2722 21.9584 12.2067C21.9859 12.1412 22 12.0709 22 11.9999C22 11.9289 21.9859 11.8586 21.9584 11.7931C21.931 11.7276 21.8908 11.6683 21.8402 11.6185L16.0574 6.83565C15.9832 6.75791 15.8873 6.70429 15.7822 6.68179C15.6772 6.65929 15.5677 6.66893 15.4682 6.70948C15.3687 6.75002 15.2837 6.81959 15.2243 6.90911C15.1648 6.99864 15.1337 7.10399 15.135 7.21144Z\" fill=\"currentColor\"/>\n\t\t\t\t</svg>\n\t\t\t",
5634
+ },
5635
+ more: {
5636
+ /**
5637
+ * CSS classes to be added to the pagination more button
5638
+ */
5639
+ class: 'kt-datatable-pagination-button kt-datatable-pagination-more',
5640
+ /**
5641
+ * Text to be displayed in the pagination more button
5642
+ */
5643
+ text: '...',
5644
+ },
5645
+ },
5646
+ /**
5647
+ * Sorting options — classes only; callback is added in datatable.ts
5648
+ */
5649
+ sort: {
5650
+ /**
5651
+ * CSS classes to be added to the sortable headers
5652
+ */
5653
+ classes: {
5654
+ base: 'kt-table-col',
5655
+ asc: 'asc',
5656
+ desc: 'desc',
5657
+ },
5658
+ },
5659
+ /**
5660
+ * Search options — delay only; callback is added in datatable.ts
5661
+ */
5662
+ search: {
5663
+ /**
5664
+ * Delay in milliseconds before the search function is applied to the data array
5665
+ * @default 500
5666
+ */
5667
+ delay: 500, // ms
5668
+ },
5669
+ /**
5670
+ * Loading spinner options
5671
+ */
5672
+ loading: {
5673
+ /**
5674
+ * Template to be displayed during data fetching process
5675
+ */
5676
+ template: "\n\t\t\t<div class=\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2\">\n\t\t\t\t<div class=\"kt-datatable-loading\">\n\t\t\t\t\t<svg class=\"animate-spin -ml-1 h-5 w-5 text-gray-600\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n\t\t\t\t\t\t<circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"3\"></circle>\n\t\t\t\t\t\t<path class=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n\t\t\t\t\t</svg>\n\t\t\t\t\t{content}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t",
5677
+ /**
5678
+ * Loading text to be displayed in the template
5679
+ */
5680
+ content: 'Loading...',
5681
+ },
5682
+ /**
5683
+ * Selectors of the elements to be targeted
5684
+ */
5685
+ attributes: {
5686
+ /**
5687
+ * Data table element
5688
+ */
5689
+ table: 'table[data-kt-datatable-table="true"]',
5690
+ /**
5691
+ * Pagination info element
5692
+ */
5693
+ info: '[data-kt-datatable-info="true"]',
5694
+ /**
5695
+ * Page size dropdown element
5696
+ */
5697
+ size: '[data-kt-datatable-size="true"]',
5698
+ /**
5699
+ * Pagination element
5700
+ */
5701
+ pagination: '[data-kt-datatable-pagination="true"]',
5702
+ /**
5703
+ * Spinner element
5704
+ */
5705
+ spinner: '[data-kt-datatable-spinner="true"]',
5706
+ /**
5707
+ * Checkbox element
5708
+ */
5709
+ check: '[data-kt-datatable-check="true"]',
5710
+ checkbox: '[data-kt-datatable-row-check="true"]',
5711
+ },
5712
+ /**
5713
+ * Enable or disable state saving
5714
+ */
5715
+ stateSave: true,
5716
+ checkbox: {
5717
+ checkedClass: 'checked',
5718
+ },
5719
+ /**
5720
+ * Table layout algorithm: 'auto' (default) or 'fixed' for consistent column widths
5721
+ */
5722
+ tableLayout: 'auto',
5723
+ /**
5724
+ * Private properties
5725
+ */
5726
+ _state: {},
5727
+ loadingClass: 'loading',
5728
+ };
5489
5729
 
5490
5730
 
5491
5731
  /***/ }),
5492
5732
 
5493
- /***/ "./src/components/datatable/datatable-event-adapter.ts":
5733
+ /***/ "./src/components/datatable/datatable-layout-plugin.ts":
5494
5734
  /*!*************************************************************!*\
5495
- !*** ./src/components/datatable/datatable-event-adapter.ts ***!
5735
+ !*** ./src/components/datatable/datatable-layout-plugin.ts ***!
5496
5736
  \*************************************************************/
5497
5737
  /***/ (function(__unused_webpack_module, exports) {
5498
5738
 
@@ -5501,16 +5741,338 @@ function createCheckboxHandler(element, config, fireEvent) {
5501
5741
  * KTUI - Free & Open-Source Tailwind UI Components by Keenthemes
5502
5742
  * Copyright 2025 by Keenthemes Inc
5503
5743
  */
5744
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
5745
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
5746
+ if (ar || !(i in from)) {
5747
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
5748
+ ar[i] = from[i];
5749
+ }
5750
+ }
5751
+ return to.concat(ar || Array.prototype.slice.call(from));
5752
+ };
5504
5753
  Object.defineProperty(exports, "__esModule", ({ value: true }));
5505
- exports.createDataTableEventAdapter = createDataTableEventAdapter;
5506
- function createDataTableEventAdapter(fireEvent, dispatchEvent) {
5754
+ exports.createStickyLayoutPlugin = void 0;
5755
+ var LOCKED_CELL_CLASS = 'kt-datatable-locked-cell';
5756
+ var LOCKED_HEADER_CLASS = 'kt-datatable-locked-header';
5757
+ var LOCKED_TOP_ROW_CLASS = 'kt-datatable-locked-top-row';
5758
+ var LOCKED_BOTTOM_ROW_CLASS = 'kt-datatable-locked-bottom-row';
5759
+ var LOCKED_LEFT_CLASS = 'kt-datatable-locked-left';
5760
+ var LOCKED_RIGHT_CLASS = 'kt-datatable-locked-right';
5761
+ var LOCKED_LAYOUT_SEPARATE_CLASS = 'kt-datatable-locked-layout-separate';
5762
+ var LOCKED_HEADER_SECTION_CLASS = 'kt-datatable-locked-header-section';
5763
+ var HEADER_Z_INDEX = 40;
5764
+ var ROW_Z_INDEX = 30;
5765
+ var COLUMN_Z_INDEX = 35;
5766
+ var INTERSECTION_Z_INDEX = 45;
5767
+ var toPositiveInteger = function (value) {
5768
+ if (typeof value !== 'number' || !Number.isFinite(value)) {
5769
+ return 0;
5770
+ }
5771
+ return Math.max(0, Math.floor(value));
5772
+ };
5773
+ var hasStickyColumns = function (config) {
5774
+ var _a, _b;
5775
+ var lockedLayout = config.lockedLayout;
5776
+ if (!(lockedLayout === null || lockedLayout === void 0 ? void 0 : lockedLayout.stickyColumns)) {
5777
+ return false;
5778
+ }
5779
+ return ((((_a = lockedLayout.stickyColumns.left) === null || _a === void 0 ? void 0 : _a.length) || 0) > 0 ||
5780
+ (((_b = lockedLayout.stickyColumns.right) === null || _b === void 0 ? void 0 : _b.length) || 0) > 0);
5781
+ };
5782
+ var hasLockedLayoutConfig = function (config) {
5783
+ var _a, _b, _c, _d, _e, _f;
5784
+ var lockedLayout = config.lockedLayout;
5785
+ if (!lockedLayout) {
5786
+ return false;
5787
+ }
5788
+ return (lockedLayout.stickyHeader === true ||
5789
+ toPositiveInteger((_a = lockedLayout.stickyRows) === null || _a === void 0 ? void 0 : _a.top) > 0 ||
5790
+ toPositiveInteger((_b = lockedLayout.stickyRows) === null || _b === void 0 ? void 0 : _b.bottom) > 0 ||
5791
+ (((_d = (_c = lockedLayout.stickyColumns) === null || _c === void 0 ? void 0 : _c.left) === null || _d === void 0 ? void 0 : _d.length) || 0) > 0 ||
5792
+ (((_f = (_e = lockedLayout.stickyColumns) === null || _e === void 0 ? void 0 : _e.right) === null || _f === void 0 ? void 0 : _f.length) || 0) > 0);
5793
+ };
5794
+ var getScrollContainer = function (rootElement) {
5795
+ return (rootElement.closest('.kt-table-wrapper') ||
5796
+ rootElement.querySelector('.kt-table-wrapper') ||
5797
+ rootElement);
5798
+ };
5799
+ var clearStickyStyles = function (tableElement, scrollContainer) {
5800
+ tableElement.classList.remove('kt-datatable-locked-layout', LOCKED_LAYOUT_SEPARATE_CLASS);
5801
+ scrollContainer.classList.remove('kt-datatable-locked-layout-host');
5802
+ tableElement.style.borderCollapse = '';
5803
+ tableElement.style.borderSpacing = '';
5804
+ var theadElement = tableElement.tHead;
5805
+ if (theadElement) {
5806
+ theadElement.classList.remove(LOCKED_HEADER_SECTION_CLASS);
5807
+ theadElement.style.position = '';
5808
+ theadElement.style.top = '';
5809
+ theadElement.style.zIndex = '';
5810
+ }
5811
+ var stickyElements = tableElement.querySelectorAll(".".concat(LOCKED_CELL_CLASS));
5812
+ stickyElements.forEach(function (element) {
5813
+ element.classList.remove(LOCKED_CELL_CLASS, LOCKED_HEADER_CLASS, LOCKED_TOP_ROW_CLASS, LOCKED_BOTTOM_ROW_CLASS, LOCKED_LEFT_CLASS, LOCKED_RIGHT_CLASS);
5814
+ element.style.position = '';
5815
+ element.style.top = '';
5816
+ element.style.bottom = '';
5817
+ element.style.left = '';
5818
+ element.style.right = '';
5819
+ element.style.zIndex = '';
5820
+ element.style.backgroundColor = '';
5821
+ });
5822
+ };
5823
+ var getDirection = function (tableElement) {
5824
+ var _a;
5825
+ var scopedDir = (_a = tableElement
5826
+ .closest('[dir]')) === null || _a === void 0 ? void 0 : _a.getAttribute('dir');
5827
+ var globalDir = typeof document !== 'undefined'
5828
+ ? document.documentElement.getAttribute('dir')
5829
+ : null;
5830
+ return scopedDir === 'rtl' || globalDir === 'rtl' ? 'rtl' : 'ltr';
5831
+ };
5832
+ var resolveEdgeProperty = function (edge, direction) {
5833
+ if (direction === 'rtl') {
5834
+ return edge === 'left' ? 'right' : 'left';
5835
+ }
5836
+ return edge;
5837
+ };
5838
+ var setStickyEdge = function (element, edge, offset, direction) {
5839
+ var resolvedEdge = resolveEdgeProperty(edge, direction);
5840
+ if (resolvedEdge === 'left') {
5841
+ element.style.left = "".concat(offset, "px");
5842
+ element.style.right = '';
5843
+ }
5844
+ else {
5845
+ element.style.right = "".concat(offset, "px");
5846
+ element.style.left = '';
5847
+ }
5848
+ };
5849
+ var ensureStickyCell = function (element, className, zIndex) {
5850
+ element.classList.add(LOCKED_CELL_CLASS, className);
5851
+ element.style.position = 'sticky';
5852
+ element.style.zIndex = String(zIndex);
5853
+ };
5854
+ var measureStickyHeaderHeight = function (theadElement) { return Math.round(theadElement.offsetHeight); };
5855
+ /** Offset for top sticky body rows so they sit flush under a sticky header. */
5856
+ var getStickyTopRowOffset = function (headerHeight, useCollapsedBorders) {
5857
+ if (headerHeight <= 0) {
5858
+ return 0;
5859
+ }
5860
+ // Collapsed row borders are shared between thead and the first tbody row.
5861
+ return useCollapsedBorders ? headerHeight - 1 : headerHeight;
5862
+ };
5863
+ var markIntersectionZIndex = function (element) {
5864
+ var isRowLocked = element.classList.contains(LOCKED_HEADER_CLASS) ||
5865
+ element.classList.contains(LOCKED_TOP_ROW_CLASS) ||
5866
+ element.classList.contains(LOCKED_BOTTOM_ROW_CLASS);
5867
+ var isColumnLocked = element.classList.contains(LOCKED_LEFT_CLASS) ||
5868
+ element.classList.contains(LOCKED_RIGHT_CLASS);
5869
+ if (isRowLocked && isColumnLocked) {
5870
+ element.style.zIndex = String(INTERSECTION_Z_INDEX);
5871
+ }
5872
+ };
5873
+ var applyStickyHeader = function (theadElement, enabled, useSectionSticky) {
5874
+ if (!enabled) {
5875
+ return 0;
5876
+ }
5877
+ if (useSectionSticky) {
5878
+ theadElement.classList.add(LOCKED_HEADER_SECTION_CLASS);
5879
+ theadElement.style.position = 'sticky';
5880
+ theadElement.style.top = '0';
5881
+ theadElement.style.zIndex = String(HEADER_Z_INDEX);
5882
+ Array.from(theadElement.rows).forEach(function (row) {
5883
+ Array.from(row.cells).forEach(function (cell) {
5884
+ var headerCell = cell;
5885
+ headerCell.classList.add(LOCKED_CELL_CLASS, LOCKED_HEADER_CLASS);
5886
+ });
5887
+ });
5888
+ return measureStickyHeaderHeight(theadElement);
5889
+ }
5890
+ var cumulativeTop = 0;
5891
+ Array.from(theadElement.rows).forEach(function (row) {
5892
+ var rowTop = cumulativeTop;
5893
+ Array.from(row.cells).forEach(function (cell) {
5894
+ var headerCell = cell;
5895
+ ensureStickyCell(headerCell, LOCKED_HEADER_CLASS, HEADER_Z_INDEX);
5896
+ headerCell.style.top = "".concat(rowTop, "px");
5897
+ });
5898
+ cumulativeTop += row.offsetHeight;
5899
+ });
5900
+ return cumulativeTop;
5901
+ };
5902
+ var applyStickyRows = function (tbodyElement, headerHeight, topCount, bottomCount, useCollapsedBorders) {
5903
+ var rows = Array.from(tbodyElement.rows);
5904
+ var topOffset = getStickyTopRowOffset(headerHeight, useCollapsedBorders);
5905
+ rows.slice(0, topCount).forEach(function (row) {
5906
+ var rowTop = topOffset;
5907
+ Array.from(row.cells).forEach(function (cell) {
5908
+ var td = cell;
5909
+ ensureStickyCell(td, LOCKED_TOP_ROW_CLASS, ROW_Z_INDEX);
5910
+ td.style.top = "".concat(rowTop, "px");
5911
+ });
5912
+ topOffset += row.offsetHeight;
5913
+ });
5914
+ var bottomOffset = 0;
5915
+ rows
5916
+ .slice(Math.max(0, rows.length - bottomCount))
5917
+ .reverse()
5918
+ .forEach(function (row) {
5919
+ var rowBottom = bottomOffset;
5920
+ Array.from(row.cells).forEach(function (cell) {
5921
+ var td = cell;
5922
+ ensureStickyCell(td, LOCKED_BOTTOM_ROW_CLASS, ROW_Z_INDEX);
5923
+ td.style.bottom = "".concat(rowBottom, "px");
5924
+ });
5925
+ bottomOffset += row.offsetHeight;
5926
+ });
5927
+ };
5928
+ var getColumnIndexMap = function (theadElement, config) {
5929
+ var map = new Map();
5930
+ var typedHeaders = Array.from(theadElement.querySelectorAll('th[data-kt-datatable-column]'));
5931
+ if (typedHeaders.length > 0) {
5932
+ typedHeaders.forEach(function (th, index) {
5933
+ var column = th.getAttribute('data-kt-datatable-column');
5934
+ if (column) {
5935
+ map.set(column, index);
5936
+ }
5937
+ });
5938
+ return map;
5939
+ }
5940
+ if (config.columns) {
5941
+ Object.keys(config.columns).forEach(function (key, index) {
5942
+ map.set(key, index);
5943
+ });
5944
+ }
5945
+ return map;
5946
+ };
5947
+ var getColumnCells = function (tableElement, columnIndex) {
5948
+ var cells = [];
5949
+ tableElement.querySelectorAll('tr').forEach(function (row) {
5950
+ var cell = row.children.item(columnIndex);
5951
+ if (cell instanceof HTMLTableCellElement) {
5952
+ cells.push(cell);
5953
+ }
5954
+ });
5955
+ return cells;
5956
+ };
5957
+ var applyStickyColumns = function (tableElement, theadElement, config) {
5958
+ var _a;
5959
+ var lockedColumns = (_a = config.lockedLayout) === null || _a === void 0 ? void 0 : _a.stickyColumns;
5960
+ if (!lockedColumns) {
5961
+ return;
5962
+ }
5963
+ var direction = getDirection(tableElement);
5964
+ var columnMap = getColumnIndexMap(theadElement, config);
5965
+ var leftOffset = 0;
5966
+ (lockedColumns.left || []).forEach(function (key) {
5967
+ var index = columnMap.get(key);
5968
+ if (typeof index !== 'number') {
5969
+ return;
5970
+ }
5971
+ var cells = getColumnCells(tableElement, index);
5972
+ if (cells.length === 0) {
5973
+ return;
5974
+ }
5975
+ var width = cells[0].getBoundingClientRect().width;
5976
+ cells.forEach(function (cell) {
5977
+ ensureStickyCell(cell, LOCKED_LEFT_CLASS, COLUMN_Z_INDEX);
5978
+ setStickyEdge(cell, 'left', leftOffset, direction);
5979
+ });
5980
+ leftOffset += width;
5981
+ });
5982
+ var rightOffset = 0;
5983
+ __spreadArray([], (lockedColumns.right || []), true).reverse().forEach(function (key) {
5984
+ var index = columnMap.get(key);
5985
+ if (typeof index !== 'number') {
5986
+ return;
5987
+ }
5988
+ var cells = getColumnCells(tableElement, index);
5989
+ if (cells.length === 0) {
5990
+ return;
5991
+ }
5992
+ var width = cells[0].getBoundingClientRect().width;
5993
+ cells.forEach(function (cell) {
5994
+ ensureStickyCell(cell, LOCKED_RIGHT_CLASS, COLUMN_Z_INDEX);
5995
+ setStickyEdge(cell, 'right', rightOffset, direction);
5996
+ });
5997
+ rightOffset += width;
5998
+ });
5999
+ tableElement
6000
+ .querySelectorAll(".".concat(LOCKED_CELL_CLASS))
6001
+ .forEach(markIntersectionZIndex);
6002
+ };
6003
+ var createStickyLayoutPlugin = function () {
6004
+ var resizeHandler = null;
6005
+ var scrollContainerTarget = null;
6006
+ var isApplying = false;
6007
+ var applyLayout = function (ctx) {
6008
+ var _a, _b;
6009
+ if (isApplying || !hasLockedLayoutConfig(ctx.config)) {
6010
+ return;
6011
+ }
6012
+ isApplying = true;
6013
+ try {
6014
+ var scrollContainer = getScrollContainer(ctx.rootElement);
6015
+ clearStickyStyles(ctx.tableElement, scrollContainer);
6016
+ ctx.tableElement.classList.add('kt-datatable-locked-layout');
6017
+ scrollContainer.classList.add('kt-datatable-locked-layout-host');
6018
+ if (hasStickyColumns(ctx.config)) {
6019
+ ctx.tableElement.classList.add(LOCKED_LAYOUT_SEPARATE_CLASS);
6020
+ ctx.tableElement.style.borderCollapse = 'separate';
6021
+ ctx.tableElement.style.borderSpacing = '0';
6022
+ }
6023
+ var lockedLayout = ctx.config.lockedLayout || {};
6024
+ var useCollapsedBorders = !hasStickyColumns(ctx.config);
6025
+ var headerHeight = applyStickyHeader(ctx.theadElement, lockedLayout.stickyHeader === true, useCollapsedBorders);
6026
+ applyStickyRows(ctx.tbodyElement, headerHeight, toPositiveInteger((_a = lockedLayout.stickyRows) === null || _a === void 0 ? void 0 : _a.top), toPositiveInteger((_b = lockedLayout.stickyRows) === null || _b === void 0 ? void 0 : _b.bottom), useCollapsedBorders);
6027
+ applyStickyColumns(ctx.tableElement, ctx.theadElement, ctx.config);
6028
+ }
6029
+ finally {
6030
+ isApplying = false;
6031
+ }
6032
+ };
6033
+ var detachResizeListener = function () {
6034
+ if (!resizeHandler) {
6035
+ return;
6036
+ }
6037
+ window.removeEventListener('resize', resizeHandler);
6038
+ if (scrollContainerTarget) {
6039
+ scrollContainerTarget.removeEventListener('scroll', resizeHandler);
6040
+ }
6041
+ resizeHandler = null;
6042
+ scrollContainerTarget = null;
6043
+ };
5507
6044
  return {
5508
- emit: function (eventName, eventData) {
5509
- fireEvent(eventName, eventData);
5510
- dispatchEvent(eventName, eventData);
6045
+ beforeDraw: function (ctx) {
6046
+ var scrollContainer = getScrollContainer(ctx.rootElement);
6047
+ clearStickyStyles(ctx.tableElement, scrollContainer);
6048
+ },
6049
+ afterDraw: function (ctx) {
6050
+ detachResizeListener();
6051
+ applyLayout(ctx);
6052
+ // Throttle re-layout with rAF to avoid running on every resize/scroll event
6053
+ var rafId = 0;
6054
+ var throttledApply = function () {
6055
+ if (rafId)
6056
+ return;
6057
+ rafId = requestAnimationFrame(function () {
6058
+ rafId = 0;
6059
+ applyLayout(ctx);
6060
+ });
6061
+ };
6062
+ var scrollContainer = getScrollContainer(ctx.rootElement);
6063
+ resizeHandler = throttledApply;
6064
+ window.addEventListener('resize', resizeHandler);
6065
+ scrollContainerTarget = scrollContainer;
6066
+ scrollContainer.addEventListener('scroll', resizeHandler);
6067
+ },
6068
+ dispose: function (ctx) {
6069
+ detachResizeListener();
6070
+ var scrollContainer = getScrollContainer(ctx.rootElement);
6071
+ clearStickyStyles(ctx.tableElement, scrollContainer);
5511
6072
  },
5512
6073
  };
5513
- }
6074
+ };
6075
+ exports.createStickyLayoutPlugin = createStickyLayoutPlugin;
5514
6076
 
5515
6077
 
5516
6078
  /***/ }),
@@ -5585,6 +6147,34 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
5585
6147
  Object.defineProperty(exports, "__esModule", ({ value: true }));
5586
6148
  exports.KTDataTableLocalDataProvider = void 0;
5587
6149
  var utils_1 = __webpack_require__(/*! ../../helpers/utils */ "./src/helpers/utils.ts");
6150
+ var datatable_column_utils_1 = __webpack_require__(/*! ./datatable-column-utils */ "./src/components/datatable/datatable-column-utils.ts");
6151
+ var datatable_utils_1 = __webpack_require__(/*! ./datatable-utils */ "./src/components/datatable/datatable-utils.ts");
6152
+ var FILTER_MATCHERS = {
6153
+ text: function (cellValue, filterValue) {
6154
+ if (!filterValue)
6155
+ return true;
6156
+ return (0, datatable_utils_1.stripHtml)(cellValue)
6157
+ .toLowerCase()
6158
+ .includes(String(filterValue).toLowerCase());
6159
+ },
6160
+ numeric: function (cellValue, filterValue) {
6161
+ var num = parseFloat(String(cellValue !== null && cellValue !== void 0 ? cellValue : '').replace(/[^0-9.-]/g, ''));
6162
+ return !Number.isNaN(num) && num === filterValue;
6163
+ },
6164
+ dateRange: function (cellValue, filterValue) {
6165
+ var range = filterValue;
6166
+ if (!(range === null || range === void 0 ? void 0 : range.from) && !(range === null || range === void 0 ? void 0 : range.to))
6167
+ return true;
6168
+ var cellDate = new Date(String(cellValue !== null && cellValue !== void 0 ? cellValue : ''));
6169
+ if (Number.isNaN(cellDate.getTime()))
6170
+ return false;
6171
+ if (range.from && cellDate < new Date(range.from))
6172
+ return false;
6173
+ if (range.to && cellDate > new Date(range.to))
6174
+ return false;
6175
+ return true;
6176
+ },
6177
+ };
5588
6178
  var KTDataTableLocalDataProvider = /** @class */ (function () {
5589
6179
  function KTDataTableLocalDataProvider(options) {
5590
6180
  this.options = options;
@@ -5600,11 +6190,13 @@ var KTDataTableLocalDataProvider = /** @class */ (function () {
5600
6190
  var _a, _b;
5601
6191
  var state = this.options.stateStore.getState();
5602
6192
  var originalData = state.originalData;
6193
+ var skipDomInvalidation = Boolean(this.options.config.lockedLayout || this.options.config.layoutPlugin);
5603
6194
  if (!this.options.elements().tableElement ||
5604
6195
  originalData === undefined ||
5605
- this.tableConfigInvalidate() ||
5606
- this.localTableHeaderInvalidate() ||
5607
- this.localTableContentInvalidate()) {
6196
+ (!skipDomInvalidation &&
6197
+ (this.tableConfigInvalidate() ||
6198
+ this.localTableHeaderInvalidate() ||
6199
+ this.localTableContentInvalidate()))) {
5608
6200
  var _c = this.localExtractTableContent(), originalData_1 = _c.originalData, originalDataAttributes = _c.originalDataAttributes;
5609
6201
  this.options.stateStore.setOriginalData(originalData_1, originalDataAttributes);
5610
6202
  }
@@ -5619,6 +6211,17 @@ var KTDataTableLocalDataProvider = /** @class */ (function () {
5619
6211
  filteredData = data = searchCallback.call(this, data, searchTerm);
5620
6212
  }
5621
6213
  }
6214
+ // Apply column filters
6215
+ var filters = this.options.stateStore.getState().filters;
6216
+ if (filters && filters.length > 0) {
6217
+ filteredData = data = data.filter(function (item) {
6218
+ return filters.every(function (filter) {
6219
+ var cellValue = item[filter.column];
6220
+ var matcher = FILTER_MATCHERS[filter.type];
6221
+ return matcher ? matcher(cellValue, filter.value) : true;
6222
+ });
6223
+ });
6224
+ }
5622
6225
  var sortCallback = (_b = this.options.config.sort) === null || _b === void 0 ? void 0 : _b.callback;
5623
6226
  if (sortField !== undefined &&
5624
6227
  sortOrder !== undefined &&
@@ -5637,9 +6240,27 @@ var KTDataTableLocalDataProvider = /** @class */ (function () {
5637
6240
  };
5638
6241
  };
5639
6242
  KTDataTableLocalDataProvider.prototype.localTableContentInvalidate = function () {
6243
+ var _a, _b;
5640
6244
  var tbodyElement = this.options.elements().tbodyElement;
5641
6245
  var checksum = utils_1.default.checksum(JSON.stringify(tbodyElement.innerHTML));
5642
6246
  if (this.options.stateStore.getState()._contentChecksum !== checksum) {
6247
+ var domRowCount = tbodyElement.querySelectorAll('tr').length;
6248
+ var storedRowCount = (_b = (_a = this.options.stateStore.getState().originalData) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0;
6249
+ // Programmatic dataset with an empty tbody must not re-import from the DOM.
6250
+ if (domRowCount === 0 && storedRowCount > 0) {
6251
+ return false;
6252
+ }
6253
+ // After pagination redraw the tbody only holds the current page. A checksum
6254
+ // mismatch there must not shrink originalData to pageSize rows.
6255
+ if (storedRowCount > 0 &&
6256
+ domRowCount > 0 &&
6257
+ domRowCount < storedRowCount) {
6258
+ var pageSize = this.options.stateStore.getState().pageSize;
6259
+ if (domRowCount <= pageSize) {
6260
+ this.options.stateStore.patchState({ _contentChecksum: checksum });
6261
+ return false;
6262
+ }
6263
+ }
5643
6264
  this.options.stateStore.patchState({ _contentChecksum: checksum });
5644
6265
  return true;
5645
6266
  }
@@ -5649,9 +6270,13 @@ var KTDataTableLocalDataProvider = /** @class */ (function () {
5649
6270
  var _a;
5650
6271
  var _b = this.options.config, _state = _b._state, restConfig = __rest(_b, ["_state"]);
5651
6272
  var checksum = utils_1.default.checksum(JSON.stringify(restConfig));
5652
- if (((_a = _state === null || _state === void 0 ? void 0 : _state._configChecksum) !== null && _a !== void 0 ? _a : '') !== checksum) {
6273
+ var previousChecksum = (_a = _state === null || _state === void 0 ? void 0 : _state._configChecksum) !== null && _a !== void 0 ? _a : '';
6274
+ if (previousChecksum !== checksum) {
5653
6275
  this.options.stateStore.patchState({ _configChecksum: checksum });
5654
- return true;
6276
+ // First load skips this check (originalData === undefined). On the first
6277
+ // pagination fetch, previousChecksum is still empty — record it but do
6278
+ // not re-extract from the paginated DOM (that would shrink originalData).
6279
+ return previousChecksum !== '';
5655
6280
  }
5656
6281
  return false;
5657
6282
  };
@@ -5661,13 +6286,7 @@ var KTDataTableLocalDataProvider = /** @class */ (function () {
5661
6286
  var _a = this.options.elements(), tbodyElement = _a.tbodyElement, theadElement = _a.theadElement;
5662
6287
  this.options.storeOriginalClasses();
5663
6288
  var rows = tbodyElement.querySelectorAll('tr');
5664
- var allThs = theadElement
5665
- ? theadElement.querySelectorAll('th')
5666
- : [];
5667
- var ths = Array.from(allThs).filter(function (th) {
5668
- return th.hasAttribute('data-kt-datatable-column');
5669
- });
5670
- var columnsByIndex = ths.length > 0 && ths.length !== allThs.length ? Array.from(allThs) : ths;
6289
+ var columnsByIndex = (0, datatable_column_utils_1.resolveColumns)(theadElement).columnsByIndex;
5671
6290
  rows.forEach(function (row) {
5672
6291
  var dataRow = {};
5673
6292
  var dataRowAttribute = {};
@@ -5690,22 +6309,23 @@ var KTDataTableLocalDataProvider = /** @class */ (function () {
5690
6309
  };
5691
6310
  KTDataTableLocalDataProvider.prototype.localTableHeaderInvalidate = function () {
5692
6311
  var originalData = this.options.stateStore.getState().originalData;
6312
+ if (!(originalData === null || originalData === void 0 ? void 0 : originalData.length)) {
6313
+ return false;
6314
+ }
5693
6315
  var theadElement = this.options.elements().theadElement;
5694
- var totalColumns = originalData.length
5695
- ? Object.keys(originalData[0]).length
5696
- : 0;
5697
- var allThs = theadElement
5698
- ? theadElement.querySelectorAll('th')
5699
- : [];
5700
- var thsWithColumn = Array.from(allThs).filter(function (th) {
5701
- return th.hasAttribute('data-kt-datatable-column');
5702
- });
5703
- var currentTableHeaders = thsWithColumn.length > 0
5704
- ? thsWithColumn.length !== allThs.length
5705
- ? allThs.length
5706
- : thsWithColumn.length
5707
- : this.options.getLogicalColumnCount();
5708
- return currentTableHeaders !== totalColumns;
6316
+ var typedThs = (0, datatable_column_utils_1.resolveColumns)(theadElement).typedThs;
6317
+ if (typedThs.length === 0) {
6318
+ return (this.options.getLogicalColumnCount() !==
6319
+ Object.keys(originalData[0]).length);
6320
+ }
6321
+ var typedColumnNames = typedThs
6322
+ .map(function (th) { return th.getAttribute('data-kt-datatable-column'); })
6323
+ .filter(function (name) { return Boolean(name); });
6324
+ var dataColumnKeys = Object.keys(originalData[0]);
6325
+ var matchingTypedColumns = typedColumnNames.filter(function (name) {
6326
+ return dataColumnKeys.includes(name);
6327
+ }).length;
6328
+ return typedColumnNames.length !== matchingTypedColumns;
5709
6329
  };
5710
6330
  return KTDataTableLocalDataProvider;
5711
6331
  }());
@@ -5718,7 +6338,7 @@ exports.KTDataTableLocalDataProvider = KTDataTableLocalDataProvider;
5718
6338
  /*!*******************************************************************!*\
5719
6339
  !*** ./src/components/datatable/datatable-pagination-renderer.ts ***!
5720
6340
  \*******************************************************************/
5721
- /***/ (function(__unused_webpack_module, exports) {
6341
+ /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
5722
6342
 
5723
6343
 
5724
6344
  /**
@@ -5727,6 +6347,7 @@ exports.KTDataTableLocalDataProvider = KTDataTableLocalDataProvider;
5727
6347
  */
5728
6348
  Object.defineProperty(exports, "__esModule", ({ value: true }));
5729
6349
  exports.KTDataTableDomPaginationRenderer = void 0;
6350
+ var datatable_defaults_1 = __webpack_require__(/*! ./datatable-defaults */ "./src/components/datatable/datatable-defaults.ts");
5730
6351
  var KTDataTableDomPaginationRenderer = /** @class */ (function () {
5731
6352
  function KTDataTableDomPaginationRenderer() {
5732
6353
  }
@@ -5743,6 +6364,7 @@ var KTDataTableDomPaginationRenderer = /** @class */ (function () {
5743
6364
  return function () {
5744
6365
  if (input.sizeElement) {
5745
6366
  input.sizeElement.onchange = null;
6367
+ _this.removeChildElements(input.sizeElement);
5746
6368
  }
5747
6369
  if (input.paginationElement) {
5748
6370
  _this.removeChildElements(input.paginationElement);
@@ -5759,21 +6381,19 @@ var KTDataTableDomPaginationRenderer = /** @class */ (function () {
5759
6381
  };
5760
6382
  KTDataTableDomPaginationRenderer.prototype.createPageSizeControls = function (input) {
5761
6383
  var _a;
6384
+ var _b;
5762
6385
  if (!input.sizeElement) {
5763
6386
  return;
5764
6387
  }
5765
- var pageSizes = (_a = input.config.pageSizes) !== null && _a !== void 0 ? _a : [5, 10, 20, 30, 50];
5766
- setTimeout(function () {
5767
- var _a;
5768
- var options = pageSizes.map(function (size) {
5769
- var option = document.createElement('option');
5770
- option.value = String(size);
5771
- option.text = String(size);
5772
- option.selected = input.state.pageSize === size;
5773
- return option;
5774
- });
5775
- (_a = input.sizeElement).append.apply(_a, options);
5776
- }, 100);
6388
+ var pageSizes = (_b = input.config.pageSizes) !== null && _b !== void 0 ? _b : datatable_defaults_1.DEFAULT_PAGE_SIZES;
6389
+ var options = pageSizes.map(function (size) {
6390
+ var option = document.createElement('option');
6391
+ option.value = String(size);
6392
+ option.text = String(size);
6393
+ option.selected = input.state.pageSize === size;
6394
+ return option;
6395
+ });
6396
+ (_a = input.sizeElement).append.apply(_a, options);
5777
6397
  input.sizeElement.onchange = function (event) {
5778
6398
  input.reloadPageSize(Number(event.target.value), 1);
5779
6399
  };
@@ -5805,7 +6425,7 @@ var KTDataTableDomPaginationRenderer = /** @class */ (function () {
5805
6425
  }
5806
6426
  var _b = input.state, currentPage = _b.page, totalPages = _b.totalPages;
5807
6427
  var previous = pagination.previous, next = pagination.next, number = pagination.number, more = pagination.more;
5808
- var pageMoreLimit = (_a = input.config.pageMoreLimit) !== null && _a !== void 0 ? _a : 3;
6428
+ var pageMoreLimit = (_a = input.config.pageMoreLimit) !== null && _a !== void 0 ? _a : datatable_defaults_1.DEFAULT_PAGE_MORE_LIMIT;
5809
6429
  var createButton = function (text, className, disabled, handleClick) {
5810
6430
  var button = document.createElement('button');
5811
6431
  button.className = className;
@@ -5865,6 +6485,81 @@ var KTDataTableDomPaginationRenderer = /** @class */ (function () {
5865
6485
  exports.KTDataTableDomPaginationRenderer = KTDataTableDomPaginationRenderer;
5866
6486
 
5867
6487
 
6488
+ /***/ }),
6489
+
6490
+ /***/ "./src/components/datatable/datatable-registry.ts":
6491
+ /*!********************************************************!*\
6492
+ !*** ./src/components/datatable/datatable-registry.ts ***!
6493
+ \********************************************************/
6494
+ /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
6495
+
6496
+
6497
+ /**
6498
+ * KTUI - Free & Open-Source Tailwind UI Components by Keenthemes
6499
+ * Copyright 2025 by Keenthemes Inc
6500
+ */
6501
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
6502
+ exports.createDataTableRegistry = createDataTableRegistry;
6503
+ var data_1 = __webpack_require__(/*! ../../helpers/data */ "./src/helpers/data.ts");
6504
+ function createDataTableRegistry() {
6505
+ var instances = new Map();
6506
+ function toElementWithInstance(element) {
6507
+ return element;
6508
+ }
6509
+ function register(element, instance) {
6510
+ instances.set(element, instance);
6511
+ toElementWithInstance(element).instance = instance;
6512
+ }
6513
+ function get(element) {
6514
+ var _a;
6515
+ return (_a = instances.get(element)) !== null && _a !== void 0 ? _a : toElementWithInstance(element).instance;
6516
+ }
6517
+ function remove(element) {
6518
+ instances.delete(element);
6519
+ var el = toElementWithInstance(element);
6520
+ if (el.instance)
6521
+ delete el.instance;
6522
+ }
6523
+ function clear() {
6524
+ instances.clear();
6525
+ }
6526
+ function createAll(factory) {
6527
+ if (typeof document === 'undefined')
6528
+ return;
6529
+ var elements = document.querySelectorAll('[data-kt-datatable="true"]');
6530
+ elements.forEach(function (element) {
6531
+ if (element.hasAttribute('data-kt-datatable') &&
6532
+ !element.classList.contains('datatable-initialized')) {
6533
+ var instance = factory(element);
6534
+ register(element, instance);
6535
+ }
6536
+ });
6537
+ }
6538
+ function reinit(factory) {
6539
+ if (typeof document === 'undefined')
6540
+ return;
6541
+ var elements = document.querySelectorAll('[data-kt-datatable="true"]');
6542
+ elements.forEach(function (element) {
6543
+ try {
6544
+ var instance = get(element);
6545
+ if (instance && typeof instance.dispose === 'function') {
6546
+ instance.dispose();
6547
+ }
6548
+ data_1.default.remove(element, 'datatable');
6549
+ element.removeAttribute('data-kt-datatable-initialized');
6550
+ element.classList.remove('datatable-initialized');
6551
+ }
6552
+ catch (_a) {
6553
+ // ignore per-element errors
6554
+ }
6555
+ });
6556
+ clear();
6557
+ createAll(factory);
6558
+ }
6559
+ return { register: register, get: get, remove: remove, clear: clear, createAll: createAll, reinit: reinit };
6560
+ }
6561
+
6562
+
5868
6563
  /***/ }),
5869
6564
 
5870
6565
  /***/ "./src/components/datatable/datatable-remote-provider.ts":
@@ -5974,7 +6669,7 @@ var KTDataTableRemoteDataProvider = /** @class */ (function () {
5974
6669
  return [3 /*break*/, 8];
5975
6670
  case 7:
5976
6671
  error_2 = _a.sent();
5977
- this.options.eventAdapter.emit('parseError', {
6672
+ this.options.eventAdapter.emit('fetchError', {
5978
6673
  response: response,
5979
6674
  error: String(error_2),
5980
6675
  status: response.status,
@@ -5985,7 +6680,6 @@ var KTDataTableRemoteDataProvider = /** @class */ (function () {
5985
6680
  if (currentRequestId !== this.requestId) {
5986
6681
  return [2 /*return*/, { data: [], totalItems: 0, skipped: true }];
5987
6682
  }
5988
- this.options.eventAdapter.emit('fetched', { response: responseData });
5989
6683
  if (typeof this.options.config.mapResponse === 'function') {
5990
6684
  responseData = this.options.config.mapResponse.call(this, responseData);
5991
6685
  }
@@ -6065,13 +6759,87 @@ var KTDataTableRemoteDataProvider = /** @class */ (function () {
6065
6759
  exports.KTDataTableRemoteDataProvider = KTDataTableRemoteDataProvider;
6066
6760
 
6067
6761
 
6762
+ /***/ }),
6763
+
6764
+ /***/ "./src/components/datatable/datatable-search-handler.ts":
6765
+ /*!**************************************************************!*\
6766
+ !*** ./src/components/datatable/datatable-search-handler.ts ***!
6767
+ \**************************************************************/
6768
+ /***/ (function(__unused_webpack_module, exports) {
6769
+
6770
+
6771
+ /**
6772
+ * KTUI - Free & Open-Source Tailwind UI Components by Keenthemes
6773
+ * Copyright 2025 by Keenthemes Inc
6774
+ */
6775
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
6776
+ exports.createSearchHandler = createSearchHandler;
6777
+ function createSearchHandler() {
6778
+ function findSearchElement(tableId) {
6779
+ return document.querySelector("[data-kt-datatable-search=\"#".concat(tableId, "\"]"));
6780
+ }
6781
+ function asSearchElementWithDebounce(element) {
6782
+ return element;
6783
+ }
6784
+ function debounce(func, wait) {
6785
+ var timeout;
6786
+ return function () {
6787
+ var args = [];
6788
+ for (var _i = 0; _i < arguments.length; _i++) {
6789
+ args[_i] = arguments[_i];
6790
+ }
6791
+ var later = function () {
6792
+ clearTimeout(timeout);
6793
+ func.apply(void 0, args);
6794
+ };
6795
+ clearTimeout(timeout);
6796
+ timeout = window.setTimeout(later, wait);
6797
+ };
6798
+ }
6799
+ function attach(tableId, currentSearch, delay, onSearch) {
6800
+ var searchElement = findSearchElement(tableId);
6801
+ if (!searchElement)
6802
+ return;
6803
+ // Restore search value from state
6804
+ if (currentSearch !== undefined && currentSearch !== null) {
6805
+ searchElement.value =
6806
+ typeof currentSearch === 'string'
6807
+ ? currentSearch
6808
+ : String(currentSearch);
6809
+ }
6810
+ // Remove existing debounced listener if any
6811
+ var el = asSearchElementWithDebounce(searchElement);
6812
+ if (el._debouncedSearch) {
6813
+ searchElement.removeEventListener('keyup', el._debouncedSearch);
6814
+ }
6815
+ // Create and attach new debounced search
6816
+ var debouncedSearch = debounce(function () {
6817
+ onSearch(searchElement.value);
6818
+ }, delay);
6819
+ el._debouncedSearch = debouncedSearch;
6820
+ searchElement.addEventListener('keyup', debouncedSearch);
6821
+ }
6822
+ function detach(tableId) {
6823
+ var searchElement = findSearchElement(tableId);
6824
+ if (!searchElement)
6825
+ return;
6826
+ var el = asSearchElementWithDebounce(searchElement);
6827
+ if (el._debouncedSearch) {
6828
+ searchElement.removeEventListener('keyup', el._debouncedSearch);
6829
+ delete el._debouncedSearch;
6830
+ }
6831
+ }
6832
+ return { attach: attach, detach: detach };
6833
+ }
6834
+
6835
+
6068
6836
  /***/ }),
6069
6837
 
6070
6838
  /***/ "./src/components/datatable/datatable-sort.ts":
6071
6839
  /*!****************************************************!*\
6072
6840
  !*** ./src/components/datatable/datatable-sort.ts ***!
6073
6841
  \****************************************************/
6074
- /***/ (function(__unused_webpack_module, exports) {
6842
+ /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
6075
6843
 
6076
6844
 
6077
6845
  /**
@@ -6079,12 +6847,21 @@ exports.KTDataTableRemoteDataProvider = KTDataTableRemoteDataProvider;
6079
6847
  * Copyright 2025 by Keenthemes Inc
6080
6848
  */
6081
6849
  Object.defineProperty(exports, "__esModule", ({ value: true }));
6082
- exports.createSortHandler = createSortHandler;
6083
- function createSortHandler(config, theadElement, getState, setState, fireEvent, dispatchEvent, updateData) {
6084
- // Helper to compare values for sorting (string)
6085
- function compareValues(a, b, sortOrder) {
6086
- var aText = String(a).replace(/<[^>]*>|&nbsp;/g, '');
6087
- var bText = String(b).replace(/<[^>]*>|&nbsp;/g, '');
6850
+ exports.KTDataTableSortHandler = void 0;
6851
+ var datatable_utils_1 = __webpack_require__(/*! ./datatable-utils */ "./src/components/datatable/datatable-utils.ts");
6852
+ var KTDataTableSortHandler = /** @class */ (function () {
6853
+ function KTDataTableSortHandler(deps) {
6854
+ this._sortAbortController = null;
6855
+ this._config = deps.config;
6856
+ this._theadElement = deps.theadElement;
6857
+ this._getState = deps.getState;
6858
+ this._setState = deps.setState;
6859
+ this._emit = deps.emit;
6860
+ this._updateData = deps.updateData;
6861
+ }
6862
+ KTDataTableSortHandler._compareValues = function (a, b, sortOrder) {
6863
+ var aText = (0, datatable_utils_1.stripHtml)(a);
6864
+ var bText = (0, datatable_utils_1.stripHtml)(b);
6088
6865
  return aText > bText
6089
6866
  ? sortOrder === 'asc'
6090
6867
  ? 1
@@ -6094,18 +6871,16 @@ function createSortHandler(config, theadElement, getState, setState, fireEvent,
6094
6871
  ? -1
6095
6872
  : 1
6096
6873
  : 0;
6097
- }
6098
- // Parse value for numeric sort: strip currency/commas, then parseFloat
6099
- function parseNumeric(value) {
6874
+ };
6875
+ KTDataTableSortHandler._parseNumeric = function (value) {
6100
6876
  if (value === null || value === undefined || value === '') {
6101
6877
  return Number.NaN;
6102
6878
  }
6103
6879
  var s = String(value).replace(/[^0-9.-]/g, '');
6104
6880
  var n = parseFloat(s);
6105
6881
  return Number.isNaN(n) ? Number.NaN : n;
6106
- }
6107
- // Compare two numbers; NaN sorts to the end for both asc and desc
6108
- function compareNumeric(aNum, bNum, sortOrder) {
6882
+ };
6883
+ KTDataTableSortHandler._compareNumeric = function (aNum, bNum, sortOrder) {
6109
6884
  var aNaN = Number.isNaN(aNum);
6110
6885
  var bNaN = Number.isNaN(bNum);
6111
6886
  if (aNaN && bNaN)
@@ -6119,42 +6894,56 @@ function createSortHandler(config, theadElement, getState, setState, fireEvent,
6119
6894
  if (aNum > bNum)
6120
6895
  return sortOrder === 'asc' ? 1 : -1;
6121
6896
  return 0;
6122
- }
6123
- function getColumnDef(sortField) {
6124
- var columns = config.columns;
6897
+ };
6898
+ KTDataTableSortHandler.prototype._getColumnDef = function (sortField) {
6899
+ var columns = this._config.columns;
6125
6900
  if (!columns)
6126
6901
  return undefined;
6127
6902
  var key = typeof sortField === 'number'
6128
6903
  ? Object.keys(columns)[sortField]
6129
6904
  : sortField;
6130
6905
  return key !== undefined ? columns[key] : undefined;
6131
- }
6132
- function sortData(data, sortField, sortOrder) {
6133
- var columnDef = getColumnDef(sortField);
6906
+ };
6907
+ KTDataTableSortHandler.prototype.sortData = function (data, sortField, sortOrder) {
6908
+ var columnDef = this._getColumnDef(sortField);
6134
6909
  var sortValueFn = columnDef === null || columnDef === void 0 ? void 0 : columnDef.sortValue;
6135
6910
  var useNumeric = !sortValueFn && (columnDef === null || columnDef === void 0 ? void 0 : columnDef.sortType) === 'numeric';
6911
+ // Pre-strip HTML from cell values once (instead of on every comparison).
6912
+ // For N rows this runs N regex replacements instead of N*log(N).
6913
+ var strippedCache = new Map();
6914
+ if (!sortValueFn) {
6915
+ for (var _i = 0, data_1 = data; _i < data_1.length; _i++) {
6916
+ var item = data_1[_i];
6917
+ strippedCache.set(item, (0, datatable_utils_1.stripHtml)(item[sortField]));
6918
+ }
6919
+ }
6136
6920
  return data.sort(function (a, b) {
6921
+ var _a, _b, _c, _d;
6137
6922
  var aRaw = a[sortField];
6138
6923
  var bRaw = b[sortField];
6139
6924
  if (typeof sortValueFn === 'function') {
6140
6925
  var aVal = sortValueFn(aRaw, a);
6141
6926
  var bVal = sortValueFn(bRaw, b);
6142
- var aNum = typeof aVal === 'number' ? aVal : parseNumeric(aVal);
6143
- var bNum = typeof bVal === 'number' ? bVal : parseNumeric(bVal);
6927
+ var aNum = typeof aVal === 'number'
6928
+ ? aVal
6929
+ : KTDataTableSortHandler._parseNumeric(aVal);
6930
+ var bNum = typeof bVal === 'number'
6931
+ ? bVal
6932
+ : KTDataTableSortHandler._parseNumeric(bVal);
6144
6933
  if (typeof aVal === 'number' && typeof bVal === 'number') {
6145
- return compareNumeric(aNum, bNum, sortOrder);
6934
+ return KTDataTableSortHandler._compareNumeric(aNum, bNum, sortOrder);
6146
6935
  }
6147
- return compareValues(aVal, bVal, sortOrder);
6936
+ return KTDataTableSortHandler._compareValues(aVal, bVal, sortOrder);
6148
6937
  }
6149
6938
  if (useNumeric) {
6150
- var aNum = parseNumeric(aRaw);
6151
- var bNum = parseNumeric(bRaw);
6152
- return compareNumeric(aNum, bNum, sortOrder);
6939
+ var aNum = KTDataTableSortHandler._parseNumeric((_a = strippedCache.get(a)) !== null && _a !== void 0 ? _a : aRaw);
6940
+ var bNum = KTDataTableSortHandler._parseNumeric((_b = strippedCache.get(b)) !== null && _b !== void 0 ? _b : bRaw);
6941
+ return KTDataTableSortHandler._compareNumeric(aNum, bNum, sortOrder);
6153
6942
  }
6154
- return compareValues(aRaw, bRaw, sortOrder);
6943
+ return KTDataTableSortHandler._compareValues((_c = strippedCache.get(a)) !== null && _c !== void 0 ? _c : aRaw, (_d = strippedCache.get(b)) !== null && _d !== void 0 ? _d : bRaw, sortOrder);
6155
6944
  });
6156
- }
6157
- function toggleSortOrder(currentField, currentOrder, newField) {
6945
+ };
6946
+ KTDataTableSortHandler.prototype.toggleSortOrder = function (currentField, currentOrder, newField) {
6158
6947
  if (currentField === newField) {
6159
6948
  switch (currentOrder) {
6160
6949
  case 'asc':
@@ -6166,17 +6955,16 @@ function createSortHandler(config, theadElement, getState, setState, fireEvent,
6166
6955
  }
6167
6956
  }
6168
6957
  return 'asc';
6169
- }
6170
- function setSortIcon(sortField, sortOrder) {
6958
+ };
6959
+ KTDataTableSortHandler.prototype.setSortIcon = function (sortField, sortOrder) {
6171
6960
  var _a, _b, _c, _d, _e, _f;
6172
- var baseClass = ((_b = (_a = config.sort) === null || _a === void 0 ? void 0 : _a.classes) === null || _b === void 0 ? void 0 : _b.base) || '';
6961
+ var baseClass = ((_b = (_a = this._config.sort) === null || _a === void 0 ? void 0 : _a.classes) === null || _b === void 0 ? void 0 : _b.base) || '';
6173
6962
  var sortClass = sortOrder
6174
6963
  ? sortOrder === 'asc'
6175
- ? ((_d = (_c = config.sort) === null || _c === void 0 ? void 0 : _c.classes) === null || _d === void 0 ? void 0 : _d.asc) || ''
6176
- : ((_f = (_e = config.sort) === null || _e === void 0 ? void 0 : _e.classes) === null || _f === void 0 ? void 0 : _f.desc) || ''
6964
+ ? ((_d = (_c = this._config.sort) === null || _c === void 0 ? void 0 : _c.classes) === null || _d === void 0 ? void 0 : _d.asc) || ''
6965
+ : ((_f = (_e = this._config.sort) === null || _e === void 0 ? void 0 : _e.classes) === null || _f === void 0 ? void 0 : _f.desc) || ''
6177
6966
  : '';
6178
- // Clear all headers: remove sort state so only the active column shows highlighted arrow
6179
- var allTh = theadElement.querySelectorAll('th');
6967
+ var allTh = this._theadElement.querySelectorAll('th');
6180
6968
  allTh.forEach(function (header) {
6181
6969
  var el = header;
6182
6970
  el.setAttribute('aria-sort', 'none');
@@ -6185,10 +6973,9 @@ function createSortHandler(config, theadElement, getState, setState, fireEvent,
6185
6973
  sortElement.className = baseClass;
6186
6974
  }
6187
6975
  });
6188
- // Apply sort state to the active column so table.css [aria-sort='asc'] / [aria-sort='desc'] can highlight the arrow
6189
6976
  var th = typeof sortField === 'number'
6190
6977
  ? allTh[sortField]
6191
- : theadElement.querySelector("th[data-kt-datatable-column=\"".concat(String(sortField), "\"], th[data-kt-datatable-column-sort=\"").concat(String(sortField), "\"]"));
6978
+ : this._theadElement.querySelector("th[data-kt-datatable-column=\"".concat(String(sortField), "\"], th[data-kt-datatable-column-sort=\"").concat(String(sortField), "\"]"));
6192
6979
  if (th) {
6193
6980
  var sortElement = th.querySelector(".".concat(baseClass));
6194
6981
  if (sortElement) {
@@ -6201,20 +6988,23 @@ function createSortHandler(config, theadElement, getState, setState, fireEvent,
6201
6988
  th.setAttribute('aria-sort', 'none');
6202
6989
  }
6203
6990
  }
6204
- }
6205
- function initSort() {
6206
- if (!theadElement)
6991
+ };
6992
+ KTDataTableSortHandler.prototype.initSort = function () {
6993
+ var _this = this;
6994
+ if (!this._theadElement)
6207
6995
  return;
6208
- // Set the initial sort icon
6209
- setSortIcon(getState().sortField, getState().sortOrder);
6210
- // Get all the table headers
6211
- var headers = Array.from(theadElement.querySelectorAll('th'));
6996
+ // Abort previous sort listeners before attaching new ones
6997
+ if (this._sortAbortController) {
6998
+ this._sortAbortController.abort();
6999
+ }
7000
+ this._sortAbortController = new AbortController();
7001
+ var signal = this._sortAbortController.signal;
7002
+ this.setSortIcon(this._getState().sortField, this._getState().sortOrder);
7003
+ var headers = Array.from(this._theadElement.querySelectorAll('th'));
6212
7004
  headers.forEach(function (header) {
6213
7005
  var _a, _b;
6214
- // If the sort class is not found, it's not a sortable column
6215
- if (!header.querySelector(".".concat((_b = (_a = config.sort) === null || _a === void 0 ? void 0 : _a.classes) === null || _b === void 0 ? void 0 : _b.base)))
7006
+ if (!header.querySelector(".".concat((_b = (_a = _this._config.sort) === null || _a === void 0 ? void 0 : _a.classes) === null || _b === void 0 ? void 0 : _b.base)))
6216
7007
  return;
6217
- // Check if sorting is disabled for this column
6218
7008
  var sortDisabled = header.getAttribute('data-kt-datatable-column-sort') === 'false';
6219
7009
  if (sortDisabled)
6220
7010
  return;
@@ -6224,17 +7014,154 @@ function createSortHandler(config, theadElement, getState, setState, fireEvent,
6224
7014
  ? sortAttribute
6225
7015
  : header.cellIndex;
6226
7016
  header.addEventListener('click', function () {
6227
- var state = getState();
6228
- var sortOrder = toggleSortOrder(state.sortField, state.sortOrder, sortField);
6229
- setSortIcon(sortField, sortOrder);
6230
- setState(sortField, sortOrder);
6231
- fireEvent('sort', { field: sortField, order: sortOrder });
6232
- dispatchEvent('sort', { field: sortField, order: sortOrder });
6233
- updateData();
6234
- });
7017
+ var state = _this._getState();
7018
+ var sortOrder = _this.toggleSortOrder(state.sortField, state.sortOrder, sortField);
7019
+ _this.setSortIcon(sortField, sortOrder);
7020
+ _this._setState(sortField, sortOrder);
7021
+ _this._emit('sort', { field: sortField, order: sortOrder });
7022
+ _this._updateData();
7023
+ }, { signal: signal });
6235
7024
  });
7025
+ };
7026
+ KTDataTableSortHandler.prototype.dispose = function () {
7027
+ if (this._sortAbortController) {
7028
+ this._sortAbortController.abort();
7029
+ this._sortAbortController = null;
7030
+ }
7031
+ };
7032
+ return KTDataTableSortHandler;
7033
+ }());
7034
+ exports.KTDataTableSortHandler = KTDataTableSortHandler;
7035
+
7036
+
7037
+ /***/ }),
7038
+
7039
+ /***/ "./src/components/datatable/datatable-spinner.ts":
7040
+ /*!*******************************************************!*\
7041
+ !*** ./src/components/datatable/datatable-spinner.ts ***!
7042
+ \*******************************************************/
7043
+ /***/ (function(__unused_webpack_module, exports) {
7044
+
7045
+
7046
+ /**
7047
+ * KTUI - Free & Open-Source Tailwind UI Components by Keenthemes
7048
+ * Copyright 2025 by Keenthemes Inc
7049
+ */
7050
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
7051
+ exports.createSpinner = createSpinner;
7052
+ function createSpinner() {
7053
+ function findSpinner(root, spinnerSel) {
7054
+ return root && spinnerSel
7055
+ ? root.querySelector(spinnerSel)
7056
+ : null;
7057
+ }
7058
+ function createSpinnerElement(tableElement, loading) {
7059
+ var template = document.createElement('template');
7060
+ template.innerHTML = loading.template
7061
+ .trim()
7062
+ .replace('{content}', loading.content);
7063
+ var first = template.content.firstChild;
7064
+ if (!first || !(first instanceof HTMLElement))
7065
+ return null;
7066
+ var spinner = first;
7067
+ spinner.setAttribute('data-kt-datatable-spinner', 'true');
7068
+ tableElement.appendChild(spinner);
7069
+ return spinner;
7070
+ }
7071
+ function show(root, config, tableElement) {
7072
+ var _a, _b;
7073
+ var spinnerSel = (_a = config.attributes) === null || _a === void 0 ? void 0 : _a.spinner;
7074
+ var fromDom = findSpinner(root, spinnerSel);
7075
+ var spinner = fromDom !== null && fromDom !== void 0 ? fromDom : (config.loading
7076
+ ? createSpinnerElement(tableElement, config.loading)
7077
+ : null);
7078
+ if (spinner)
7079
+ spinner.style.display = 'block';
7080
+ root === null || root === void 0 ? void 0 : root.classList.add((_b = config.loadingClass) !== null && _b !== void 0 ? _b : 'loading');
7081
+ }
7082
+ function hide(root, config) {
7083
+ var _a, _b;
7084
+ var spinner = findSpinner(root, (_a = config.attributes) === null || _a === void 0 ? void 0 : _a.spinner);
7085
+ if (spinner)
7086
+ spinner.style.display = 'none';
7087
+ root === null || root === void 0 ? void 0 : root.classList.remove((_b = config.loadingClass) !== null && _b !== void 0 ? _b : 'loading');
7088
+ }
7089
+ function remove(root, config) {
7090
+ var _a, _b;
7091
+ var spinner = findSpinner(root, (_a = config.attributes) === null || _a === void 0 ? void 0 : _a.spinner);
7092
+ if (spinner === null || spinner === void 0 ? void 0 : spinner.parentNode)
7093
+ spinner.parentNode.removeChild(spinner);
7094
+ root === null || root === void 0 ? void 0 : root.classList.remove((_b = config.loadingClass) !== null && _b !== void 0 ? _b : 'loading');
6236
7095
  }
6237
- return { initSort: initSort, sortData: sortData, toggleSortOrder: toggleSortOrder, setSortIcon: setSortIcon };
7096
+ return { show: show, hide: hide, remove: remove };
7097
+ }
7098
+
7099
+
7100
+ /***/ }),
7101
+
7102
+ /***/ "./src/components/datatable/datatable-state-persistence.ts":
7103
+ /*!*****************************************************************!*\
7104
+ !*** ./src/components/datatable/datatable-state-persistence.ts ***!
7105
+ \*****************************************************************/
7106
+ /***/ (function(__unused_webpack_module, exports) {
7107
+
7108
+
7109
+ /**
7110
+ * KTUI - Free & Open-Source Tailwind UI Components by Keenthemes
7111
+ * Copyright 2025 by Keenthemes Inc
7112
+ */
7113
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
7114
+ exports.createStatePersistence = createStatePersistence;
7115
+ exports.resolveTableNamespace = resolveTableNamespace;
7116
+ function createStatePersistence() {
7117
+ function save(namespace, state) {
7118
+ if (namespace) {
7119
+ try {
7120
+ localStorage.setItem(namespace, JSON.stringify(state));
7121
+ }
7122
+ catch (_a) {
7123
+ // localStorage unavailable (e.g. Node.js without --localstorage-file)
7124
+ }
7125
+ }
7126
+ }
7127
+ function load(namespace) {
7128
+ try {
7129
+ var stateString = localStorage.getItem(namespace);
7130
+ if (!stateString)
7131
+ return null;
7132
+ return JSON.parse(stateString);
7133
+ }
7134
+ catch (_a) {
7135
+ return null;
7136
+ }
7137
+ }
7138
+ function remove(namespace) {
7139
+ if (namespace) {
7140
+ try {
7141
+ localStorage.removeItem(namespace);
7142
+ }
7143
+ catch (_a) {
7144
+ // localStorage unavailable
7145
+ }
7146
+ }
7147
+ }
7148
+ return { save: save, load: load, remove: remove };
7149
+ }
7150
+ /**
7151
+ * Resolve the namespace for a datatable state key.
7152
+ * Priority: config.stateNamespace > table element ID > root element ID > fallback name.
7153
+ */
7154
+ function resolveTableNamespace(config, tableElement, rootElement, fallbackName) {
7155
+ if (config.stateNamespace) {
7156
+ return config.stateNamespace;
7157
+ }
7158
+ var tableIdAttr = tableElement === null || tableElement === void 0 ? void 0 : tableElement.getAttribute('id');
7159
+ if (tableIdAttr)
7160
+ return tableIdAttr;
7161
+ var rootIdAttr = rootElement === null || rootElement === void 0 ? void 0 : rootElement.getAttribute('id');
7162
+ if (rootIdAttr)
7163
+ return rootIdAttr;
7164
+ return fallbackName;
6238
7165
  }
6239
7166
 
6240
7167
 
@@ -6334,7 +7261,7 @@ exports.KTDataTableConfigStateStore = KTDataTableConfigStateStore;
6334
7261
  /*!**************************************************************!*\
6335
7262
  !*** ./src/components/datatable/datatable-table-renderer.ts ***!
6336
7263
  \**************************************************************/
6337
- /***/ (function(__unused_webpack_module, exports) {
7264
+ /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
6338
7265
 
6339
7266
 
6340
7267
  /**
@@ -6343,6 +7270,7 @@ exports.KTDataTableConfigStateStore = KTDataTableConfigStateStore;
6343
7270
  */
6344
7271
  Object.defineProperty(exports, "__esModule", ({ value: true }));
6345
7272
  exports.KTDataTableDomTableRenderer = void 0;
7273
+ var datatable_column_utils_1 = __webpack_require__(/*! ./datatable-column-utils */ "./src/components/datatable/datatable-column-utils.ts");
6346
7274
  var KTDataTableDomTableRenderer = /** @class */ (function () {
6347
7275
  function KTDataTableDomTableRenderer() {
6348
7276
  }
@@ -6350,20 +7278,77 @@ var KTDataTableDomTableRenderer = /** @class */ (function () {
6350
7278
  while (input.tableElement.tBodies.length) {
6351
7279
  input.tableElement.removeChild(input.tableElement.tBodies[0]);
6352
7280
  }
6353
- var tbodyElement = input.tableElement.createTBody();
6354
- if (input.originalTbodyClass) {
6355
- tbodyElement.className = input.originalTbodyClass;
7281
+ var tbodyElement = input.tableElement.createTBody();
7282
+ if (input.originalClasses.tbody) {
7283
+ tbodyElement.className = input.originalClasses.tbody;
7284
+ }
7285
+ this.applyTableLayout(input);
7286
+ this.renderContent(input, tbodyElement);
7287
+ return tbodyElement;
7288
+ };
7289
+ KTDataTableDomTableRenderer.prototype.notice = function (tableElement, getLogicalColumnCount, message) {
7290
+ if (message === void 0) { message = ''; }
7291
+ var row = tableElement.tBodies[0].insertRow();
7292
+ var cell = row.insertCell();
7293
+ var logicalCount = getLogicalColumnCount();
7294
+ cell.colSpan = logicalCount > 0 ? logicalCount : 1;
7295
+ cell.style.textAlign = 'center';
7296
+ cell.innerHTML = message;
7297
+ };
7298
+ KTDataTableDomTableRenderer.prototype.applyTableLayout = function (input) {
7299
+ var tableLayout = input.config.tableLayout || 'auto';
7300
+ var tableElement = input.tableElement;
7301
+ tableElement.style.tableLayout = tableLayout;
7302
+ if (tableLayout === 'fixed') {
7303
+ if (!tableElement.style.width) {
7304
+ tableElement.style.width = '100%';
7305
+ }
7306
+ this.updateColgroup(input);
7307
+ }
7308
+ else {
7309
+ var existingColgroup = tableElement.querySelector('colgroup');
7310
+ if (existingColgroup) {
7311
+ tableElement.removeChild(existingColgroup);
7312
+ }
7313
+ }
7314
+ };
7315
+ KTDataTableDomTableRenderer.prototype.updateColgroup = function (input) {
7316
+ var tableElement = input.tableElement;
7317
+ var existingColgroup = tableElement.querySelector('colgroup');
7318
+ if (existingColgroup) {
7319
+ tableElement.removeChild(existingColgroup);
7320
+ }
7321
+ var colgroup = document.createElement('colgroup');
7322
+ if (input.config.columns) {
7323
+ var columns = input.config.columns;
7324
+ for (var _i = 0, _a = Object.keys(columns); _i < _a.length; _i++) {
7325
+ var key = _a[_i];
7326
+ var col = document.createElement('col');
7327
+ if (columns[key].width) {
7328
+ col.style.width = columns[key].width;
7329
+ }
7330
+ colgroup.appendChild(col);
7331
+ }
7332
+ }
7333
+ else {
7334
+ var columnsByIndex = (0, datatable_column_utils_1.resolveColumns)(input.theadElement).columnsByIndex;
7335
+ for (var _b = 0, columnsByIndex_1 = columnsByIndex; _b < columnsByIndex_1.length; _b++) {
7336
+ var th = columnsByIndex_1[_b];
7337
+ var col = document.createElement('col');
7338
+ var width = th.getAttribute('data-kt-datatable-column-width');
7339
+ if (width) {
7340
+ col.style.width = width;
7341
+ }
7342
+ colgroup.appendChild(col);
7343
+ }
7344
+ }
7345
+ var thead = tableElement.querySelector('thead');
7346
+ if (thead) {
7347
+ tableElement.insertBefore(colgroup, thead);
7348
+ }
7349
+ else {
7350
+ tableElement.appendChild(colgroup);
6356
7351
  }
6357
- this.renderContent(input, tbodyElement);
6358
- return tbodyElement;
6359
- };
6360
- KTDataTableDomTableRenderer.prototype.notice = function (tableElement, getLogicalColumnCount, message) {
6361
- if (message === void 0) { message = ''; }
6362
- var row = tableElement.tBodies[0].insertRow();
6363
- var cell = row.insertCell();
6364
- var logicalCount = getLogicalColumnCount();
6365
- cell.colSpan = logicalCount > 0 ? logicalCount : 1;
6366
- cell.innerHTML = message;
6367
7352
  };
6368
7353
  KTDataTableDomTableRenderer.prototype.renderContent = function (input, tbodyElement) {
6369
7354
  var _this = this;
@@ -6373,20 +7358,14 @@ var KTDataTableDomTableRenderer = /** @class */ (function () {
6373
7358
  this.notice(input.tableElement, input.getLogicalColumnCount, input.config.infoEmpty || '');
6374
7359
  return tbodyElement;
6375
7360
  }
6376
- var allThs = input.theadElement
6377
- ? input.theadElement.querySelectorAll('th')
6378
- : [];
6379
- var ths = Array.from(allThs).filter(function (th) {
6380
- return th.hasAttribute('data-kt-datatable-column');
6381
- });
6382
- var columnsToRender = ths.length > 0 && ths.length !== allThs.length ? Array.from(allThs) : ths;
7361
+ var columnsToRender = (0, datatable_column_utils_1.resolveColumns)(input.theadElement).columnsByIndex;
6383
7362
  var logicalColumnCount = columnsToRender.length > 0
6384
7363
  ? columnsToRender.length
6385
7364
  : input.getLogicalColumnCount();
6386
7365
  input.data.forEach(function (item, rowIndex) {
6387
7366
  var row = document.createElement('tr');
6388
- if (input.originalTrClasses && input.originalTrClasses[rowIndex]) {
6389
- row.className = input.originalTrClasses[rowIndex];
7367
+ if (input.originalClasses.tr && input.originalClasses.tr[rowIndex]) {
7368
+ row.className = input.originalClasses.tr[rowIndex];
6390
7369
  }
6391
7370
  if (!input.config.columns) {
6392
7371
  _this.renderImplicitColumns(input, row, item, rowIndex, {
@@ -6451,7 +7430,14 @@ var KTDataTableDomTableRenderer = /** @class */ (function () {
6451
7430
  }
6452
7431
  }
6453
7432
  else {
6454
- td.textContent = item[colKey];
7433
+ var cellValue = item[colKey];
7434
+ if (cellValue === null || cellValue === undefined) {
7435
+ td.textContent = '';
7436
+ }
7437
+ else {
7438
+ // Match implicit column rendering: preserve HTML from DOM extraction.
7439
+ td.innerHTML = String(cellValue);
7440
+ }
6455
7441
  }
6456
7442
  if (typeof columnDef.createdCell === 'function') {
6457
7443
  columnDef.createdCell.call(input.context, td, item[colKey], item, row);
@@ -6460,10 +7446,10 @@ var KTDataTableDomTableRenderer = /** @class */ (function () {
6460
7446
  });
6461
7447
  };
6462
7448
  KTDataTableDomTableRenderer.prototype.applyOriginalTdClass = function (input, td, rowIndex, colIndex) {
6463
- if (input.originalTdClasses &&
6464
- input.originalTdClasses[rowIndex] &&
6465
- input.originalTdClasses[rowIndex][colIndex]) {
6466
- td.className = input.originalTdClasses[rowIndex][colIndex];
7449
+ if (input.originalClasses.td &&
7450
+ input.originalClasses.td[rowIndex] &&
7451
+ input.originalClasses.td[rowIndex][colIndex]) {
7452
+ td.className = input.originalClasses.td[rowIndex][colIndex];
6467
7453
  }
6468
7454
  };
6469
7455
  KTDataTableDomTableRenderer.prototype.applyDataRowAttributes = function (td, dataRowAttributes, colIndex) {
@@ -6478,6 +7464,30 @@ var KTDataTableDomTableRenderer = /** @class */ (function () {
6478
7464
  exports.KTDataTableDomTableRenderer = KTDataTableDomTableRenderer;
6479
7465
 
6480
7466
 
7467
+ /***/ }),
7468
+
7469
+ /***/ "./src/components/datatable/datatable-utils.ts":
7470
+ /*!*****************************************************!*\
7471
+ !*** ./src/components/datatable/datatable-utils.ts ***!
7472
+ \*****************************************************/
7473
+ /***/ (function(__unused_webpack_module, exports) {
7474
+
7475
+
7476
+ /**
7477
+ * KTUI - Free & Open-Source Tailwind UI Components by Keenthemes
7478
+ * Copyright 2025 by Keenthemes Inc
7479
+ */
7480
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
7481
+ exports.stripHtml = stripHtml;
7482
+ /**
7483
+ * Strip HTML tags and &nbsp; entities from a value, returning plain text.
7484
+ * Used by sort, search, and filter pipelines.
7485
+ */
7486
+ function stripHtml(value) {
7487
+ return String(value).replace(/<[^>]*>|&nbsp;/g, '');
7488
+ }
7489
+
7490
+
6481
7491
  /***/ }),
6482
7492
 
6483
7493
  /***/ "./src/components/datatable/datatable.ts":
@@ -6553,20 +7563,36 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
6553
7563
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
6554
7564
  }
6555
7565
  };
7566
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
7567
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
7568
+ if (ar || !(i in from)) {
7569
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
7570
+ ar[i] = from[i];
7571
+ }
7572
+ }
7573
+ return to.concat(ar || Array.prototype.slice.call(from));
7574
+ };
6556
7575
  Object.defineProperty(exports, "__esModule", ({ value: true }));
6557
7576
  exports.KTDataTable = void 0;
6558
7577
  exports.initAllDataTables = initAllDataTables;
6559
7578
  var component_1 = __webpack_require__(/*! ../component */ "./src/components/component.ts");
6560
- var index_1 = __webpack_require__(/*! ../../index */ "./src/index.ts");
6561
7579
  var data_1 = __webpack_require__(/*! ../../helpers/data */ "./src/helpers/data.ts");
6562
7580
  var datatable_checkbox_1 = __webpack_require__(/*! ./datatable-checkbox */ "./src/components/datatable/datatable-checkbox.ts");
6563
7581
  var datatable_sort_1 = __webpack_require__(/*! ./datatable-sort */ "./src/components/datatable/datatable-sort.ts");
6564
- var datatable_event_adapter_1 = __webpack_require__(/*! ./datatable-event-adapter */ "./src/components/datatable/datatable-event-adapter.ts");
7582
+ var datatable_layout_plugin_1 = __webpack_require__(/*! ./datatable-layout-plugin */ "./src/components/datatable/datatable-layout-plugin.ts");
7583
+ var datatable_defaults_1 = __webpack_require__(/*! ./datatable-defaults */ "./src/components/datatable/datatable-defaults.ts");
7584
+ var datatable_column_utils_1 = __webpack_require__(/*! ./datatable-column-utils */ "./src/components/datatable/datatable-column-utils.ts");
6565
7585
  var datatable_local_provider_1 = __webpack_require__(/*! ./datatable-local-provider */ "./src/components/datatable/datatable-local-provider.ts");
6566
7586
  var datatable_remote_provider_1 = __webpack_require__(/*! ./datatable-remote-provider */ "./src/components/datatable/datatable-remote-provider.ts");
6567
7587
  var datatable_state_store_1 = __webpack_require__(/*! ./datatable-state-store */ "./src/components/datatable/datatable-state-store.ts");
6568
7588
  var datatable_pagination_renderer_1 = __webpack_require__(/*! ./datatable-pagination-renderer */ "./src/components/datatable/datatable-pagination-renderer.ts");
6569
7589
  var datatable_table_renderer_1 = __webpack_require__(/*! ./datatable-table-renderer */ "./src/components/datatable/datatable-table-renderer.ts");
7590
+ var utils_1 = __webpack_require__(/*! ../../helpers/utils */ "./src/helpers/utils.ts");
7591
+ var datatable_search_handler_1 = __webpack_require__(/*! ./datatable-search-handler */ "./src/components/datatable/datatable-search-handler.ts");
7592
+ var datatable_state_persistence_1 = __webpack_require__(/*! ./datatable-state-persistence */ "./src/components/datatable/datatable-state-persistence.ts");
7593
+ var datatable_spinner_1 = __webpack_require__(/*! ./datatable-spinner */ "./src/components/datatable/datatable-spinner.ts");
7594
+ var datatable_registry_1 = __webpack_require__(/*! ./datatable-registry */ "./src/components/datatable/datatable-registry.ts");
7595
+ var datatable_utils_1 = __webpack_require__(/*! ./datatable-utils */ "./src/components/datatable/datatable-utils.ts");
6570
7596
  /**
6571
7597
  * Custom DataTable plugin class with server-side API, pagination, and sorting
6572
7598
  * @classdesc A custom KTComponent class that integrates server-side API, pagination, and sorting functionality into a table.
@@ -6576,27 +7602,34 @@ var datatable_table_renderer_1 = __webpack_require__(/*! ./datatable-table-rende
6576
7602
  * @param {HTMLElement} element The table element
6577
7603
  * @param {KTDataTableConfigInterface} [config] Additional configuration options
6578
7604
  */
7605
+ var datatableRegistry = (0, datatable_registry_1.createDataTableRegistry)();
6579
7606
  var KTDataTable = /** @class */ (function (_super) {
6580
7607
  __extends(KTDataTable, _super);
6581
7608
  function KTDataTable(element, config) {
6582
7609
  var _this = _super.call(this) || this;
6583
7610
  _this._name = 'datatable';
6584
- _this._originalTbodyClass = ''; // Store original tbody class
6585
- _this._originalTrClasses = []; // Store original tr classes
6586
- _this._originalTheadClass = ''; // Store original thead class
6587
- _this._originalTdClasses = []; // Store original td classes as a 2D array [row][col]
6588
- _this._originalThClasses = []; // Store original th classes
7611
+ _this._originalClasses = {
7612
+ tbody: '',
7613
+ thead: '',
7614
+ tr: [],
7615
+ td: [],
7616
+ th: [],
7617
+ };
6589
7618
  _this._infoElement = null;
6590
7619
  _this._sizeElement = null;
6591
7620
  _this._paginationElement = null;
7621
+ _this._layoutPlugin = null;
6592
7622
  _this._cleanupCallbacks = [];
7623
+ _this._searchHandler = (0, datatable_search_handler_1.createSearchHandler)();
7624
+ _this._statePersistence = (0, datatable_state_persistence_1.createStatePersistence)();
7625
+ _this._spinner = (0, datatable_spinner_1.createSpinner)();
6593
7626
  _this._data = [];
6594
7627
  _this._isFetching = false;
6595
7628
  if (data_1.default.has(element, _this._name)) {
6596
- // Already initialized (e.g. by createInstances). Merge user config so columns/sortType etc. apply.
7629
+ // Already initialized (e.g. by createInstances). Merge demo config and redraw once.
6597
7630
  var existing = KTDataTable.getInstance(element);
6598
7631
  if (existing && config) {
6599
- existing._mergeConfig(config);
7632
+ existing._applyRuntimeConfig(config);
6600
7633
  }
6601
7634
  return _this;
6602
7635
  }
@@ -6605,43 +7638,59 @@ var KTDataTable = /** @class */ (function (_super) {
6605
7638
  if (!_this._element) {
6606
7639
  return _this;
6607
7640
  }
7641
+ if (!_this._element.hasAttribute('data-kt-datatable')) {
7642
+ _this._element.setAttribute('data-kt-datatable', 'true');
7643
+ }
6608
7644
  _this._buildConfig();
7645
+ _this._normalizePageSizeConfig();
6609
7646
  _this._stateStore = new datatable_state_store_1.KTDataTableConfigStateStore(_this._config);
6610
- _this._eventAdapter = (0, datatable_event_adapter_1.createDataTableEventAdapter)(_this._fireEvent.bind(_this), _this._dispatchEvent.bind(_this));
7647
+ _this._eventAdapter = {
7648
+ emit: function (eventName, eventData) {
7649
+ _this._emit(eventName, eventData);
7650
+ },
7651
+ };
6611
7652
  // Store the instance directly on the element
6612
- KTDataTable.asElementWithInstance(element).instance = _this;
7653
+ datatableRegistry.register(element, _this);
6613
7654
  _this._initElements();
7655
+ _this._layoutPlugin = _this._createLayoutPlugin();
6614
7656
  _this._tableRenderer = new datatable_table_renderer_1.KTDataTableDomTableRenderer();
6615
7657
  _this._paginationRenderer = new datatable_pagination_renderer_1.KTDataTableDomPaginationRenderer();
6616
7658
  _this._initDataProviders();
6617
7659
  // Initialize checkbox handler
6618
- _this._checkbox = (0, datatable_checkbox_1.createCheckboxHandler)(_this._element, _this._config, _this._emit.bind(_this));
7660
+ _this._checkbox = new datatable_checkbox_1.KTDataTableCheckboxHandler(_this._element, _this._config, _this._emit.bind(_this), {
7661
+ getState: function () { return _this._stateStore.getState(); },
7662
+ setSelectedRows: function (rows) {
7663
+ _this._stateStore.patchState({ selectedRows: rows });
7664
+ },
7665
+ });
6619
7666
  // Initialize sort handler
6620
- _this._sortHandler = (0, datatable_sort_1.createSortHandler)(_this._config, _this._theadElement, function () { return ({
6621
- sortField: _this.getState().sortField,
6622
- sortOrder: _this.getState().sortOrder,
6623
- }); }, function (field, order) {
6624
- _this._stateStore.setSort(field, order);
6625
- }, _this._fireEvent.bind(_this), _this._dispatchEvent.bind(_this), _this._updateData.bind(_this));
7667
+ _this._sortHandler = new datatable_sort_1.KTDataTableSortHandler({
7668
+ config: _this._config,
7669
+ theadElement: _this._theadElement,
7670
+ getState: function () { return ({
7671
+ sortField: _this.getState().sortField,
7672
+ sortOrder: _this.getState().sortOrder,
7673
+ }); },
7674
+ setState: function (field, order) {
7675
+ _this._stateStore.setSort(field, order);
7676
+ },
7677
+ emit: _this._emit.bind(_this),
7678
+ updateData: _this._updateData.bind(_this),
7679
+ });
6626
7680
  _this._sortHandler.initSort();
6627
7681
  if (_this._config.stateSave === false) {
6628
7682
  _this._deleteState();
6629
7683
  }
6630
7684
  if (_this._config.stateSave) {
6631
7685
  _this._loadState();
7686
+ _this._normalizePageState();
6632
7687
  }
6633
7688
  _this._updateData();
6634
- _this._emit('init');
6635
7689
  return _this;
6636
7690
  }
6637
- KTDataTable.asElementWithInstance = function (element) {
6638
- return element;
6639
- };
6640
- KTDataTable.asSearchElementWithDebounce = function (element) {
6641
- return element;
6642
- };
6643
7691
  KTDataTable.prototype._emit = function (eventName, eventData) {
6644
- this._eventAdapter.emit(eventName, eventData);
7692
+ this._fireEvent(eventName, eventData);
7693
+ this._dispatchEvent("kt.datatable.".concat(eventName), eventData);
6645
7694
  };
6646
7695
  KTDataTable.prototype._initDataProviders = function () {
6647
7696
  var _this = this;
@@ -6664,206 +7713,96 @@ var KTDataTable = /** @class */ (function (_super) {
6664
7713
  stateStore: this._stateStore,
6665
7714
  });
6666
7715
  };
7716
+ KTDataTable.prototype._createLayoutPlugin = function () {
7717
+ if (this._config.layoutPlugin) {
7718
+ return this._config.layoutPlugin;
7719
+ }
7720
+ if (this._config.lockedLayout) {
7721
+ return (0, datatable_layout_plugin_1.createStickyLayoutPlugin)();
7722
+ }
7723
+ return null;
7724
+ };
7725
+ /**
7726
+ * Apply config from a late constructor call (e.g. docs demo script after auto-init).
7727
+ */
7728
+ KTDataTable.prototype._applyRuntimeConfig = function (config) {
7729
+ this._mergeConfig(config);
7730
+ this._normalizePageSizeConfig();
7731
+ this._layoutPlugin = this._createLayoutPlugin();
7732
+ this.reload();
7733
+ };
7734
+ KTDataTable.prototype._normalizePageSizeConfig = function () {
7735
+ var configuredPageSizes = Array.isArray(this._config.pageSizes)
7736
+ ? this._config.pageSizes
7737
+ : [];
7738
+ var pageSizes = configuredPageSizes
7739
+ .map(function (size) { return Number(size); })
7740
+ .filter(function (size) { return Number.isFinite(size) && size > 0; })
7741
+ .map(function (size) { return Math.floor(size); });
7742
+ var fallbackPageSizes = __spreadArray([], datatable_defaults_1.DEFAULT_PAGE_SIZES, true);
7743
+ this._config.pageSizes =
7744
+ pageSizes.length > 0 ? Array.from(new Set(pageSizes)) : fallbackPageSizes;
7745
+ var configuredPageSize = Number(this._config.pageSize);
7746
+ this._config.pageSize =
7747
+ Number.isFinite(configuredPageSize) && configuredPageSize > 0
7748
+ ? Math.floor(configuredPageSize)
7749
+ : this._config.pageSizes[0];
7750
+ };
7751
+ KTDataTable.prototype._normalizePageState = function () {
7752
+ var statePageSize = Number(this._config._state.pageSize);
7753
+ this._config._state.pageSize =
7754
+ Number.isFinite(statePageSize) && statePageSize > 0
7755
+ ? Math.floor(statePageSize)
7756
+ : this._config.pageSize;
7757
+ var statePage = Number(this._config._state.page);
7758
+ this._config._state.page =
7759
+ Number.isFinite(statePage) && statePage > 0 ? Math.floor(statePage) : 1;
7760
+ };
7761
+ KTDataTable.prototype._getLayoutPluginContext = function () {
7762
+ return {
7763
+ rootElement: this._element,
7764
+ tableElement: this._tableElement,
7765
+ theadElement: this._theadElement,
7766
+ tbodyElement: this._tbodyElement,
7767
+ config: this._config,
7768
+ };
7769
+ };
6667
7770
  /**
6668
7771
  * Initialize default configuration for the datatable
6669
7772
  * @param config User-provided configuration options
6670
7773
  * @returns Default configuration merged with user-provided options
6671
7774
  */
7775
+ KTDataTable.prototype._createDefaultSearchCallback = function () {
7776
+ return (function (data, search) {
7777
+ if (!data || !search) {
7778
+ return [];
7779
+ }
7780
+ var searchLower = search.toLowerCase();
7781
+ return data.filter(function (item) {
7782
+ if (!item) {
7783
+ return false;
7784
+ }
7785
+ return Object.values(item).some(function (value) {
7786
+ if (typeof value !== 'string' &&
7787
+ typeof value !== 'number' &&
7788
+ typeof value !== 'boolean') {
7789
+ return false;
7790
+ }
7791
+ var valueText = (0, datatable_utils_1.stripHtml)(value).toLowerCase();
7792
+ return valueText.includes(searchLower);
7793
+ });
7794
+ });
7795
+ });
7796
+ };
6672
7797
  KTDataTable.prototype._initDefaultConfig = function (config) {
6673
7798
  var _this = this;
6674
- return __assign({
6675
- /**
6676
- * HTTP method for server-side API call
6677
- */
6678
- requestMethod: 'GET',
6679
- /**
6680
- * Custom HTTP headers for the API request
6681
- */
6682
- requestHeaders: {
6683
- 'Content-Type': 'application/x-www-form-urlencoded',
6684
- },
6685
- /**
6686
- * Pagination info template
6687
- */
6688
- info: '{start}-{end} of {total}',
6689
- /**
6690
- * Info text when there is no data
6691
- */
6692
- infoEmpty: 'No records found',
6693
- /**
6694
- * Available page sizes
6695
- */
6696
- pageSizes: [5, 10, 20, 30, 50],
6697
- /**
6698
- * Default page size
6699
- */
6700
- pageSize: 10,
6701
- /**
6702
- * Enable or disable pagination more button
6703
- */
6704
- pageMore: true,
6705
- /**
6706
- * Maximum number of pages before enabling pagination more button
6707
- */
6708
- pageMoreLimit: 3,
6709
- /**
6710
- * Pagination button templates
6711
- */
6712
- pagination: {
6713
- number: {
6714
- /**
6715
- * CSS classes to be added to the pagination button
6716
- */
6717
- class: 'kt-datatable-pagination-button',
6718
- /**
6719
- * Text to be displayed in the pagination button
6720
- */
6721
- text: '{page}',
6722
- },
6723
- previous: {
6724
- /**
6725
- * CSS classes to be added to the previous pagination button
6726
- */
6727
- class: 'kt-datatable-pagination-button kt-datatable-pagination-prev',
6728
- /**
6729
- * Text to be displayed in the previous pagination button
6730
- */
6731
- text: "\n\t\t\t\t\t\t<svg class=\"rtl:transform rtl:rotate-180 size-3.5 shrink-0\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n\t\t\t\t\t\t\t<path d=\"M8.86501 16.7882V12.8481H21.1459C21.3724 12.8481 21.5897 12.7581 21.7498 12.5979C21.91 12.4378 22 12.2205 22 11.994C22 11.7675 21.91 11.5503 21.7498 11.3901C21.5897 11.2299 21.3724 11.1399 21.1459 11.1399H8.86501V7.2112C8.86628 7.10375 8.83517 6.9984 8.77573 6.90887C8.7163 6.81934 8.63129 6.74978 8.53177 6.70923C8.43225 6.66869 8.32283 6.65904 8.21775 6.68155C8.11267 6.70405 8.0168 6.75766 7.94262 6.83541L2.15981 11.6182C2.1092 11.668 2.06901 11.7274 2.04157 11.7929C2.01413 11.8584 2 11.9287 2 11.9997C2 12.0707 2.01413 12.141 2.04157 12.2065C2.06901 12.272 2.1092 12.3314 2.15981 12.3812L7.94262 17.164C8.0168 17.2417 8.11267 17.2953 8.21775 17.3178C8.32283 17.3403 8.43225 17.3307 8.53177 17.2902C8.63129 17.2496 8.7163 17.18 8.77573 17.0905C8.83517 17.001 8.86628 16.8956 8.86501 16.7882Z\" fill=\"currentColor\"/>\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t",
6732
- },
6733
- next: {
6734
- /**
6735
- * CSS classes to be added to the next pagination button
6736
- */
6737
- class: 'kt-datatable-pagination-button kt-datatable-pagination-next',
6738
- /**
6739
- * Text to be displayed in the next pagination button
6740
- */
6741
- text: "\n\t\t\t\t\t\t<svg class=\"rtl:transform rtl:rotate-180 size-3.5 shrink-0\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n\t\t\t\t\t\t\t<path d=\"M15.135 7.21144V11.1516H2.85407C2.62756 11.1516 2.41032 11.2415 2.25015 11.4017C2.08998 11.5619 2 11.7791 2 12.0056C2 12.2321 2.08998 12.4494 2.25015 12.6096C2.41032 12.7697 2.62756 12.8597 2.85407 12.8597H15.135V16.7884C15.1337 16.8959 15.1648 17.0012 15.2243 17.0908C15.2837 17.1803 15.3687 17.2499 15.4682 17.2904C15.5677 17.3309 15.6772 17.3406 15.7822 17.3181C15.8873 17.2956 15.9832 17.242 16.0574 17.1642L21.8402 12.3814C21.8908 12.3316 21.931 12.2722 21.9584 12.2067C21.9859 12.1412 22 12.0709 22 11.9999C22 11.9289 21.9859 11.8586 21.9584 11.7931C21.931 11.7276 21.8908 11.6683 21.8402 11.6185L16.0574 6.83565C15.9832 6.75791 15.8873 6.70429 15.7822 6.68179C15.6772 6.65929 15.5677 6.66893 15.4682 6.70948C15.3687 6.75002 15.2837 6.81959 15.2243 6.90911C15.1648 6.99864 15.1337 7.10399 15.135 7.21144Z\" fill=\"currentColor\"/>\n\t\t\t\t\t\t</svg>\n\t\t\t\t\t",
6742
- },
6743
- more: {
6744
- /**
6745
- * CSS classes to be added to the pagination more button
6746
- */
6747
- class: 'kt-datatable-pagination-button kt-datatable-pagination-more',
6748
- /**
6749
- * Text to be displayed in the pagination more button
6750
- */
6751
- text: '...',
6752
- },
6753
- },
6754
- /**
6755
- * Sorting options
6756
- */
6757
- sort: {
6758
- /**
6759
- * CSS classes to be added to the sortable headers
6760
- */
6761
- classes: {
6762
- base: 'kt-table-col',
6763
- asc: 'asc',
6764
- desc: 'desc',
6765
- },
6766
- /**
6767
- * Local sorting callback function
6768
- * Sorts the data array based on the sort field and order
6769
- * @param data Data array to be sorted
6770
- * @param sortField Property name of the data object to be sorted by
6771
- * @param sortOrder Sorting order (ascending or descending)
6772
- * @returns Sorted data array
6773
- */
6774
- callback: function (data, sortField, sortOrder) {
7799
+ return __assign(__assign(__assign({}, datatable_defaults_1.DATATABLE_DEFAULTS), {
7800
+ // Per-instance state; DATATABLE_DEFAULTS._state is a shared singleton.
7801
+ _state: {}, sort: __assign(__assign({}, datatable_defaults_1.DATATABLE_DEFAULTS.sort), { callback: function (data, sortField, sortOrder) {
6775
7802
  return _this._sortHandler
6776
7803
  ? _this._sortHandler.sortData(data, sortField, sortOrder)
6777
7804
  : data;
6778
- },
6779
- }, search: {
6780
- /**
6781
- * Delay in milliseconds before the search function is applied to the data array
6782
- * @default 500
6783
- */
6784
- delay: 500, // ms
6785
- /**
6786
- * Local search callback function
6787
- * Filters the data array based on the search string
6788
- * @param data Data array to be filtered
6789
- * @param search Search string used to filter the data array
6790
- * @returns Filtered data array
6791
- */
6792
- callback: function (data, search) {
6793
- if (!data || !search) {
6794
- return [];
6795
- }
6796
- return data.filter(function (item) {
6797
- if (!item) {
6798
- return false;
6799
- }
6800
- return Object.values(item).some(function (value) {
6801
- if (typeof value !== 'string' &&
6802
- typeof value !== 'number' &&
6803
- typeof value !== 'boolean') {
6804
- return false;
6805
- }
6806
- var valueText = String(value)
6807
- .replace(/<|>|&nbsp;/g, '')
6808
- .toLowerCase();
6809
- return valueText.includes(search.toLowerCase());
6810
- });
6811
- });
6812
- },
6813
- },
6814
- /**
6815
- * Loading spinner options
6816
- */
6817
- loading: {
6818
- /**
6819
- * Template to be displayed during data fetching process
6820
- */
6821
- template: "\n\t\t\t\t\t<div class=\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2\">\n\t\t\t\t\t\t<div class=\"kt-datatable-loading\">\n\t\t\t\t\t\t\t<svg class=\"animate-spin -ml-1 h-5 w-5 text-gray-600\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n\t\t\t\t\t\t\t\t<circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"3\"></circle>\n\t\t\t\t\t\t\t\t<path class=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t{content}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t",
6822
- /**
6823
- * Loading text to be displayed in the template
6824
- */
6825
- content: 'Loading...',
6826
- },
6827
- /**
6828
- * Selectors of the elements to be targeted
6829
- */
6830
- attributes: {
6831
- /**
6832
- * Data table element
6833
- */
6834
- table: 'table[data-kt-datatable-table="true"]',
6835
- /**
6836
- * Pagination info element
6837
- */
6838
- info: '[data-kt-datatable-info="true"]',
6839
- /**
6840
- * Page size dropdown element
6841
- */
6842
- size: '[data-kt-datatable-size="true"]',
6843
- /**
6844
- * Pagination element
6845
- */
6846
- pagination: '[data-kt-datatable-pagination="true"]',
6847
- /**
6848
- * Spinner element
6849
- */
6850
- spinner: '[data-kt-datatable-spinner="true"]',
6851
- /**
6852
- * Checkbox element
6853
- */
6854
- check: '[data-kt-datatable-check="true"]',
6855
- checkbox: '[data-kt-datatable-row-check="true"]',
6856
- },
6857
- /**
6858
- * Enable or disable state saving
6859
- */
6860
- stateSave: true, checkbox: {
6861
- checkedClass: 'checked',
6862
- },
6863
- /**
6864
- * Private properties
6865
- */
6866
- _state: {}, loadingClass: 'loading' }, config);
7805
+ } }), search: __assign(__assign({}, datatable_defaults_1.DATATABLE_DEFAULTS.search), { callback: this._createDefaultSearchCallback() }) }), config);
6867
7806
  };
6868
7807
  /**
6869
7808
  * Initialize table, tbody, thead, info, size, and pagination elements
@@ -6904,24 +7843,24 @@ var KTDataTable = /** @class */ (function (_super) {
6904
7843
  var _this = this;
6905
7844
  // Store tbody class
6906
7845
  if (this._tbodyElement) {
6907
- this._originalTbodyClass = this._tbodyElement.className || '';
7846
+ this._originalClasses.tbody = this._tbodyElement.className || '';
6908
7847
  }
6909
7848
  // Store thead class and th classes
6910
7849
  if (this._theadElement) {
6911
- this._originalTheadClass = this._theadElement.className || '';
7850
+ this._originalClasses.thead = this._theadElement.className || '';
6912
7851
  // Store th classes
6913
7852
  var thElements = this._theadElement.querySelectorAll('th');
6914
- this._originalThClasses = Array.from(thElements).map(function (th) { return th.className || ''; });
7853
+ this._originalClasses.th = Array.from(thElements).map(function (th) { return th.className || ''; });
6915
7854
  }
6916
7855
  // Store tr and td classes
6917
7856
  if (this._tbodyElement) {
6918
7857
  var originalRows = this._tbodyElement.querySelectorAll('tr');
6919
- this._originalTrClasses = Array.from(originalRows).map(function (row) { return row.className || ''; });
7858
+ this._originalClasses.tr = Array.from(originalRows).map(function (row) { return row.className || ''; });
6920
7859
  // Store td classes as a 2D array
6921
- this._originalTdClasses = [];
7860
+ this._originalClasses.td = [];
6922
7861
  Array.from(originalRows).forEach(function (row, rowIndex) {
6923
7862
  var tdElements = row.querySelectorAll('td');
6924
- _this._originalTdClasses[rowIndex] = Array.from(tdElements).map(function (td) { return td.className || ''; });
7863
+ _this._originalClasses.td[rowIndex] = Array.from(tdElements).map(function (td) { return td.className || ''; });
6925
7864
  });
6926
7865
  }
6927
7866
  };
@@ -6941,8 +7880,7 @@ var KTDataTable = /** @class */ (function (_super) {
6941
7880
  _b.label = 1;
6942
7881
  case 1:
6943
7882
  _b.trys.push([1, , 8, 9]);
6944
- this._showSpinner(); // Show spinner before fetching data
6945
- this._emit('fetch');
7883
+ this._spinner.show(this._element, this._config, this._tableElement); // Show spinner before fetching data
6946
7884
  if (!(typeof this._config.apiEndpoint === 'undefined')) return [3 /*break*/, 2];
6947
7885
  _a = this._localProvider.fetchSync();
6948
7886
  return [3 /*break*/, 4];
@@ -6958,11 +7896,11 @@ var KTDataTable = /** @class */ (function (_super) {
6958
7896
  return [4 /*yield*/, this._draw()];
6959
7897
  case 5:
6960
7898
  _b.sent();
6961
- this._emit('fetched');
6962
7899
  _b.label = 6;
6963
7900
  case 6: return [4 /*yield*/, this._finalize()];
6964
7901
  case 7:
6965
7902
  _b.sent();
7903
+ this._emit('update');
6966
7904
  return [3 /*break*/, 9];
6967
7905
  case 8:
6968
7906
  // Finally block now correctly executes after promises resolve, not immediately
@@ -6978,7 +7916,8 @@ var KTDataTable = /** @class */ (function (_super) {
6978
7916
  * @returns {void}
6979
7917
  */
6980
7918
  KTDataTable.prototype._finalize = function () {
6981
- var _a;
7919
+ var _this = this;
7920
+ var _a, _b, _c;
6982
7921
  (_a = this._element) === null || _a === void 0 ? void 0 : _a.classList.add('datatable-initialized');
6983
7922
  // Initialize checkbox logic
6984
7923
  this._checkbox.init();
@@ -6986,50 +7925,20 @@ var KTDataTable = /** @class */ (function (_super) {
6986
7925
  if (this._sortHandler) {
6987
7926
  this._sortHandler.initSort();
6988
7927
  }
6989
- this._attachSearchEvent();
6990
- if (typeof index_1.default !== 'undefined') {
6991
- index_1.default.init();
6992
- }
7928
+ this._searchHandler.attach(this._tableId(), this.getState().search, (_c = (_b = this._config.search) === null || _b === void 0 ? void 0 : _b.delay) !== null && _c !== void 0 ? _c : datatable_defaults_1.DEFAULT_SEARCH_DELAY, function (query) { return _this.search(query); });
6993
7929
  /**
6994
7930
  * Hide spinner
6995
7931
  */
6996
- this._hideSpinner();
6997
- };
6998
- /**
6999
- * Attach search event to the search input element
7000
- * @returns {void}
7001
- */
7002
- KTDataTable.prototype._attachSearchEvent = function () {
7003
- var _this = this;
7004
- var _a, _b;
7005
- var tableId = this._tableId();
7006
- var searchElement = document.querySelector("[data-kt-datatable-search=\"#".concat(tableId, "\"]"));
7007
- // Get search state
7008
- var search = this.getState().search;
7009
- // Set search value
7010
- if (searchElement) {
7011
- searchElement.value =
7012
- search === undefined || search === null
7013
- ? ''
7014
- : typeof search === 'string'
7015
- ? search
7016
- : String(search);
7017
- }
7018
- if (searchElement) {
7019
- // Check if a debounced search function already exists
7020
- var searchWithDebounce = KTDataTable.asSearchElementWithDebounce(searchElement);
7021
- if (searchWithDebounce._debouncedSearch) {
7022
- // Remove the existing debounced event listener
7023
- searchElement.removeEventListener('keyup', searchWithDebounce._debouncedSearch);
7024
- }
7025
- // Create a new debounced search function
7026
- var debouncedSearch = this._debounce(function () {
7027
- _this.search(searchElement.value);
7028
- }, (_b = (_a = this._config.search) === null || _a === void 0 ? void 0 : _a.delay) !== null && _b !== void 0 ? _b : 500);
7029
- // Store the new debounced function as a property of the element
7030
- searchWithDebounce._debouncedSearch = debouncedSearch;
7031
- // Add the new debounced event listener
7032
- searchElement.addEventListener('keyup', debouncedSearch);
7932
+ this._spinner.hide(this._element, this._config);
7933
+ // Update content checksum AFTER all DOM modifications (checkbox init
7934
+ // adds checked-class to <tr> elements which changes tbody innerHTML).
7935
+ // If we save the checksum earlier (in _draw), the next fetchSync()
7936
+ // sees a mismatch, re-extracts from the DOM, and loses rows that
7937
+ // were on other pages — making pagination show empty.
7938
+ if (!this._config.apiEndpoint) {
7939
+ this._stateStore.patchState({
7940
+ _contentChecksum: utils_1.default.checksum(JSON.stringify(this._tbodyElement.innerHTML)),
7941
+ });
7033
7942
  }
7034
7943
  };
7035
7944
  /**
@@ -7038,17 +7947,7 @@ var KTDataTable = /** @class */ (function (_super) {
7038
7947
  * @returns {number} Number of data columns, or 0 if unknown
7039
7948
  */
7040
7949
  KTDataTable.prototype._getLogicalColumnCount = function () {
7041
- var originalData = this.getState().originalData;
7042
- if (originalData && originalData.length > 0) {
7043
- return Object.keys(originalData[0]).length;
7044
- }
7045
- if (this._tbodyElement) {
7046
- var firstRow = this._tbodyElement.querySelector('tr');
7047
- if (firstRow) {
7048
- return firstRow.querySelectorAll('td').length;
7049
- }
7050
- }
7051
- return 0;
7950
+ return (0, datatable_column_utils_1.getLogicalColumnCount)(this._theadElement, this._tbodyElement, this.getState().originalData);
7052
7951
  };
7053
7952
  /**
7054
7953
  * Creates a complete URL from a relative path or a full URL.
@@ -7117,12 +8016,17 @@ var KTDataTable = /** @class */ (function (_super) {
7117
8016
  */
7118
8017
  KTDataTable.prototype._draw = function () {
7119
8018
  return __awaiter(this, void 0, void 0, function () {
7120
- return __generator(this, function (_a) {
7121
- this._stateStore.patchState({
7122
- totalPages: Math.ceil(this.getState().totalItems / this.getState().pageSize) || 0,
7123
- });
7124
- this._emit('draw');
7125
- this._dispose();
8019
+ var normalizedPageSize, totalPages, page;
8020
+ var _a, _b, _c, _d;
8021
+ return __generator(this, function (_e) {
8022
+ normalizedPageSize = Math.max(1, Number(this.getState().pageSize) || Number(this._config.pageSize) || 1);
8023
+ totalPages = Math.ceil(this.getState().totalItems / normalizedPageSize) || 0;
8024
+ page = totalPages > 0
8025
+ ? Math.min(Math.max(1, this.getState().page), totalPages)
8026
+ : 1;
8027
+ this._stateStore.patchState({ totalPages: totalPages, page: page });
8028
+ (_b = (_a = this._layoutPlugin) === null || _a === void 0 ? void 0 : _a.beforeDraw) === null || _b === void 0 ? void 0 : _b.call(_a, this._getLayoutPluginContext());
8029
+ this._cleanupForRedraw();
7126
8030
  // Update the table and pagination controls
7127
8031
  if (this._theadElement && this._tbodyElement) {
7128
8032
  this._updateTable();
@@ -7130,7 +8034,7 @@ var KTDataTable = /** @class */ (function (_super) {
7130
8034
  if (this._infoElement || this._sizeElement || this._paginationElement) {
7131
8035
  this._updatePagination();
7132
8036
  }
7133
- this._emit('drew');
8037
+ (_d = (_c = this._layoutPlugin) === null || _c === void 0 ? void 0 : _c.afterDraw) === null || _d === void 0 ? void 0 : _d.call(_c, this._getLayoutPluginContext());
7134
8038
  // Spinner is hidden in _finalize() to ensure it stays visible until the entire request completes
7135
8039
  // Removed duplicate _hideSpinner() call here to prevent premature hiding
7136
8040
  if (this._config.stateSave) {
@@ -7145,18 +8049,17 @@ var KTDataTable = /** @class */ (function (_super) {
7145
8049
  * @returns {HTMLTableSectionElement} The new table body element
7146
8050
  */
7147
8051
  KTDataTable.prototype._updateTable = function () {
7148
- return this._tableRenderer.render({
8052
+ this._tbodyElement = this._tableRenderer.render({
7149
8053
  config: this._config,
7150
8054
  context: this,
7151
8055
  data: this._data,
7152
8056
  getLogicalColumnCount: this._getLogicalColumnCount.bind(this),
7153
8057
  getState: this.getState.bind(this),
7154
- originalTbodyClass: this._originalTbodyClass,
7155
- originalTrClasses: this._originalTrClasses,
7156
- originalTdClasses: this._originalTdClasses,
8058
+ originalClasses: this._originalClasses,
7157
8059
  tableElement: this._tableElement,
7158
8060
  theadElement: this._theadElement,
7159
8061
  });
8062
+ return this._tbodyElement;
7160
8063
  };
7161
8064
  /**
7162
8065
  * Show a notice on the table
@@ -7202,91 +8105,31 @@ var KTDataTable = /** @class */ (function (_super) {
7202
8105
  if (page < 1 || !Number.isInteger(page)) {
7203
8106
  return;
7204
8107
  }
7205
- this._emit('pagination', { page: page });
7206
8108
  if (page >= 1 && page <= this.getState().totalPages) {
7207
8109
  this._stateStore.setPage(page);
7208
8110
  this._updateData();
7209
8111
  }
7210
8112
  };
7211
- // Method to show the loading spinner
7212
- KTDataTable.prototype._showSpinner = function () {
7213
- var _a, _b;
7214
- var root = this._element;
7215
- var spinnerSel = (_a = this._config.attributes) === null || _a === void 0 ? void 0 : _a.spinner;
7216
- var fromDom = root && spinnerSel
7217
- ? root.querySelector(spinnerSel)
7218
- : null;
7219
- var spinner = fromDom !== null && fromDom !== void 0 ? fromDom : this._createSpinner();
7220
- if (spinner) {
7221
- spinner.style.display = 'block';
7222
- }
7223
- root === null || root === void 0 ? void 0 : root.classList.add((_b = this._config.loadingClass) !== null && _b !== void 0 ? _b : 'loading');
7224
- };
7225
- // Method to hide the loading spinner
7226
- KTDataTable.prototype._hideSpinner = function () {
7227
- var _a, _b;
7228
- var root = this._element;
7229
- var spinnerSel = (_a = this._config.attributes) === null || _a === void 0 ? void 0 : _a.spinner;
7230
- var spinner = root && spinnerSel
7231
- ? root.querySelector(spinnerSel)
7232
- : null;
7233
- if (spinner) {
7234
- spinner.style.display = 'none';
7235
- }
7236
- root === null || root === void 0 ? void 0 : root.classList.remove((_b = this._config.loadingClass) !== null && _b !== void 0 ? _b : 'loading');
7237
- };
7238
- // Method to create a spinner element if it doesn't exist
7239
- KTDataTable.prototype._createSpinner = function () {
7240
- var loading = this._config.loading;
7241
- if (!loading) {
7242
- return null;
7243
- }
7244
- var template = document.createElement('template');
7245
- template.innerHTML = loading.template
7246
- .trim()
7247
- .replace('{content}', loading.content);
7248
- var first = template.content.firstChild;
7249
- if (!first || !(first instanceof HTMLElement)) {
7250
- return null;
7251
- }
7252
- var spinner = first;
7253
- spinner.setAttribute('data-kt-datatable-spinner', 'true');
7254
- this._tableElement.appendChild(spinner);
7255
- return spinner;
7256
- };
7257
8113
  /**
7258
8114
  * Saves the current state of the table to local storage.
7259
8115
  * @returns {void}
7260
8116
  */
7261
8117
  KTDataTable.prototype._saveState = function () {
7262
- this._emit('stateSave');
7263
- var ns = this._tableNamespace();
7264
- if (ns) {
7265
- localStorage.setItem(ns, JSON.stringify(this.getState()));
7266
- }
8118
+ this._statePersistence.save(this._tableNamespace(), this.getState());
7267
8119
  };
7268
8120
  /**
7269
8121
  * Loads the saved state of the table from local storage, if it exists.
7270
8122
  * @returns {Object} The saved state of the table, or null if no saved state exists.
7271
8123
  */
7272
8124
  KTDataTable.prototype._loadState = function () {
7273
- var stateString = localStorage.getItem(this._tableNamespace());
7274
- if (!stateString)
7275
- return null;
7276
- try {
7277
- var state = JSON.parse(stateString);
7278
- if (state)
7279
- this._stateStore.replaceState(state);
7280
- return state;
7281
- }
7282
- catch (_a) { }
7283
- return null;
8125
+ var ns = this._tableNamespace();
8126
+ var saved = this._statePersistence.load(ns);
8127
+ if (saved)
8128
+ this._stateStore.replaceState(saved);
8129
+ return saved;
7284
8130
  };
7285
8131
  KTDataTable.prototype._deleteState = function () {
7286
- var ns = this._tableNamespace();
7287
- if (ns) {
7288
- localStorage.removeItem(ns);
7289
- }
8132
+ this._statePersistence.remove(this._tableNamespace());
7290
8133
  };
7291
8134
  /**
7292
8135
  * Gets the namespace for the table's state.
@@ -7297,13 +8140,7 @@ var KTDataTable = /** @class */ (function (_super) {
7297
8140
  * @returns {string} The namespace for the table's state.
7298
8141
  */
7299
8142
  KTDataTable.prototype._tableNamespace = function () {
7300
- var _a;
7301
- // Use the specified namespace, if one is given
7302
- if (this._config.stateNamespace) {
7303
- return this._config.stateNamespace;
7304
- }
7305
- // Fallback to the component's UID
7306
- return (_a = this._tableId()) !== null && _a !== void 0 ? _a : this._name;
8143
+ return (0, datatable_state_persistence_1.resolveTableNamespace)(this._config, this._tableElement, this._element, this._name);
7307
8144
  };
7308
8145
  KTDataTable.prototype._tableId = function () {
7309
8146
  var _a, _b;
@@ -7321,90 +8158,43 @@ var KTDataTable = /** @class */ (function (_super) {
7321
8158
  * Clean up all event listeners, handlers, and DOM nodes created by this instance.
7322
8159
  * This method is called before re-rendering or when disposing the component.
7323
8160
  */
7324
- KTDataTable.prototype._dispose = function () {
7325
- var _a, _b, _c;
7326
- var root = this._element;
7327
- if (!root) {
8161
+ /**
8162
+ * Clean up event listeners and DOM artifacts for a redraw cycle.
8163
+ * Does NOT remove the instance from the registry — the datatable
8164
+ * remains accessible via getInstance() during the redraw window.
8165
+ */
8166
+ KTDataTable.prototype._cleanupForRedraw = function () {
8167
+ var _a, _b;
8168
+ (_b = (_a = this._layoutPlugin) === null || _a === void 0 ? void 0 : _a.dispose) === null || _b === void 0 ? void 0 : _b.call(_a, this._getLayoutPluginContext());
8169
+ if (!this._element) {
7328
8170
  return;
7329
8171
  }
7330
8172
  this._cleanupCallbacks.forEach(function (cleanup) { return cleanup(); });
7331
8173
  this._cleanupCallbacks = [];
7332
- // --- 1. Remove search input event listener (debounced) ---
7333
- var tableId = this._tableId();
7334
- var searchElement = document.querySelector("[data-kt-datatable-search=\"#".concat(tableId, "\"]"));
7335
- if (searchElement) {
7336
- var searchWithDebounce = KTDataTable.asSearchElementWithDebounce(searchElement);
7337
- if (searchWithDebounce._debouncedSearch) {
7338
- searchElement.removeEventListener('keyup', searchWithDebounce._debouncedSearch);
7339
- delete searchWithDebounce._debouncedSearch;
7340
- }
7341
- }
7342
- // --- 2. Remove page size dropdown event listener ---
8174
+ this._searchHandler.detach(this._tableId());
7343
8175
  if (this._sizeElement && this._sizeElement.onchange) {
7344
8176
  this._sizeElement.onchange = null;
7345
8177
  }
7346
- // --- 3. Remove all pagination button event listeners ---
7347
8178
  if (this._paginationElement) {
7348
- // Remove all child nodes (buttons) to ensure no lingering listeners
7349
8179
  while (this._paginationElement.firstChild) {
7350
8180
  this._paginationElement.removeChild(this._paginationElement.firstChild);
7351
8181
  }
7352
8182
  }
7353
- // --- 4. Dispose of handler objects (checkbox, sort) ---
7354
- // KTDataTableCheckboxAPI does not have a dispose method, but we can remove header checkbox listener
7355
- var checkboxWithDispose = this._checkbox;
7356
- if (this._checkbox && typeof checkboxWithDispose.dispose === 'function') {
7357
- checkboxWithDispose.dispose();
7358
- }
7359
- else {
7360
- var checkSel = (_a = this._config.attributes) === null || _a === void 0 ? void 0 : _a.check;
7361
- if (checkSel) {
7362
- var headerCheckElement = root.querySelector(checkSel);
7363
- if (headerCheckElement) {
7364
- headerCheckElement.replaceWith(headerCheckElement.cloneNode(true));
7365
- }
7366
- }
7367
- }
7368
- // KTDataTableSortAPI does not have a dispose method, but we can remove th click listeners by replacing them
7369
- if (this._theadElement) {
7370
- var ths = this._theadElement.querySelectorAll('th');
7371
- ths.forEach(function (th) {
7372
- th.replaceWith(th.cloneNode(true));
7373
- });
7374
- }
7375
- // --- 5. Remove spinner DOM node if it exists ---
7376
- var spinnerSel = (_b = this._config.attributes) === null || _b === void 0 ? void 0 : _b.spinner;
7377
- if (spinnerSel) {
7378
- var spinner = root.querySelector(spinnerSel);
7379
- if (spinner === null || spinner === void 0 ? void 0 : spinner.parentNode) {
7380
- spinner.parentNode.removeChild(spinner);
7381
- }
7382
- }
7383
- root.classList.remove((_c = this._config.loadingClass) !== null && _c !== void 0 ? _c : 'loading');
7384
- // --- 6. Remove instance reference from the DOM element ---
7385
- var elementWithInstance = KTDataTable.asElementWithInstance(root);
7386
- if (elementWithInstance.instance) {
7387
- delete elementWithInstance.instance;
7388
- }
7389
- data_1.default.remove(root, this._name);
7390
- // --- 7. (Optional) Clear localStorage state ---
7391
- // Uncomment the following line if you want to clear state on dispose:
7392
- // this._deleteState();
8183
+ this._checkbox.dispose();
8184
+ this._sortHandler.dispose();
8185
+ this._spinner.remove(this._element, this._config);
7393
8186
  };
7394
- KTDataTable.prototype._debounce = function (func, wait) {
7395
- var timeout;
7396
- return function () {
7397
- var args = [];
7398
- for (var _i = 0; _i < arguments.length; _i++) {
7399
- args[_i] = arguments[_i];
7400
- }
7401
- var later = function () {
7402
- clearTimeout(timeout);
7403
- func.apply(void 0, args);
7404
- };
7405
- clearTimeout(timeout);
7406
- timeout = window.setTimeout(later, wait);
7407
- };
8187
+ /**
8188
+ * Full disposal — cleans up listeners AND removes the instance from
8189
+ * the registry. Only called when the component is being destroyed.
8190
+ */
8191
+ KTDataTable.prototype._dispose = function () {
8192
+ this._cleanupForRedraw();
8193
+ var root = this._element;
8194
+ if (root) {
8195
+ datatableRegistry.remove(root);
8196
+ data_1.default.remove(root, this._name);
8197
+ }
7408
8198
  };
7409
8199
  /**
7410
8200
  * Gets the current state of the table.
@@ -7415,12 +8205,14 @@ var KTDataTable = /** @class */ (function (_super) {
7415
8205
  };
7416
8206
  /**
7417
8207
  * Sorts the data in the table by the specified field.
8208
+ * When `order` is provided, applies that sort direction instead of toggling.
7418
8209
  * @param field The field to sort by.
8210
+ * @param order Optional sort direction (`asc`, `desc`, or `''` to clear).
7419
8211
  */
7420
- KTDataTable.prototype.sort = function (field) {
7421
- // Use the sort handler to update state and trigger sorting
7422
- var state = this.getState();
7423
- var sortOrder = this._sortHandler.toggleSortOrder(state.sortField, state.sortOrder, field);
8212
+ KTDataTable.prototype.sort = function (field, order) {
8213
+ var sortOrder = order !== undefined
8214
+ ? order
8215
+ : this._sortHandler.toggleSortOrder(this.getState().sortField, this.getState().sortOrder, field);
7424
8216
  this._sortHandler.setSortIcon(field, sortOrder);
7425
8217
  this._stateStore.setSort(field, sortOrder);
7426
8218
  this._emit('sort', { field: field, order: sortOrder });
@@ -7452,36 +8244,28 @@ var KTDataTable = /** @class */ (function (_super) {
7452
8244
  this._reloadPageSize(pageSize);
7453
8245
  };
7454
8246
  /**
7455
- * Reloads the data from the server and updates the table.
7456
- * Triggers the 'reload' event and the 'kt.datatable.reload' custom event.
8247
+ * Reloads the data from the source (API or DOM) and redraws the table.
8248
+ * @returns {Promise<void>}
7457
8249
  */
7458
8250
  KTDataTable.prototype.reload = function () {
7459
- this._emit('reload');
7460
8251
  // Fetch the data from the server using the current sort and filter settings
7461
8252
  this._updateData();
7462
8253
  };
7463
8254
  KTDataTable.prototype.redraw = function (page) {
7464
8255
  if (page === void 0) { page = 1; }
7465
- this._emit('redraw');
7466
8256
  this._paginateData(page);
7467
8257
  };
7468
8258
  /**
7469
8259
  * Show the loading spinner of the data table.
7470
8260
  */
7471
8261
  KTDataTable.prototype.showSpinner = function () {
7472
- /**
7473
- * Show the loading spinner of the data table.
7474
- */
7475
- this._showSpinner();
8262
+ this._spinner.show(this._element, this._config, this._tableElement);
7476
8263
  };
7477
8264
  /**
7478
8265
  * Hide the loading spinner of the data table.
7479
8266
  */
7480
8267
  KTDataTable.prototype.hideSpinner = function () {
7481
- /**
7482
- * Hide the loading spinner of the data table.
7483
- */
7484
- this._hideSpinner();
8268
+ this._spinner.hide(this._element, this._config);
7485
8269
  };
7486
8270
  /**
7487
8271
  * Filter data using the specified filter object.
@@ -7508,21 +8292,7 @@ var KTDataTable = /** @class */ (function (_super) {
7508
8292
  * This function is now browser-guarded and must be called explicitly.
7509
8293
  */
7510
8294
  KTDataTable.createInstances = function () {
7511
- var _this = this;
7512
- if (typeof document === 'undefined')
7513
- return;
7514
- var elements = document.querySelectorAll('[data-kt-datatable="true"]');
7515
- elements.forEach(function (element) {
7516
- if (element.hasAttribute('data-kt-datatable') &&
7517
- !element.classList.contains('datatable-initialized')) {
7518
- /**
7519
- * Create an instance of KTDataTable for the given element
7520
- * @param element The element to create an instance for
7521
- */
7522
- var instance = new KTDataTable(element);
7523
- _this._instances.set(element, instance);
7524
- }
7525
- });
8295
+ datatableRegistry.createAll(function (el) { return new KTDataTable(el); });
7526
8296
  };
7527
8297
  /**
7528
8298
  * Get the KTDataTable instance for a given element.
@@ -7531,21 +8301,13 @@ var KTDataTable = /** @class */ (function (_super) {
7531
8301
  * @returns The KTDataTable instance or undefined if not found
7532
8302
  */
7533
8303
  KTDataTable.getInstance = function (element) {
7534
- // First check the static Map (for instances created via createInstances)
7535
- var instanceFromMap = this._instances.get(element);
7536
- if (instanceFromMap) {
7537
- return instanceFromMap;
7538
- }
7539
- // Fallback to element's instance property (for manually created instances)
7540
- return KTDataTable.asElementWithInstance(element).instance;
8304
+ return datatableRegistry.get(element);
7541
8305
  };
7542
8306
  /**
7543
8307
  * Initializes all KTDataTable instances on the page.
7544
8308
  * This function is now browser-guarded and must be called explicitly.
7545
8309
  */
7546
8310
  KTDataTable.init = function () {
7547
- if (typeof document === 'undefined')
7548
- return;
7549
8311
  KTDataTable.createInstances();
7550
8312
  };
7551
8313
  /**
@@ -7553,25 +8315,7 @@ var KTDataTable = /** @class */ (function (_super) {
7553
8315
  * Useful for Livewire wire:navigate where the DOM is replaced and new tables need to be initialized.
7554
8316
  */
7555
8317
  KTDataTable.reinit = function () {
7556
- if (typeof document === 'undefined')
7557
- return;
7558
- var elements = document.querySelectorAll('[data-kt-datatable="true"]');
7559
- elements.forEach(function (element) {
7560
- try {
7561
- var instance = KTDataTable.getInstance(element);
7562
- if (instance && typeof instance.dispose === 'function') {
7563
- instance.dispose();
7564
- }
7565
- data_1.default.remove(element, 'datatable');
7566
- element.removeAttribute('data-kt-datatable-initialized');
7567
- element.classList.remove('datatable-initialized');
7568
- }
7569
- catch (_a) {
7570
- // ignore per-element errors
7571
- }
7572
- });
7573
- KTDataTable._instances.clear();
7574
- KTDataTable.createInstances();
8318
+ datatableRegistry.reinit(function (el) { return new KTDataTable(el); });
7575
8319
  };
7576
8320
  /**
7577
8321
  * Check if all visible rows are checked (header checkbox state)
@@ -7611,16 +8355,18 @@ var KTDataTable = /** @class */ (function (_super) {
7611
8355
  return this._checkbox.getChecked();
7612
8356
  };
7613
8357
  /**
7614
- * Reapply checked state to visible checkboxes (after redraw/pagination)
8358
+ * Re-apply checkbox checked states to visible rows after a redraw or pagination change.
7615
8359
  * @returns {void}
7616
8360
  */
7617
- KTDataTable.prototype.update = function () {
8361
+ KTDataTable.prototype.refreshCheckboxes = function () {
7618
8362
  this._checkbox.updateState();
7619
8363
  };
7620
8364
  /**
7621
- * Static variables
8365
+ * @deprecated Use {@link refreshCheckboxes} instead.
7622
8366
  */
7623
- KTDataTable._instances = new Map();
8367
+ KTDataTable.prototype.update = function () {
8368
+ this.refreshCheckboxes();
8369
+ };
7624
8370
  return KTDataTable;
7625
8371
  }(component_1.default));
7626
8372
  exports.KTDataTable = KTDataTable;
@@ -20186,6 +20932,12 @@ exports.KTComponents = {
20186
20932
  carousel_1.KTCarousel.init();
20187
20933
  },
20188
20934
  };
20935
+ // Livewire wire:navigate support: re-init all components after SPA navigation
20936
+ if (typeof window !== 'undefined') {
20937
+ document.addEventListener('livewire:navigate', function () {
20938
+ exports.KTComponents.init();
20939
+ });
20940
+ }
20189
20941
  exports["default"] = exports.KTComponents;
20190
20942
 
20191
20943