@keenthemes/ktui 1.0.19 → 1.0.20

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 (42) hide show
  1. package/dist/ktui.js +277 -27
  2. package/dist/ktui.min.js +1 -1
  3. package/dist/ktui.min.js.map +1 -1
  4. package/dist/styles.css +27 -1
  5. package/lib/cjs/components/component.js +57 -5
  6. package/lib/cjs/components/component.js.map +1 -1
  7. package/lib/cjs/components/datatable/datatable.js +71 -10
  8. package/lib/cjs/components/datatable/datatable.js.map +1 -1
  9. package/lib/cjs/components/select/config.js +1 -0
  10. package/lib/cjs/components/select/config.js.map +1 -1
  11. package/lib/cjs/components/select/search.js +8 -0
  12. package/lib/cjs/components/select/search.js.map +1 -1
  13. package/lib/cjs/components/select/select.js +75 -0
  14. package/lib/cjs/components/select/select.js.map +1 -1
  15. package/lib/cjs/components/select/templates.js +6 -0
  16. package/lib/cjs/components/select/templates.js.map +1 -1
  17. package/lib/cjs/components/stepper/stepper.js +59 -12
  18. package/lib/cjs/components/stepper/stepper.js.map +1 -1
  19. package/lib/esm/components/component.js +57 -5
  20. package/lib/esm/components/component.js.map +1 -1
  21. package/lib/esm/components/datatable/datatable.js +70 -10
  22. package/lib/esm/components/datatable/datatable.js.map +1 -1
  23. package/lib/esm/components/select/config.js +1 -0
  24. package/lib/esm/components/select/config.js.map +1 -1
  25. package/lib/esm/components/select/search.js +8 -0
  26. package/lib/esm/components/select/search.js.map +1 -1
  27. package/lib/esm/components/select/select.js +75 -0
  28. package/lib/esm/components/select/select.js.map +1 -1
  29. package/lib/esm/components/select/templates.js +6 -0
  30. package/lib/esm/components/select/templates.js.map +1 -1
  31. package/lib/esm/components/stepper/stepper.js +59 -12
  32. package/lib/esm/components/stepper/stepper.js.map +1 -1
  33. package/package.json +2 -2
  34. package/src/components/component.ts +18 -4
  35. package/src/components/datatable/datatable.ts +86 -12
  36. package/src/components/datatable/types.ts +5 -1
  37. package/src/components/select/config.ts +2 -0
  38. package/src/components/select/search.ts +9 -0
  39. package/src/components/select/select.css +14 -6
  40. package/src/components/select/select.ts +102 -0
  41. package/src/components/select/templates.ts +13 -0
  42. package/src/components/stepper/stepper.ts +2 -2
package/dist/ktui.js CHANGED
@@ -568,6 +568,42 @@ var __extends = (this && this.__extends) || (function () {
568
568
  d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
569
569
  };
570
570
  })();
571
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
572
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
573
+ return new (P || (P = Promise))(function (resolve, reject) {
574
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
575
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
576
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
577
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
578
+ });
579
+ };
580
+ var __generator = (this && this.__generator) || function (thisArg, body) {
581
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
582
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
583
+ function verb(n) { return function (v) { return step([n, v]); }; }
584
+ function step(op) {
585
+ if (f) throw new TypeError("Generator is already executing.");
586
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
587
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
588
+ if (y = 0, t) op = [op[0] & 2, t.value];
589
+ switch (op[0]) {
590
+ case 0: case 1: t = op; break;
591
+ case 4: _.label++; return { value: op[1], done: false };
592
+ case 5: _.label++; y = op[1]; op = [0]; continue;
593
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
594
+ default:
595
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
596
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
597
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
598
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
599
+ if (t[2]) _.ops.pop();
600
+ _.trys.pop(); continue;
601
+ }
602
+ op = body.call(thisArg, _);
603
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
604
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
605
+ }
606
+ };
571
607
  Object.defineProperty(exports, "__esModule", ({ value: true }));
