@keenthemes/ktui 1.1.1 → 1.1.3

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 (81) hide show
  1. package/dist/ktui.js +674 -225
  2. package/dist/ktui.min.js +1 -1
  3. package/dist/ktui.min.js.map +1 -1
  4. package/dist/styles.css +13 -1
  5. package/lib/cjs/components/component.js +22 -0
  6. package/lib/cjs/components/component.js.map +1 -1
  7. package/lib/cjs/components/datatable/datatable.js +7 -1
  8. package/lib/cjs/components/datatable/datatable.js.map +1 -1
  9. package/lib/cjs/components/drawer/drawer.js +255 -9
  10. package/lib/cjs/components/drawer/drawer.js.map +1 -1
  11. package/lib/cjs/components/dropdown/dropdown.js +55 -8
  12. package/lib/cjs/components/dropdown/dropdown.js.map +1 -1
  13. package/lib/cjs/components/select/combobox.js +0 -2
  14. package/lib/cjs/components/select/combobox.js.map +1 -1
  15. package/lib/cjs/components/select/config.js +4 -1
  16. package/lib/cjs/components/select/config.js.map +1 -1
  17. package/lib/cjs/components/select/dropdown.js +0 -16
  18. package/lib/cjs/components/select/dropdown.js.map +1 -1
  19. package/lib/cjs/components/select/remote.js +0 -40
  20. package/lib/cjs/components/select/remote.js.map +1 -1
  21. package/lib/cjs/components/select/search.js +93 -22
  22. package/lib/cjs/components/select/search.js.map +1 -1
  23. package/lib/cjs/components/select/select.js +180 -114
  24. package/lib/cjs/components/select/select.js.map +1 -1
  25. package/lib/cjs/components/select/tags.js +0 -2
  26. package/lib/cjs/components/select/tags.js.map +1 -1
  27. package/lib/cjs/components/sticky/sticky.js +44 -5
  28. package/lib/cjs/components/sticky/sticky.js.map +1 -1
  29. package/lib/cjs/helpers/data.js +8 -0
  30. package/lib/cjs/helpers/data.js.map +1 -1
  31. package/lib/cjs/helpers/event-handler.js +6 -5
  32. package/lib/cjs/helpers/event-handler.js.map +1 -1
  33. package/lib/cjs/index.js.map +1 -1
  34. package/lib/esm/components/component.js +22 -0
  35. package/lib/esm/components/component.js.map +1 -1
  36. package/lib/esm/components/datatable/datatable.js +7 -1
  37. package/lib/esm/components/datatable/datatable.js.map +1 -1
  38. package/lib/esm/components/drawer/drawer.js +255 -9
  39. package/lib/esm/components/drawer/drawer.js.map +1 -1
  40. package/lib/esm/components/dropdown/dropdown.js +55 -8
  41. package/lib/esm/components/dropdown/dropdown.js.map +1 -1
  42. package/lib/esm/components/select/combobox.js +0 -2
  43. package/lib/esm/components/select/combobox.js.map +1 -1
  44. package/lib/esm/components/select/config.js +4 -1
  45. package/lib/esm/components/select/config.js.map +1 -1
  46. package/lib/esm/components/select/dropdown.js +0 -16
  47. package/lib/esm/components/select/dropdown.js.map +1 -1
  48. package/lib/esm/components/select/remote.js +0 -40
  49. package/lib/esm/components/select/remote.js.map +1 -1
  50. package/lib/esm/components/select/search.js +93 -22
  51. package/lib/esm/components/select/search.js.map +1 -1
  52. package/lib/esm/components/select/select.js +180 -114
  53. package/lib/esm/components/select/select.js.map +1 -1
  54. package/lib/esm/components/select/tags.js +0 -2
  55. package/lib/esm/components/select/tags.js.map +1 -1
  56. package/lib/esm/components/sticky/sticky.js +44 -5
  57. package/lib/esm/components/sticky/sticky.js.map +1 -1
  58. package/lib/esm/helpers/data.js +8 -0
  59. package/lib/esm/helpers/data.js.map +1 -1
  60. package/lib/esm/helpers/event-handler.js +6 -5
  61. package/lib/esm/helpers/event-handler.js.map +1 -1
  62. package/lib/esm/index.js.map +1 -1
  63. package/package.json +6 -4
  64. package/src/components/component.ts +26 -0
  65. package/src/components/datatable/__tests__/race-conditions.test.ts +7 -7
  66. package/src/components/datatable/datatable.ts +8 -1
  67. package/src/components/drawer/drawer.ts +266 -10
  68. package/src/components/dropdown/dropdown.ts +63 -8
  69. package/src/components/select/__tests__/ux-behaviors.test.ts +997 -0
  70. package/src/components/select/combobox.ts +0 -1
  71. package/src/components/select/config.ts +7 -1
  72. package/src/components/select/dropdown.ts +0 -24
  73. package/src/components/select/remote.ts +0 -49
  74. package/src/components/select/search.ts +97 -24
  75. package/src/components/select/select.css +5 -1
  76. package/src/components/select/select.ts +211 -153
  77. package/src/components/select/tags.ts +0 -1
  78. package/src/components/sticky/sticky.ts +55 -5
  79. package/src/helpers/data.ts +10 -0
  80. package/src/helpers/event-handler.ts +7 -6
  81. package/src/index.ts +2 -0
package/dist/ktui.js CHANGED
@@ -173,6 +173,15 @@ var __extends = (this && this.__extends) || (function () {
173
173
  d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
174
174
  };
175
175
  })();
176
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
177
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
178
+ if (ar || !(i in from)) {
179
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
180
+ ar[i] = from[i];
181
+ }
182
+ }
183
+ return to.concat(ar || Array.prototype.slice.call(from));
184
+ };
176
185
  Object.defineProperty(exports, "__esModule", ({ value: true }));
177
186
  exports.KTDrawer = void 0;
178
187
  var data_1 = __webpack_require__(8716);
