admin-lte 4.1.0 → 4.3.1

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 (57) hide show
  1. package/CHANGELOG.md +57 -1
  2. package/README.md +23 -7
  3. package/dist/css/adminlte-docs.css +1 -1
  4. package/dist/css/adminlte-docs.css.map +1 -1
  5. package/dist/css/adminlte-docs.min.css +1 -1
  6. package/dist/css/adminlte-docs.min.css.map +1 -1
  7. package/dist/css/adminlte-docs.rtl.css +1 -1
  8. package/dist/css/adminlte-docs.rtl.css.map +1 -1
  9. package/dist/css/adminlte-docs.rtl.min.css +1 -1
  10. package/dist/css/adminlte-docs.rtl.min.css.map +1 -1
  11. package/dist/css/adminlte-select2.css +329 -0
  12. package/dist/css/adminlte-select2.css.map +1 -0
  13. package/dist/css/adminlte-select2.min.css +12 -0
  14. package/dist/css/adminlte-select2.min.css.map +1 -0
  15. package/dist/css/adminlte-select2.rtl.css +328 -0
  16. package/dist/css/adminlte-select2.rtl.css.map +1 -0
  17. package/dist/css/adminlte-select2.rtl.min.css +12 -0
  18. package/dist/css/adminlte-select2.rtl.min.css.map +1 -0
  19. package/dist/css/adminlte.css +332 -131
  20. package/dist/css/adminlte.css.map +1 -1
  21. package/dist/css/adminlte.min.css +2 -2
  22. package/dist/css/adminlte.min.css.map +1 -1
  23. package/dist/css/adminlte.rtl.css +332 -131
  24. package/dist/css/adminlte.rtl.css.map +1 -1
  25. package/dist/css/adminlte.rtl.min.css +2 -2
  26. package/dist/css/adminlte.rtl.min.css.map +1 -1
  27. package/dist/js/adminlte.esm.js +300 -109
  28. package/dist/js/adminlte.esm.js.map +1 -1
  29. package/dist/js/adminlte.esm.min.js +2 -2
  30. package/dist/js/adminlte.esm.min.js.map +1 -1
  31. package/dist/js/adminlte.js +302 -108
  32. package/dist/js/adminlte.js.map +1 -1
  33. package/dist/js/adminlte.min.js +2 -2
  34. package/dist/js/adminlte.min.js.map +1 -1
  35. package/dist/js/types/adminlte.d.ts +3 -1
  36. package/dist/js/types/base-component.d.ts +24 -0
  37. package/dist/js/types/color-mode.d.ts +24 -6
  38. package/dist/js/types/push-menu.d.ts +21 -0
  39. package/dist/js/types/sidebar-search.d.ts +46 -0
  40. package/dist/js/types/util/index.d.ts +38 -1
  41. package/package.json +24 -23
  42. package/src/scss/_app-sidebar.scss +12 -0
  43. package/src/scss/_ribbon.scss +75 -0
  44. package/src/scss/_variables.scss +28 -0
  45. package/src/scss/_widgets.scss +192 -0
  46. package/src/scss/adminlte-docs.scss +1 -1
  47. package/src/scss/adminlte-select2.scss +31 -0
  48. package/src/scss/adminlte.scss +1 -1
  49. package/src/scss/compat/_select2.scss +476 -0
  50. package/src/scss/parts/_extra-components.scss +2 -0
  51. package/src/ts/accessibility.ts +31 -15
  52. package/src/ts/adminlte.ts +7 -3
  53. package/src/ts/base-component.ts +30 -3
  54. package/src/ts/color-mode.ts +100 -20
  55. package/src/ts/push-menu.ts +37 -7
  56. package/src/ts/sidebar-search.ts +252 -0
  57. package/src/ts/util/index.ts +79 -15
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * AdminLTE v4.1.0 (https://adminlte.io)
2
+ * AdminLTE v4.3.1 (https://adminlte.io)
3
3
  * Copyright 2014-2026 Colorlib <https://colorlib.com>
4
4
  * Licensed under MIT (https://github.com/ColorlibHQ/AdminLTE/blob/master/LICENSE)
5
5
  */
@@ -12,7 +12,8 @@
12
12
  const lifecycleCallbacks = [];
13
13
  const lifecycleState = {
14
14
  controller: new AbortController(),
15
- hasInitialized: false
15
+ hasInitialized: false,
16
+ isReplaying: false
16
17
  };
17
18
  const getLifecycleSignal = () => lifecycleState.controller.signal;
18
19
  const runLifecycleCallbacks = () => {
@@ -20,8 +21,14 @@
20
21
  return;
21
22
  }
22
23
  lifecycleState.hasInitialized = true;
23
- for (const callback of lifecycleCallbacks) {
24
- callback();
24
+ lifecycleState.isReplaying = true;
25
+ try {
26
+ for (const callback of lifecycleCallbacks) {
27
+ callback();
28
+ }
29
+ }
30
+ finally {
31
+ lifecycleState.isReplaying = false;
25
32
  }
26
33
  };
27
34
  const onDOMContentLoaded = (callback) => {
@@ -30,17 +37,25 @@
30
37
  callback();
31
38
  }
32
39
  };
40
+ const teardown = () => {
41
+ lifecycleState.controller.abort();
42
+ lifecycleState.controller = new AbortController();
43
+ lifecycleState.hasInitialized = false;
44
+ };
45
+ const initialize = () => {
46
+ if (lifecycleState.isReplaying) {
47
+ return;
48
+ }
49
+ teardown();
50
+ runLifecycleCallbacks();
51
+ };
33
52
  if (document.readyState === 'loading') {
34
- document.addEventListener('DOMContentLoaded', runLifecycleCallbacks, { once: true });
53
+ document.addEventListener('DOMContentLoaded', initialize, { once: true });
35
54
  }
36
55
  else {
37
56
  runLifecycleCallbacks();
38
57
  }
39
- document.addEventListener('turbo:before-render', () => {
40
- lifecycleState.controller.abort();
41
- lifecycleState.controller = new AbortController();
42
- lifecycleState.hasInitialized = false;
43
- });
58
+ document.addEventListener('turbo:before-render', teardown);
44
59
  document.addEventListener('turbo:load', runLifecycleCallbacks);
45
60
  const slideTimers = new WeakMap();
46
61
  const cancelSlide = (target) => {
@@ -183,16 +198,16 @@
183
198
  return event;
184
199
  };
185
200
 
186
- const NAME$4 = 'card-widget';
187
- const EVENT_KEY$5 = `.lte.${NAME$4}`;
188
- const EVENT_COLLAPSE$2 = `collapse${EVENT_KEY$5}`;
189
- const EVENT_EXPAND$1 = `expand${EVENT_KEY$5}`;
190
- const EVENT_REMOVE = `remove${EVENT_KEY$5}`;
191
- const EVENT_COLLAPSED$3 = `collapsed${EVENT_KEY$5}`;
192
- const EVENT_EXPANDED$2 = `expanded${EVENT_KEY$5}`;
193
- const EVENT_REMOVED = `removed${EVENT_KEY$5}`;
194
- const EVENT_MAXIMIZED$1 = `maximized${EVENT_KEY$5}`;
195
- const EVENT_MINIMIZED$1 = `minimized${EVENT_KEY$5}`;
201
+ const NAME$5 = 'card-widget';
202
+ const EVENT_KEY$6 = `.lte.${NAME$5}`;
203
+ const EVENT_COLLAPSE$2 = `collapse${EVENT_KEY$6}`;
204
+ const EVENT_EXPAND$1 = `expand${EVENT_KEY$6}`;
205
+ const EVENT_REMOVE = `remove${EVENT_KEY$6}`;
206
+ const EVENT_COLLAPSED$3 = `collapsed${EVENT_KEY$6}`;
207
+ const EVENT_EXPANDED$2 = `expanded${EVENT_KEY$6}`;
208
+ const EVENT_REMOVED = `removed${EVENT_KEY$6}`;
209
+ const EVENT_MAXIMIZED$1 = `maximized${EVENT_KEY$6}`;
210
+ const EVENT_MINIMIZED$1 = `minimized${EVENT_KEY$6}`;
196
211
  const CLASS_NAME_CARD = 'card';
197
212
  const CLASS_NAME_COLLAPSED = 'collapsed-card';
198
213
  const CLASS_NAME_COLLAPSING = 'collapsing-card';
@@ -213,7 +228,7 @@
213
228
  };
214
229
  class CardWidget extends BaseComponent {
215
230
  static get NAME() {
216
- return NAME$4;
231
+ return NAME$5;
217
232
  }
218
233
  static getInstance(element) {
219
234
  return this._getInstance(element);
@@ -380,29 +395,29 @@
380
395
  }
381
396
  });