572
608
  exports.KTStepper = void 0;
573
609
  var data_1 = __webpack_require__(8716);
@@ -677,18 +713,29 @@ var KTStepper = /** @class */ (function (_super) {
677
713
  return elements;
678
714
  };
679
715
  KTStepper.prototype._go = function (step) {
680
- if (step === this._activeStep || step > this._getTotalSteps() || step < 0)
681
- return;
682
- var payload = { step: step, cancel: false };
683
- this._fireEvent('change', payload);
684
- this._dispatchEvent('change', payload);
685
- if (payload.cancel === true) {
686
- return;
687
- }
688
- this._activeStep = step;
689
- this._update();
690
- this._fireEvent('changed');
691
- this._dispatchEvent('changed');
716
+ return __awaiter(this, void 0, void 0, function () {
717
+ var payload;
718
+ return __generator(this, function (_a) {
719
+ switch (_a.label) {
720
+ case 0:
721
+ if (step === this._activeStep || step > this._getTotalSteps() || step < 0)
722
+ return [2 /*return*/];
723
+ payload = { step: step, cancel: false };
724
+ return [4 /*yield*/, this._fireEvent('change', payload)];
725
+ case 1:
726
+ _a.sent();
727
+ this._dispatchEvent('change', payload);
728
+ if (payload.cancel === true) {
729
+ return [2 /*return*/];
730
+ }
731
+ this._activeStep = step;
732
+ this._update();
733
+ this._fireEvent('changed');
734
+ this._dispatchEvent('changed');
735
+ return [2 /*return*/];
736
+ }
737
+ });
738
+ });
692
739
  };
693
740
  KTStepper.prototype._goTo = function (itemElement) {
694
741
  var step = this._getStep(itemElement);
@@ -2395,6 +2442,42 @@ var __assign = (this && this.__assign) || function () {
2395
2442
  };
2396
2443
  return __assign.apply(this, arguments);
2397
2444
  };
2445
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2446
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
2447
+ return new (P || (P = Promise))(function (resolve, reject) {
2448
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
2449
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
2450
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
2451
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
2452
+ });
2453
+ };
2454
+ var __generator = (this && this.__generator) || function (thisArg, body) {
2455
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
2456
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
2457
+ function verb(n) { return function (v) { return step([n, v]); }; }
2458
+ function step(op) {
2459
+ if (f) throw new TypeError("Generator is already executing.");
2460
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
2461
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
2462
+ if (y = 0, t) op = [op[0] & 2, t.value];
2463
+ switch (op[0]) {
2464
+ case 0: case 1: t = op; break;
2465
+ case 4: _.label++; return { value: op[1], done: false };
2466
+ case 5: _.label++; y = op[1]; op = [0]; continue;
2467
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
2468
+ default:
2469
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
2470
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
2471
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
2472
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
2473
+ if (t[2]) _.ops.pop();
2474
+ _.trys.pop(); continue;
2475
+ }
2476
+ op = body.call(thisArg, _);
2477
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
2478
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
2479
+ }
2480
+ };
2398
2481
  Object.defineProperty(exports, "__esModule", ({ value: true }));
2399
2482
  var data_1 = __webpack_require__(8716);
2400
2483
  var dom_1 = __webpack_require__(9010);