@@ -205,8 +214,9 @@ var KTDrawer = /** @class */ (function (_super) {
205
214
  _this._isTransitioning = false;
206
215
  _this._backdropElement = null;
207
216
  _this._relatedTarget = null;
208
- if (data_1.default.has(element, _this._name))
217
+ if (data_1.default.has(element, _this._name)) {
209
218
  return _this;
219
+ }
210
220
  _this._init(element);
211
221
  _this._buildConfig(config);
212
222
  _this._handleClose();
@@ -248,6 +258,27 @@ var KTDrawer = /** @class */ (function (_super) {
248
258
  return;
249
259
  }
250
260
  KTDrawer.hide();
261
+ // If drawer needs to be in front of backdrop, ensure it's in body (for proper z-index stacking)
262
+ // This ensures the drawer and backdrop are in the same stacking context
263
+ if (this._getOption('container') === 'body' && this._element.parentElement !== document.body) {
264
+ // Store original parent for restoration when hiding
265
+ if (!this._element.hasAttribute('data-kt-drawer-original-parent-id')) {
266
+ var originalParent = this._element.parentElement;
267
+ if (originalParent && originalParent !== document.body) {
268
+ this._element.setAttribute('data-kt-drawer-original-parent-id', originalParent.id || '');
269
+ // Store a reference to find the parent later (using closest to find Livewire component or header)
270
+ var livewireComponent = originalParent.closest('[wire\\:id]');
271
+ var header = originalParent.closest('header#header');
272
+ if (livewireComponent) {
273
+ this._element.setAttribute('data-kt-drawer-original-wire-id', livewireComponent.getAttribute('wire:id') || '');
274
+ }
275
+ if (header) {
276
+ this._element.setAttribute('data-kt-drawer-original-in-header', 'true');
277
+ }
278
+ }
279
+ }
280
+ document.body.appendChild(this._element);
281
+ }
251
282
  if (this._getOption('backdrop') === true)
252
283
  this._createBackdrop();
253
284
  if (relatedTarget)
@@ -312,6 +343,9 @@ var KTDrawer = /** @class */ (function (_super) {
312
343
  _this._element.classList.add(_this._getOption('hiddenClass'));
313
344
  _this._element.classList.remove(_this._getOption('shownClass'));
314
345
  _this._element.style.zIndex = '';
346
+ // Note: We don't move drawer back to original location here
347
+ // Livewire will handle DOM structure on next navigation, and drawer will be reinitialized
348
+ // in its original location from the persisted component HTML
315
349
  _this._fireEvent('hidden');
316
350
  _this._dispatchEvent('hidden');
317
351
  });
@@ -331,7 +365,25 @@ var KTDrawer = /** @class */ (function (_super) {
331
365
  var _a;
332
366
  if (this._getOption('container')) {
333
367
  if (this._getOption('container') === 'body') {
334
- document.body.appendChild(this._element);
368
+ // Check if drawer is in a persisted Livewire component (like header with @persist)
369
+ // If so, don't move it to body - keep it in place so Livewire can preserve it
370
+ // This follows the same pattern as dropdowns/menus which work with wire:navigate
371
+ var originalParent = this._element.parentNode;
372
+ var isInPersistedComponent = originalParent &&
373
+ (originalParent.closest('[wire\\:id]') !== null ||
374
+ originalParent.closest('header#header') !== null);
375
+ if (isInPersistedComponent) {
376
+ // Don't move to body - keep in original location for Livewire persistence
377
+ // Use fixed positioning to achieve the same visual effect
378
+ // Ensure drawer has fixed positioning to work from its current location
379
+ if (!this._element.style.position || this._element.style.position === 'static') {
380
+ this._element.style.position = 'fixed';
381
+ }
382
+ }
383
+ else {
384
+ // Not in persisted component - safe to move to body (follows original behavior)
385
+ document.body.appendChild(this._element);
386
+ }
335
387
  }
336
388
  else {
337
389
  (_a = document
@@ -402,14 +454,117 @@ var KTDrawer = /** @class */ (function (_super) {
402
454
  KTDrawer.prototype.isEnabled = function () {
403
455
  return this._isEnabled();
404
456
  };
457
+ KTDrawer.getElement = function (reference) {
458
+ if (reference && reference.hasAttribute('data-kt-drawer-initialized'))
459
+ return reference;
460
+ var findElement = reference &&
461
+ reference.closest('[data-kt-drawer-initialized]');
462
+ if (findElement)
463
+ return findElement;
464
+ // Fallback: look for parent with data-kt-drawer attribute
465
+ if (reference) {
466
+ var drawerContainer = reference.closest('[data-kt-drawer]');
467
+ if (drawerContainer)
468
+ return drawerContainer;
469
+ }
470
+ // If reference is a toggle button with a selector, find the drawer by selector
471
+ // This handles cases where the toggle button is not a child of the drawer
472
+ if (reference && reference.hasAttribute('data-kt-drawer-toggle')) {
473
+ var selector = reference.getAttribute('data-kt-drawer-toggle');
474
+ if (selector) {
475
+ // Check both document and body (drawers with container="body" are moved to body)
476
+ var drawerElInDoc = document.querySelector(selector);
477
+ var drawerElInBody = document.body.querySelector(selector);
478
+ var drawerEl = drawerElInDoc || drawerElInBody;
479
+ if (drawerEl)
480
+ return drawerEl;
481
+ }
482
+ }
483
+ return null;
484
+ };
485
+ /**
486
+ * Wait for an element to appear in the DOM using polling with MutationObserver fallback
487
+ * Useful for persisted Livewire components that may not be in DOM immediately
488
+ */
489
+ KTDrawer.waitForElement = function (selector, timeout) {
490
+ if (timeout === void 0) { timeout = 2000; }
491
+ return new Promise(function (resolve) {
492
+ var resolved = false;
493
+ var doResolve = function (element) {
494
+ if (!resolved) {
495
+ resolved = true;
496
+ resolve(element);
497
+ }
498
+ };
499
+ // Check if element already exists
500
+ var existing = document.querySelector(selector) || document.body.querySelector(selector);
501
+ if (existing) {
502
+ doResolve(existing);
503
+ return;
504
+ }
505
+ // Use polling for faster detection (check every 50ms)
506
+ var attempts = 0;
507
+ var maxAttempts = timeout / 50;
508
+ var pollInterval = setInterval(function () {
509
+ if (resolved) {
510
+ clearInterval(pollInterval);
511
+ return;
512
+ }
513
+ attempts++;
514
+ var element = document.querySelector(selector) || document.body.querySelector(selector);
515
+ if (element) {
516
+ clearInterval(pollInterval);
517
+ doResolve(element);
518
+ return;
519
+ }
520
+ if (attempts >= maxAttempts) {
521
+ clearInterval(pollInterval);
522
+ doResolve(null);
523
+ }
524
+ }, 50);
525
+ // Also use MutationObserver as backup for immediate detection
526
+ var observer = new MutationObserver(function () {
527
+ if (resolved) {
528
+ observer.disconnect();
529
+ return;
530
+ }
531
+ var element = document.querySelector(selector) || document.body.querySelector(selector);
532
+ if (element) {
533
+ clearInterval(pollInterval);
534
+ observer.disconnect();
535
+ doResolve(element);
536
+ }
537
+ });
538
+ observer.observe(document.body, {
539
+ childList: true,
540
+ subtree: true,
541
+ });
542
+ // Cleanup on timeout
543
+ setTimeout(function () {
544
+ if (!resolved) {
545
+ clearInterval(pollInterval);
546
+ observer.disconnect();
547
+ doResolve(null);
548
+ }
549
+ }, timeout);
550
+ });
551
+ };
405
552
  KTDrawer.getInstance = function (element) {
406
553
  if (!element)
407
554
  return null;
408
- if (data_1.default.has(element, 'drawer')) {
409
- return data_1.default.get(element, 'drawer');
555
+ var drawerElement = KTDrawer.getElement(element);
556
+ if (!drawerElement) {
557
+ // If element is a toggle button and drawer element wasn't found, return null
558
+ // The handleToggle() will handle waiting for the element to appear
559
+ if (element.hasAttribute('data-kt-drawer-toggle')) {
560
+ }
561
+ return null;
410
562
  }
411
- if (element.getAttribute('data-kt-drawer-initialized') === 'true') {
412
- return new KTDrawer(element);
563
+ if (data_1.default.has(drawerElement, 'drawer')) {
564
+ return data_1.default.get(drawerElement, 'drawer');
565
+ }
566
+ if (drawerElement.getAttribute('data-kt-drawer-initialized') === 'true') {
567
+ return new KTDrawer(drawerElement);
413
568
  }
414
569
  return null;
415
570
  };
@@ -442,16 +597,62 @@ var KTDrawer = /** @class */ (function (_super) {
442
597
  });
443
598
  };
444
599
  KTDrawer.handleToggle = function () {
600
+ // Add raw click listener to document.body to track all clicks
601
+ document.body.addEventListener('click', function (rawEvent) {
602
+ var target = rawEvent.target;
603
+ if (target && target.hasAttribute('data-kt-drawer-toggle')) {
604
+ }
605
+ }, true); // Use capture phase to catch before any stopPropagation
445
606
  event_handler_1.default.on(document.body, '[data-kt-drawer-toggle]', 'click', function (event, target) {
607
+ var _a;
446
608
  event.stopPropagation();
447
609
  var selector = target.getAttribute('data-kt-drawer-toggle');
448
610
  if (!selector)
449
611
  return;
450
- var drawerEl = document.querySelector(selector);
451
- var drawer = KTDrawer.getInstance(drawerEl);
612
+ // Try to get instance immediately
613
+ var drawer = KTDrawer.getInstance(target);
452
614
  if (drawer) {
453
615
  drawer.toggle();
454
616
  }
617
+ else {
618
+ // Drawer element not found - wait for it to appear (handles persisted Livewire components)
619
+ // Check if drawer exists in persisted components (might be in header that's persisted)
620
+ var persistedHeader = ((_a = document.querySelector('[wire\\:id]')) === null || _a === void 0 ? void 0 : _a.closest('[wire\\:id]')) || document.querySelector('header#header');
621
+ var drawerInPersisted = persistedHeader ? persistedHeader.querySelector(selector) : null;
622
+ // Wait longer for persisted components that may take time to render
623
+ // Also check if drawer exists in persisted header component
624
+ KTDrawer.waitForElement(selector, 5000).then(function (drawerElement) {
625
+ if (drawerElement) {
626
+ // Initialize the drawer if not already initialized
627
+ if (!data_1.default.has(drawerElement, 'drawer')) {
628
+ new KTDrawer(drawerElement);
629
+ }
630
+ // Get instance and toggle
631
+ var drawerInstance = KTDrawer.getInstance(drawerElement);
632
+ if (drawerInstance) {
633
+ drawerInstance.toggle();
634
+ }
635
+ }
636
+ else {
637
+ // Drawer never appeared - trigger a reinit to see if it helps
638
+ // This handles cases where drawers are in persisted components that haven't rendered yet
639
+ setTimeout(function () {
640
+ KTDrawer.reinit();
641
+ // Try one more time after reinit
642
+ var drawerAfterReinit = document.querySelector(selector) || document.body.querySelector(selector);
643
+ if (drawerAfterReinit) {
644
+ if (!data_1.default.has(drawerAfterReinit, 'drawer')) {
645
+ new KTDrawer(drawerAfterReinit);
646
+ }
647
+ var drawerInstance = KTDrawer.getInstance(drawerAfterReinit);
648
+ if (drawerInstance) {
649
+ drawerInstance.toggle();
650
+ }
651
+ }
652
+ }, 500);
653
+ }
654
+ });
655
+ }
455
656
  });
456
657
  };
457
658
  KTDrawer.handleDismiss = function () {
@@ -503,7 +704,12 @@ var KTDrawer = /** @class */ (function (_super) {
503
704
  });
504
705
  };
505
706
  KTDrawer.createInstances = function () {
506
- var elements = document.querySelectorAll('[data-kt-drawer]');
707
+ // Find all drawer elements - check both document and body (drawers with container="body" are moved there)
708
+ var elementsInDoc = document.querySelectorAll('[data-kt-drawer]');
709
+ var elementsInBody = document.body.querySelectorAll('[data-kt-drawer]');
710
+ // Combine and deduplicate
711
+ var allElements = new Set(__spreadArray(__spreadArray([], Array.from(elementsInDoc), true), Array.from(elementsInBody), true));
712
+ var elements = Array.from(allElements);
507
713
  elements.forEach(function (element) {
508
714
  new KTDrawer(element);
509
715
  });
@@ -519,6 +725,46 @@ var KTDrawer = /** @class */ (function (_super) {
519
725
  window.KT_DRAWER_INITIALIZED = true;
520
726
  }
521
727
  };
728
+ /**
729
+ * Force reinitialization of drawers by clearing KTData entries.
730
+ * Useful for Livewire wire:navigate where persisted elements need reinitialization.
731
+ */
732
+ KTDrawer.reinit = function () {
733
+ // Follow the same simple pattern as KTDropdown.reinit()
734
+ // Find all drawer elements - check both document and body (some may be moved to body)
735
+ var elementsInDoc = document.querySelectorAll('[data-kt-drawer]');
736
+ var elementsInBody = document.body.querySelectorAll('[data-kt-drawer]');
737
+ // Combine and deduplicate
738
+ var allElements = new Set(__spreadArray(__spreadArray([], Array.from(elementsInDoc), true), Array.from(elementsInBody), true));
739
+ var elements = Array.from(allElements);
740
+ // Clean up existing instances
741
+ elements.forEach(function (element) {
742
+ try {
743
+ // Get existing instance to clean up
744
+ var instance = KTDrawer.getInstance(element);
745
+ if (instance && typeof instance.hide === 'function') {
746
+ instance.hide(); // This will clean up backdrop and state
747
+ }
748
+ // Clear KTData entries
749
+ var hadDrawer = data_1.default.has(element, 'drawer');
750
+ data_1.default.remove(element, 'drawer');
751
+ // Remove initialization attribute to allow fresh initialization
752
+ element.removeAttribute('data-kt-drawer-initialized');
753
+ }
754
+ catch (e) {
755
+ // Ignore errors for individual elements
756
+ }
757
+ });
758
+ // Now create fresh instances
759
+ KTDrawer.createInstances();
760
+ // Always ensure handlers are set up (similar to KTMenu.init() behavior)
761
+ // Event handlers use delegation so they persist, but we ensure they're attached
762
+ KTDrawer.handleToggle();
763
+ KTDrawer.handleDismiss();
764
+ KTDrawer.handleResize();
765
+ KTDrawer.handleClickAway();
766
+ KTDrawer.handleKeyword();
767
+ };
522
768
  return KTDrawer;
523
769
  }(component_1.default));
524
770
  exports.KTDrawer = KTDrawer;
@@ -1929,6 +2175,28 @@ var KTComponent = /** @class */ (function () {
1929
2175
  this._uid = null;
1930
2176
  this._element = null;
1931
2177
  }
2178
+ /**
2179
+ * Check if component should skip initialization
2180
+ * Returns true if element already has an instance and is still connected to DOM
2181
+ * Returns false if element should be initialized (no instance or disconnected)
2182
+ * @param element The element to check
2183
+ * @returns true if initialization should be skipped, false otherwise
2184
+ */
2185
+ KTComponent.prototype._shouldSkipInit = function (element) {
2186
+ if (!data_1.default.has(element, this._name)) {
2187
+ return false;
2188
+ }
2189
+ var existingInstance = data_1.default.get(element, this._name);
2190
+ // If element is not connected to DOM, dispose old instance and allow reinitialization
2191
+ if (element.isConnected === false) {
2192
+ if (existingInstance && typeof existingInstance.dispose === 'function') {
2193
+ existingInstance.dispose();
2194
+ }
2195
+ return false;
2196
+ }
2197
+ // Element is connected and has instance, skip initialization
2198
+ return true;
2199
+ };
1932
2200
  KTComponent.prototype._init = function (element) {
1933
2201
  element = dom_1.default.getElement(element);
1934
2202
  if (!element) {
@@ -2307,8 +2575,12 @@ var KTSticky = /** @class */ (function (_super) {
2307
2575
  };
2308
2576
  _this._config = _this._defaultConfig;
2309
2577
  _this._targetElement = null;
2310
- if (data_1.default.has(element, _this._name))
2578
+ _this._resizeHandler = null;
2579
+ _this._scrollHandler = null;
2580
+ // Check if element already has an instance and is still connected
2581
+ if (_this._shouldSkipInit(element)) {
2311
2582
  return _this;
2583
+ }
2312
2584
  _this._init(element);
2313
2585
  _this._buildConfig(config);
2314
2586
  _this._releaseElement = dom_1.default.getElement(_this._getOption('release'));
@@ -2334,15 +2606,26 @@ var KTSticky = /** @class */ (function (_super) {
2334
2606
  };
2335
2607
  KTSticky.prototype._handlers = function () {
2336
2608
  var _this = this;
2337
- window.addEventListener('resize', function () {
2609
+ // Store resize handler reference for cleanup
2610
+ this._resizeHandler = function () {
2338
2611
  var timer;
2339
2612
  utils_1.default.throttle(timer, function () {
2340
2613
  _this._update();
2341
2614
  }, 200);
2342
- });
2343
- this._targetElement.addEventListener('scroll', function () {
2615
+ };
2616
+ window.addEventListener('resize', this._resizeHandler);
2617
+ // Store scroll handler reference for cleanup
2618
+ this._scrollHandler = function () {
2344
2619
  _this._process();
2345
- });
2620
+ };
2621
+ if (this._targetElement) {
2622
+ if (this._targetElement === document) {
2623
+ window.addEventListener('scroll', this._scrollHandler);
2624
+ }
2625
+ else {
2626
+ this._targetElement.addEventListener('scroll', this._scrollHandler);
2627
+ }
2628
+ }
2346
2629
  };
2347
2630
  KTSticky.prototype._process = function () {
2348
2631
  var reverse = this._getOption('reverse');
@@ -2583,6 +2866,30 @@ var KTSticky = /** @class */ (function (_super) {
2583
2866
  KTSticky.prototype.isActive = function () {
2584
2867
  return this._isActive();
2585
2868
  };
2869
+ KTSticky.prototype.dispose = function () {
2870
+ // Remove resize event listener
2871
+ if (this._resizeHandler) {
2872
+ window.removeEventListener('resize', this._resizeHandler);
2873
+ this._resizeHandler = null;
2874
+ }
2875
+ // Remove scroll event listener
2876
+ if (this._scrollHandler) {
2877
+ if (this._targetElement === document) {
2878
+ window.removeEventListener('scroll', this._scrollHandler);
2879
+ }
2880
+ else if (this._targetElement) {
2881
+ this._targetElement.removeEventListener('scroll', this._scrollHandler);
2882
+ }
2883
+ this._scrollHandler = null;
2884
+ }
2885
+ // Clean up state
2886
+ this._disable();
2887
+ if (this._attributeRoot && document.body.hasAttribute(this._attributeRoot)) {
2888
+ document.body.removeAttribute(this._attributeRoot);
2889
+ }
2890
+ // Call parent dispose to clean up data attributes and KTData
2891
+ _super.prototype.dispose.call(this);
2892
+ };
2586
2893
  KTSticky.getInstance = function (element) {
2587
2894
  if (!element)
2588
2895
  return null;
@@ -2678,8 +2985,6 @@ var KTSelectRemote = /** @class */ (function () {
2678
2985
  this._lastQuery = query || '';
2679
2986
  this._currentPage = page;
2680
2987
  var url = this._buildUrl(query, page);
2681
- if (this._config.debug)
2682
- console.log('Fetching remote data from:', url);
2683
2988
  // Dispatch search start event
2684
2989
  this._dispatchEvent('remoteSearchStart');
2685
2990
  return fetch(url)
@@ -2766,24 +3071,16 @@ var KTSelectRemote = /** @class */ (function () {
2766
3071
  KTSelectRemote.prototype._processData = function (data) {
2767
3072
  var _this = this;
2768
3073
  try {
2769
- if (this._config.debug)
2770
- console.log('Processing API response:', data);
2771
3074
  var processedData = data;
2772
3075
  // Extract data from the API property if specified
2773
3076
  if (this._config.apiDataProperty && data[this._config.apiDataProperty]) {
2774
- if (this._config.debug)
2775
- console.log("Extracting data from property: ".concat(this._config.apiDataProperty));
2776
3077
  // If pagination metadata is available, extract it
2777
3078
  if (this._config.pagination) {
2778
3079
  if (data.total_pages) {
2779
3080
  this._totalPages = data.total_pages;
2780
- if (this._config.debug)
2781
- console.log("Total pages found: ".concat(this._totalPages));
2782
3081
  }
2783
3082
  if (data.total) {
2784
3083
  this._totalPages = Math.ceil(data.total / (this._config.paginationLimit || 10));
2785
- if (this._config.debug)
2786
- console.log("Calculated total pages: ".concat(this._totalPages, " from total: ").concat(data.total));
2787
3084
  }
2788
3085
  }
2789
3086
  processedData = data[this._config.apiDataProperty];
@@ -2793,8 +3090,6 @@ var KTSelectRemote = /** @class */ (function () {
2793
3090
  console.warn('Remote data is not an array:', processedData);
2794
3091
  return [];
2795
3092
  }
2796
- if (this._config.debug)
2797
- console.log("Mapping ".concat(processedData.length, " items to KTSelectOptionData format"));
2798
3093
  // Map data to KTSelectOptionData format
2799
3094
  var mappedData = processedData.map(function (item) {
2800
3095
  var mappedItem = _this._mapItemToOption(item);
@@ -2820,19 +3115,13 @@ var KTSelectRemote = /** @class */ (function () {
2820
3115
  // If we found a value, verify it matches what was extracted
2821
3116
  if (nestedValue !== null && nestedValue !== undefined) {
2822
3117
  var expectedValue = String(nestedValue);
2823
- if (_this._config.debug)
2824
- console.log("Data path verification for [".concat(_this._config.dataValueField, "]: Expected: ").concat(expectedValue, ", Got: ").concat(mappedItem.id));
2825
3118
  if (mappedItem.id !== expectedValue && expectedValue) {
2826
3119
  console.warn("Value mismatch! Path: ".concat(_this._config.dataValueField, ", Expected: ").concat(expectedValue, ", Got: ").concat(mappedItem.id));
2827
3120
  }
2828
3121
  }
2829
3122
  }
2830
- if (_this._config.debug)
2831
- console.log("Mapped item: ".concat(JSON.stringify(mappedItem)));
2832
3123
  return mappedItem;
2833
3124
  });
2834
- if (this._config.debug)
2835
- console.log("Returned ".concat(mappedData.length, " mapped items"));
2836
3125
  return mappedData;
2837
3126
  }
2838
3127
  catch (error) {
@@ -2848,14 +3137,9 @@ var KTSelectRemote = /** @class */ (function () {
2848
3137
  * @returns KTSelectOptionData object
2849
3138
  */
2850
3139
  KTSelectRemote.prototype._mapItemToOption = function (item) {
2851
- var _this = this;
2852
3140
  // Get the field mapping from config with fallbacks for common field names
2853
3141
  var valueField = this._config.dataValueField || 'id';
2854
3142
  var labelField = this._config.dataFieldText || 'title';
2855
- if (this._config.debug)
2856
- console.log("Mapping fields: value=".concat(valueField, ", label=").concat(labelField));
2857
- if (this._config.debug)
2858
- console.log('Item data:', JSON.stringify(item).substring(0, 200) + '...'); // Trimmed for readability
2859
3143
  // Extract values using improved getValue function
2860
3144
  var getValue = function (obj, path) {
2861
3145
  if (!path || !obj)
@@ -2873,13 +3157,6 @@ var KTSelectRemote = /** @class */ (function () {
2873
3157
  }
2874
3158
  result_1 = result_1[part];
2875
3159
  }
2876
- // Log the extraction result
2877
- if (_this._config.debug)
2878
- console.log("Extracted [".concat(path, "] => ").concat(result_1 !== null && result_1 !== undefined
2879
- ? typeof result_1 === 'object'
2880
- ? JSON.stringify(result_1).substring(0, 50)
2881
- : String(result_1).substring(0, 50)
2882
- : 'null'));
2883
3160
  return result_1;
2884
3161
  }
2885
3162
  catch (error) {
@@ -2896,8 +3173,6 @@ var KTSelectRemote = /** @class */ (function () {
2896
3173
  var field = fallbackFields_1[_i];
2897
3174
  if (item[field] !== null && item[field] !== undefined) {
2898
3175
  id = String(item[field]);
2899
- if (this._config.debug)
2900
- console.log("Using fallback field '".concat(field, "' for ID: ").concat(id));
2901
3176
  break;
2902
3177
  }
2903
3178
  }
@@ -2908,8 +3183,6 @@ var KTSelectRemote = /** @class */ (function () {
2908
3183
  // If still no ID, generate one
2909
3184
  if (!id) {
2910
3185
  id = "option-".concat(Math.random().toString(36).substr(2, 9));
2911
- if (this._config.debug)
2912
- console.log("Generated fallback ID: ".concat(id));
2913
3186
  }
2914
3187
  // Get label with proper fallbacks
2915
3188
  var title = getValue(item, labelField);
@@ -2927,8 +3200,6 @@ var KTSelectRemote = /** @class */ (function () {
2927
3200
  var field = fallbackFields_2[_a];
2928
3201
  if (item[field] !== null && item[field] !== undefined) {
2929
3202
  title = String(item[field]);
2930
- if (this._config.debug)
2931
- console.log("Using fallback field '".concat(field, "' for title: ").concat(title));
2932
3203
  break;
2933
3204
  }
2934
3205
  }
@@ -2939,8 +3210,6 @@ var KTSelectRemote = /** @class */ (function () {
2939
3210
  // If still no title, use ID as fallback
2940
3211
  if (!title) {
2941
3212
  title = "Option ".concat(id);
2942
- if (this._config.debug)
2943
- console.log("Using ID as fallback title: ".concat(title));
2944
3213
  }
2945
3214
  // Create the option object with consistent structure
2946
3215
  var result = {
@@ -2949,8 +3218,6 @@ var KTSelectRemote = /** @class */ (function () {
2949
3218
  selected: Boolean(item.selected),
2950
3219
  disabled: Boolean(item.disabled),
2951
3220
  };
2952
- if (this._config.debug)
2953
- console.log('Final mapped item:', JSON.stringify(result));
2954
3221
  return result;
2955
3222
  };
2956
3223
  /**
@@ -5783,13 +6050,14 @@ var KTEventHandler = {
5783
6050
  }
5784
6051
  var eventId = utils_1.default.geUID('event');
5785
6052
  KTDelegatedEventHandlers[eventId] = function (event) {
5786
- var targets = element.querySelectorAll(selector);
6053
+ // Fix: Check selector dynamically instead of pre-computing targets
6054
+ // This allows event delegation to work with dynamically added elements
5787
6055
  var target = event.target;
5788
6056
  while (target && target !== element) {
5789
- for (var i = 0, j = targets.length; i < j; i++) {
5790
- if (target === targets[i]) {
5791
- handler.call(_this, event, target);
5792
- }
6057
+ // Check if current target matches the selector
6058
+ if (target.matches && target.matches(selector)) {
6059
+ handler.call(_this, event, target);
6060
+ return; // Stop bubbling once we've handled it
5793
6061
  }
5794
6062
  target = target.parentNode;
5795
6063
  }
@@ -6150,8 +6418,6 @@ var KTSelectCombobox = /** @class */ (function () {
6150
6418
  _this._toggleClearButtonVisibility(_this._searchInputElement.value);
6151
6419
  // this._select.showAllOptions(); // showAllOptions might be too broad, filtering is managed by typing.
6152
6420
  });
6153
- if (this._config.debug)
6154
- console.log('KTSelectCombobox initialized');
6155
6421
  }
6156
6422
  /**
6157
6423
  * Attach event listeners specific to combobox
@@ -8132,7 +8398,13 @@ var KTDataTable = /** @class */ (function (_super) {
8132
8398
  * @returns The KTDataTable instance or undefined if not found
8133
8399
  */
8134
8400
  KTDataTable.getInstance = function (element) {
8135
- return this._instances.get(element);
8401
+ // First check the static Map (for instances created via createInstances)
8402
+ var instanceFromMap = this._instances.get(element);
8403
+ if (instanceFromMap) {
8404
+ return instanceFromMap;
8405
+ }
8406
+ // Fallback to element's instance property (for manually created instances)
8407
+ return element.instance;
8136
8408
  };
8137
8409
  /**
8138
8410
  * Initializes all KTDataTable instances on the page.
@@ -8643,8 +8915,6 @@ var KTSelectDropdown = /** @class */ (function (_super) {
8643
8915
  event.preventDefault();
8644
8916
  event.stopPropagation();
8645
8917
  if (this._config.disabled) {
8646
- if (this._config.debug)
8647
- console.log('KTSelectDropdown._handleToggleClick: select is disabled');
8648
8918
  return;
8649
8919
  }
8650
8920
  // Call KTSelect's methods
@@ -8818,8 +9088,6 @@ var KTSelectDropdown = /** @class */ (function (_super) {
8818
9088
  KTSelectDropdown.prototype.open = function () {
8819
9089
  var _this = this;
8820
9090
  if (this._config.disabled) {
8821
- if (this._config.debug)
8822
- console.log('KTSelectDropdown.open: select is disabled, not opening');
8823
9091
  return;
8824
9092
  }
8825
9093
  if (this._isOpen || this._isTransitioning)
@@ -8876,23 +9144,15 @@ var KTSelectDropdown = /** @class */ (function (_super) {
8876
9144
  */
8877
9145
  KTSelectDropdown.prototype.close = function () {
8878
9146
  var _this = this;
8879
- if (this._config.debug)
8880
- console.log('KTSelectDropdown.close called - isOpen:', this._isOpen, 'isTransitioning:', this._isTransitioning);
8881
9147
  if (!this._isOpen || this._isTransitioning) {
8882
- if (this._config.debug)
8883
- console.log('KTSelectDropdown.close - early return: dropdown not open or is transitioning');
8884
9148
  return;
8885
9149
  }
8886
9150
  // Events and ARIA will be handled by KTSelect
8887
- if (this._config.debug)
8888
- console.log('KTSelectDropdown.close - starting transition');
8889
9151
  this._isTransitioning = true;
8890
9152
  this._dropdownElement.style.opacity = '0';
8891
9153
  var transitionComplete = false;
8892
9154
  var fallbackTimer = setTimeout(function () {
8893
9155
  if (!transitionComplete) {
8894
- if (_this._config.debug)
8895
- console.log('KTSelectDropdown.close - fallback timer triggered');
8896
9156
  completeTransition();
8897
9157
  }
8898
9158
  }, 300);
@@ -8901,8 +9161,6 @@ var KTSelectDropdown = /** @class */ (function (_super) {
8901
9161
  return;
8902
9162
  transitionComplete = true;
8903
9163
  clearTimeout(fallbackTimer);
8904
- if (_this._config.debug)
8905
- console.log('KTSelectDropdown.close - transition ended');
8906
9164
  _this._dropdownElement.classList.add('hidden');
8907
9165
  _this._dropdownElement.classList.remove('open');
8908
9166
  _this._toggleElement.classList.remove('active');
@@ -8911,8 +9169,6 @@ var KTSelectDropdown = /** @class */ (function (_super) {
8911
9169
  _this._isTransitioning = false;
8912
9170
  _this._isOpen = false;
8913
9171
  // Events will be handled by KTSelect
8914
- if (_this._config.debug)
8915
- console.log('KTSelectDropdown.close - visual part complete');
8916
9172
  };
8917
9173
  dom_1.default.transitionEnd(this._dropdownElement, completeTransition);
8918
9174
  if (dom_1.default.getCssProp(this._dropdownElement, 'transition-duration') === '0s') {
@@ -9292,8 +9548,6 @@ var KTSelectSearch = /** @class */ (function () {
9292
9548
  if (this._select.getConfig().enableSearch) {
9293
9549
  this._searchInput = this._select.getSearchInput();
9294
9550
  if (this._searchInput) {
9295
- if (this._config.debug)
9296
- console.log('Initializing search module with input:', this._searchInput);
9297
9551
  // First remove any existing listeners to prevent duplicates
9298
9552
  this._removeEventListeners();
9299
9553
  // Add the input event listener for filtering
@@ -9329,22 +9583,37 @@ var KTSelectSearch = /** @class */ (function () {
9329
9583
  .getWrapperElement()
9330
9584
  .addEventListener('dropdown.close', function () {
9331
9585
  _this._focusManager.resetFocus();
9332
- // If clearSearchOnClose is false and there's a value, the search term and filtered state should persist.
9333
- // KTSelect's closeDropdown method already calls this._searchModule.clearSearch() (which clears highlights)
9334
- // and conditionally clears the input value based on KTSelect's config.clearSearchOnClose.
9335
- // This listener in search.ts seems to unconditionally clear everything.
9336
- // For now, keeping its original behavior:
9337
- _this.clearSearch(); // Clears highlights from current options
9338
- _this._searchInput.value = ''; // Clears the search input field
9339
- _this._resetAllOptions(); // Shows all options, restores original text, removes highlights
9340
- _this._clearNoResultsMessage(); // Clears any "no results" message
9586
+ var config = _this._select.getConfig();
9587
+ // Clear highlights from current options (always do this)
9588
+ _this.clearSearch();
9589
+ // Respect clearSearchOnClose config option
9590
+ if (config.clearSearchOnClose) {
9591
+ // Clear the search input field
9592
+ _this._searchInput.value = '';
9593
+ // Reset all options to their original state
9594
+ _this._resetAllOptions();
9595
+ // Clear any "no results" message
9596
+ _this._clearNoResultsMessage();
9597
+ }
9598
+ else {
9599
+ // When clearSearchOnClose is false, preserve search text
9600
+ // The search input value is already preserved by KTSelect's closeDropdown method
9601
+ // Reset options visibility to show all (they will be re-filtered when dropdown reopens)
9602
+ _this._resetAllOptions();
9603
+ // Clear any "no results" message
9604
+ _this._clearNoResultsMessage();
9605
+ // Note: The search input value is preserved, so when dropdown reopens,
9606
+ // the dropdown.show listener will detect it and re-filter options accordingly
9607
+ }
9341
9608
  });
9342
9609
  // Clear highlights when an option is selected - ATTACH TO ORIGINAL SELECT (standard 'change' event)
9343
9610
  this._select.getElement().addEventListener('change', function () {
9344
9611
  _this.clearSearch();
9345
- // Close dropdown only for single select mode
9612
+ // Close dropdown only for single select mode, and only if closeOnEnter is not false
9346
9613
  // Keep dropdown open for multiple select mode to allow additional selections
9347
- if (!_this._select.getConfig().multiple) {
9614
+ // Also respect closeOnEnter config when it's explicitly set to false
9615
+ var config = _this._select.getConfig();
9616
+ if (!config.multiple && config.closeOnEnter !== false) {
9348
9617
  _this._select.closeDropdown();
9349
9618
  }
9350
9619
  });
@@ -9367,12 +9636,9 @@ var KTSelectSearch = /** @class */ (function () {
9367
9636
  // 2. Clear any "no results" message.
9368
9637
  _this._clearNoResultsMessage();
9369
9638
  }
9370
- // Handle autofocus for the search input (this was one of the original separate listeners)
9639
+ // Handle autofocus for the search input with retry mechanism
9371
9640
  if (_this._select.getConfig().searchAutofocus) {
9372
- setTimeout(function () {
9373
- var _a;
9374
- (_a = _this._searchInput) === null || _a === void 0 ? void 0 : _a.focus(); // Focus search input
9375
- }, 50); // Delay to ensure dropdown is visible
9641
+ _this._focusSearchInputWithRetry();
9376
9642
  }
9377
9643
  _this._select.updateSelectAllButtonState();
9378
9644
  });
@@ -9387,10 +9653,59 @@ var KTSelectSearch = /** @class */ (function () {
9387
9653
  this._eventManager.removeAllListeners(this._searchInput);
9388
9654
  }
9389
9655
  };
9656
+ /**
9657
+ * Focus the search input with retry mechanism for reliability
9658
+ * Retries up to 3 times with exponential backoff (50ms, 100ms, 200ms)
9659
+ */
9660
+ KTSelectSearch.prototype._focusSearchInputWithRetry = function (attempt) {
9661
+ var _this = this;
9662
+ if (attempt === void 0) { attempt = 0; }
9663
+ if (!this._searchInput) {
9664
+ return;
9665
+ }
9666
+ var maxAttempts = 3;
9667
+ var delays = [0, 50, 100, 200]; // Initial attempt + 3 retries
9668
+ if (attempt > maxAttempts) {
9669
+ if (this._config.debug) {
9670
+ console.warn('KTSelect: Failed to focus search input after', maxAttempts, 'attempts');
9671
+ }
9672
+ return;
9673
+ }
9674
+ var delay = delays[attempt] || 200;
9675
+ var focusAttempt = function () {
9676
+ var _a;
9677
+ try {
9678
+ (_a = _this._searchInput) === null || _a === void 0 ? void 0 : _a.focus();
9679
+ // Check if focus was successful
9680
+ var isFocused = document.activeElement === _this._searchInput || _this._searchInput === document.activeElement;
9681
+ if (isFocused) {
9682
+ // Focus successful
9683
+ return;
9684
+ }
9685
+ // Focus failed, retry if we haven't exceeded max attempts
9686
+ if (attempt < maxAttempts) {
9687
+ _this._focusSearchInputWithRetry(attempt + 1);
9688
+ }
9689
+ }
9690
+ catch (error) {
9691
+ // Focus failed with error, retry if we haven't exceeded max attempts
9692
+ if (attempt < maxAttempts) {
9693
+ _this._focusSearchInputWithRetry(attempt + 1);
9694
+ }
9695
+ }
9696
+ };
9697
+ if (delay === 0) {
9698
+ focusAttempt();
9699
+ }
9700
+ else {
9701
+ setTimeout(focusAttempt, delay);
9702
+ }
9703
+ };
9390
9704
  /**
9391
9705
  * Handles keydown events on the search input for navigation and actions.
9392
9706
  */
9393
9707
  KTSelectSearch.prototype._handleSearchKeyDown = function (event) {
9708
+ var _this = this;
9394
9709
  var key = event.key;
9395
9710
  switch (key) {
9396
9711
  case ' ': // Spacebar
@@ -9408,14 +9723,26 @@ var KTSelectSearch = /** @class */ (function () {
9408
9723
  break;
9409
9724
  case 'Enter':
9410
9725
  event.preventDefault();
9411
- // Always attempt to select the first available option in the list.
9412
- // focusFirst() finds, focuses, and returns the first visible, non-disabled option.
9413
9726
  var firstAvailableOption = this._focusManager.focusFirst();
9414
9727
  if (firstAvailableOption) {
9415
9728
  var optionValue = firstAvailableOption.getAttribute('data-value');
9416
9729
  if (optionValue) {
9417
- this._select.toggleSelection(optionValue);
9418
- // KTSelect.toggleSelection handles closing the dropdown based on config.closeOnSelect and config.multiple
9730
+ var config = this._select.getConfig();
9731
+ var isAlreadySelected = !config.multiple && this._select.getSelectedOptions().includes(optionValue);
9732
+ var shouldClose = !config.multiple && config.closeOnEnter !== false;
9733
+ if (isAlreadySelected && shouldClose) {
9734
+ this._select.closeDropdown();
9735
+ }
9736
+ else {
9737
+ this._select.toggleSelection(optionValue);
9738
+ }
9739
+ // Focus display element after closing so user can press Enter again
9740
+ if (shouldClose) {
9741
+ setTimeout(function () {
9742
+ var _a;
9743
+ (_a = _this._select.getDisplayElement()) === null || _a === void 0 ? void 0 : _a.focus();
9744
+ }, 0);
9745
+ }
9419
9746
  }
9420
9747
  }
9421
9748
  break;
@@ -9743,8 +10070,6 @@ var KTSelect = /** @class */ (function (_super) {
9743
10070
  _this._state
9744
10071
  .setItems()
9745
10072
  .then(function () {
9746
- if (_this._config.debug)
9747
- console.log('Setting up component after remote data is loaded');
9748
10073
  _this._setupComponent();
9749
10074
  })
9750
10075
  .catch(function (error) {
@@ -9779,6 +10104,41 @@ var KTSelect = /** @class */ (function (_super) {
9779
10104
  // Cast to writable to allow assignment (config is readonly but needs initialization)
9780
10105
  this._config = __assign(__assign(__assign(__assign(__assign({}, this._defaultConfig), KTSelect.globalConfig), this._getGlobalConfig()), dom_1.default.getDataAttributes(this._element, this._dataOptionPrefix + this._name)), config);
9781
10106
  };
10107
+ /**
10108
+ * Override _dispatchEvent to also dispatch on document for global listeners (jQuery compatibility)
10109
+ */
10110
+ KTSelect.prototype._dispatchEvent = function (eventType, payload) {
10111
+ if (payload === void 0) { payload = null; }
10112
+ // Call parent method to dispatch on element (existing behavior)
10113
+ _super.prototype._dispatchEvent.call(this, eventType, payload);
10114
+ // Also dispatch on document if configured
10115
+ var dispatchGlobalEvents = this._config.dispatchGlobalEvents !== false; // Default to true
10116
+ if (dispatchGlobalEvents) {
10117
+ // Create event detail structure
10118
+ var eventDetail = {
10119
+ payload: payload,
10120
+ instance: this, // Include component instance reference
10121
+ element: this._element, // Include element reference
10122
+ };
10123
+ // Dispatch non-namespaced event on document (for jQuery compatibility: $(document).on('show', ...))
10124
+ var nonNamespacedEvent = new CustomEvent(eventType, {
10125
+ detail: eventDetail,
10126
+ bubbles: true,
10127
+ cancelable: true,
10128
+ composed: true, // Allow event to cross shadow DOM boundaries
10129
+ });
10130
+ document.dispatchEvent(nonNamespacedEvent);
10131
+ // Also dispatch namespaced event on document (for namespaced listeners: $(document).on('kt-select:show', ...))
10132
+ var namespacedEventType = "kt-select:".concat(eventType);
10133
+ var namespacedEvent = new CustomEvent(namespacedEventType, {
10134
+ detail: eventDetail,
10135
+ bubbles: true,
10136
+ cancelable: true,
10137
+ composed: true, // Allow event to cross shadow DOM boundaries
10138
+ });
10139
+ document.dispatchEvent(namespacedEvent);
10140
+ }
10141
+ };
9782
10142
  /**
9783
10143
  * Initialize remote data fetching
9784
10144
  */
@@ -9786,8 +10146,6 @@ var KTSelect = /** @class */ (function (_super) {
9786
10146
  var _this = this;
9787
10147
  if (!this._remoteModule || !this._config.remote)
9788
10148
  return;
9789
- if (this._config.debug)
9790
- console.log('Initializing remote data with URL:', this._config.dataUrl);
9791
10149
  // For remote data, we need to create the HTML structure first
9792
10150
  // so that the component can be properly initialized
9793
10151
  this._createHtmlStructure();
@@ -9798,8 +10156,6 @@ var KTSelect = /** @class */ (function (_super) {
9798
10156
  this._remoteModule
9799
10157
  .fetchData()
9800
10158
  .then(function (items) {
9801
- if (_this._config.debug)
9802
- console.log('Remote data fetched:', items);
9803
10159
  // Remove placeholder/loading options before setting new items
9804
10160
  _this._clearExistingOptions();
9805
10161
  // Update state with fetched items
@@ -9808,8 +10164,6 @@ var KTSelect = /** @class */ (function (_super) {
9808
10164
  .then(function () {
9809
10165
  // Generate options from the fetched data
9810
10166
  _this._generateOptionsHtml(_this._element);
9811
- if (_this._config.debug)
9812
- console.log('Generating options HTML from remote data');
9813
10167
  // Update the dropdown to show the new options
9814
10168
  _this._updateDropdownWithNewOptions();
9815
10169
  // Complete the component setup with the fetched data
@@ -9837,9 +10191,6 @@ var KTSelect = /** @class */ (function (_super) {
9837
10191
  var selectedOptions = Array.from(this._element.querySelectorAll('option[selected]:not([value=""])'));
9838
10192
  if (selectedOptions.length > 0) {
9839
10193
  this._preSelectedValues = selectedOptions.map(function (opt) { return opt.value; });
9840
- if (this._config.debug) {
9841
- console.log('Captured pre-selected values before clearing:', this._preSelectedValues);
9842
- }
9843
10194
  }
9844
10195
  // Keep only the empty/placeholder option and remove the rest
9845
10196
  var options = Array.from(this._element.querySelectorAll('option:not([value=""])'));
@@ -9898,9 +10249,6 @@ var KTSelect = /** @class */ (function (_super) {
9898
10249
  optionsContainer.appendChild(fragment);
9899
10250
  // Update options NodeList
9900
10251
  this._options = this._dropdownContentElement.querySelectorAll('[data-kt-select-option]');
9901
- if (this._config.debug) {
9902
- console.log("Rendered ".concat(optionsData.length, " options in dropdown"));
9903
- }
9904
10252
  };
9905
10253
  /**
9906
10254
  * Update dropdown with new options from the original select element
@@ -9925,9 +10273,6 @@ var KTSelect = /** @class */ (function (_super) {
9925
10273
  }
9926
10274
  // Apply pre-selected values captured before remote data was loaded
9927
10275
  if (this._preSelectedValues.length > 0) {
9928
- if (this._config.debug) {
9929
- console.log('Applying pre-selected values after remote data loaded:', this._preSelectedValues);
9930
- }
9931
10276
  // Get all available option values from the loaded remote data
9932
10277
  var availableValues_1 = Array.from(this._element.querySelectorAll('option')).map(function (opt) { return opt.value; });
9933
10278
  // Filter pre-selected values to only those that exist in remote data
@@ -9939,9 +10284,6 @@ var KTSelect = /** @class */ (function (_super) {
9939
10284
  var valuesToSelect = this._config.multiple
9940
10285
  ? validPreSelectedValues
9941
10286
  : [validPreSelectedValues[0]];
9942
- if (this._config.debug) {
9943
- console.log('Selecting matched values:', valuesToSelect);
9944
- }
9945
10287
  // Get any existing selections from _preSelectOptions (e.g., data-kt-select-pre-selected)
9946
10288
  var existingSelections = this._state.getSelectedOptions();
9947
10289
  // Merge existing selections with native pre-selected values (no duplicates)
@@ -9958,9 +10300,6 @@ var KTSelect = /** @class */ (function (_super) {
9958
10300
  this.updateSelectedOptionDisplay();
9959
10301
  this._updateSelectedOptionClass();
9960
10302
  }
9961
- else if (this._config.debug) {
9962
- console.log('None of the pre-selected values matched remote data:', this._preSelectedValues);
9963
- }
9964
10303
  // Clear the pre-selected values array after processing
9965
10304
  this._preSelectedValues = [];
9966
10305
  }
@@ -10035,8 +10374,6 @@ var KTSelect = /** @class */ (function (_super) {
10035
10374
  // If dropdown is already created, show error message there
10036
10375
  this._showDropdownMessage('error', message);
10037
10376
  if (!this._wrapperElement) {
10038
- if (this._config.debug)
10039
- console.log('Setting up component after error');
10040
10377
  this._setupComponent();
10041
10378
  }
10042
10379
  };
@@ -10148,8 +10485,6 @@ var KTSelect = /** @class */ (function (_super) {
10148
10485
  });
10149
10486
  // Update options NodeList to include the new options
10150
10487
  this._options = this._dropdownContentElement.querySelectorAll("[data-kt-select-option]");
10151
- if (this._config.debug)
10152
- console.log("Added ".concat(newItems.length, " more options to dropdown"));
10153
10488
  };
10154
10489
  /**
10155
10490
  * ========================================================================
@@ -10288,10 +10623,18 @@ var KTSelect = /** @class */ (function (_super) {
10288
10623
  return;
10289
10624
  }
10290
10625
  // Get search input element - this is used for the search functionality
10291
- this._searchInputElement = this._dropdownContentElement.querySelector("[data-kt-select-search]");
10292
- // If not found in dropdown, check if it's the display element itself
10626
+ // First try to find the actual input element (not the wrapper div)
10627
+ this._searchInputElement = this._dropdownContentElement.querySelector("input[data-kt-select-search]");
10628
+ // If not found, try the wrapper selector (for backward compatibility)
10629
+ if (!this._searchInputElement) {
10630
+ var searchWrapper = this._dropdownContentElement.querySelector("[data-kt-select-search]");
10631
+ if (searchWrapper) {
10632
+ this._searchInputElement = searchWrapper.querySelector('input');
10633
+ }
10634
+ }
10635
+ // If still not found in dropdown, check if it's the display element itself (combobox mode)
10293
10636
  if (!this._searchInputElement) {
10294
- this._searchInputElement = this._displayElement;
10637
+ this._searchInputElement = this._displayElement.querySelector('input[data-kt-select-search]');
10295
10638
  }
10296
10639
  this._selectAllButton = this._wrapperElement.querySelector('[data-kt-select-select-all]');
10297
10640
  // Cache the options container for performance
@@ -10357,8 +10700,6 @@ var KTSelect = /** @class */ (function (_super) {
10357
10700
  KTSelect.prototype._generateOptionsHtml = function (element) {
10358
10701
  var _this = this;
10359
10702
  var items = this._state.getItems() || [];
10360
- if (this._config.debug)
10361
- console.log("Generating options HTML from ".concat(items.length, " items"));
10362
10703
  // Only modify options if we have items to replace them with
10363
10704
  if (items && items.length > 0) {
10364
10705
  // Clear existing options except the first empty one
@@ -10386,9 +10727,6 @@ var KTSelect = /** @class */ (function (_super) {
10386
10727
  label =
10387
10728
  extractedLabel !== null ? String(extractedLabel) : 'Unnamed option';
10388
10729
  }
10389
- // Log the extracted values for debugging
10390
- if (_this._config.debug)
10391
- console.log("Option: value=".concat(value, ", label=").concat(label));
10392
10730
  // Set option attributes
10393
10731
  optionElement.value = value;
10394
10732
  optionElement.textContent = label || 'Unnamed option';
@@ -10397,12 +10735,6 @@ var KTSelect = /** @class */ (function (_super) {
10397
10735
  }
10398
10736
  element.appendChild(optionElement);
10399
10737
  });
10400
- if (this._config.debug)
10401
- console.log("Added ".concat(items.length, " options to select element"));
10402
- }
10403
- else {
10404
- if (this._config.debug)
10405
- console.log('No items to generate options from');
10406
10738
  }
10407
10739
  };
10408
10740
  /**
@@ -10415,8 +10747,6 @@ var KTSelect = /** @class */ (function (_super) {
10415
10747
  var result = key
10416
10748
  .split('.')
10417
10749
  .reduce(function (o, k) { return (o && o[k] !== undefined ? o[k] : null); }, obj);
10418
- if (this._config.debug)
10419
- console.log("Extracting [".concat(key, "] from object => ").concat(result !== null ? JSON.stringify(result) : 'null'));
10420
10750
  return result;
10421
10751
  };
10422
10752
  /**
@@ -10449,55 +10779,79 @@ var KTSelect = /** @class */ (function (_super) {
10449
10779
  * Open the dropdown
10450
10780
  */
10451
10781
  KTSelect.prototype.openDropdown = function () {
10782
+ var _this = this;
10452
10783
  if (this._config.disabled) {
10453
- if (this._config.debug)
10454
- console.log('openDropdown: select is disabled, not opening');
10455
10784
  return;
10456
10785
  }
10457
- if (this._config.debug)
10458
- console.log('openDropdown called, dropdownModule exists:', !!this._dropdownModule);
10459
10786
  if (!this._dropdownModule) {
10460
- if (this._config.debug)
10461
- console.log('Early return from openDropdown - module missing');
10462
10787
  return;
10463
10788
  }
10464
10789
  // Don't open dropdown if the select is disabled
10465
10790
  if (this._config.disabled) {
10466
- if (this._config.debug)
10467
- console.log('Early return from openDropdown - select is disabled');
10468
10791
  return;
10469
10792
  }
10470
- if (this._config.debug)
10471
- console.log('Opening dropdown via dropdownModule...');
10793
+ // Global dropdown management: close other open dropdowns if configured
10794
+ var closeOnOtherOpen = this._config.closeOnOtherOpen !== false; // Default to true
10795
+ if (closeOnOtherOpen) {
10796
+ // Close all other open dropdowns
10797
+ var otherSelectsToClose_1 = [];
10798
+ KTSelect.openDropdowns.forEach(function (otherSelect) {
10799
+ var isOther = otherSelect !== _this;
10800
+ var isOpen = otherSelect._dropdownIsOpen;
10801
+ if (isOther && isOpen) {
10802
+ otherSelectsToClose_1.push(otherSelect);
10803
+ }
10804
+ });
10805
+ otherSelectsToClose_1.forEach(function (otherSelect) {
10806
+ otherSelect.closeDropdown();
10807
+ });
10808
+ }
10472
10809
  // Set our internal flag to match what we're doing
10473
10810
  this._dropdownIsOpen = true;
10811
+ // Add to registry
10812
+ KTSelect.openDropdowns.add(this);
10474
10813
  // Open the dropdown via the module
10475
10814
  this._dropdownModule.open();
10476
- // Dispatch custom event
10815
+ // Dispatch custom events
10477
10816
  this._dispatchEvent('show');
10478
10817
  this._fireEvent('show');
10818
+ // Dispatch dropdown.show event on wrapper for search module
10819
+ var dropdownShowEvent = new CustomEvent('dropdown.show', {
10820
+ bubbles: true,
10821
+ cancelable: true,
10822
+ });
10823
+ this._wrapperElement.dispatchEvent(dropdownShowEvent);
10479
10824
  // Update ARIA states
10480
10825
  this._setAriaAttributes();
10481
10826
  // Update select all button state
10482
10827
  this.updateSelectAllButtonState();
10483
10828
  // Focus the first selected option or first option if nothing selected
10484
- this._focusSelectedOption();
10829
+ // BUT: Skip this if search autofocus is enabled, as we want search input to get focus
10830
+ if (!(this._config.enableSearch && this._config.searchAutofocus)) {
10831
+ this._focusSelectedOption();
10832
+ }
10833
+ // Dispatch dropdown.show event on the wrapper element for search module
10834
+ // Use requestAnimationFrame to ensure dropdown is visible and transition has started
10835
+ requestAnimationFrame(function () {
10836
+ requestAnimationFrame(function () {
10837
+ if (_this._wrapperElement) {
10838
+ var dropdownShowEvent_1 = new CustomEvent('dropdown.show', {
10839
+ bubbles: true,
10840
+ cancelable: true,
10841
+ });
10842
+ _this._wrapperElement.dispatchEvent(dropdownShowEvent_1);
10843
+ }
10844
+ });
10845
+ });
10485
10846
  };
10486
10847
  /**
10487
10848
  * Close the dropdown
10488
10849
  */
10489
10850
  KTSelect.prototype.closeDropdown = function () {
10490
- if (this._config.debug)
10491
- console.log('closeDropdown called, dropdownModule exists:', !!this._dropdownModule);
10492
10851
  // Only check if dropdown module exists, not dropdownIsOpen flag
10493
10852
  if (!this._dropdownModule) {
10494
- if (this._config.debug)
10495
- console.log('Early return from closeDropdown - module missing');
10496
10853
  return;
10497
10854
  }
10498
- // Always close by delegating to the dropdown module, which is the source of truth
10499
- if (this._config.debug)
10500
- console.log('Closing dropdown via dropdownModule...');
10501
10855
  // Clear search input if the dropdown is closing
10502
10856
  if (this._searchModule && this._searchInputElement) {
10503
10857
  // Clear search input if configured to do so
@@ -10509,19 +10863,25 @@ var KTSelect = /** @class */ (function (_super) {
10509
10863
  }
10510
10864
  // Set our internal flag to match what we're doing
10511
10865
  this._dropdownIsOpen = false;
10866
+ // Remove from registry
10867
+ KTSelect.openDropdowns.delete(this);
10512
10868
  // Call the dropdown module's close method
10513
10869
  this._dropdownModule.close();
10514
10870
  // Reset all focus states
10515
10871
  if (this._focusManager) {
10516
10872
  this._focusManager.resetFocus();
10517
10873
  }
10518
- // Dispatch custom events
10874
+ // Dispatch custom events on the select element
10519
10875
  this._dispatchEvent('close');
10520
10876
  this._fireEvent('close');
10877
+ // Dispatch dropdown.close event on wrapper for search module
10878
+ var dropdownCloseEvent = new CustomEvent('dropdown.close', {
10879
+ bubbles: true,
10880
+ cancelable: true,
10881
+ });
10882
+ this._wrapperElement.dispatchEvent(dropdownCloseEvent);
10521
10883
  // Update ARIA states
10522
10884
  this._setAriaAttributes();
10523
- if (this._config.debug)
10524
- console.log('closeDropdown complete');
10525
10885
  };
10526
10886
  /**
10527
10887
  * Update dropdown position
@@ -10558,8 +10918,6 @@ var KTSelect = /** @class */ (function (_super) {
10558
10918
  KTSelect.prototype._selectOption = function (value) {
10559
10919
  // Prevent selection if the option is disabled (in dropdown or original select)
10560
10920
  if (this._isOptionDisabled(value)) {
10561
- if (this._config.debug)
10562
- console.log('_selectOption: Option is disabled, ignoring selection');
10563
10921
  return;
10564
10922
  }
10565
10923
  // Get current selection state
@@ -10688,8 +11046,6 @@ var KTSelect = /** @class */ (function (_super) {
10688
11046
  var selectedValues = this._state.getSelectedOptions();
10689
11047
  var maxReached = typeof this._config.maxSelections === 'number' &&
10690
11048
  selectedValues.length >= this._config.maxSelections;
10691
- if (this._config.debug)
10692
- console.log('Updating selected classes for options, selected values:', selectedValues);
10693
11049
  allOptions.forEach(function (option) {
10694
11050
  var optionValue = option.getAttribute('data-value');
10695
11051
  if (!optionValue)
@@ -10739,6 +11095,55 @@ var KTSelect = /** @class */ (function (_super) {
10739
11095
  this._dispatchEvent('change');
10740
11096
  this._fireEvent('change');
10741
11097
  };
11098
+ /**
11099
+ * Deselect a specific option by value
11100
+ * @param value The value of the option to deselect
11101
+ * @public
11102
+ */
11103
+ KTSelect.prototype.deselectOption = function (value) {
11104
+ // Check if the option is currently selected
11105
+ if (!this._state.isSelected(value)) {
11106
+ return; // Already deselected
11107
+ }
11108
+ // For single-select mode, check if clearing is allowed
11109
+ if (!this._config.multiple && !this._config.allowClear) {
11110
+ return; // Cannot deselect in single-select mode unless allowClear is true
11111
+ }
11112
+ // Remove from selected options
11113
+ if (this._config.multiple) {
11114
+ // For multiple select, just toggle it off
11115
+ this._state.toggleSelectedOptions(value);
11116
+ }
11117
+ else {
11118
+ // For single select, clear all selections
11119
+ this._state.setSelectedOptions([]);
11120
+ }
11121
+ // Update the native select element
11122
+ var optionEl = Array.from(this._element.querySelectorAll('option')).find(function (opt) { return opt.value === value; });
11123
+ if (optionEl) {
11124
+ optionEl.selected = false;
11125
+ }
11126
+ // For single select, clear the native select value
11127
+ if (!this._config.multiple) {
11128
+ this._element.value = '';
11129
+ }
11130
+ // Update the display
11131
+ this.updateSelectedOptionDisplay();
11132
+ this._updateSelectedOptionClass();
11133
+ // Update select all button state
11134
+ this.updateSelectAllButtonState();
11135
+ // Dispatch change event
11136
+ this._dispatchEvent('change', {
11137
+ value: value,
11138
+ selected: false,
11139
+ selectedOptions: this.getSelectedOptions(),
11140
+ });
11141
+ this._fireEvent('change', {
11142
+ value: value,
11143
+ selected: false,
11144
+ selectedOptions: this.getSelectedOptions(),
11145
+ });
11146
+ };
10742
11147
  /**
10743
11148
  * Set selected options programmatically
10744
11149
  */
@@ -10790,36 +11195,24 @@ var KTSelect = /** @class */ (function (_super) {
10790
11195
  * Handle clicking on an option in the dropdown
10791
11196
  */
10792
11197
  KTSelect.prototype._handleOptionClick = function (event) {
10793
- if (this._config.debug)
10794
- console.log('_handleOptionClick called', event.target);
10795
11198
  event.preventDefault();
10796
11199
  event.stopPropagation();
10797
11200
  // Find the clicked option element
10798
11201
  var clickedOption = event.target.closest("[data-kt-select-option]");
10799
11202
  if (!clickedOption) {
10800
- if (this._config.debug)
10801
- console.log('No clicked option found');
10802
11203
  return;
10803
11204
  }
10804
11205
  // Check if the option is disabled
10805
11206
  if (clickedOption.getAttribute('aria-disabled') === 'true') {
10806
- if (this._config.debug)
10807
- console.log('Option is disabled, ignoring click');
10808
11207
  return;
10809
11208
  }
10810
11209
  // Use dataset.value to get the option value
10811
11210
  var optionValue = clickedOption.dataset.value;
10812
11211
  if (optionValue === undefined) {
10813
- if (this._config.debug)
10814
- console.log('Option value is undefined');
10815
11212
  return;
10816
11213
  }
10817
- if (this._config.debug)
10818
- console.log('Option clicked:', optionValue);
10819
11214
  // If in single-select mode and the clicked option is already selected, just close the dropdown.
10820
11215
  if (!this._config.multiple && this._state.isSelected(optionValue)) {
10821
- if (this._config.debug)
10822
- console.log('Single select mode: clicked already selected option. Closing dropdown.');
10823
11216
  this.closeDropdown();
10824
11217
  return;
10825
11218
  }
@@ -10948,22 +11341,19 @@ var KTSelect = /** @class */ (function (_super) {
10948
11341
  KTSelect.prototype.toggleSelection = function (value) {
10949
11342
  // Prevent selection if the option is disabled (in dropdown or original select)
10950
11343
  if (this._isOptionDisabled(value)) {
10951
- if (this._config.debug)
10952
- console.log('toggleSelection: Option is disabled, ignoring selection');
10953
11344
  return;
10954
11345
  }
10955
11346
  // Get current selection state
10956
11347
  var isSelected = this._state.isSelected(value);
10957
- if (this._config.debug)
10958
- console.log("toggleSelection called for value: ".concat(value, ", isSelected: ").concat(isSelected, ", multiple: ").concat(this._config.multiple));
10959
- // If already selected in single select mode, do nothing (can't deselect in single select)
11348
+ // If already selected in single select mode, allow deselecting only if allowClear is true
10960
11349
  if (isSelected && !this._config.multiple) {
10961
- if (this._config.debug)
10962
- console.log('Early return from toggleSelection - already selected in single select mode');
10963
- return;
11350
+ if (this._config.allowClear) {
11351
+ // Use the deselectOption method to handle clearing
11352
+ this.deselectOption(value);
11353
+ return;
11354
+ }
11355
+ return; // Can't deselect in single select mode when allowClear is false
10964
11356
  }
10965
- if (this._config.debug)
10966
- console.log("Toggling selection for option: ".concat(value, ", currently selected: ").concat(isSelected));
10967
11357
  // Ensure any search input is cleared when selection changes
10968
11358
  if (this._searchModule) {
10969
11359
  this._searchModule.clearSearch();
@@ -10988,16 +11378,21 @@ var KTSelect = /** @class */ (function (_super) {
10988
11378
  this.updateSelectedOptionDisplay();
10989
11379
  // Update option classes without re-rendering the dropdown content
10990
11380
  this._updateSelectedOptionClass();
10991
- // For single select mode, always close the dropdown after selection
11381
+ // For single select mode, close the dropdown after selection unless closeOnEnter is false
10992
11382
  // For multiple select mode, keep the dropdown open to allow multiple selections
10993
11383
  if (!this._config.multiple) {
10994
- if (this._config.debug)
10995
- console.log('About to call closeDropdown() for single select mode - always close after selection');
10996
- this.closeDropdown();
11384
+ // Check if we should close based on closeOnEnter config
11385
+ // closeOnEnter only applies to Enter key selections, but for backward compatibility,
11386
+ // we'll respect it for all selections when explicitly set to false
11387
+ var shouldClose = this._config.closeOnEnter !== false; // Default to true
11388
+ if (shouldClose) {
11389
+ this.closeDropdown();
11390
+ }
11391
+ else {
11392
+ this.updateSelectAllButtonState();
11393
+ }
10997
11394
  }
10998
11395
  else {
10999
- if (this._config.debug)
11000
- console.log('Multiple select mode - keeping dropdown open for additional selections');
11001
11396
  // Don't close dropdown in multiple select mode to allow multiple selections
11002
11397
  this.updateSelectAllButtonState();
11003
11398
  }
@@ -11129,9 +11524,6 @@ var KTSelect = /** @class */ (function (_super) {
11129
11524
  var validSelections = currentlySelected.filter(function (value) {
11130
11525
  return availableValues.includes(value);
11131
11526
  });
11132
- if (_this._config.debug && currentlySelected.length > 0) {
11133
- console.log('update(): Preserving selections that exist in new data:', validSelections);
11134
- }
11135
11527
  // Add new options from remote data and restore selection state
11136
11528
  items.forEach(function (item) {
11137
11529
  var option = document.createElement('option');
@@ -11214,9 +11606,6 @@ var KTSelect = /** @class */ (function (_super) {
11214
11606
  var validSelections = currentlySelected.filter(function (value) {
11215
11607
  return availableValues.includes(value);
11216
11608
  });
11217
- if (_this._config.debug && currentlySelected.length > 0) {
11218
- console.log('reload(): Preserving selections that exist in new data:', validSelections);
11219
- }
11220
11609
  // Mark preserved selections on new options
11221
11610
  validSelections.forEach(function (value) {
11222
11611
  var option = Array.from(_this._element.querySelectorAll('option')).find(function (opt) { return opt.value === value; });
@@ -11280,9 +11669,6 @@ var KTSelect = /** @class */ (function (_super) {
11280
11669
  var validSelections = currentlySelected.filter(function (value) {
11281
11670
  return availableValues.includes(value);
11282
11671
  });
11283
- if (_this._config.debug && currentlySelected.length > 0) {
11284
- console.log('refresh(): Preserving selections that exist in new data:', validSelections);
11285
- }
11286
11672
  // Add new options and restore selection state
11287
11673
  items.forEach(function (item) {
11288
11674
  var option = document.createElement('option');
@@ -11461,9 +11847,6 @@ var KTSelect = /** @class */ (function (_super) {
11461
11847
  this._searchModule.refreshAfterSearch();
11462
11848
  }
11463
11849
  this.updateSelectAllButtonState();
11464
- if (this._config.debug) {
11465
- console.log('Restored original options after search clear');
11466
- }
11467
11850
  };
11468
11851
  /**
11469
11852
  * Update search results in the dropdown
@@ -11514,9 +11897,6 @@ var KTSelect = /** @class */ (function (_super) {
11514
11897
  }
11515
11898
  _this._element.appendChild(optionElement);
11516
11899
  });
11517
- if (this._config.debug) {
11518
- console.log("Updated original select with ".concat(items.length, " search results"));
11519
- }
11520
11900
  };
11521
11901
  /**
11522
11902
  * Check if dropdown is open
@@ -11641,8 +12021,6 @@ var KTSelect = /** @class */ (function (_super) {
11641
12021
  if (val !== undefined &&
11642
12022
  !this._config.multiple &&
11643
12023
  this._state.isSelected(val)) {
11644
- if (this._config.debug)
11645
- console.log('Enter on already selected item in single-select mode. Closing.');
11646
12024
  this.closeDropdown();
11647
12025
  event.preventDefault();
11648
12026
  break;
@@ -11826,8 +12204,23 @@ var KTSelect = /** @class */ (function (_super) {
11826
12204
  ? this._config.clearAllText
11827
12205
  : this._config.selectAllText;
11828
12206
  };
12207
+ /**
12208
+ * Destroy the component and clean up resources
12209
+ */
12210
+ KTSelect.prototype.destroy = function () {
12211
+ // Remove from global dropdown registry
12212
+ KTSelect.openDropdowns.delete(this);
12213
+ // Close dropdown if open
12214
+ if (this._dropdownIsOpen) {
12215
+ this.closeDropdown();
12216
+ }
12217
+ // Call parent dispose method
12218
+ _super.prototype.dispose.call(this);
12219
+ };
11829
12220
  // Static global configuration
11830
12221
  KTSelect.globalConfig = {};
12222
+ // Static registry for tracking open dropdowns (global dropdown management)
12223
+ KTSelect.openDropdowns = new Set();
11831
12224
  return KTSelect;
11832
12225
  }(component_1.default));
11833
12226
  exports.KTSelect = KTSelect;
@@ -12028,16 +12421,19 @@ var KTDropdown = /** @class */ (function (_super) {
12028
12421
  _this._disabled = false;
12029
12422
  _this._isTransitioning = false;
12030
12423
  _this._isOpen = false;
12031
- if (data_1.default.has(element, _this._name))
12424
+ if (data_1.default.has(element, _this._name)) {
12032
12425
  return _this;
12426
+ }
12033
12427
  _this._init(element);
12034
12428
  _this._buildConfig(config);
12035
12429
  _this._toggleElement = _this._element.querySelector('[data-kt-dropdown-toggle]');
12036
- if (!_this._toggleElement)
12430
+ if (!_this._toggleElement) {
12037
12431
  return _this;
12432
+ }
12038
12433
  _this._menuElement = _this._element.querySelector('[data-kt-dropdown-menu]');
12039
- if (!_this._menuElement)
12434
+ if (!_this._menuElement) {
12040
12435
  return _this;
12436
+ }
12041
12437
  data_1.default.set(_this._menuElement, 'dropdownElement', _this._element);
12042
12438
  _this._setupNestedDropdowns();
12043
12439
  _this._handleContainer();
@@ -12070,10 +12466,12 @@ var KTDropdown = /** @class */ (function (_super) {
12070
12466
  KTDropdown.prototype._click = function (event) {
12071
12467
  event.preventDefault();
12072
12468
  event.stopPropagation();
12073
- if (this._disabled)
12469
+ if (this._disabled) {
12074
12470
  return;
12075
- if (this._getOption('trigger') !== 'click')
12471
+ }
12472
+ if (this._getOption('trigger') !== 'click') {
12076
12473
  return;
12474
+ }
12077
12475
  this._toggle();
12078
12476
  };
12079
12477
  KTDropdown.prototype._mouseover = function (event) {
@@ -12116,8 +12514,9 @@ var KTDropdown = /** @class */ (function (_super) {
12116
12514
  };
12117
12515
  KTDropdown.prototype._show = function () {
12118
12516
  var _this = this;
12119
- if (this._isOpen || this._isTransitioning)
12517
+ if (this._isOpen || this._isTransitioning) {
12120
12518
  return;
12519
+ }
12121
12520
  var payload = { cancel: false };
12122
12521
  this._fireEvent('show', payload);
12123
12522
  this._dispatchEvent('show', payload);
@@ -12290,6 +12689,12 @@ var KTDropdown = /** @class */ (function (_super) {
12290
12689
  reference.closest('[data-kt-dropdown-initialized]');
12291
12690
  if (findElement)
12292
12691
  return findElement;
12692
+ // Fallback: look for parent with data-kt-dropdown attribute
12693
+ if (reference) {
12694
+ var dropdownContainer = reference.closest('[data-kt-dropdown]');
12695
+ if (dropdownContainer)
12696
+ return dropdownContainer;
12697
+ }
12293
12698
  if (reference &&
12294
12699
  reference.hasAttribute('data-kt-dropdown-menu') &&
12295
12700
  data_1.default.has(reference, 'dropdownElement')) {
@@ -12299,10 +12704,12 @@ var KTDropdown = /** @class */ (function (_super) {
12299
12704
  };
12300
12705
  KTDropdown.getInstance = function (element) {
12301
12706
  element = this.getElement(element);
12302
- if (!element)
12707
+ if (!element) {
12303
12708
  return null;
12709
+ }
12304
12710
  if (data_1.default.has(element, 'dropdown')) {
12305
- return data_1.default.get(element, 'dropdown');
12711
+ var instance = data_1.default.get(element, 'dropdown');
12712
+ return instance;
12306
12713
  }
12307
12714
  if (element.getAttribute('data-kt-dropdown-initialized') === 'true') {
12308
12715
  return new KTDropdown(element);
@@ -12417,6 +12824,39 @@ var KTDropdown = /** @class */ (function (_super) {
12417
12824
  window.KT_DROPDOWN_INITIALIZED = true;
12418
12825
  }
12419
12826
  };
12827
+ /**
12828
+ * Force reinitialization of dropdowns by clearing KTData entries.
12829
+ * Useful for Livewire wire:navigate where persisted elements need reinitialization.
12830
+ */
12831
+ KTDropdown.reinit = function () {
12832
+ var elements = document.querySelectorAll('[data-kt-dropdown]');
12833
+ elements.forEach(function (element) {
12834
+ try {
12835
+ // Get existing instance to clean up Popper
12836
+ var instance = KTDropdown.getInstance(element);
12837
+ if (instance && typeof instance.hide === 'function') {
12838
+ instance.hide(); // This will destroy Popper
12839
+ }
12840
+ // Clear KTData entries
12841
+ data_1.default.remove(element, 'dropdown');
12842
+ data_1.default.remove(element, 'popper');
12843
+ // Remove initialization attribute to allow fresh initialization
12844
+ element.removeAttribute('data-kt-dropdown-initialized');
12845
+ var menu = element.querySelector('[data-kt-dropdown-menu]');
12846
+ if (menu) {
12847
+ data_1.default.remove(menu, 'dropdownElement');
12848
+ }
12849
+ }
12850
+ catch (e) {
12851
+ // Ignore errors for individual elements
12852
+ }
12853
+ });
12854
+ // Now create fresh instances
12855
+ KTDropdown.createInstances();
12856
+ // Always ensure handlers are set up (similar to KTMenu.init() behavior)
12857
+ // Event handlers use delegation so they persist, but we ensure they're attached
12858
+ KTDropdown.initHandlers();
12859
+ };
12420
12860
  return KTDropdown;
12421
12861
  }(component_1.default));
12422
12862
  exports.KTDropdown = KTDropdown;
@@ -12480,7 +12920,15 @@ var KTData = {
12480
12920
  KTElementMap.delete(element);
12481
12921
  }
12482
12922
  },
12923
+ // Clear all data for a specific element (useful for reinitialization)
12924
+ clear: function (element) {
12925
+ KTElementMap.delete(element);
12926
+ },
12483
12927
  };
12928
+ // Expose KTData on window for external access (useful for Livewire wire:navigate)
12929
+ if (typeof window !== 'undefined') {
12930
+ window.KTData = KTData;
12931
+ }
12484
12932
  exports["default"] = KTData;
12485
12933
 
12486
12934
 
@@ -12510,8 +12958,6 @@ var KTSelectTags = /** @class */ (function () {
12510
12958
  this._config = select.getConfig();
12511
12959
  this._valueDisplayElement = select.getValueDisplayElement();
12512
12960
  this._eventManager = new utils_1.EventManager();
12513
- if (this._config.debug)
12514
- console.log('KTSelectTags initialized');
12515
12961
  }
12516
12962
  /**
12517
12963
  * Update selected tags display
@@ -14358,7 +14804,8 @@ exports.DefaultConfig = {
14358
14804
  searchMinLength: 0, // Minimum characters required to trigger search
14359
14805
  searchMaxItems: 50, // Maximum number of search results to display
14360
14806
  searchEmpty: 'No results', // Text to display when no search results are found
14361
- clearSearchOnClose: true, // Clear search input when dropdown closes
14807
+ clearSearchOnClose: false, // Clear search input when dropdown closes (default: false to persist search text)
14808
+ closeOnEnter: true, // Close dropdown when Enter is pressed in search input
14362
14809
  // Multi-Select Display
14363
14810
  selectAllText: 'Select all', // Text for the "Select All" option (if implemented)
14364
14811
  clearAllText: 'Clear all', // Text for the "Clear All" option (if implemented)
@@ -14376,6 +14823,8 @@ exports.DefaultConfig = {
14376
14823
  dropdownPreventOverflow: false,
14377
14824
  dropdownStrategy: null,
14378
14825
  dropdownWidth: null, // Custom width for dropdown (e.g., '300px'), null to match toggle element width
14826
+ closeOnOtherOpen: true, // Close other open dropdowns when this one opens
14827
+ dispatchGlobalEvents: true, // Dispatch events on document for global listeners (jQuery compatibility)
14379
14828
  // New Config
14380
14829
  dropdownTemplate: '',
14381
14830
  };