382
397
 
383
- const NAME$3 = 'treeview';
384
- const EVENT_KEY$4 = `.lte.${NAME$3}`;
385
- const EVENT_EXPAND = `expand${EVENT_KEY$4}`;
386
- const EVENT_COLLAPSE$1 = `collapse${EVENT_KEY$4}`;
387
- const EVENT_EXPANDED$1 = `expanded${EVENT_KEY$4}`;
388
- const EVENT_COLLAPSED$2 = `collapsed${EVENT_KEY$4}`;
389
- const EVENT_LOAD_DATA_API = `load${EVENT_KEY$4}`;
390
- const CLASS_NAME_MENU_OPEN = 'menu-open';
391
- const SELECTOR_NAV_ITEM = '.nav-item';
392
- const SELECTOR_NAV_LINK = '.nav-link';
393
- const SELECTOR_TREEVIEW_MENU = '.nav-treeview';
394
- const SELECTOR_DATA_TOGGLE$1 = '[data-lte-toggle="treeview"]';
398
+ const NAME$4 = 'treeview';
399
+ const EVENT_KEY$5 = `.lte.${NAME$4}`;
400
+ const EVENT_EXPAND = `expand${EVENT_KEY$5}`;
401
+ const EVENT_COLLAPSE$1 = `collapse${EVENT_KEY$5}`;
402
+ const EVENT_EXPANDED$1 = `expanded${EVENT_KEY$5}`;
403
+ const EVENT_COLLAPSED$2 = `collapsed${EVENT_KEY$5}`;
404
+ const EVENT_LOAD_DATA_API = `load${EVENT_KEY$5}`;
405
+ const CLASS_NAME_MENU_OPEN$1 = 'menu-open';
406
+ const SELECTOR_NAV_ITEM$1 = '.nav-item';
407
+ const SELECTOR_NAV_LINK$1 = '.nav-link';
408
+ const SELECTOR_TREEVIEW_MENU$1 = '.nav-treeview';
409
+ const SELECTOR_DATA_TOGGLE$2 = '[data-lte-toggle="treeview"]';
395
410
  const Default = {
396
411
  animationSpeed: 300,
397
412
  accordion: true
398
413
  };