@@ -2416,11 +2499,27 @@ var KTComponent = /** @class */ (function () {
2416
2499
  this._element.setAttribute("data-kt-".concat(this._name, "-initialized"), 'true');
2417
2500
  data_1.default.set(this._element, this._name, this);
2418
2501
  };
2419
- KTComponent.prototype._fireEvent = function (eventType, payload) {
2420
- var _a;
2421
- if (payload === void 0) { payload = null; }
2422
- (_a = this._events.get(eventType)) === null || _a === void 0 ? void 0 : _a.forEach(function (callable) {
2423
- callable(payload);
2502
+ KTComponent.prototype._fireEvent = function (eventType_1) {
2503
+ return __awaiter(this, arguments, void 0, function (eventType, payload) {
2504
+ var callbacks;
2505
+ if (payload === void 0) { payload = null; }
2506
+ return __generator(this, function (_a) {
2507
+ switch (_a.label) {
2508
+ case 0:
2509
+ callbacks = this._events.get(eventType);
2510
+ if ((callbacks instanceof Map) == false) {
2511
+ return [2 /*return*/];
2512
+ }
2513
+ return [4 /*yield*/, Promise.all(Array.from(callbacks.values()).filter(function (callable) {
2514
+ return typeof callable === 'function';
2515
+ }).map(function (callable) {
2516
+ return Promise.resolve(callable(payload));
2517
+ }))];
2518
+ case 1:
2519
+ _a.sent();
2520
+ return [2 /*return*/];
2521
+ }
2522
+ });
2424
2523
  });
2425
2524
  };
2426
2525
  KTComponent.prototype._dispatchEvent = function (eventType, payload) {
@@ -7587,6 +7686,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
7587
7686
  };
7588
7687
  Object.defineProperty(exports, "__esModule", ({ value: true }));
7589
7688
  exports.KTDataTable = void 0;
7689
+ exports.initAllDataTables = initAllDataTables;
7590
7690
  var component_1 = __webpack_require__(2658);
7591
7691
  var utils_1 = __webpack_require__(2599);
7592
7692
  var index_1 = __webpack_require__(8156);
@@ -8693,8 +8793,61 @@ var KTDataTable = /** @class */ (function (_super) {
8693
8793
  }
8694
8794
  return id;
8695
8795
  };
8796
+ /**
8797
+ * Clean up all event listeners, handlers, and DOM nodes created by this instance.
8798
+ * This method is called before re-rendering or when disposing the component.
8799
+ */
8696
8800
  KTDataTable.prototype._dispose = function () {
8697
- // Remove all event listeners and clean up resources
8801
+ // --- 1. Remove search input event listener (debounced) ---
8802
+ var tableId = this._tableId();
8803
+ var searchElement = document.querySelector("[data-kt-datatable-search=\"#".concat(tableId, "\"]"));
8804
+ if (searchElement && searchElement._debouncedSearch) {
8805
+ searchElement.removeEventListener('keyup', searchElement._debouncedSearch);
8806
+ delete searchElement._debouncedSearch;
8807
+ }
8808
+ // --- 2. Remove page size dropdown event listener ---
8809
+ if (this._sizeElement && this._sizeElement.onchange) {
8810
+ this._sizeElement.onchange = null;
8811
+ }
8812
+ // --- 3. Remove all pagination button event listeners ---
8813
+ if (this._paginationElement) {
8814
+ // Remove all child nodes (buttons) to ensure no lingering listeners
8815
+ while (this._paginationElement.firstChild) {
8816
+ this._paginationElement.removeChild(this._paginationElement.firstChild);
8817
+ }
8818
+ }
8819
+ // --- 4. Dispose of handler objects (checkbox, sort) ---
8820
+ // KTDataTableCheckboxAPI does not have a dispose method, but we can remove header checkbox listener
8821
+ if (this._checkbox && typeof this._checkbox.dispose === 'function') {
8822
+ this._checkbox.dispose();
8823
+ }
8824
+ else {
8825
+ // Remove header checkbox event listener if possible
8826
+ var headerCheckElement = this._element.querySelector(this._config.attributes.check);
8827
+ if (headerCheckElement) {
8828
+ headerCheckElement.replaceWith(headerCheckElement.cloneNode(true));
8829
+ }
8830
+ }
8831
+ // KTDataTableSortAPI does not have a dispose method, but we can remove th click listeners by replacing them
8832
+ if (this._theadElement) {
8833
+ var ths = this._theadElement.querySelectorAll('th');
8834
+ ths.forEach(function (th) {
8835
+ th.replaceWith(th.cloneNode(true));
8836
+ });
8837
+ }
8838
+ // --- 5. Remove spinner DOM node if it exists ---
8839
+ var spinner = this._element.querySelector(this._config.attributes.spinner);
8840
+ if (spinner && spinner.parentNode) {
8841
+ spinner.parentNode.removeChild(spinner);
8842
+ }
8843
+ this._element.classList.remove(this._config.loadingClass);
8844
+ // --- 6. Remove instance reference from the DOM element ---
8845
+ if (this._element.instance) {
8846
+ delete this._element.instance;
8847
+ }
8848
+ // --- 7. (Optional) Clear localStorage state ---
8849
+ // Uncomment the following line if you want to clear state on dispose:
8850
+ // this._deleteState();
8698
8851
  };
8699
8852
  KTDataTable.prototype._debounce = function (func, wait) {
8700
8853
  var timeout;
@@ -8830,13 +8983,12 @@ var KTDataTable = /** @class */ (function (_super) {
8830
8983
  };
8831
8984
  /**
8832
8985
  * Create KTDataTable instances for all elements with a data-kt-datatable="true" attribute.
8833
- *
8834
- * This function should be called after the control(s) have been
8835
- * loaded and parsed by the browser. It will create instances of
8836
- * KTDataTable for all elements with a data-kt-datatable="true" attribute.
8986
+ * This function is now browser-guarded and must be called explicitly.
8837
8987
  */
8838
8988
  KTDataTable.createInstances = function () {
8839
8989
  var _this = this;
8990
+ if (typeof document === 'undefined')
8991
+ return;
8840
8992
  var elements = document.querySelectorAll('[data-kt-datatable="true"]');
8841
8993
  elements.forEach(function (element) {
8842
8994
  if (element.hasAttribute('data-kt-datatable') &&
@@ -8861,11 +9013,11 @@ var KTDataTable = /** @class */ (function (_super) {
8861
9013
  };
8862
9014
  /**
8863
9015
  * Initializes all KTDataTable instances on the page.
8864
- *
8865
- * This function should be called after the control(s) have been
8866
- * loaded and parsed by the browser.
9016
+ * This function is now browser-guarded and must be called explicitly.
8867
9017
  */
8868
9018
  KTDataTable.init = function () {
9019
+ if (typeof document === 'undefined')
9020
+ return;
8869
9021
  // Create instances of KTDataTable for all elements with a
8870
9022
  // data-kt-datatable="true" attribute
8871
9023
  KTDataTable.createInstances();
@@ -8923,8 +9075,16 @@ var KTDataTable = /** @class */ (function (_super) {
8923
9075
  return KTDataTable;
8924
9076
  }(component_1.default));
8925
9077
  exports.KTDataTable = KTDataTable;
8926
- if (typeof window !== 'undefined') {
8927
- window.KTDataTable = KTDataTable;
9078
+ /**
9079
+ * NOTE: This module is now PURE. No side effects or DOM/global assignments occur on import.
9080
+ * To auto-initialize all datatables on the page, call the exported `initAllDataTables()` function explicitly in the browser.
9081
+ */
9082
+ function initAllDataTables() {
9083
+ if (typeof document !== 'undefined') {
9084
+ KTDataTable.createInstances();
9085
+ // Optionally assign to window for legacy support
9086
+ window.KTDataTable = KTDataTable;
9087
+ }
8928
9088
  }
8929
9089
 
8930
9090
 
@@ -10023,6 +10183,7 @@ var KTSelectSearch = /** @class */ (function () {
10023
10183
  (_a = _this._searchInput) === null || _a === void 0 ? void 0 : _a.focus(); // Focus search input
10024
10184
  }, 50); // Delay to ensure dropdown is visible
10025
10185
  }
10186
+ _this._select.updateSelectAllButtonState();
10026
10187
  });
10027
10188
  }
10028
10189
  }
@@ -10041,6 +10202,11 @@ var KTSelectSearch = /** @class */ (function () {
10041
10202
  KTSelectSearch.prototype._handleSearchKeyDown = function (event) {
10042
10203
  var key = event.key;
10043
10204
  switch (key) {
10205
+ case ' ': // Spacebar
10206
+ // Do nothing, allow space to be typed into the input
10207
+ // Stop propagation to prevent parent handlers from processing this event
10208
+ event.stopPropagation();
10209
+ break;
10044
10210
  case 'ArrowDown':
10045
10211
  event.preventDefault();
10046
10212
  this._focusManager.focusNext();
@@ -10158,6 +10324,7 @@ var KTSelectSearch = /** @class */ (function () {
10158
10324
  var visibleCount = (0, utils_1.filterOptions)(options, query, config, dropdownElement, function (count) {
10159
10325
  return _this._handleNoResults(count);
10160
10326
  });
10327
+ this._select.updateSelectAllButtonState();
10161
10328
  };
10162
10329
  /**
10163
10330
  * Reset all options to their original state
@@ -10185,6 +10352,7 @@ var KTSelectSearch = /** @class */ (function () {
10185
10352
  }
10186
10353
  });
10187
10354
  this._clearNoResultsMessage(); // Ensure no results message is cleared when resetting
10355
+ this._select.updateSelectAllButtonState();
10188
10356
  };
10189
10357
  KTSelectSearch.prototype._handleNoResults = function (visibleOptionsCount) {
10190
10358
  var _a, _b;
@@ -11394,6 +11562,8 @@ var KTSelect = /** @class */ (function (_super) {
11394
11562
  _this._tagsModule = null;
11395
11563
  _this._dropdownModule = null;
11396
11564
  _this._loadMoreIndicator = null;
11565
+ _this._selectAllButton = null;
11566
+ _this._selectAllButtonToggle = null;
11397
11567
  _this._typeToSearchBuffer = new utils_1.TypeToSearchBuffer();
11398
11568
  _this._mutationObserver = null;
11399
11569
  // Search debounce timeout
@@ -11674,6 +11844,10 @@ var KTSelect = /** @class */ (function (_super) {
11674
11844
  this._updateDisplayAndAriaAttributes();
11675
11845
  this.updateSelectedOptionDisplay();
11676
11846
  this._setAriaAttributes();
11847
+ // Update select all button state
11848
+ this.updateSelectAllButtonState();
11849
+ // Focus the first selected option or first option if nothing selected
11850
+ this._focusSelectedOption();
11677
11851
  // Attach event listeners after all modules are initialized
11678
11852
  this._attachEventListeners();
11679
11853
  this._observeNativeSelect();
@@ -11712,6 +11886,11 @@ var KTSelect = /** @class */ (function (_super) {
11712
11886
  var searchElement = templates_1.defaultTemplates.search(this._config);
11713
11887
  dropdownElement.appendChild(searchElement);
11714
11888
  }
11889
+ // Add select all button if needed
11890
+ if (this._config.multiple && this._config.enableSelectAll) {
11891
+ var selectAllElement = templates_1.defaultTemplates.selectAll(this._config);
11892
+ dropdownElement.appendChild(selectAllElement);
11893
+ }
11715
11894
  // Create options container using template
11716
11895
  var optionsContainer = templates_1.defaultTemplates.options(this._config);
11717
11896
  // Add each option directly to the container
@@ -11755,6 +11934,7 @@ var KTSelect = /** @class */ (function (_super) {
11755
11934
  if (!this._searchInputElement) {
11756
11935
  this._searchInputElement = this._displayElement;
11757
11936
  }
11937
+ this._selectAllButton = this._wrapperElement.querySelector('[data-kt-select-select-all]');
11758
11938
  this._options = this._wrapperElement.querySelectorAll("[data-kt-select-option]");
11759
11939
  };
11760
11940
  /**
@@ -11765,6 +11945,12 @@ var KTSelect = /** @class */ (function (_super) {
11765
11945
  document.addEventListener('click', this._handleDocumentClick.bind(this));
11766
11946
  // Dropdown option click events
11767
11947
  this._eventManager.addListener(this._dropdownContentElement, 'click', this._handleDropdownOptionClick.bind(this));
11948
+ if (this._selectAllButton) {
11949
+ this._selectAllButtonToggle = this._selectAllButton.querySelector('button');
11950
+ if (this._selectAllButtonToggle) {
11951
+ this._eventManager.addListener(this._selectAllButtonToggle, 'click', this._handleSelectAllClick.bind(this));
11952
+ }
11953
+ }
11768
11954
  // Attach centralized keyboard handler to the wrapper element.
11769
11955
  // Events from focusable children like _displayElement or _searchInputElement (if present) will bubble up.
11770
11956
  if (this._wrapperElement) {
@@ -11930,6 +12116,8 @@ var KTSelect = /** @class */ (function (_super) {
11930
12116
  this._fireEvent('show');
11931
12117
  // Update ARIA states
11932
12118
  this._setAriaAttributes();
12119
+ // Update select all button state
12120
+ this.updateSelectAllButtonState();
11933
12121
  // Focus the first selected option or first option if nothing selected
11934
12122
  this._focusSelectedOption();
11935
12123
  };
@@ -12157,6 +12345,8 @@ var KTSelect = /** @class */ (function (_super) {
12157
12345
  this._state.setSelectedOptions([]);
12158
12346
  this.updateSelectedOptionDisplay();
12159
12347
  this._updateSelectedOptionClass();
12348
+ // Update select all button state
12349
+ this.updateSelectAllButtonState();
12160
12350
  // Dispatch change event
12161
12351
  this._dispatchEvent('change');
12162
12352
  this._fireEvent('change');
@@ -12421,6 +12611,7 @@ var KTSelect = /** @class */ (function (_super) {
12421
12611
  if (this._config.debug)
12422
12612
  console.log('Multiple select mode - keeping dropdown open for additional selections');
12423
12613
  // Don't close dropdown in multiple select mode to allow multiple selections
12614
+ this.updateSelectAllButtonState();
12424
12615
  }
12425
12616
  // Dispatch custom change event with additional data
12426
12617
  this._dispatchEvent('change', {
@@ -12523,6 +12714,7 @@ var KTSelect = /** @class */ (function (_super) {
12523
12714
  if (_this._searchModule) {
12524
12715
  _this._searchModule.refreshAfterSearch();
12525
12716
  }
12717
+ _this.updateSelectAllButtonState();
12526
12718
  })
12527
12719
  .catch(function (error) {
12528
12720
  console.error('Error updating search results:', error);
@@ -12827,6 +13019,57 @@ var KTSelect = /** @class */ (function (_super) {
12827
13019
  this._state.setSelectedOptions(this._config.multiple ? selected : selected[0] || '');
12828
13020
  this.updateSelectedOptionDisplay();
12829
13021
  this._updateSelectedOptionClass();
13022
+ this.updateSelectAllButtonState();
13023
+ };
13024
+ KTSelect.prototype._handleSelectAllClick = function (event) {
13025
+ event.preventDefault();
13026
+ event.stopPropagation();
13027
+ var visibleOptions = this._focusManager
13028
+ .getVisibleOptions()
13029
+ .filter(function (opt) { return opt.getAttribute('aria-disabled') !== 'true'; });
13030
+ if (visibleOptions.length === 0)
13031
+ return;
13032
+ var visibleValues = visibleOptions.map(function (opt) { return opt.dataset.value; });
13033
+ var selectedValues = new Set(this.getSelectedOptions());
13034
+ var isAllSelected = visibleOptions.every(function (opt) {
13035
+ return selectedValues.has(opt.dataset.value);
13036
+ });
13037
+ if (isAllSelected) {
13038
+ // Deselect all visible
13039
+ visibleValues.forEach(function (value) { return selectedValues.delete(value); });
13040
+ }
13041
+ else {
13042
+ // Select all visible
13043
+ visibleValues.forEach(function (value) { return selectedValues.add(value); });
13044
+ }
13045
+ this._state.setSelectedOptions(Array.from(selectedValues));
13046
+ this.updateSelectedOptionDisplay();
13047
+ this._updateSelectedOptionClass();
13048
+ this.updateSelectAllButtonState();
13049
+ this._dispatchEvent('change');
13050
+ this._fireEvent('change');
13051
+ };
13052
+ KTSelect.prototype.updateSelectAllButtonState = function () {
13053
+ if (!this._config.multiple ||
13054
+ !this._config.enableSelectAll ||
13055
+ !this._selectAllButtonToggle) {
13056
+ return;
13057
+ }
13058
+ var visibleOptions = this._focusManager
13059
+ .getVisibleOptions()
13060
+ .filter(function (opt) { return opt.getAttribute('aria-disabled') !== 'true'; });
13061
+ if (visibleOptions.length === 0) {
13062
+ this._selectAllButton.style.display = 'none';
13063
+ return;
13064
+ }
13065
+ this._selectAllButton.style.display = '';
13066
+ var selectedValues = new Set(this.getSelectedOptions());
13067
+ var isAllSelected = visibleOptions.every(function (opt) {
13068
+ return selectedValues.has(opt.dataset.value);
13069
+ });
13070
+ this._selectAllButtonToggle.textContent = isAllSelected
13071
+ ? this._config.clearAllText
13072
+ : this._config.selectAllText;
12830
13073
  };
12831
13074
  /**
12832
13075
  * ========================================================================
@@ -16162,6 +16405,7 @@ exports.coreTemplateStrings = {
16162
16405
  loading: "<li class=\"kt-select-loading {{class}}\" role=\"status\" aria-live=\"polite\"></li>",
16163
16406
  tag: "<div data-kt-select-tag=\"true\" class=\"kt-select-tag {{class}}\"></div>",
16164
16407
  loadMore: "<li class=\"kt-select-load-more {{class}}\" data-kt-select-load-more=\"true\"></li>",
16408
+ selectAll: "<div data-kt-select-select-all class=\"kt-select-select-all\"><button type=\"button\" class=\"kt-select-select-all-button\">{{text}}</button></div>",
16165
16409
  tagRemoveButton: "<button type=\"button\" data-kt-select-remove-button class=\"kt-select-tag-remove\" aria-label=\"Remove tag\" tabindex=\"0\"><svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><line x1=\"3\" y1=\"3\" x2=\"9\" y2=\"9\"/><line x1=\"9\" y1=\"3\" x2=\"3\" y2=\"9\"/></svg></button>",
16166
16410
  };
16167
16411
  /**
@@ -16435,6 +16679,11 @@ exports.defaultTemplates = {
16435
16679
  return element;
16436
16680
  }
16437
16681
  },
16682
+ selectAll: function (config) {
16683
+ var template = getTemplateStrings(config).selectAll;
16684
+ var element = stringToElement(template.replace('{{text}}', config.selectAllText || 'Select All'));
16685
+ return element;
16686
+ },
16438
16687
  };
16439
16688
 
16440
16689
 
@@ -17597,6 +17846,7 @@ exports.DefaultConfig = {
17597
17846
  // Multi-Select Display
17598
17847
  selectAllText: 'Select all', // Text for the "Select All" option (if implemented)
17599
17848
  clearAllText: 'Clear all', // Text for the "Clear All" option (if implemented)
17849
+ enableSelectAll: false, // Enable/disable "Select All" button for multi-select
17600
17850
  showSelectedCount: true, // Show the number of selected options in multi-select mode
17601
17851
  renderSelected: null, // Custom function to render the selected value(s) in the display area
17602
17852
  // Accessibility & Usability