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
@@ -16,6 +16,18 @@
16
16
  * cycle's listeners before the callbacks run again. Listeners bound to elements
17
17
  * inside <body> don't need the signal — Turbo discards the old <body>, so they
18
18
  * are cleaned up automatically.
19
+ *
20
+ * Turbo is not the only environment that renders after `DOMContentLoaded`:
21
+ * client-side frameworks that build the layout themselves (GWT, and other
22
+ * imperative widget toolkits) have an empty <body> when the initial batch runs,
23
+ * so the per-page init pass finds no sidebar and no menu. Those consumers call
24
+ * the exported `initialize()` once the layout is attached — it performs the same
25
+ * reset-then-replay cycle Turbo gets, without faking Turbo events.
26
+ *
27
+ * Unlike Turbo, such frameworks keep the same <body> across a re-init, so
28
+ * element-level listeners are NOT discarded for them. Callbacks should therefore
29
+ * pass `getLifecycleSignal()` to every `addEventListener` they make — including
30
+ * ones on elements — whenever the element can outlive the cycle.
19
31
  */
20
32
 
21
33
  const lifecycleCallbacks: Array<() => void> = []
@@ -24,7 +36,10 @@ const lifecycleCallbacks: Array<() => void> = []
24
36
  // without reassigning top-level bindings.
25
37
  const lifecycleState = {
26
38
  controller: new AbortController(),
27
- hasInitialized: false
39
+ hasInitialized: false,
40
+ // True while the callback batch is executing — lets initialize() refuse
41
+ // re-entrant calls made from inside a lifecycle callback.
42
+ isReplaying: false
28
43
  }
29
44
 
30
45
  /**
@@ -40,9 +55,14 @@ const runLifecycleCallbacks = (): void => {
40
55
  }
41
56
 
42
57
  lifecycleState.hasInitialized = true
58
+ lifecycleState.isReplaying = true
43
59
 
44
- for (const callback of lifecycleCallbacks) {
45
- callback()
60
+ try {
61
+ for (const callback of lifecycleCallbacks) {
62
+ callback()
63
+ }
64
+ } finally {
65
+ lifecycleState.isReplaying = false
46
66
  }
47
67
  }
48
68
 
@@ -58,24 +78,66 @@ const onDOMContentLoaded = (callback: () => void): void => {
58
78
  }
59
79
  }
60
80
 
61
- // Initial page load.
81
+ /**
82
+ * End the current lifecycle: abort the cycle's signal so listeners registered
83
+ * with it are removed, then arm a fresh cycle for the next replay.
84
+ *
85
+ * Exported for SPA containers that unmount the AdminLTE layout: calling it
86
+ * drops the window/document listeners the current cycle added without
87
+ * immediately re-initialising. Internally it is also the first half of
88
+ * `initialize()` and the `turbo:before-render` handler.
89
+ */
90
+ const teardown = (): void => {
91
+ lifecycleState.controller.abort()
92
+ lifecycleState.controller = new AbortController()
93
+ lifecycleState.hasInitialized = false
94
+ }
95
+
96
+ /**
97
+ * Re-run every plugin's initialisation against the DOM as it stands right now.
98
+ *
99
+ * Intended for frameworks that render the layout after `DOMContentLoaded` has
100
+ * already fired — call it once the sidebar and menu are attached, and PushMenu,
101
+ * Treeview and ColorMode pick them up as if they had been in the initial HTML.
102
+ * Delegated click handling never needs this; only the per-page init pass does.
103
+ *
104
+ * The previous cycle is torn down first, so calling it repeatedly does not stack
105
+ * listeners registered with `getLifecycleSignal()`. Calling it before the
106
+ * initial batch has run (while `document.readyState === 'loading'`) runs that
107
+ * batch early, against whatever DOM exists at the time — the initial
108
+ * `DOMContentLoaded` pass below still replays against the complete DOM.
109
+ */
110
+ const initialize = (): void => {
111
+ // Re-entrancy guard: a lifecycle callback calling initialize() would tear
112
+ // down its own cycle mid-replay and recurse without end.
113
+ if (lifecycleState.isReplaying) {
114
+ return
115
+ }
116
+
117
+ teardown()
118
+ runLifecycleCallbacks()
119
+ }
120
+
121
+ // Initial page load. Routed through initialize() so that an early initialize()
122
+ // call (a framework initialising before the document finished loading) cannot
123
+ // mark the cycle as done and suppress this pass — the replay tears the early
124
+ // cycle down and re-runs every callback against the complete DOM.
62
125
  if (document.readyState === 'loading') {
63
- document.addEventListener('DOMContentLoaded', runLifecycleCallbacks, { once: true })
126
+ document.addEventListener('DOMContentLoaded', initialize, { once: true })
64
127
  } else {
65
128
  runLifecycleCallbacks()
66
129
  }
67
130
 
68
131
  // Hotwired Turbo: drop the previous cycle's window/document listeners, then
69
- // re-run initialisation against the freshly rendered <body>.
70
- document.addEventListener('turbo:before-render', () => {
71
- lifecycleState.controller.abort()
72
- lifecycleState.controller = new AbortController()
73
- lifecycleState.hasInitialized = false
74
- })
132
+ // re-run initialisation against the freshly rendered <body>. The teardown has to
133
+ // happen at `before-render` rather than as part of the replay, so the outgoing
134
+ // <body>'s listeners are gone before Turbo swaps in the new one — which is why
135
+ // this is the two-step form of `initialize()` rather than a call to it.
136
+ document.addEventListener('turbo:before-render', teardown)
75
137
 
76
138
  document.addEventListener('turbo:load', runLifecycleCallbacks)
77
139
 
78
- /* ES2022 UTILITY FUNCTIONS */
140
+ // ES2022 UTILITY FUNCTIONS
79
141
 
80
142
  /**
81
143
  * Check if an element has a specific data attribute using ES2022 Object.hasOwn()
@@ -126,7 +188,7 @@ const clearSlideStyles = (target: HTMLElement): void => {
126
188
  }
127
189
  }
128
190
 
129
- /* SLIDE UP */
191
+ // SLIDE UP
130
192
  const slideUp = (target: HTMLElement, duration = 500) => {
131
193
  cancelSlide(target)
132
194
 
@@ -159,7 +221,7 @@ const slideUp = (target: HTMLElement, duration = 500) => {
159
221
  slideTimers.set(target, [stepTimer, cleanupTimer])
160
222
  }
161
223
 
162
- /* SLIDE DOWN */
224
+ // SLIDE DOWN
163
225
  const slideDown = (target: HTMLElement, duration = 500) => {
164
226
  cancelSlide(target)
165
227
  // Drop inline styles a cancelled slideUp may have left behind (height: 0,
@@ -206,7 +268,7 @@ const slideDown = (target: HTMLElement, duration = 500) => {
206
268
  slideTimers.set(target, [stepTimer, cleanupTimer])
207
269
  }
208
270
 
209
- /* TOGGLE */
271
+ // TOGGLE
210
272
  const slideToggle = (target: HTMLElement, duration = 500) => {
211
273
  if (globalThis.getComputedStyle(target).display === 'none') {
212
274
  slideDown(target, duration)
@@ -219,6 +281,8 @@ const slideToggle = (target: HTMLElement, duration = 500) => {
219
281
  export {
220
282
  onDOMContentLoaded,
221
283
  getLifecycleSignal,
284
+ initialize,
285
+ teardown,
222
286
  slideUp,
223
287
  slideDown,
224
288
  slideToggle,