399
414
  const setAriaExpanded = (navItem, expanded) => {
400
- const link = navItem.querySelector(`:scope > ${SELECTOR_NAV_LINK}`);
415
+ const link = navItem.querySelector(`:scope > ${SELECTOR_NAV_LINK$1}`);
401
416
  link?.setAttribute('aria-expanded', String(expanded));
402
417
  };
403
418
  class Treeview extends BaseComponent {
404
419
  static get NAME() {
405
- return NAME$3;
420
+ return NAME$4;
406
421
  }
407
422
  static getInstance(element) {
408
423
  return this._getInstance(element);
@@ -420,26 +435,26 @@
420
435
  return;
421
436
  }
422
437
  if (this._config.accordion) {
423
- const openMenuList = this._element.parentElement?.querySelectorAll(`${SELECTOR_NAV_ITEM}.${CLASS_NAME_MENU_OPEN}`);
438
+ const openMenuList = this._element.parentElement?.querySelectorAll(`${SELECTOR_NAV_ITEM$1}.${CLASS_NAME_MENU_OPEN$1}`);
424
439
  openMenuList?.forEach(openMenu => {
425
440
  if (!this._element.contains(openMenu)) {
426
- openMenu.classList.remove(CLASS_NAME_MENU_OPEN);
441
+ openMenu.classList.remove(CLASS_NAME_MENU_OPEN$1);
427
442
  setAriaExpanded(openMenu, false);
428
- const childElement = openMenu?.querySelector(SELECTOR_TREEVIEW_MENU);
443
+ const childElement = openMenu?.querySelector(SELECTOR_TREEVIEW_MENU$1);
429
444
  if (childElement) {
430
445
  slideUp(childElement, this._config.animationSpeed);
431
446
  }
432
447
  }
433
448
  });
434
449
  }
435
- this._element.classList.add(CLASS_NAME_MENU_OPEN);
450
+ this._element.classList.add(CLASS_NAME_MENU_OPEN$1);
436
451
  setAriaExpanded(this._element, true);
437
- const childElement = this._element.querySelector(SELECTOR_TREEVIEW_MENU);
452
+ const childElement = this._element.querySelector(SELECTOR_TREEVIEW_MENU$1);
438
453
  if (childElement) {
439
454
  slideDown(childElement, this._config.animationSpeed);
440
455
  }
441
456
  setTimeout(() => {
442
- if (this._element.classList.contains(CLASS_NAME_MENU_OPEN)) {
457
+ if (this._element.classList.contains(CLASS_NAME_MENU_OPEN$1)) {
443
458
  dispatchCustomEvent(this._element, EVENT_EXPANDED$1);
444
459
  }
445
460
  }, this._config.animationSpeed);
@@ -448,20 +463,20 @@
448
463
  if (dispatchCustomEvent(this._element, EVENT_COLLAPSE$1, { cancelable: true }).defaultPrevented) {
449
464
  return;
450
465
  }
451
- this._element.classList.remove(CLASS_NAME_MENU_OPEN);
466
+ this._element.classList.remove(CLASS_NAME_MENU_OPEN$1);
452
467
  setAriaExpanded(this._element, false);
453
- const childElement = this._element.querySelector(SELECTOR_TREEVIEW_MENU);
468
+ const childElement = this._element.querySelector(SELECTOR_TREEVIEW_MENU$1);
454
469
  if (childElement) {
455
470
  slideUp(childElement, this._config.animationSpeed);
456
471
  }
457
472
  setTimeout(() => {
458
- if (!this._element.classList.contains(CLASS_NAME_MENU_OPEN)) {
473
+ if (!this._element.classList.contains(CLASS_NAME_MENU_OPEN$1)) {
459
474
  dispatchCustomEvent(this._element, EVENT_COLLAPSED$2);
460
475
  }
461
476
  }, this._config.animationSpeed);
462
477
  }
463
478
  toggle() {
464
- if (this._element.classList.contains(CLASS_NAME_MENU_OPEN)) {
479
+ if (this._element.classList.contains(CLASS_NAME_MENU_OPEN$1)) {
465
480
  this.close();
466
481
  }
467
482
  else {
@@ -474,13 +489,13 @@
474
489
  if (!(target instanceof Element)) {
475
490
  return;
476
491
  }
477
- const toggleRoot = target.closest(SELECTOR_DATA_TOGGLE$1);
492
+ const toggleRoot = target.closest(SELECTOR_DATA_TOGGLE$2);
478
493
  if (!toggleRoot) {
479
494
  return;
480
495
  }
481
- const targetItem = target.closest(SELECTOR_NAV_ITEM);
482
- const targetLink = target.closest(SELECTOR_NAV_LINK);
483
- if (!targetItem?.querySelector(SELECTOR_TREEVIEW_MENU)) {
496
+ const targetItem = target.closest(SELECTOR_NAV_ITEM$1);
497
+ const targetLink = target.closest(SELECTOR_NAV_LINK$1);
498
+ if (!targetItem?.querySelector(SELECTOR_TREEVIEW_MENU$1)) {
484
499
  return;
485
500
  }
486
501
  if (target.getAttribute('href') === '#' || targetLink?.getAttribute('href') === '#') {
@@ -495,34 +510,34 @@
495
510
  Treeview.getOrCreateInstance(targetItem, config).toggle();
496
511
  });
497
512
  onDOMContentLoaded(() => {
498
- const openMenuItems = document.querySelectorAll(`${SELECTOR_NAV_ITEM}.${CLASS_NAME_MENU_OPEN}`);
513
+ const openMenuItems = document.querySelectorAll(`${SELECTOR_NAV_ITEM$1}.${CLASS_NAME_MENU_OPEN$1}`);
499
514
  openMenuItems.forEach(menuItem => {
500
- const childElement = menuItem.querySelector(SELECTOR_TREEVIEW_MENU);
515
+ const childElement = menuItem.querySelector(SELECTOR_TREEVIEW_MENU$1);
501
516
  if (childElement) {
502
517
  slideDown(childElement, 0);
503
518
  const event = new Event(EVENT_LOAD_DATA_API);
504
519
  menuItem.dispatchEvent(event);
505
520
  }
506
521
  });
507
- document.querySelectorAll(SELECTOR_DATA_TOGGLE$1).forEach(root => {
508
- root.querySelectorAll(SELECTOR_NAV_ITEM).forEach(item => {
509
- if (item.querySelector(`:scope > ${SELECTOR_TREEVIEW_MENU}`)) {
510
- setAriaExpanded(item, item.classList.contains(CLASS_NAME_MENU_OPEN));
522
+ document.querySelectorAll(SELECTOR_DATA_TOGGLE$2).forEach(root => {
523
+ root.querySelectorAll(SELECTOR_NAV_ITEM$1).forEach(item => {
524
+ if (item.querySelector(`:scope > ${SELECTOR_TREEVIEW_MENU$1}`)) {
525
+ setAriaExpanded(item, item.classList.contains(CLASS_NAME_MENU_OPEN$1));
511
526
  }
512
527
  });
513
528
  });
514
529
  });
515
530
 
516
- const NAME$2 = 'direct-chat';
517
- const EVENT_KEY$3 = `.lte.${NAME$2}`;
518
- const EVENT_EXPANDED = `expanded${EVENT_KEY$3}`;
519
- const EVENT_COLLAPSED$1 = `collapsed${EVENT_KEY$3}`;
520
- const SELECTOR_DATA_TOGGLE = '[data-lte-toggle="chat-pane"]';
531
+ const NAME$3 = 'direct-chat';
532
+ const EVENT_KEY$4 = `.lte.${NAME$3}`;
533
+ const EVENT_EXPANDED = `expanded${EVENT_KEY$4}`;
534
+ const EVENT_COLLAPSED$1 = `collapsed${EVENT_KEY$4}`;
535
+ const SELECTOR_DATA_TOGGLE$1 = '[data-lte-toggle="chat-pane"]';
521
536
  const SELECTOR_DIRECT_CHAT = '.direct-chat';
522
537
  const CLASS_NAME_DIRECT_CHAT_OPEN = 'direct-chat-contacts-open';
523
538
  class DirectChat extends BaseComponent {
524
539
  static get NAME() {
525
- return NAME$2;
540
+ return NAME$3;
526
541
  }
527
542
  static getInstance(element) {
528
543
  return this._getInstance(element);
@@ -546,7 +561,7 @@
546
561
  if (!(target instanceof Element)) {
547
562
  return;
548
563
  }
549
- const trigger = target.closest(SELECTOR_DATA_TOGGLE);
564
+ const trigger = target.closest(SELECTOR_DATA_TOGGLE$1);
550
565
  if (!trigger) {
551
566
  return;
552
567
  }
@@ -557,10 +572,10 @@
557
572
  }
558
573
  });
559
574
 
560
- const NAME$1 = 'fullscreen';
561
- const EVENT_KEY$2 = `.lte.${NAME$1}`;
562
- const EVENT_MAXIMIZED = `maximized${EVENT_KEY$2}`;
563
- const EVENT_MINIMIZED = `minimized${EVENT_KEY$2}`;
575
+ const NAME$2 = 'fullscreen';
576
+ const EVENT_KEY$3 = `.lte.${NAME$2}`;
577
+ const EVENT_MAXIMIZED = `maximized${EVENT_KEY$3}`;
578
+ const EVENT_MINIMIZED = `minimized${EVENT_KEY$3}`;
564
579
  const SELECTOR_FULLSCREEN_TOGGLE = '[data-lte-toggle="fullscreen"]';
565
580
  const SELECTOR_MAXIMIZE_ICON = '[data-lte-icon="maximize"]';
566
581
  const SELECTOR_MINIMIZE_ICON = '[data-lte-icon="minimize"]';
@@ -577,7 +592,7 @@
577
592
  }
578
593
  class FullScreen extends BaseComponent {
579
594
  static get NAME() {
580
- return NAME$1;
595
+ return NAME$2;
581
596
  }
582
597
  static getInstance(element) {
583
598
  return this._getInstance(element);
@@ -621,12 +636,12 @@
621
636
  document.addEventListener('fullscreenchange', syncFullScreenState, { signal: getLifecycleSignal() });
622
637
  });
623
638
 
624
- const NAME = 'push-menu';
625
- const EVENT_KEY$1 = `.lte.${NAME}`;
626
- const EVENT_OPEN = `open${EVENT_KEY$1}`;
627
- const EVENT_COLLAPSE = `collapse${EVENT_KEY$1}`;
628
- const EVENT_OPENED = `opened${EVENT_KEY$1}`;
629
- const EVENT_COLLAPSED = `collapsed${EVENT_KEY$1}`;
639
+ const NAME$1 = 'push-menu';
640
+ const EVENT_KEY$2 = `.lte.${NAME$1}`;
641
+ const EVENT_OPEN = `open${EVENT_KEY$2}`;
642
+ const EVENT_COLLAPSE = `collapse${EVENT_KEY$2}`;
643
+ const EVENT_OPENED = `opened${EVENT_KEY$2}`;
644
+ const EVENT_COLLAPSED = `collapsed${EVENT_KEY$2}`;
630
645
  const CLASS_NAME_SIDEBAR_MINI = 'sidebar-mini';
631
646
  const CLASS_NAME_SIDEBAR_EXPAND = 'sidebar-expand';
632
647
  const CLASS_NAME_SIDEBAR_OVERLAY = 'sidebar-overlay';
@@ -643,7 +658,7 @@
643
658
  };
644
659
  class PushMenu extends BaseComponent {
645
660
  static get NAME() {
646
- return NAME;
661
+ return NAME$1;
647
662
  }
648
663
  static getInstance(element) {
649
664
  return this._getInstance(element);
@@ -774,7 +789,7 @@
774
789
  if (this._config.enablePersistence && !this.isMobileSize()) {
775
790
  this.loadSidebarState();
776
791
  }
777
- else {
792
+ else if (!this.isCollapsed()) {
778
793
  this.updateStateByResponsiveLogic();
779
794
  }
780
795
  }
@@ -822,46 +837,66 @@
822
837
  sidebarOverlay.className = CLASS_NAME_SIDEBAR_OVERLAY;
823
838
  appWrapper?.append(sidebarOverlay);
824
839
  }
840
+ const overlaySignal = getLifecycleSignal();
825
841
  let overlayTouchMoved = false;
826
842
  sidebarOverlay.addEventListener('touchstart', () => {
827
843
  overlayTouchMoved = false;
828
- }, { passive: true });
844
+ }, { passive: true, signal: overlaySignal });
829
845
  sidebarOverlay.addEventListener('touchmove', () => {
830
846
  overlayTouchMoved = true;
831
- }, { passive: true });
847
+ }, { passive: true, signal: overlaySignal });
832
848
  sidebarOverlay.addEventListener('touchend', event => {
833
849
  if (!overlayTouchMoved) {
834
850
  event.preventDefault();
835
851
  pushMenu.collapse();
836
852
  }
837
853
  overlayTouchMoved = false;
838
- }, { passive: false });
854
+ }, { passive: false, signal: overlaySignal });
839
855
  sidebarOverlay.addEventListener('click', event => {
840
856
  event.preventDefault();
841
857
  pushMenu.collapse();
842
- });
858
+ }, { signal: overlaySignal });
843
859
  });
