@keenthemes/ktui 1.2.6 → 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 (190) hide show
  1. package/README.md +14 -5
  2. package/dist/ktui.js +3775 -2298
  3. package/dist/ktui.min.js +1 -1
  4. package/dist/ktui.min.js.map +1 -1
  5. package/dist/styles.css +25 -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.map +1 -1
  21. package/lib/cjs/components/datatable/datatable-layout-plugin.js +11 -1
  22. package/lib/cjs/components/datatable/datatable-layout-plugin.js.map +1 -1
  23. package/lib/cjs/components/datatable/datatable-local-provider.d.ts.map +1 -1
  24. package/lib/cjs/components/datatable/datatable-local-provider.js +80 -24
  25. package/lib/cjs/components/datatable/datatable-local-provider.js.map +1 -1
  26. package/lib/cjs/components/datatable/datatable-pagination-renderer.d.ts.map +1 -1
  27. package/lib/cjs/components/datatable/datatable-pagination-renderer.js +3 -2
  28. package/lib/cjs/components/datatable/datatable-pagination-renderer.js.map +1 -1
  29. package/lib/cjs/components/datatable/datatable-registry.d.ts +18 -0
  30. package/lib/cjs/components/datatable/datatable-registry.d.ts.map +1 -0
  31. package/lib/cjs/components/datatable/datatable-registry.js +66 -0
  32. package/lib/cjs/components/datatable/datatable-registry.js.map +1 -0
  33. package/lib/cjs/components/datatable/datatable-remote-provider.d.ts.map +1 -1
  34. package/lib/cjs/components/datatable/datatable-remote-provider.js +1 -2
  35. package/lib/cjs/components/datatable/datatable-remote-provider.js.map +1 -1
  36. package/lib/cjs/components/datatable/datatable-search-handler.d.ts +10 -0
  37. package/lib/cjs/components/datatable/datatable-search-handler.d.ts.map +1 -0
  38. package/lib/cjs/components/datatable/datatable-search-handler.js +65 -0
  39. package/lib/cjs/components/datatable/datatable-search-handler.js.map +1 -0
  40. package/lib/cjs/components/datatable/datatable-sort.d.ts +31 -4
  41. package/lib/cjs/components/datatable/datatable-sort.d.ts.map +1 -1
  42. package/lib/cjs/components/datatable/datatable-sort.js +86 -58
  43. package/lib/cjs/components/datatable/datatable-sort.js.map +1 -1
  44. package/lib/cjs/components/datatable/datatable-spinner.d.ts +30 -0
  45. package/lib/cjs/components/datatable/datatable-spinner.d.ts.map +1 -0
  46. package/lib/cjs/components/datatable/datatable-spinner.js +54 -0
  47. package/lib/cjs/components/datatable/datatable-spinner.js.map +1 -0
  48. package/lib/cjs/components/datatable/datatable-state-persistence.d.ts +19 -0
  49. package/lib/cjs/components/datatable/datatable-state-persistence.d.ts.map +1 -0
  50. package/lib/cjs/components/datatable/datatable-state-persistence.js +59 -0
  51. package/lib/cjs/components/datatable/datatable-state-persistence.js.map +1 -0
  52. package/lib/cjs/components/datatable/datatable-table-renderer.d.ts +2 -0
  53. package/lib/cjs/components/datatable/datatable-table-renderer.d.ts.map +1 -1
  54. package/lib/cjs/components/datatable/datatable-table-renderer.js +75 -16
  55. package/lib/cjs/components/datatable/datatable-table-renderer.js.map +1 -1
  56. package/lib/cjs/components/datatable/datatable-utils.d.ts +10 -0
  57. package/lib/cjs/components/datatable/datatable-utils.d.ts.map +1 -0
  58. package/lib/cjs/components/datatable/datatable-utils.js +15 -0
  59. package/lib/cjs/components/datatable/datatable-utils.js.map +1 -0
  60. package/lib/cjs/components/datatable/datatable.d.ts +26 -34
  61. package/lib/cjs/components/datatable/datatable.d.ts.map +1 -1
  62. package/lib/cjs/components/datatable/datatable.js +155 -492
  63. package/lib/cjs/components/datatable/datatable.js.map +1 -1
  64. package/lib/cjs/components/datatable/index.d.ts +1 -1
  65. package/lib/cjs/components/datatable/index.d.ts.map +1 -1
  66. package/lib/cjs/components/datatable/types.d.ts +100 -11
  67. package/lib/cjs/components/datatable/types.d.ts.map +1 -1
  68. package/lib/cjs/index.d.ts +1 -1
  69. package/lib/cjs/index.d.ts.map +1 -1
  70. package/lib/cjs/index.js +6 -0
  71. package/lib/cjs/index.js.map +1 -1
  72. package/lib/esm/components/datatable/datatable-checkbox.d.ts +37 -1
  73. package/lib/esm/components/datatable/datatable-checkbox.d.ts.map +1 -1
  74. package/lib/esm/components/datatable/datatable-checkbox.js +142 -155
  75. package/lib/esm/components/datatable/datatable-checkbox.js.map +1 -1
  76. package/lib/esm/components/datatable/datatable-column-utils.d.ts +30 -0
  77. package/lib/esm/components/datatable/datatable-column-utils.d.ts.map +1 -0
  78. package/lib/esm/components/datatable/datatable-column-utils.js +38 -0
  79. package/lib/esm/components/datatable/datatable-column-utils.js.map +1 -0
  80. package/lib/esm/components/datatable/datatable-contracts.d.ts +2 -4
  81. package/lib/esm/components/datatable/datatable-contracts.d.ts.map +1 -1
  82. package/lib/esm/components/datatable/datatable-defaults.d.ts +20 -0
  83. package/lib/esm/components/datatable/datatable-defaults.d.ts.map +1 -0
  84. package/lib/esm/components/datatable/datatable-defaults.js +190 -0
  85. package/lib/esm/components/datatable/datatable-defaults.js.map +1 -0
  86. package/lib/esm/components/datatable/datatable-layout-plugin.d.ts.map +1 -1
  87. package/lib/esm/components/datatable/datatable-layout-plugin.js +11 -1
  88. package/lib/esm/components/datatable/datatable-layout-plugin.js.map +1 -1
  89. package/lib/esm/components/datatable/datatable-local-provider.d.ts.map +1 -1
  90. package/lib/esm/components/datatable/datatable-local-provider.js +80 -24
  91. package/lib/esm/components/datatable/datatable-local-provider.js.map +1 -1
  92. package/lib/esm/components/datatable/datatable-pagination-renderer.d.ts.map +1 -1
  93. package/lib/esm/components/datatable/datatable-pagination-renderer.js +3 -2
  94. package/lib/esm/components/datatable/datatable-pagination-renderer.js.map +1 -1
  95. package/lib/esm/components/datatable/datatable-registry.d.ts +18 -0
  96. package/lib/esm/components/datatable/datatable-registry.d.ts.map +1 -0
  97. package/lib/esm/components/datatable/datatable-registry.js +63 -0
  98. package/lib/esm/components/datatable/datatable-registry.js.map +1 -0
  99. package/lib/esm/components/datatable/datatable-remote-provider.d.ts.map +1 -1
  100. package/lib/esm/components/datatable/datatable-remote-provider.js +1 -2
  101. package/lib/esm/components/datatable/datatable-remote-provider.js.map +1 -1
  102. package/lib/esm/components/datatable/datatable-search-handler.d.ts +10 -0
  103. package/lib/esm/components/datatable/datatable-search-handler.d.ts.map +1 -0
  104. package/lib/esm/components/datatable/datatable-search-handler.js +62 -0
  105. package/lib/esm/components/datatable/datatable-search-handler.js.map +1 -0
  106. package/lib/esm/components/datatable/datatable-sort.d.ts +31 -4
  107. package/lib/esm/components/datatable/datatable-sort.d.ts.map +1 -1
  108. package/lib/esm/components/datatable/datatable-sort.js +85 -57
  109. package/lib/esm/components/datatable/datatable-sort.js.map +1 -1
  110. package/lib/esm/components/datatable/datatable-spinner.d.ts +30 -0
  111. package/lib/esm/components/datatable/datatable-spinner.d.ts.map +1 -0
  112. package/lib/esm/components/datatable/datatable-spinner.js +51 -0
  113. package/lib/esm/components/datatable/datatable-spinner.js.map +1 -0
  114. package/lib/esm/components/datatable/datatable-state-persistence.d.ts +19 -0
  115. package/lib/esm/components/datatable/datatable-state-persistence.d.ts.map +1 -0
  116. package/lib/esm/components/datatable/datatable-state-persistence.js +55 -0
  117. package/lib/esm/components/datatable/datatable-state-persistence.js.map +1 -0
  118. package/lib/esm/components/datatable/datatable-table-renderer.d.ts +2 -0
  119. package/lib/esm/components/datatable/datatable-table-renderer.d.ts.map +1 -1
  120. package/lib/esm/components/datatable/datatable-table-renderer.js +75 -16
  121. package/lib/esm/components/datatable/datatable-table-renderer.js.map +1 -1
  122. package/lib/esm/components/datatable/datatable-utils.d.ts +10 -0
  123. package/lib/esm/components/datatable/datatable-utils.d.ts.map +1 -0
  124. package/lib/esm/components/datatable/datatable-utils.js +12 -0
  125. package/lib/esm/components/datatable/datatable-utils.js.map +1 -0
  126. package/lib/esm/components/datatable/datatable.d.ts +26 -34
  127. package/lib/esm/components/datatable/datatable.d.ts.map +1 -1
  128. package/lib/esm/components/datatable/datatable.js +157 -494
  129. package/lib/esm/components/datatable/datatable.js.map +1 -1
  130. package/lib/esm/components/datatable/index.d.ts +1 -1
  131. package/lib/esm/components/datatable/index.d.ts.map +1 -1
  132. package/lib/esm/components/datatable/types.d.ts +100 -11
  133. package/lib/esm/components/datatable/types.d.ts.map +1 -1
  134. package/lib/esm/index.d.ts +1 -1
  135. package/lib/esm/index.d.ts.map +1 -1
  136. package/lib/esm/index.js +6 -0
  137. package/lib/esm/index.js.map +1 -1
  138. package/package.json +5 -1
  139. package/skills/ktui/SKILL.md +711 -0
  140. package/skills/ktui-datatable/SKILL.md +302 -0
  141. package/skills/ktui-install/SKILL.md +150 -0
  142. package/skills/ktui-select/SKILL.md +271 -0
  143. package/src/components/__tests__/component.test.ts +347 -0
  144. package/src/components/collapse/collapse.css +2 -2
  145. package/src/components/datatable/__tests__/architecture-boundaries.test.ts +56 -8
  146. package/src/components/datatable/__tests__/currency-sort.test.ts +25 -28
  147. package/src/components/datatable/__tests__/datatable-checkbox.test.ts +527 -0
  148. package/src/components/datatable/__tests__/datatable-column-utils.test.ts +117 -0
  149. package/src/components/datatable/__tests__/datatable-defaults.test.ts +57 -0
  150. package/src/components/datatable/__tests__/datatable-finalize-extended.test.ts +361 -0
  151. package/src/components/datatable/__tests__/datatable-fixed-layout.test.ts +427 -0
  152. package/src/components/datatable/__tests__/datatable-improvements.test.ts +484 -0
  153. package/src/components/datatable/__tests__/datatable-pagination-extended.test.ts +508 -0
  154. package/src/components/datatable/__tests__/datatable-public-api.test.ts +269 -0
  155. package/src/components/datatable/__tests__/datatable-registry.test.ts +172 -0
  156. package/src/components/datatable/__tests__/datatable-remote-provider.test.ts +468 -0
  157. package/src/components/datatable/__tests__/datatable-search-handler.test.ts +124 -0
  158. package/src/components/datatable/__tests__/datatable-sort-extended.test.ts +417 -0
  159. package/src/components/datatable/__tests__/datatable-spinner.test.ts +95 -0
  160. package/src/components/datatable/__tests__/datatable-table-renderer-extended.test.ts +425 -0
  161. package/src/components/datatable/__tests__/datatable-types.test.ts +117 -0
  162. package/src/components/datatable/__tests__/datatable-utils.test.ts +52 -0
  163. package/src/components/datatable/__tests__/multi-row-headers.test.ts +7 -7
  164. package/src/components/datatable/__tests__/pagination-reset.test.ts +129 -6
  165. package/src/components/datatable/__tests__/race-conditions.test.ts +11 -11
  166. package/src/components/datatable/__tests__/setup.ts +12 -4
  167. package/src/components/datatable/datatable-checkbox.ts +144 -145
  168. package/src/components/datatable/datatable-column-utils.ts +63 -0
  169. package/src/components/datatable/datatable-contracts.ts +2 -3
  170. package/src/components/datatable/datatable-defaults.ts +204 -0
  171. package/src/components/datatable/datatable-layout-plugin.ts +11 -1
  172. package/src/components/datatable/datatable-local-provider.ts +91 -28
  173. package/src/components/datatable/datatable-pagination-renderer.ts +3 -2
  174. package/src/components/datatable/datatable-registry.ts +89 -0
  175. package/src/components/datatable/datatable-remote-provider.ts +1 -3
  176. package/src/components/datatable/datatable-search-handler.ts +97 -0
  177. package/src/components/datatable/datatable-sort.ts +111 -66
  178. package/src/components/datatable/datatable-spinner.ts +103 -0
  179. package/src/components/datatable/datatable-state-persistence.ts +67 -0
  180. package/src/components/datatable/datatable-table-renderer.ts +81 -18
  181. package/src/components/datatable/datatable-utils.ts +12 -0
  182. package/src/components/datatable/datatable.ts +191 -580
  183. package/src/components/datatable/index.ts +3 -0
  184. package/src/components/datatable/types.ts +124 -23
  185. package/src/helpers/__tests__/dom.test.ts +776 -0
  186. package/src/helpers/__tests__/utils.test.ts +332 -0
  187. package/src/index.ts +10 -0
  188. package/skills/ktui-components/SKILL.md +0 -41
  189. package/skills/ktui-theming/SKILL.md +0 -50
  190. package/src/components/datatable/datatable-event-adapter.ts +0 -21