844
860
 
845
861
  const DATA_KEY = 'lte.color-mode';
846
- const EVENT_KEY = `.${DATA_KEY}`;
847
- const EVENT_CHANGED = `changed${EVENT_KEY}`;
862
+ const EVENT_KEY$1 = `.${DATA_KEY}`;
863
+ const EVENT_CHANGED = `changed${EVENT_KEY$1}`;
848
864
  const STORAGE_KEY = 'lte-theme';
849
- const SELECTOR_TOGGLE = '[data-bs-theme-value]';
865
+ const ATTRIBUTE_THEME = 'data-bs-theme';
866
+ const ATTRIBUTE_TOGGLE = 'data-bs-theme-value';
867
+ const ATTRIBUTE_DISABLED = 'data-lte-color-mode';
868
+ const ATTRIBUTE_RESOLVED = 'data-lte-theme-resolved';
869
+ const SELECTOR_TOGGLE = `[${ATTRIBUTE_TOGGLE}]`;
850
870
  const SELECTOR_ICON = '[data-lte-theme-icon]';
871
+ const THEMES = new Set(['light', 'dark', 'auto']);
872
+ const isValidTheme = (value) => THEMES.has(value);
873
+ const isDisabled = () => document.documentElement.getAttribute(ATTRIBUTE_DISABLED) === 'off';
874
+ const readMarkupTheme = () => {
875
+ const { documentElement } = document;
876
+ if (documentElement.hasAttribute(ATTRIBUTE_RESOLVED)) {
877
+ return null;
878
+ }
879
+ const declared = documentElement.getAttribute(ATTRIBUTE_THEME);
880
+ return declared && isValidTheme(declared) ? declared : null;
881
+ };
882
+ const MARKUP_THEME = readMarkupTheme();
851
883
  class ColorMode {
852
884
  getStoredTheme() {
853
885
  try {
854
886
  const stored = localStorage.getItem(STORAGE_KEY);
855
- return stored && ['light', 'dark', 'auto'].includes(stored) ? stored : null;
887
+ return stored && isValidTheme(stored) ? stored : null;
856
888
  }
857
889
  catch {
858
890
  return null;
859
891
  }
860
892
  }
893
+ getMarkupTheme() {
894
+ return MARKUP_THEME;
895
+ }
861
896
  getPreferredTheme() {
862
- const stored = this.getStoredTheme();
863
- if (stored) {
864
- return stored;
897
+ const preferred = this.getStoredTheme() ?? this.getMarkupTheme();
898
+ if (preferred) {
899
+ return preferred;
865
900
  }
866
901
  return this._prefersDark() ? 'dark' : 'light';
867
902
  }
@@ -885,7 +920,7 @@
885
920
  }
886
921
  _applyTheme(theme) {
887
922
  const resolved = this.resolveTheme(theme);
888
- document.documentElement.setAttribute('data-bs-theme', resolved);
923
+ document.documentElement.setAttribute(ATTRIBUTE_THEME, resolved);
889
924
  document.documentElement.style.colorScheme = resolved;
890
925
  }
891
926
  _prefersDark() {
@@ -893,7 +928,7 @@
893
928
  }
894
929
  _showActiveTheme(theme) {
895
930
  document.querySelectorAll(SELECTOR_TOGGLE).forEach(toggle => {
896
- const isActive = toggle.getAttribute('data-bs-theme-value') === theme;
931
+ const isActive = toggle.getAttribute(ATTRIBUTE_TOGGLE) === theme;
897
932
  toggle.classList.toggle('active', isActive);
898
933
  toggle.setAttribute('aria-pressed', String(isActive));
899
934
  toggle.querySelector('.bi-check-lg')?.classList.toggle('d-none', !isActive);
@@ -903,6 +938,9 @@
903
938
  });
904
939
  }
905
940
  init() {
941
+ if (isDisabled()) {
942
+ return;
943
+ }
906
944
  const theme = this.getPreferredTheme();
907
945
  this._applyTheme(theme);
908
946
  this._showActiveTheme(theme);
@@ -910,12 +948,12 @@
910
948
  }
911
949
  document.addEventListener('click', event => {
912
950
  const target = event.target;
913
- if (!(target instanceof Element)) {
951
+ if (!(target instanceof Element) || isDisabled()) {
914
952
  return;
915
953
  }
916
954
  const toggle = target.closest(SELECTOR_TOGGLE);
917
- const theme = toggle?.getAttribute('data-bs-theme-value');
918
- if (theme) {
955
+ const theme = toggle?.getAttribute(ATTRIBUTE_TOGGLE);
956
+ if (theme && isValidTheme(theme)) {
919
957
  new ColorMode().setTheme(theme);
920
958
  }
921
959
  });
@@ -923,14 +961,165 @@
923
961
  const colorMode = new ColorMode();
924
962
  colorMode.init();
925
963
  globalThis.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
926
- const stored = colorMode.getStoredTheme();
927
- if (!stored || stored === 'auto') {
964
+ if (isDisabled()) {
965
+ return;
966
+ }
967
+ const preferred = colorMode.getStoredTheme() ?? colorMode.getMarkupTheme();
968
+ if (!preferred || preferred === 'auto') {
928
969
  colorMode._applyTheme('auto');
929
- colorMode._showActiveTheme(stored ?? 'auto');
970
+ colorMode._showActiveTheme(preferred ?? 'auto');
930
971
  }
931
972
  }, { signal: getLifecycleSignal() });
932
973
  });
933
974
 
975
+ const NAME = 'sidebar-search';
976
+ const EVENT_KEY = `.lte.${NAME}`;
977
+ const EVENT_FILTERED = `filtered${EVENT_KEY}`;
978
+ const CLASS_NAME_MENU_OPEN = 'menu-open';
979
+ const SELECTOR_DATA_TOGGLE = '[data-lte-toggle="sidebar-search"]';
980
+ const SELECTOR_SIDEBAR = '.app-sidebar';
981
+ const SELECTOR_MENU = '.sidebar-menu';
982
+ const SELECTOR_NAV_ITEM = '.nav-item';
983
+ const SELECTOR_NAV_HEADER = '.nav-header';
984
+ const SELECTOR_NAV_LINK = ':scope > .nav-link';
985
+ const SELECTOR_TREEVIEW_MENU = ':scope > .nav-treeview';
986
+ const SELECTOR_EMPTY_STATE = '[data-lte-search-empty]';
987
+ const submenuOf = (item) => item.querySelector(SELECTOR_TREEVIEW_MENU);
988
+ const setOpen = (item, submenu, open, display) => {
989
+ item.classList.toggle(CLASS_NAME_MENU_OPEN, open);
990
+ item.querySelector(SELECTOR_NAV_LINK)?.setAttribute('aria-expanded', String(open));
991
+ submenu.style.display = display;
992
+ };
993
+ class SidebarSearch extends BaseComponent {
994
+ static get NAME() {
995
+ return NAME;
996
+ }
997
+ static getInstance(element) {
998
+ return this._getInstance(element);
999
+ }
1000
+ static getOrCreateInstance(element) {
1001
+ return this.getInstance(element) ?? new this(element);
1002
+ }
1003
+ _menu;
1004
+ _emptyState;
1005
+ _snapshot = null;
1006
+ constructor(element) {
1007
+ super(element);
1008
+ const target = element.dataset.lteTarget;
1009
+ const scope = element.closest(SELECTOR_SIDEBAR) ?? document;
1010
+ this._menu = target ?
1011
+ document.querySelector(target) :
1012
+ scope.querySelector(SELECTOR_MENU);
1013
+ this._emptyState = scope.querySelector(SELECTOR_EMPTY_STATE);
1014
+ }
1015
+ search(term) {
1016
+ const menu = this._menu;
1017
+ if (!menu) {
1018
+ return;
1019
+ }
1020
+ const query = term.trim().toLowerCase();
1021
+ if (!query) {
1022
+ this.clear();
1023
+ return;
1024
+ }
1025
+ this._snapshot ??= this._takeSnapshot(menu);
1026
+ const items = [...menu.querySelectorAll(SELECTOR_NAV_ITEM)];
1027
+ const matched = new Set();
1028
+ for (const item of items) {
1029
+ const label = item.querySelector(SELECTOR_NAV_LINK)?.textContent?.replace(/\s+/g, ' ').trim().toLowerCase();
1030
+ if (label?.includes(query)) {
1031
+ matched.add(item);
1032
+ }
1033
+ }
1034
+ for (let index = items.length - 1; index >= 0; index--) {
1035
+ const item = items[index];
1036
+ item.hidden = !(matched.has(item) || item.querySelector(`${SELECTOR_NAV_ITEM}:not([hidden])`));
1037
+ }
1038
+ for (const item of matched) {
1039
+ for (const descendant of item.querySelectorAll(SELECTOR_NAV_ITEM)) {
1040
+ descendant.hidden = false;
1041
+ }
1042
+ }
1043
+ let visible = 0;
1044
+ for (const item of items) {
1045
+ if (!item.hidden) {
1046
+ visible++;
1047
+ }
1048
+ const submenu = submenuOf(item);
1049
+ if (submenu) {
1050
+ const expand = !item.hidden && Boolean(item.querySelector(`${SELECTOR_NAV_ITEM}:not([hidden])`));
1051
+ setOpen(item, submenu, expand, expand ? 'block' : 'none');
1052
+ }
1053
+ }
1054
+ for (const header of menu.querySelectorAll(SELECTOR_NAV_HEADER)) {
1055
+ header.hidden = true;
1056
+ }
1057
+ if (this._emptyState) {
1058
+ this._emptyState.hidden = visible > 0;
1059
+ }
1060
+ dispatchCustomEvent(this._element, EVENT_FILTERED, { detail: { query, matches: visible } });
1061
+ }
1062
+ clear() {
1063
+ const menu = this._menu;
1064
+ if (!menu) {
1065
+ return;
1066
+ }
1067
+ for (const item of menu.querySelectorAll(`${SELECTOR_NAV_ITEM}, ${SELECTOR_NAV_HEADER}`)) {
1068
+ item.hidden = false;
1069
+ }
1070
+ if (this._snapshot) {
1071
+ for (const [item, state] of this._snapshot) {
1072
+ const submenu = submenuOf(item);
1073
+ if (submenu) {
1074
+ setOpen(item, submenu, state.open, state.display);
1075
+ }
1076
+ }
1077
+ this._snapshot = null;
1078
+ }
1079
+ if (this._emptyState) {
1080
+ this._emptyState.hidden = true;
1081
+ }
1082
+ dispatchCustomEvent(this._element, EVENT_FILTERED, { detail: { query: '', matches: -1 } });
1083
+ }
1084
+ dispose() {
1085
+ this.clear();
1086
+ super.dispose();
1087
+ }
1088
+ _takeSnapshot(menu) {
1089
+ const snapshot = new Map();
1090
+ for (const item of menu.querySelectorAll(SELECTOR_NAV_ITEM)) {
1091
+ const submenu = submenuOf(item);
1092
+ if (submenu) {
1093
+ snapshot.set(item, {
1094
+ open: item.classList.contains(CLASS_NAME_MENU_OPEN),
1095
+ display: submenu.style.display
1096
+ });
1097
+ }
1098
+ }
1099
+ return snapshot;
1100
+ }
1101
+ }
1102
+ document.addEventListener('input', event => {
1103
+ const target = event.target;
1104
+ if (target instanceof HTMLInputElement && target.matches(SELECTOR_DATA_TOGGLE)) {
1105
+ SidebarSearch.getOrCreateInstance(target).search(target.value);
1106
+ }
1107
+ });
1108
+ document.addEventListener('keydown', event => {
1109
+ const target = event.target;
1110
+ if (event.key === 'Escape' && target instanceof HTMLInputElement && target.matches(SELECTOR_DATA_TOGGLE)) {
1111
+ target.value = '';
1112
+ SidebarSearch.getOrCreateInstance(target).clear();
1113
+ }
1114
+ });
1115
+ onDOMContentLoaded(() => {
1116
+ document.querySelectorAll(SELECTOR_DATA_TOGGLE).forEach(input => {
1117
+ if (input.value) {
1118
+ SidebarSearch.getOrCreateInstance(input).search(input.value);
1119
+ }
1120
+ });
1121
+ });
1122
+
934
1123
  class AccessibilityManager {
935
1124
  config;
936
1125
  liveRegion = null;
@@ -1004,19 +1193,21 @@
1004
1193
  this.ensureSkipTargets();
1005
1194
  }