@@ -64,19 +64,33 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
64
64
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
65
65
  }
66
66
  };
67
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
68
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
69
+ if (ar || !(i in from)) {
70
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
71
+ ar[i] = from[i];
72
+ }
73
+ }
74
+ return to.concat(ar || Array.prototype.slice.call(from));
75
+ };
67
76
  import KTComponent from '../component';
68
- import KTComponents from '../../index';
69
77
  import KTData from '../../helpers/data';
70
- import { createCheckboxHandler, } from './datatable-checkbox';
71
- import { createSortHandler } from './datatable-sort';
78
+ import { KTDataTableCheckboxHandler, } from './datatable-checkbox';
79
+ import { KTDataTableSortHandler } from './datatable-sort';
72
80
  import { createStickyLayoutPlugin } from './datatable-layout-plugin';
73
- import { createDataTableEventAdapter } from './datatable-event-adapter';
81
+ import { DATATABLE_DEFAULTS, DEFAULT_PAGE_SIZES, DEFAULT_SEARCH_DELAY } from './datatable-defaults';
82
+ import { getLogicalColumnCount } from './datatable-column-utils';
74
83
  import { KTDataTableLocalDataProvider } from './datatable-local-provider';
75
84
  import { KTDataTableRemoteDataProvider } from './datatable-remote-provider';