1006
1195
  ensureSkipTargets() {
1007
- const main = document.querySelector('#main, main, [role="main"]');
1008
- if (main && !main.id) {
1009
- main.id = 'main';
1010
- }
1011
- if (main && !main.hasAttribute('tabindex')) {
1012
- main.setAttribute('tabindex', '-1');
1013
- }
1014
- const nav = document.querySelector('#navigation, nav, [role="navigation"]');
1015
- if (nav && !nav.id) {
1016
- nav.id = 'navigation';
1017
- }
1018
- if (nav && !nav.hasAttribute('tabindex')) {
1019
- nav.setAttribute('tabindex', '-1');
1196
+ const targets = [
1197
+ ['main', 'main, [role="main"]'],
1198
+ ['navigation', 'nav, [role="navigation"]']
1199
+ ];
1200
+ for (const [id, fallbackSelector] of targets) {
1201
+ const target = document.getElementById(id) ?? document.querySelector(fallbackSelector);
1202
+ if (!target) {
1203
+ continue;
1204
+ }
1205
+ if (!target.id) {
1206
+ target.id = id;
1207
+ }
1208
+ if (!target.hasAttribute('tabindex')) {
1209
+ target.setAttribute('tabindex', '-1');
1210
+ }
1020
1211
  }
1021
1212
  }
1022
1213
  initFocusManagement() {
@@ -1181,7 +1372,7 @@
1181
1372
  if (!htmlInput.classList.contains('disable-adminlte-validations')) {
1182
1373
  htmlInput.addEventListener('invalid', () => {
1183
1374
  this.handleFormError(htmlInput);
1184
- });
1375
+ }, { signal: this.signal });
1185
1376
  }
1186
1377
  });
1187
1378
  }
@@ -1373,8 +1564,11 @@
1373
1564
  exports.FullScreen = FullScreen;
1374
1565
  exports.Layout = Layout;
1375
1566
  exports.PushMenu = PushMenu;
1567
+ exports.SidebarSearch = SidebarSearch;
1376
1568
  exports.Treeview = Treeview;
1377
1569
  exports.initAccessibility = initAccessibility;
1570
+ exports.initialize = initialize;
1571
+ exports.teardown = teardown;
1378
1572
 
1379
1573
  }));
1380
1574
  //# sourceMappingURL=adminlte.js.map