76
85
  import { KTDataTableConfigStateStore } from './datatable-state-store';
77
86
  import { KTDataTableDomPaginationRenderer } from './datatable-pagination-renderer';
78
87
  import { KTDataTableDomTableRenderer } from './datatable-table-renderer';
79
88
  import KTUtils from '../../helpers/utils';
89
+ import { createSearchHandler } from './datatable-search-handler';
90
+ import { createStatePersistence, resolveTableNamespace, } from './datatable-state-persistence';
91
+ import { createSpinner } from './datatable-spinner';
92
+ import { createDataTableRegistry } from './datatable-registry';
93
+ import { stripHtml } from './datatable-utils';
80
94
  /**
81
95
  * Custom DataTable plugin class with server-side API, pagination, and sorting
82
96
  * @classdesc A custom KTComponent class that integrates server-side API, pagination, and sorting functionality into a table.
@@ -86,21 +100,27 @@ import KTUtils from '../../helpers/utils';
86
100
  * @param {HTMLElement} element The table element
87
101
  * @param {KTDataTableConfigInterface} [config] Additional configuration options
88
102
  */
103
+ var datatableRegistry = createDataTableRegistry();
89
104
  var KTDataTable = /** @class */ (function (_super) {
90
105
  __extends(KTDataTable, _super);
91
106
  function KTDataTable(element, config) {
92
107
  var _this = _super.call(this) || this;
93
108
  _this._name = 'datatable';
94
- _this._originalTbodyClass = ''; // Store original tbody class
95
- _this._originalTrClasses = []; // Store original tr classes
96
- _this._originalTheadClass = ''; // Store original thead class
97
- _this._originalTdClasses = []; // Store original td classes as a 2D array [row][col]
98
- _this._originalThClasses = []; // Store original th classes
109
+ _this._originalClasses = {
110
+ tbody: '',
111
+ thead: '',
112
+ tr: [],
113
+ td: [],
114
+ th: [],
115
+ };
99
116
  _this._infoElement = null;
100
117
  _this._sizeElement = null;
101
118
  _this._paginationElement = null;
102
119
  _this._layoutPlugin = null;
103
120
  _this._cleanupCallbacks = [];
121
+ _this._searchHandler = createSearchHandler();
122
+ _this._statePersistence = createStatePersistence();
123
+ _this._spinner = createSpinner();
104
124
  _this._data = [];
105
125
  _this._isFetching = false;
106
126
  if (KTData.has(element, _this._name)) {
@@ -122,23 +142,39 @@ var KTDataTable = /** @class */ (function (_super) {
122
142
  _this._buildConfig();
123
143
  _this._normalizePageSizeConfig();
124
144
  _this._stateStore = new KTDataTableConfigStateStore(_this._config);
125
- _this._eventAdapter = createDataTableEventAdapter(_this._fireEvent.bind(_this), _this._dispatchEvent.bind(_this));
145
+ _this._eventAdapter = {
146
+ emit: function (eventName, eventData) {
147
+ _this._emit(eventName, eventData);
148
+ },
149
+ };
126
150
  // Store the instance directly on the element
127
- KTDataTable.asElementWithInstance(element).instance = _this;
151
+ datatableRegistry.register(element, _this);
128
152
  _this._initElements();
129
153
  _this._layoutPlugin = _this._createLayoutPlugin();
130
154
  _this._tableRenderer = new KTDataTableDomTableRenderer();
131
155
  _this._paginationRenderer = new KTDataTableDomPaginationRenderer();
132
156
  _this._initDataProviders();
133
157
  // Initialize checkbox handler
134
- _this._checkbox = createCheckboxHandler(_this._element, _this._config, _this._emit.bind(_this));
158
+ _this._checkbox = new KTDataTableCheckboxHandler(_this._element, _this._config, _this._emit.bind(_this), {
159
+ getState: function () { return _this._stateStore.getState(); },
160
+ setSelectedRows: function (rows) {
161
+ _this._stateStore.patchState({ selectedRows: rows });
162
+ },
163
+ });
135
164
  // Initialize sort handler
136
- _this._sortHandler = createSortHandler(_this._config, _this._theadElement, function () { return ({
137
- sortField: _this.getState().sortField,
138
- sortOrder: _this.getState().sortOrder,
139
- }); }, function (field, order) {
140
- _this._stateStore.setSort(field, order);
141
- }, _this._fireEvent.bind(_this), _this._dispatchEvent.bind(_this), _this._updateData.bind(_this));
165
+ _this._sortHandler = new KTDataTableSortHandler({
166
+ config: _this._config,
167
+ theadElement: _this._theadElement,
168
+ getState: function () { return ({
169
+ sortField: _this.getState().sortField,
170
+ sortOrder: _this.getState().sortOrder,
171
+ }); },
172
+ setState: function (field, order) {
173
+ _this._stateStore.setSort(field, order);
174
+ },
175
+ emit: _this._emit.bind(_this),
176
+ updateData: _this._updateData.bind(_this),
177
+ });
142
178
  _this._sortHandler.initSort();
143
179
  if (_this._config.stateSave === false) {
144
180
  _this._deleteState();
@@ -148,17 +184,11 @@ var KTDataTable = /** @class */ (function (_super) {
148
184
  _this._normalizePageState();
149
185
  }
150
186
  _this._updateData();
151
- _this._emit('init');
152
187
  return _this;
153
188
  }
154
- KTDataTable.asElementWithInstance = function (element) {
155
- return element;
156
- };
157
- KTDataTable.asSearchElementWithDebounce = function (element) {
158
- return element;
159
- };
160
189
  KTDataTable.prototype._emit = function (eventName, eventData) {
161
- this._eventAdapter.emit(eventName, eventData);
190
+ this._fireEvent(eventName, eventData);
191
+ this._dispatchEvent("kt.datatable.".concat(eventName), eventData);
162
192
  };
163
193
  KTDataTable.prototype._initDataProviders = function () {
164
194
  var _this = this;
@@ -207,7 +237,7 @@ var KTDataTable = /** @class */ (function (_super) {
207
237
  .map(function (size) { return Number(size); })
208
238
  .filter(function (size) { return Number.isFinite(size) && size > 0; })
209
239
  .map(function (size) { return Math.floor(size); });
210
- var fallbackPageSizes = [5, 10, 20, 30, 50];
240
+ var fallbackPageSizes = __spreadArray([], DEFAULT_PAGE_SIZES, true);
211
241
  this._config.pageSizes =
212
242
  pageSizes.length > 0 ? Array.from(new Set(pageSizes)) : fallbackPageSizes;
213
243
  var configuredPageSize = Number(this._config.pageSize);
@@ -240,201 +270,37 @@ var KTDataTable = /** @class */ (function (_super) {
240
270
  * @param config User-provided configuration options
241
271
  * @returns Default configuration merged with user-provided options
242
272
  */
273
+ KTDataTable.prototype._createDefaultSearchCallback = function () {
274
+ return (function (data, search) {
275
+ if (!data || !search) {
276
+ return [];
277
+ }
278
+ var searchLower = search.toLowerCase();
279
+ return data.filter(function (item) {
280
+ if (!item) {
281
+ return false;
282
+ }
283
+ return Object.values(item).some(function (value) {
284
+ if (typeof value !== 'string' &&
285
+ typeof value !== 'number' &&
286
+ typeof value !== 'boolean') {
287
+ return false;
288
+ }
289
+ var valueText = stripHtml(value).toLowerCase();
290
+ return valueText.includes(searchLower);
291
+ });
292
+ });
293
+ });
294
+ };
243
295
  KTDataTable.prototype._initDefaultConfig = function (config) {
244
296
  var _this = this;
245
- return __assign({
246
- /**
247
- * HTTP method for server-side API call
248
- */
249
- requestMethod: 'GET',
250
- /**
251
- * Custom HTTP headers for the API request
252
- */
253
- requestHeaders: {
254
- 'Content-Type': 'application/x-www-form-urlencoded',
255
- },
256
- /**
257
- * Pagination info template
258
- */
259
- info: '{start}-{end} of {total}',
260
- /**
261
- * Info text when there is no data
262
- */
263
- infoEmpty: 'No records found',
264
- /**
265
- * Available page sizes
266
- */
267
- pageSizes: [5, 10, 20, 30, 50],
268
- /**
269
- * Default page size
270
- */
271
- pageSize: 10,
272
- /**
273
- * Enable or disable pagination more button
274
- */
275
- pageMore: true,
276
- /**
277
- * Maximum number of pages before enabling pagination more button
278
- */
279
- pageMoreLimit: 3,
280
- /**
281
- * Pagination button templates
282
- */
283
- pagination: {
284
- number: {
285
- /**
286
- * CSS classes to be added to the pagination button
287
- */
288
- class: 'kt-datatable-pagination-button',
289
- /**
290
- * Text to be displayed in the pagination button
291
- */
292
- text: '{page}',
293
- },
294
- previous: {
295
- /**
296
- * CSS classes to be added to the previous pagination button
297
- */
298
- class: 'kt-datatable-pagination-button kt-datatable-pagination-prev',
299
- /**
300
- * Text to be displayed in the previous pagination button
301
- */
302
- 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",
303
- },
304
- next: {
305
- /**
306
- * CSS classes to be added to the next pagination button
307
- */
308
- class: 'kt-datatable-pagination-button kt-datatable-pagination-next',
309
- /**
310
- * Text to be displayed in the next pagination button
311
- */
312
- 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",
313
- },
314
- more: {
315
- /**
316
- * CSS classes to be added to the pagination more button
317
- */
318
- class: 'kt-datatable-pagination-button kt-datatable-pagination-more',
319
- /**
320
- * Text to be displayed in the pagination more button
321
- */
322
- text: '...',
323
- },
324
- },
325
- /**
326
- * Sorting options
327
- */
328
- sort: {
329
- /**
330
- * CSS classes to be added to the sortable headers
331
- */
332
- classes: {
333
- base: 'kt-table-col',
334
- asc: 'asc',
335
- desc: 'desc',
336
- },
337
- /**
338
- * Local sorting callback function
339
- * Sorts the data array based on the sort field and order
340
- * @param data Data array to be sorted
341
- * @param sortField Property name of the data object to be sorted by
342
- * @param sortOrder Sorting order (ascending or descending)
343
- * @returns Sorted data array
344
- */
345
- callback: function (data, sortField, sortOrder) {
297
+ return __assign(__assign(__assign({}, DATATABLE_DEFAULTS), {
298
+ // Per-instance state; DATATABLE_DEFAULTS._state is a shared singleton.
299
+ _state: {}, sort: __assign(__assign({}, DATATABLE_DEFAULTS.sort), { callback: function (data, sortField, sortOrder) {
346
300
  return _this._sortHandler
347
301
  ? _this._sortHandler.sortData(data, sortField, sortOrder)
348
302
  : data;
349
- },
350
- }, search: {
351
- /**
352
- * Delay in milliseconds before the search function is applied to the data array
353
- * @default 500
354
- */
355
- delay: 500, // ms
356
- /**
357
- * Local search callback function
358
- * Filters the data array based on the search string
359
- * @param data Data array to be filtered
360
- * @param search Search string used to filter the data array
361
- * @returns Filtered data array
362
- */
363
- callback: function (data, search) {
364
- if (!data || !search) {
365
- return [];
366
- }
367
- return data.filter(function (item) {
368
- if (!item) {
369
- return false;
370
- }
371
- return Object.values(item).some(function (value) {
372
- if (typeof value !== 'string' &&
373
- typeof value !== 'number' &&
374
- typeof value !== 'boolean') {
375
- return false;
376
- }
377
- var valueText = String(value)
378
- .replace(/<|>|&nbsp;/g, '')
379
- .toLowerCase();
380
- return valueText.includes(search.toLowerCase());
381
- });
382
- });
383
- },
384
- },
385
- /**
386
- * Loading spinner options
387
- */
388
- loading: {
389
- /**
390
- * Template to be displayed during data fetching process
391
- */
392
- 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",
393
- /**
394
- * Loading text to be displayed in the template
395
- */
396
- content: 'Loading...',
397
- },
398
- /**
399
- * Selectors of the elements to be targeted
400
- */
401
- attributes: {
402
- /**
403
- * Data table element
404
- */
405
- table: 'table[data-kt-datatable-table="true"]',
406
- /**
407
- * Pagination info element
408
- */
409
- info: '[data-kt-datatable-info="true"]',
410
- /**
411
- * Page size dropdown element
412
- */
413
- size: '[data-kt-datatable-size="true"]',
414
- /**
415
- * Pagination element
416
- */
417
- pagination: '[data-kt-datatable-pagination="true"]',
418
- /**
419
- * Spinner element
420
- */
421
- spinner: '[data-kt-datatable-spinner="true"]',
422
- /**
423
- * Checkbox element
424
- */
425
- check: '[data-kt-datatable-check="true"]',
426
- checkbox: '[data-kt-datatable-row-check="true"]',
427
- },
428
- /**
429
- * Enable or disable state saving
430
- */
431
- stateSave: true, checkbox: {
432
- checkedClass: 'checked',
433
- },
434
- /**
435
- * Private properties
436
- */
437
- _state: {}, loadingClass: 'loading' }, config);
303
+ } }), search: __assign(__assign({}, DATATABLE_DEFAULTS.search), { callback: this._createDefaultSearchCallback() }) }), config);
438
304
  };
439
305
  /**
440
306
  * Initialize table, tbody, thead, info, size, and pagination elements
@@ -475,24 +341,24 @@ var KTDataTable = /** @class */ (function (_super) {
475
341
  var _this = this;
476
342
  // Store tbody class
477
343
  if (this._tbodyElement) {
478
- this._originalTbodyClass = this._tbodyElement.className || '';
344
+ this._originalClasses.tbody = this._tbodyElement.className || '';
479
345
  }
480
346
  // Store thead class and th classes
481
347
  if (this._theadElement) {
482
- this._originalTheadClass = this._theadElement.className || '';
348
+ this._originalClasses.thead = this._theadElement.className || '';
483
349
  // Store th classes
484
350
  var thElements = this._theadElement.querySelectorAll('th');
485
- this._originalThClasses = Array.from(thElements).map(function (th) { return th.className || ''; });
351
+ this._originalClasses.th = Array.from(thElements).map(function (th) { return th.className || ''; });
486
352
  }
487
353
  // Store tr and td classes
488
354
  if (this._tbodyElement) {
489
355
  var originalRows = this._tbodyElement.querySelectorAll('tr');
490
- this._originalTrClasses = Array.from(originalRows).map(function (row) { return row.className || ''; });
356
+ this._originalClasses.tr = Array.from(originalRows).map(function (row) { return row.className || ''; });
491
357
  // Store td classes as a 2D array
492
- this._originalTdClasses = [];
358
+ this._originalClasses.td = [];
493
359
  Array.from(originalRows).forEach(function (row, rowIndex) {
494
360
  var tdElements = row.querySelectorAll('td');
495
- _this._originalTdClasses[rowIndex] = Array.from(tdElements).map(function (td) { return td.className || ''; });
361
+ _this._originalClasses.td[rowIndex] = Array.from(tdElements).map(function (td) { return td.className || ''; });
496
362
  });
497
363
  }
498
364
  };
@@ -512,8 +378,7 @@ var KTDataTable = /** @class */ (function (_super) {
512
378
  _b.label = 1;
513
379
  case 1:
514
380
  _b.trys.push([1, , 8, 9]);
515
- this._showSpinner(); // Show spinner before fetching data
516
- this._emit('fetch');
381
+ this._spinner.show(this._element, this._config, this._tableElement); // Show spinner before fetching data
517
382
  if (!(typeof this._config.apiEndpoint === 'undefined')) return [3 /*break*/, 2];
518
383
  _a = this._localProvider.fetchSync();
519
384
  return [3 /*break*/, 4];
@@ -529,11 +394,11 @@ var KTDataTable = /** @class */ (function (_super) {
529
394
  return [4 /*yield*/, this._draw()];
530
395
  case 5:
531
396
  _b.sent();
532
- this._emit('fetched');
533
397
  _b.label = 6;
534
398
  case 6: return [4 /*yield*/, this._finalize()];
535
399
  case 7:
536
400
  _b.sent();
401
+ this._emit('update');
537
402
  return [3 /*break*/, 9];
538
403
  case 8:
539
404
  // Finally block now correctly executes after promises resolve, not immediately
@@ -549,7 +414,8 @@ var KTDataTable = /** @class */ (function (_super) {
549
414
  * @returns {void}
550
415
  */
551
416
  KTDataTable.prototype._finalize = function () {
552
- var _a;
417
+ var _this = this;
418
+ var _a, _b, _c;
553
419
  (_a = this._element) === null || _a === void 0 ? void 0 : _a.classList.add('datatable-initialized');
554
420
  // Initialize checkbox logic
555
421
  this._checkbox.init();
@@ -557,50 +423,20 @@ var KTDataTable = /** @class */ (function (_super) {
557
423
  if (this._sortHandler) {
558
424
  this._sortHandler.initSort();
559
425
  }
560
- this._attachSearchEvent();
561
- if (typeof KTComponents !== 'undefined') {
562
- KTComponents.init();
563
- }
426
+ 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 : DEFAULT_SEARCH_DELAY, function (query) { return _this.search(query); });
564
427
  /**
565
428
  * Hide spinner
566
429
  */
567
- this._hideSpinner();
568
- };
569
- /**
570
- * Attach search event to the search input element
571
- * @returns {void}
572
- */
573
- KTDataTable.prototype._attachSearchEvent = function () {
574
- var _this = this;
575
- var _a, _b;
576
- var tableId = this._tableId();
577
- var searchElement = document.querySelector("[data-kt-datatable-search=\"#".concat(tableId, "\"]"));
578
- // Get search state
579
- var search = this.getState().search;
580
- // Set search value
581
- if (searchElement) {
582
- searchElement.value =
583
- search === undefined || search === null
584
- ? ''
585
- : typeof search === 'string'
586
- ? search
587
- : String(search);
588
- }
589
- if (searchElement) {
590
- // Check if a debounced search function already exists
591
- var searchWithDebounce = KTDataTable.asSearchElementWithDebounce(searchElement);
592
- if (searchWithDebounce._debouncedSearch) {
593
- // Remove the existing debounced event listener
594
- searchElement.removeEventListener('keyup', searchWithDebounce._debouncedSearch);
595
- }
596
- // Create a new debounced search function
597
- var debouncedSearch = this._debounce(function () {
598
- _this.search(searchElement.value);
599
- }, (_b = (_a = this._config.search) === null || _a === void 0 ? void 0 : _a.delay) !== null && _b !== void 0 ? _b : 500);
600
- // Store the new debounced function as a property of the element
601
- searchWithDebounce._debouncedSearch = debouncedSearch;
602
- // Add the new debounced event listener
603
- searchElement.addEventListener('keyup', debouncedSearch);
430
+ this._spinner.hide(this._element, this._config);
431
+ // Update content checksum AFTER all DOM modifications (checkbox init
432
+ // adds checked-class to <tr> elements which changes tbody innerHTML).
433
+ // If we save the checksum earlier (in _draw), the next fetchSync()
434
+ // sees a mismatch, re-extracts from the DOM, and loses rows that
435
+ // were on other pages — making pagination show empty.
436
+ if (!this._config.apiEndpoint) {
437
+ this._stateStore.patchState({
438
+ _contentChecksum: KTUtils.checksum(JSON.stringify(this._tbodyElement.innerHTML)),
439
+ });
604
440
  }
605
441
  };
606
442
  /**
@@ -609,17 +445,7 @@ var KTDataTable = /** @class */ (function (_super) {
609
445
  * @returns {number} Number of data columns, or 0 if unknown
610
446
  */
611
447
  KTDataTable.prototype._getLogicalColumnCount = function () {
612
- var originalData = this.getState().originalData;
613
- if (originalData && originalData.length > 0) {
614
- return Object.keys(originalData[0]).length;
615
- }
616
- if (this._tbodyElement) {
617
- var firstRow = this._tbodyElement.querySelector('tr');
618
- if (firstRow) {
619
- return firstRow.querySelectorAll('td').length;
620
- }
621
- }
622
- return 0;
448
+ return getLogicalColumnCount(this._theadElement, this._tbodyElement, this.getState().originalData);
623
449
  };
624
450
  /**
625
451
  * Creates a complete URL from a relative path or a full URL.
@@ -698,8 +524,7 @@ var KTDataTable = /** @class */ (function (_super) {
698
524
  : 1;
699
525
  this._stateStore.patchState({ totalPages: totalPages, page: page });
700
526
  (_b = (_a = this._layoutPlugin) === null || _a === void 0 ? void 0 : _a.beforeDraw) === null || _b === void 0 ? void 0 : _b.call(_a, this._getLayoutPluginContext());
701
- this._emit('draw');
702
- this._dispose();
527
+ this._cleanupForRedraw();
703
528
  // Update the table and pagination controls
704
529
  if (this._theadElement && this._tbodyElement) {
705
530
  this._updateTable();
@@ -708,12 +533,6 @@ var KTDataTable = /** @class */ (function (_super) {
708
533
  this._updatePagination();
709
534
  }
710
535
  (_d = (_c = this._layoutPlugin) === null || _c === void 0 ? void 0 : _c.afterDraw) === null || _d === void 0 ? void 0 : _d.call(_c, this._getLayoutPluginContext());
711
- if (!this._config.apiEndpoint) {
712
- this._stateStore.patchState({
713
- _contentChecksum: KTUtils.checksum(JSON.stringify(this._tbodyElement.innerHTML)),
714
- });
715
- }
716
- this._emit('drew');
717
536
  // Spinner is hidden in _finalize() to ensure it stays visible until the entire request completes
718
537
  // Removed duplicate _hideSpinner() call here to prevent premature hiding
719
538
  if (this._config.stateSave) {
@@ -734,9 +553,7 @@ var KTDataTable = /** @class */ (function (_super) {
734
553
  data: this._data,
735
554
  getLogicalColumnCount: this._getLogicalColumnCount.bind(this),
736
555
  getState: this.getState.bind(this),
737
- originalTbodyClass: this._originalTbodyClass,
738
- originalTrClasses: this._originalTrClasses,
739
- originalTdClasses: this._originalTdClasses,
556
+ originalClasses: this._originalClasses,
740
557
  tableElement: this._tableElement,
741
558
  theadElement: this._theadElement,
742
559
  });
@@ -786,87 +603,31 @@ var KTDataTable = /** @class */ (function (_super) {
786
603
  if (page < 1 || !Number.isInteger(page)) {
787
604
  return;
788
605
  }
789
- this._emit('pagination', { page: page });
790
606
  if (page >= 1 && page <= this.getState().totalPages) {
791
607
  this._stateStore.setPage(page);
792
608
  this._updateData();
793
609
  }
794
610
  };
795
- // Method to show the loading spinner
796
- KTDataTable.prototype._showSpinner = function () {
797
- var _a, _b;
798
- var root = this._element;
799
- var spinnerSel = (_a = this._config.attributes) === null || _a === void 0 ? void 0 : _a.spinner;
800
- var fromDom = root && spinnerSel ? root.querySelector(spinnerSel) : null;
801
- var spinner = fromDom !== null && fromDom !== void 0 ? fromDom : this._createSpinner();
802
- if (spinner) {
803
- spinner.style.display = 'block';
804
- }
805
- root === null || root === void 0 ? void 0 : root.classList.add((_b = this._config.loadingClass) !== null && _b !== void 0 ? _b : 'loading');
806
- };
807
- // Method to hide the loading spinner
808
- KTDataTable.prototype._hideSpinner = function () {
809
- var _a, _b;
810
- var root = this._element;
811
- var spinnerSel = (_a = this._config.attributes) === null || _a === void 0 ? void 0 : _a.spinner;
812
- var spinner = root && spinnerSel ? root.querySelector(spinnerSel) : null;
813
- if (spinner) {
814
- spinner.style.display = 'none';
815
- }
816
- root === null || root === void 0 ? void 0 : root.classList.remove((_b = this._config.loadingClass) !== null && _b !== void 0 ? _b : 'loading');
817
- };
818
- // Method to create a spinner element if it doesn't exist
819
- KTDataTable.prototype._createSpinner = function () {
820
- var loading = this._config.loading;
821
- if (!loading) {
822
- return null;
823
- }
824
- var template = document.createElement('template');
825
- template.innerHTML = loading.template
826
- .trim()
827
- .replace('{content}', loading.content);
828
- var first = template.content.firstChild;
829
- if (!first || !(first instanceof HTMLElement)) {
830
- return null;
831
- }
832
- var spinner = first;
833
- spinner.setAttribute('data-kt-datatable-spinner', 'true');
834
- this._tableElement.appendChild(spinner);
835
- return spinner;
836
- };
837
611
  /**
838
612
  * Saves the current state of the table to local storage.
839
613
  * @returns {void}
840
614
  */
841
615
  KTDataTable.prototype._saveState = function () {
842
- this._emit('stateSave');
843
- var ns = this._tableNamespace();
844
- if (ns) {
845
- localStorage.setItem(ns, JSON.stringify(this.getState()));
846
- }
616
+ this._statePersistence.save(this._tableNamespace(), this.getState());
847
617
  };
848
618
  /**
849
619
  * Loads the saved state of the table from local storage, if it exists.
850
620
  * @returns {Object} The saved state of the table, or null if no saved state exists.
851
621
  */
852
622
  KTDataTable.prototype._loadState = function () {
853
- var stateString = localStorage.getItem(this._tableNamespace());
854
- if (!stateString)
855
- return null;
856
- try {
857
- var state = JSON.parse(stateString);
858
- if (state)
859
- this._stateStore.replaceState(state);
860
- return state;
861
- }
862
- catch (_a) { }
863
- return null;
623
+ var ns = this._tableNamespace();
624
+ var saved = this._statePersistence.load(ns);
625
+ if (saved)
626
+ this._stateStore.replaceState(saved);
627
+ return saved;
864
628
  };
865
629
  KTDataTable.prototype._deleteState = function () {
866
- var ns = this._tableNamespace();
867
- if (ns) {
868
- localStorage.removeItem(ns);
869
- }
630
+ this._statePersistence.remove(this._tableNamespace());
870
631
  };
871
632
  /**
872
633
  * Gets the namespace for the table's state.
@@ -877,13 +638,7 @@ var KTDataTable = /** @class */ (function (_super) {
877
638
  * @returns {string} The namespace for the table's state.
878
639
  */
879
640
  KTDataTable.prototype._tableNamespace = function () {
880
- var _a;
881
- // Use the specified namespace, if one is given
882
- if (this._config.stateNamespace) {
883
- return this._config.stateNamespace;
884
- }
885
- // Fallback to the component's UID
886
- return (_a = this._tableId()) !== null && _a !== void 0 ? _a : this._name;
641
+ return resolveTableNamespace(this._config, this._tableElement, this._element, this._name);
887
642
  };
888
643
  KTDataTable.prototype._tableId = function () {
889
644
  var _a, _b;
@@ -901,91 +656,43 @@ var KTDataTable = /** @class */ (function (_super) {
901
656
  * Clean up all event listeners, handlers, and DOM nodes created by this instance.
902
657
  * This method is called before re-rendering or when disposing the component.
903
658
  */
904
- KTDataTable.prototype._dispose = function () {
905
- var _a, _b, _c, _d, _e;
659
+ /**
660
+ * Clean up event listeners and DOM artifacts for a redraw cycle.
661
+ * Does NOT remove the instance from the registry — the datatable
662
+ * remains accessible via getInstance() during the redraw window.
663
+ */
664
+ KTDataTable.prototype._cleanupForRedraw = function () {
665
+ var _a, _b;
906
666
  (_b = (_a = this._layoutPlugin) === null || _a === void 0 ? void 0 : _a.dispose) === null || _b === void 0 ? void 0 : _b.call(_a, this._getLayoutPluginContext());
907
- var root = this._element;
908
- if (!root) {
667
+ if (!this._element) {
909
668
  return;
910
669
  }
911
670
  this._cleanupCallbacks.forEach(function (cleanup) { return cleanup(); });
912
671
  this._cleanupCallbacks = [];
913
- // --- 1. Remove search input event listener (debounced) ---
914
- var tableId = this._tableId();
915
- var searchElement = document.querySelector("[data-kt-datatable-search=\"#".concat(tableId, "\"]"));
916
- if (searchElement) {
917
- var searchWithDebounce = KTDataTable.asSearchElementWithDebounce(searchElement);
918
- if (searchWithDebounce._debouncedSearch) {
919
- searchElement.removeEventListener('keyup', searchWithDebounce._debouncedSearch);
920
- delete searchWithDebounce._debouncedSearch;
921
- }
922
- }
923
- // --- 2. Remove page size dropdown event listener ---
672
+ this._searchHandler.detach(this._tableId());
924
673
  if (this._sizeElement && this._sizeElement.onchange) {
925
674
  this._sizeElement.onchange = null;
926
675
  }
927
- // --- 3. Remove all pagination button event listeners ---
928
676
  if (this._paginationElement) {
929
- // Remove all child nodes (buttons) to ensure no lingering listeners
930
677
  while (this._paginationElement.firstChild) {
931
678
  this._paginationElement.removeChild(this._paginationElement.firstChild);
932
679
  }
933
680
  }
934
- // --- 4. Dispose of handler objects (checkbox, sort) ---
935
- // KTDataTableCheckboxAPI does not have a dispose method, but we can remove header checkbox listener
936
- var checkboxWithDispose = this._checkbox;
937
- if (this._checkbox && typeof checkboxWithDispose.dispose === 'function') {
938
- checkboxWithDispose.dispose();
939
- }
940
- else {
941
- var checkSel = (_c = this._config.attributes) === null || _c === void 0 ? void 0 : _c.check;
942
- if (checkSel) {
943
- var headerCheckElement = root.querySelector(checkSel);
944
- if (headerCheckElement) {
945
- headerCheckElement.replaceWith(headerCheckElement.cloneNode(true));
946
- }
947
- }
948
- }
949
- // KTDataTableSortAPI does not have a dispose method, but we can remove th click listeners by replacing them
950
- if (this._theadElement) {
951
- var ths = this._theadElement.querySelectorAll('th');
952
- ths.forEach(function (th) {
953
- th.replaceWith(th.cloneNode(true));
954
- });
955
- }
956
- // --- 5. Remove spinner DOM node if it exists ---
957
- var spinnerSel = (_d = this._config.attributes) === null || _d === void 0 ? void 0 : _d.spinner;
958
- if (spinnerSel) {
959
- var spinner = root.querySelector(spinnerSel);
960
- if (spinner === null || spinner === void 0 ? void 0 : spinner.parentNode) {
961
- spinner.parentNode.removeChild(spinner);
962
- }
963
- }
964
- root.classList.remove((_e = this._config.loadingClass) !== null && _e !== void 0 ? _e : 'loading');
965
- // --- 6. Remove instance reference from the DOM element ---
966
- var elementWithInstance = KTDataTable.asElementWithInstance(root);
967
- if (elementWithInstance.instance) {
968
- delete elementWithInstance.instance;
969
- }
970
- KTData.remove(root, this._name);
971
- // --- 7. (Optional) Clear localStorage state ---
972
- // Uncomment the following line if you want to clear state on dispose:
973
- // this._deleteState();
681
+ this._checkbox.dispose();
682
+ this._sortHandler.dispose();
683
+ this._spinner.remove(this._element, this._config);
974
684
  };
975
- KTDataTable.prototype._debounce = function (func, wait) {
976
- var timeout;
977
- return function () {
978
- var args = [];
979
- for (var _i = 0; _i < arguments.length; _i++) {
980
- args[_i] = arguments[_i];
981
- }
982
- var later = function () {
983
- clearTimeout(timeout);
984
- func.apply(void 0, args);
985
- };
986
- clearTimeout(timeout);
987
- timeout = window.setTimeout(later, wait);
988
- };
685
+ /**
686
+ * Full disposal — cleans up listeners AND removes the instance from
687
+ * the registry. Only called when the component is being destroyed.
688
+ */
689
+ KTDataTable.prototype._dispose = function () {
690
+ this._cleanupForRedraw();
691
+ var root = this._element;
692
+ if (root) {
693
+ datatableRegistry.remove(root);
694
+ KTData.remove(root, this._name);
695
+ }
989
696
  };
990
697
  /**
991
698
  * Gets the current state of the table.
@@ -996,12 +703,14 @@ var KTDataTable = /** @class */ (function (_super) {
996
703
  };
997
704
  /**
998
705
  * Sorts the data in the table by the specified field.
706
+ * When `order` is provided, applies that sort direction instead of toggling.
999
707
  * @param field The field to sort by.
708
+ * @param order Optional sort direction (`asc`, `desc`, or `''` to clear).
1000
709
  */
1001
- KTDataTable.prototype.sort = function (field) {
1002
- // Use the sort handler to update state and trigger sorting
1003
- var state = this.getState();
1004
- var sortOrder = this._sortHandler.toggleSortOrder(state.sortField, state.sortOrder, field);
710
+ KTDataTable.prototype.sort = function (field, order) {
711
+ var sortOrder = order !== undefined
712
+ ? order
713
+ : this._sortHandler.toggleSortOrder(this.getState().sortField, this.getState().sortOrder, field);
1005
714
  this._sortHandler.setSortIcon(field, sortOrder);
1006
715
  this._stateStore.setSort(field, sortOrder);
1007
716
  this._emit('sort', { field: field, order: sortOrder });
@@ -1033,36 +742,28 @@ var KTDataTable = /** @class */ (function (_super) {
1033
742
  this._reloadPageSize(pageSize);
1034
743
  };
1035
744
  /**
1036
- * Reloads the data from the server and updates the table.
1037
- * Triggers the 'reload' event and the 'kt.datatable.reload' custom event.
745
+ * Reloads the data from the source (API or DOM) and redraws the table.
746
+ * @returns {Promise<void>}
1038
747
  */
1039
748
  KTDataTable.prototype.reload = function () {
1040
- this._emit('reload');
1041
749
  // Fetch the data from the server using the current sort and filter settings
1042
750
  this._updateData();
1043
751
  };
1044
752
  KTDataTable.prototype.redraw = function (page) {
1045
753
  if (page === void 0) { page = 1; }
1046
- this._emit('redraw');
1047
754
  this._paginateData(page);
1048
755
  };
1049
756
  /**
1050
757
  * Show the loading spinner of the data table.
1051
758
  */
1052
759
  KTDataTable.prototype.showSpinner = function () {
1053
- /**
1054
- * Show the loading spinner of the data table.
1055
- */
1056
- this._showSpinner();
760
+ this._spinner.show(this._element, this._config, this._tableElement);
1057
761
  };
1058
762
  /**
1059
763
  * Hide the loading spinner of the data table.
1060
764
  */
1061
765
  KTDataTable.prototype.hideSpinner = function () {
1062
- /**
1063
- * Hide the loading spinner of the data table.
1064
- */
1065
- this._hideSpinner();
766
+ this._spinner.hide(this._element, this._config);
1066
767
  };
1067
768
  /**
1068
769
  * Filter data using the specified filter object.
@@ -1089,21 +790,7 @@ var KTDataTable = /** @class */ (function (_super) {
1089
790
  * This function is now browser-guarded and must be called explicitly.
1090
791
  */
1091
792
  KTDataTable.createInstances = function () {
1092
- var _this = this;
1093
- if (typeof document === 'undefined')
1094
- return;
1095
- var elements = document.querySelectorAll('[data-kt-datatable="true"]');
1096
- elements.forEach(function (element) {
1097
- if (element.hasAttribute('data-kt-datatable') &&
1098
- !element.classList.contains('datatable-initialized')) {
1099
- /**
1100
- * Create an instance of KTDataTable for the given element
1101
- * @param element The element to create an instance for
1102
- */
1103
- var instance = new KTDataTable(element);
1104
- _this._instances.set(element, instance);
1105
- }
1106
- });
793
+ datatableRegistry.createAll(function (el) { return new KTDataTable(el); });
1107
794
  };
1108
795
  /**
1109
796
  * Get the KTDataTable instance for a given element.
@@ -1112,21 +799,13 @@ var KTDataTable = /** @class */ (function (_super) {
1112
799
  * @returns The KTDataTable instance or undefined if not found
1113
800
  */
1114
801
  KTDataTable.getInstance = function (element) {
1115
- // First check the static Map (for instances created via createInstances)
1116
- var instanceFromMap = this._instances.get(element);
1117
- if (instanceFromMap) {
1118
- return instanceFromMap;
1119
- }
1120
- // Fallback to element's instance property (for manually created instances)
1121
- return KTDataTable.asElementWithInstance(element).instance;
802
+ return datatableRegistry.get(element);
1122
803
  };
1123
804
  /**
1124
805
  * Initializes all KTDataTable instances on the page.
1125
806
  * This function is now browser-guarded and must be called explicitly.
1126
807
  */
1127
808
  KTDataTable.init = function () {
1128
- if (typeof document === 'undefined')
1129
- return;
1130
809
  KTDataTable.createInstances();
1131
810
  };
1132
811
  /**
@@ -1134,25 +813,7 @@ var KTDataTable = /** @class */ (function (_super) {
1134
813
  * Useful for Livewire wire:navigate where the DOM is replaced and new tables need to be initialized.
1135
814
  */
1136
815
  KTDataTable.reinit = function () {
1137
- if (typeof document === 'undefined')
1138
- return;
1139
- var elements = document.querySelectorAll('[data-kt-datatable="true"]');
1140
- elements.forEach(function (element) {
1141
- try {
1142
- var instance = KTDataTable.getInstance(element);
1143
- if (instance && typeof instance.dispose === 'function') {
1144
- instance.dispose();
1145
- }
1146
- KTData.remove(element, 'datatable');
1147
- element.removeAttribute('data-kt-datatable-initialized');
1148
- element.classList.remove('datatable-initialized');
1149
- }
1150
- catch (_a) {
1151
- // ignore per-element errors
1152
- }
1153
- });
1154
- KTDataTable._instances.clear();
1155
- KTDataTable.createInstances();
816
+ datatableRegistry.reinit(function (el) { return new KTDataTable(el); });
1156
817
  };
1157
818
  /**
1158
819
  * Check if all visible rows are checked (header checkbox state)
@@ -1192,16 +853,18 @@ var KTDataTable = /** @class */ (function (_super) {
1192
853
  return this._checkbox.getChecked();
1193
854
  };
1194
855
  /**
1195
- * Reapply checked state to visible checkboxes (after redraw/pagination)
856
+ * Re-apply checkbox checked states to visible rows after a redraw or pagination change.
1196
857
  * @returns {void}
1197
858
  */
1198
- KTDataTable.prototype.update = function () {
859
+ KTDataTable.prototype.refreshCheckboxes = function () {
1199
860
  this._checkbox.updateState();
1200
861
  };
1201
862
  /**
1202
- * Static variables
863
+ * @deprecated Use {@link refreshCheckboxes} instead.
1203
864
  */
1204
- KTDataTable._instances = new Map();
865
+ KTDataTable.prototype.update = function () {
866
+ this.refreshCheckboxes();
867
+ };
1205
868
  return KTDataTable;
1206
869
  }(KTComponent));
1207
870
  export { KTDataTable };