admin-lte 4.0.0-alpha2 → 4.0.0-beta1

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 (142) hide show
  1. package/.bundlewatch.config.json +6 -6
  2. package/.cache/.eslintcache +1 -1
  3. package/.cache/.stylelintcache +1 -1
  4. package/.gitpod.yml +1 -1
  5. package/README.md +9 -4
  6. package/dist/assets/img/AdminLTEFullLogo.png +0 -0
  7. package/dist/css/adminlte.css +879 -418
  8. package/dist/css/adminlte.css.map +1 -1
  9. package/dist/css/adminlte.min.css +2 -2
  10. package/dist/css/adminlte.min.css.map +1 -1
  11. package/dist/css/adminlte.rtl.css +886 -416
  12. package/dist/css/adminlte.rtl.css.map +1 -1
  13. package/dist/css/adminlte.rtl.min.css +2 -2
  14. package/dist/css/adminlte.rtl.min.css.map +1 -1
  15. package/dist/js/adminlte.js +178 -96
  16. package/dist/js/adminlte.js.map +1 -1
  17. package/dist/js/adminlte.min.js +3 -3
  18. package/dist/js/adminlte.min.js.map +1 -1
  19. package/dist/pages/UI/general.html +895 -0
  20. package/dist/pages/UI/timeline.html +309 -515
  21. package/dist/pages/docs/browser-support.html +265 -433
  22. package/dist/pages/docs/color-mode.html +482 -615
  23. package/dist/pages/docs/components/main-header.html +516 -703
  24. package/dist/pages/docs/components/main-sidebar.html +550 -0
  25. package/dist/pages/docs/faq.html +433 -0
  26. package/dist/pages/docs/how-to-contribute.html +474 -0
  27. package/dist/pages/docs/introduction.html +463 -0
  28. package/dist/pages/docs/javascript/treeview.html +453 -0
  29. package/dist/pages/docs/layout.html +293 -433
  30. package/dist/pages/docs/license.html +436 -0
  31. package/dist/pages/examples/lockscreen.html +69 -0
  32. package/dist/pages/examples/login-v2.html +88 -0
  33. package/dist/pages/examples/login.html +49 -100
  34. package/dist/pages/examples/register-v2.html +90 -0
  35. package/dist/pages/examples/register.html +50 -103
  36. package/dist/pages/forms/general.html +430 -454
  37. package/dist/pages/index.html +466 -740
  38. package/dist/pages/index2.html +672 -1041
  39. package/dist/pages/index3.html +371 -629
  40. package/dist/pages/layout/collapsed-sidebar.html +441 -0
  41. package/dist/pages/layout/fixed-complete.html +541 -0
  42. package/dist/pages/layout/fixed-sidebar.html +263 -446
  43. package/dist/pages/layout/layout-rtl.html +263 -445
  44. package/dist/pages/layout/logo-switch.html +234 -0
  45. package/dist/pages/layout/sidebar-mini.html +263 -445
  46. package/dist/pages/layout/unfixed-sidebar.html +263 -445
  47. package/dist/pages/tables/simple.html +314 -499
  48. package/dist/pages/widgets/cards.html +326 -629
  49. package/dist/pages/widgets/info-box.html +348 -674
  50. package/dist/pages/widgets/small-box.html +279 -465
  51. package/index.html +6 -10
  52. package/package.json +34 -30
  53. package/src/assets/img/AdminLTEFullLogo.png +0 -0
  54. package/src/config/astro.config.mjs +3 -1
  55. package/src/html/.prettierrc.js +11 -0
  56. package/src/html/components/_head.astro +32 -26
  57. package/src/html/components/_scripts.astro +27 -28
  58. package/src/html/components/dashboard/_footer.astro +14 -8
  59. package/src/html/components/dashboard/_sidenav.astro +352 -113
  60. package/src/html/components/dashboard/_topbar.astro +99 -50
  61. package/src/html/components/docs/{browser-support/index.md → browser-support.mdx} +2 -1
  62. package/src/html/components/docs/color-mode.mdx +169 -0
  63. package/src/html/components/docs/components/{main-header-1.md → main-header.mdx} +60 -21
  64. package/src/html/components/docs/components/main-sidebar.mdx +129 -0
  65. package/src/html/components/docs/faq.mdx +11 -0
  66. package/src/html/components/docs/how-to-contribute.mdx +34 -0
  67. package/src/html/components/docs/{introduction/index.md → introduction.mdx} +30 -5
  68. package/src/html/components/docs/license.mdx +9 -0
  69. package/src/html/components/javascript/treeview.mdx +39 -0
  70. package/src/html/pages/UI/general.astro +1451 -0
  71. package/src/html/pages/UI/timeline.astro +111 -48
  72. package/src/html/pages/docs/browser-support.astro +24 -11
  73. package/src/html/pages/docs/color-mode.astro +91 -42
  74. package/src/html/pages/docs/components/main-header.astro +134 -46
  75. package/src/html/pages/docs/components/main-sidebar.astro +71 -0
  76. package/src/html/pages/docs/faq.astro +71 -0
  77. package/src/html/pages/docs/how-to-contribute.astro +71 -0
  78. package/src/html/pages/docs/{index.astro → introduction.astro} +24 -11
  79. package/src/html/pages/docs/javascript/treeview.astro +71 -0
  80. package/src/html/pages/docs/layout.astro +62 -19
  81. package/src/html/pages/docs/license.astro +71 -0
  82. package/src/html/pages/examples/lockscreen.astro +63 -0
  83. package/src/html/pages/examples/login-v2.astro +109 -0
  84. package/src/html/pages/examples/login.astro +34 -16
  85. package/src/html/pages/examples/register-v2.astro +116 -0
  86. package/src/html/pages/examples/register.astro +36 -18
  87. package/src/html/pages/forms/general.astro +568 -37
  88. package/src/html/pages/index.astro +403 -157
  89. package/src/html/pages/index2.astro +715 -255
  90. package/src/html/pages/index3.astro +298 -197
  91. package/src/html/pages/layout/collapsed-sidebar.astro +110 -0
  92. package/src/html/pages/layout/fixed-complete.astro +209 -0
  93. package/src/html/pages/layout/fixed-sidebar.astro +52 -27
  94. package/src/html/pages/layout/layout-rtl.astro +53 -28
  95. package/src/html/pages/layout/logo-switch.astro +212 -0
  96. package/src/html/pages/layout/sidebar-mini.astro +53 -28
  97. package/src/html/pages/layout/unfixed-sidebar.astro +51 -27
  98. package/src/html/pages/tables/simple.astro +226 -86
  99. package/src/html/pages/widgets/cards.astro +137 -72
  100. package/src/html/pages/widgets/info-box.astro +96 -41
  101. package/src/html/pages/widgets/small-box.astro +93 -32
  102. package/src/scss/_app-content.scss +52 -0
  103. package/src/scss/_app-footer.scss +1 -1
  104. package/src/scss/_app-main.scss +6 -5
  105. package/src/scss/_app-sidebar.scss +244 -70
  106. package/src/scss/_bootstrap-variables.scss +26 -22
  107. package/src/scss/_callouts.scss +6 -0
  108. package/src/scss/_cards.scss +32 -7
  109. package/src/scss/_compact-mode.scss +79 -0
  110. package/src/scss/_direct-chat.scss +5 -0
  111. package/src/scss/_dropdown.scss +1 -0
  112. package/src/scss/_info-box.scss +2 -10
  113. package/src/scss/_small-box.scss +0 -3
  114. package/src/scss/_timeline.scss +1 -0
  115. package/src/scss/_toasts.scss +33 -0
  116. package/src/scss/_variables.scss +32 -9
  117. package/src/scss/adminlte.scss +1 -2
  118. package/src/scss/mixins/_animations.scss +0 -5
  119. package/src/scss/pages/_lockscreen.scss +75 -0
  120. package/src/scss/pages/_login_and_register.scss +1 -3
  121. package/src/scss/parts/_core.scss +2 -0
  122. package/src/scss/parts/_extra-components.scss +1 -0
  123. package/src/scss/parts/_pages.scss +1 -0
  124. package/src/ts/adminlte.ts +3 -1
  125. package/src/ts/card-widget.ts +20 -52
  126. package/src/ts/direct-chat.ts +5 -4
  127. package/src/ts/fullscreen.ts +110 -0
  128. package/src/ts/layout.ts +5 -4
  129. package/src/ts/push-menu.ts +6 -22
  130. package/src/ts/treeview.ts +34 -11
  131. package/src/ts/util/index.ts +15 -13
  132. package/src/utils/index.js +20 -3
  133. package/.idea/AdminLTE.iml +0 -12
  134. package/.idea/codeStyles/Project.xml +0 -29
  135. package/.idea/codeStyles/codeStyleConfig.xml +0 -5
  136. package/.idea/inspectionProfiles/Project_Default.xml +0 -7
  137. package/.idea/modules.xml +0 -8
  138. package/.idea/php.xml +0 -28
  139. package/.idea/vcs.xml +0 -6
  140. package/dist/pages/docs.html +0 -617
  141. package/src/html/components/docs/color-mode/navbar-html.md +0 -80
  142. package/src/html/components/docs/color-mode/toggle-script.md +0 -48
@@ -1,12 +1,13 @@
1
1
  /**
2
2
  * --------------------------------------------
3
- * AdminLTE card-widget.ts
4
- * License MIT
3
+ * @file AdminLTE card-widget.ts
4
+ * @description Card widget for AdminLTE.
5
+ * @license MIT
5
6
  * --------------------------------------------
6
7
  */
7
8
 
8
9
  import {
9
- domReady,
10
+ onDOMContentLoaded,
10
11
  slideUp,
11
12
  slideDown
12
13
  } from './util/index'
@@ -31,40 +32,33 @@ const CLASS_NAME_EXPANDING = 'expanding-card'
31
32
  const CLASS_NAME_WAS_COLLAPSED = 'was-collapsed'
32
33
  const CLASS_NAME_MAXIMIZED = 'maximized-card'
33
34
 
34
- const SELECTOR_DATA_REMOVE = '[data-lte-dismiss="card-remove"]'
35
+ const SELECTOR_DATA_REMOVE = '[data-lte-toggle="card-remove"]'
35
36
  const SELECTOR_DATA_COLLAPSE = '[data-lte-toggle="card-collapse"]'
36
37
  const SELECTOR_DATA_MAXIMIZE = '[data-lte-toggle="card-maximize"]'
37
38
  const SELECTOR_CARD = `.${CLASS_NAME_CARD}`
38
- const SELECTOR_CARD_HEADER = '.card-header'
39
39
  const SELECTOR_CARD_BODY = '.card-body'
40
40
  const SELECTOR_CARD_FOOTER = '.card-footer'
41
41
 
42
- const Default = {
43
- animationSpeed: 500,
44
- collapseTrigger: SELECTOR_DATA_COLLAPSE,
45
- removeTrigger: SELECTOR_DATA_REMOVE,
46
- maximizeTrigger: SELECTOR_DATA_MAXIMIZE,
47
- collapseIcon: 'fa-minus',
48
- expandIcon: 'fa-plus',
49
- maximizeIcon: 'fa-expand',
50
- minimizeIcon: 'fa-compress'
51
- }
52
-
53
42
  type Config = {
54
43
  animationSpeed: number;
55
44
  collapseTrigger: string;
56
45
  removeTrigger: string;
57
46
  maximizeTrigger: string;
58
- collapseIcon: string;
59
- expandIcon: string;
60
- maximizeIcon: string;
61
- minimizeIcon: string;
47
+ }
48
+
49
+ const Default: Config = {
50
+ animationSpeed: 500,
51
+ collapseTrigger: SELECTOR_DATA_COLLAPSE,
52
+ removeTrigger: SELECTOR_DATA_REMOVE,
53
+ maximizeTrigger: SELECTOR_DATA_MAXIMIZE
62
54
  }
63
55
 
64
56
  class CardWidget {
65
57
  _element: HTMLElement
66
58
  _parent: HTMLElement | undefined
59
+ _clone: HTMLElement | undefined
67
60
  _config: Config
61
+
68
62
  constructor(element: HTMLElement, config: Config) {
69
63
  this._element = element
70
64
  this._parent = element.closest(SELECTOR_CARD) as HTMLElement | undefined
@@ -98,13 +92,6 @@ class CardWidget {
98
92
  }, this._config.animationSpeed)
99
93
  }
100
94
 
101
- const icon = this._parent?.querySelector(`${SELECTOR_CARD_HEADER} ${this._config.collapseTrigger} .${this._config.collapseIcon}`)
102
-
103
- if (icon) {
104
- icon.classList.remove(this._config.collapseIcon)
105
- icon.classList.add(this._config.expandIcon)
106
- }
107
-
108
95
  this._element?.dispatchEvent(event)
109
96
  }
110
97
 
@@ -130,13 +117,6 @@ class CardWidget {
130
117
  }, this._config.animationSpeed)
131
118
  }
132
119
 
133
- const icon = this._parent?.querySelector(`${SELECTOR_CARD_HEADER} ${this._config.collapseTrigger} .${this._config.expandIcon}`)
134
-
135
- if (icon) {
136
- icon.classList.add(this._config.collapseIcon)
137
- icon.classList.remove(this._config.expandIcon)
138
- }
139
-
140
120
  this._element?.dispatchEvent(event)
141
121
  }
142
122
 
@@ -163,15 +143,8 @@ class CardWidget {
163
143
  const event = new Event(EVENT_MAXIMIZED)
164
144
 
165
145
  if (this._parent) {
166
- const maxElm = this._parent.querySelector(`${this._config.maximizeTrigger} .${this._config.maximizeIcon}`)
167
-
168
- if (maxElm) {
169
- maxElm.classList.add(this._config.minimizeIcon)
170
- maxElm.classList.remove(this._config.maximizeIcon)
171
- }
172
-
173
- this._parent.style.height = `${this._parent.scrollHeight}px`
174
- this._parent.style.width = `${this._parent.scrollWidth}px`
146
+ this._parent.style.height = `${this._parent.offsetHeight}px`
147
+ this._parent.style.width = `${this._parent.offsetWidth}px`
175
148
  this._parent.style.transition = 'all .15s'
176
149
 
177
150
  setTimeout(() => {
@@ -198,14 +171,9 @@ class CardWidget {
198
171
  const event = new Event(EVENT_MINIMIZED)
199
172
 
200
173
  if (this._parent) {
201
- const minElm = this._parent.querySelector(`${this._config.maximizeTrigger} .${this._config.minimizeIcon}`)
202
-
203
- if (minElm) {
204
- minElm.classList.add(this._config.maximizeIcon)
205
- minElm.classList.remove(this._config.minimizeIcon)
206
- }
207
-
208
- this._parent.style.cssText = `height: ${this._parent.style.height} !important; width: ${this._parent.style.width} !important; transition: all .15s;`
174
+ this._parent.style.height = 'auto'
175
+ this._parent.style.width = 'auto'
176
+ this._parent.style.transition = 'all .15s'
209
177
 
210
178
  setTimeout(() => {
211
179
  const htmlTag = document.querySelector('html')
@@ -243,7 +211,7 @@ class CardWidget {
243
211
  * ====================================================
244
212
  */
245
213
 
246
- domReady(() => {
214
+ onDOMContentLoaded(() => {
247
215
  const collapseBtn = document.querySelectorAll(SELECTOR_DATA_COLLAPSE)
248
216
 
249
217
  collapseBtn.forEach(btn => {
@@ -1,12 +1,13 @@
1
1
  /**
2
2
  * --------------------------------------------
3
- * AdminLTE direct-chat.ts
4
- * License MIT
3
+ * @file AdminLTE direct-chat.ts
4
+ * @description Direct chat for AdminLTE.
5
+ * @license MIT
5
6
  * --------------------------------------------
6
7
  */
7
8
 
8
9
  import {
9
- domReady
10
+ onDOMContentLoaded
10
11
  } from './util/index'
11
12
 
12
13
  /**
@@ -58,7 +59,7 @@ class DirectChat {
58
59
  * ====================================================
59
60
  */
60
61
 
61
- domReady(() => {
62
+ onDOMContentLoaded(() => {
62
63
  const button = document.querySelectorAll(SELECTOR_DATA_TOGGLE)
63
64
 
64
65
  button.forEach(btn => {
@@ -0,0 +1,110 @@
1
+ /**
2
+ * --------------------------------------------
3
+ * @file AdminLTE fullscreen.ts
4
+ * @description Fullscreen plugin for AdminLTE.
5
+ * @license MIT
6
+ * --------------------------------------------
7
+ */
8
+
9
+ import {
10
+ onDOMContentLoaded
11
+ } from './util/index'
12
+
13
+ /**
14
+ * Constants
15
+ * ============================================================================
16
+ */
17
+ const DATA_KEY = 'lte.fullscreen'
18
+ const EVENT_KEY = `.${DATA_KEY}`
19
+ const EVENT_MAXIMIZED = `maximized${EVENT_KEY}`
20
+ const EVENT_MINIMIZED = `minimized${EVENT_KEY}`
21
+
22
+ const SELECTOR_FULLSCREEN_TOGGLE = '[data-lte-toggle="fullscreen"]'
23
+ const SELECTOR_MAXIMIZE_ICON = '[data-lte-icon="maximize"]'
24
+ const SELECTOR_MINIMIZE_ICON = '[data-lte-icon="minimize"]'
25
+
26
+ /**
27
+ * Class Definition.
28
+ * ============================================================================
29
+ */
30
+ class FullScreen {
31
+ _element: HTMLElement
32
+ _config: undefined
33
+
34
+ constructor(element: HTMLElement, config?: undefined) {
35
+ this._element = element
36
+ this._config = config
37
+ }
38
+
39
+ inFullScreen(): void {
40
+ const event = new Event(EVENT_MAXIMIZED)
41
+
42
+ const iconMaximize = document.querySelector<HTMLElement>(SELECTOR_MAXIMIZE_ICON)
43
+ const iconMinimize = document.querySelector<HTMLElement>(SELECTOR_MINIMIZE_ICON)
44
+
45
+ void document.documentElement.requestFullscreen()
46
+
47
+ if (iconMaximize) {
48
+ iconMaximize.style.display = 'none'
49
+ }
50
+
51
+ if (iconMinimize) {
52
+ iconMinimize.style.display = 'block'
53
+ }
54
+
55
+ this._element.dispatchEvent(event)
56
+ }
57
+
58
+ outFullscreen(): void {
59
+ const event = new Event(EVENT_MINIMIZED)
60
+
61
+ const iconMaximize = document.querySelector<HTMLElement>(SELECTOR_MAXIMIZE_ICON)
62
+ const iconMinimize = document.querySelector<HTMLElement>(SELECTOR_MINIMIZE_ICON)
63
+
64
+ void document.exitFullscreen()
65
+
66
+ if (iconMaximize) {
67
+ iconMaximize.style.display = 'block'
68
+ }
69
+
70
+ if (iconMinimize) {
71
+ iconMinimize.style.display = 'none'
72
+ }
73
+
74
+ this._element.dispatchEvent(event)
75
+ }
76
+
77
+ toggleFullScreen(): void {
78
+ if (document.fullscreenEnabled) {
79
+ if (document.fullscreenElement) {
80
+ this.outFullscreen()
81
+ } else {
82
+ this.inFullScreen()
83
+ }
84
+ }
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Data Api implementation
90
+ * ============================================================================
91
+ */
92
+ onDOMContentLoaded(() => {
93
+ const buttons = document.querySelectorAll(SELECTOR_FULLSCREEN_TOGGLE)
94
+
95
+ buttons.forEach(btn => {
96
+ btn.addEventListener('click', event => {
97
+ event.preventDefault()
98
+
99
+ const target = event.target as HTMLElement
100
+ const button = target.closest(SELECTOR_FULLSCREEN_TOGGLE) as HTMLElement | undefined
101
+
102
+ if (button) {
103
+ const data = new FullScreen(button, undefined)
104
+ data.toggleFullScreen()
105
+ }
106
+ })
107
+ })
108
+ })
109
+
110
+ export default FullScreen
package/src/ts/layout.ts CHANGED
@@ -1,12 +1,13 @@
1
1
  /**
2
2
  * --------------------------------------------
3
- * AdminLTE layout.ts
4
- * License MIT
3
+ * @file AdminLTE layout.ts
4
+ * @description Layout for AdminLTE.
5
+ * @license MIT
5
6
  * --------------------------------------------
6
7
  */
7
8
 
8
9
  import {
9
- domReady
10
+ onDOMContentLoaded
10
11
  } from './util/index'
11
12
 
12
13
  /**
@@ -42,7 +43,7 @@ class Layout {
42
43
  }
43
44
  }
44
45
 
45
- domReady(() => {
46
+ onDOMContentLoaded(() => {
46
47
  const data = new Layout(document.body)
47
48
  data.holdTransition()
48
49
  setTimeout(() => {
@@ -1,12 +1,13 @@
1
1
  /**
2
2
  * --------------------------------------------
3
- * AdminLTE push-menu.ts
4
- * License MIT
3
+ * @file AdminLTE push-menu.ts
4
+ * @description Push menu for AdminLTE.
5
+ * @license MIT
5
6
  * --------------------------------------------
6
7
  */
7
8
 
8
9
  import {
9
- domReady
10
+ onDOMContentLoaded
10
11
  } from './util/index'
11
12
 
12
13
  /**
@@ -24,13 +25,11 @@ const EVENT_COLLAPSE = `collapse${EVENT_KEY}`
24
25
  const CLASS_NAME_SIDEBAR_MINI = 'sidebar-mini'
25
26
  const CLASS_NAME_SIDEBAR_COLLAPSE = 'sidebar-collapse'
26
27
  const CLASS_NAME_SIDEBAR_OPEN = 'sidebar-open'
27
- const CLASS_NAME_SIDEBAR_IS_HOVER = 'sidebar-is-hover'
28
28
  const CLASS_NAME_SIDEBAR_EXPAND = 'sidebar-expand'
29
29
  const CLASS_NAME_SIDEBAR_OVERLAY = 'sidebar-overlay'
30
30
  const CLASS_NAME_MENU_OPEN = 'menu-open'
31
31
 
32
32
  const SELECTOR_APP_SIDEBAR = '.app-sidebar'
33
- const SELECTOR_SIDEBAR_WRAPPER = '.sidebar-wrapper'
34
33
  const SELECTOR_SIDEBAR_MENU = '.sidebar-menu'
35
34
  const SELECTOR_NAV_ITEM = '.nav-item'
36
35
  const SELECTOR_NAV_TREEVIEW = '.nav-treeview'
@@ -97,20 +96,6 @@ class PushMenu {
97
96
  this._element.dispatchEvent(event)
98
97
  }
99
98
 
100
- sidebarHover() {
101
- const selSidebar = document.querySelector(SELECTOR_SIDEBAR_WRAPPER)
102
-
103
- if (selSidebar) {
104
- selSidebar.addEventListener('mouseover', () => {
105
- document.body.classList.add(CLASS_NAME_SIDEBAR_IS_HOVER)
106
- })
107
-
108
- selSidebar.addEventListener('mouseout', () => {
109
- document.body.classList.remove(CLASS_NAME_SIDEBAR_IS_HOVER)
110
- })
111
- }
112
- }
113
-
114
99
  addSidebarBreakPoint() {
115
100
  const sidebarExpandList = document.querySelector(SELECTOR_SIDEBAR_EXPAND)?.classList ?? []
116
101
  const sidebarExpand = Array.from(sidebarExpandList).find(className => className.startsWith(CLASS_NAME_SIDEBAR_EXPAND)) ?? ''
@@ -125,7 +110,7 @@ class PushMenu {
125
110
  this.expand()
126
111
  }
127
112
 
128
- if (document.body.classList.contains(CLASS_NAME_SIDEBAR_MINI)) {
113
+ if (document.body.classList.contains(CLASS_NAME_SIDEBAR_MINI) && document.body.classList.contains(CLASS_NAME_SIDEBAR_COLLAPSE)) {
129
114
  this.collapse()
130
115
  }
131
116
  }
@@ -141,7 +126,6 @@ class PushMenu {
141
126
 
142
127
  init() {
143
128
  this.addSidebarBreakPoint()
144
- this.sidebarHover()
145
129
  }
146
130
  }
147
131
 
@@ -151,7 +135,7 @@ class PushMenu {
151
135
  * ------------------------------------------------------------------------
152
136
  */
153
137
 
154
- domReady(() => {
138
+ onDOMContentLoaded(() => {
155
139
  const sidebar = document?.querySelector(SELECTOR_APP_SIDEBAR) as HTMLElement | undefined
156
140
 
157
141
  if (sidebar) {
@@ -1,12 +1,13 @@
1
1
  /**
2
2
  * --------------------------------------------
3
- * AdminLTE treeview.ts
4
- * License MIT
3
+ * @file AdminLTE treeview.ts
4
+ * @description Treeview plugin for AdminLTE.
5
+ * @license MIT
5
6
  * --------------------------------------------
6
7
  */
7
8
 
8
9
  import {
9
- domReady,
10
+ onDOMContentLoaded,
10
11
  slideDown,
11
12
  slideUp
12
13
  } from './util/index'
@@ -27,15 +28,18 @@ const EVENT_COLLAPSED = `collapsed${EVENT_KEY}`
27
28
 
28
29
  const CLASS_NAME_MENU_OPEN = 'menu-open'
29
30
  const SELECTOR_NAV_ITEM = '.nav-item'
31
+ const SELECTOR_NAV_LINK = '.nav-link'
30
32
  const SELECTOR_TREEVIEW_MENU = '.nav-treeview'
31
33
  const SELECTOR_DATA_TOGGLE = '[data-lte-toggle="treeview"]'
32
34
 
33
35
  const Default = {
34
- animationSpeed: 300
36
+ animationSpeed: 300,
37
+ accordion: true
35
38
  }
36
39
 
37
40
  type Config = {
38
41
  animationSpeed: number;
42
+ accordion: boolean;
39
43
  }
40
44
 
41
45
  /**
@@ -46,21 +50,34 @@ type Config = {
46
50
  class Treeview {
47
51
  _element: HTMLElement
48
52
  _config: Config
49
- _childNavItem: HTMLElement | undefined
50
53
 
51
54
  constructor(element: HTMLElement, config: Config) {
52
55
  this._element = element
53
56
  this._config = { ...Default, ...config }
54
- this._childNavItem = this._element.querySelector(SELECTOR_TREEVIEW_MENU) as HTMLElement | undefined
55
57
  }
56
58
 
57
59
  open(): void {
58
60
  const event = new Event(EVENT_EXPANDED)
59
61
 
62
+ if (this._config.accordion) {
63
+ const openMenuList = this._element.parentElement?.querySelectorAll(`${SELECTOR_NAV_ITEM}.${CLASS_NAME_MENU_OPEN}`)
64
+
65
+ openMenuList?.forEach(openMenu => {
66
+ if (openMenu !== this._element.parentElement) {
67
+ openMenu.classList.remove(CLASS_NAME_MENU_OPEN)
68
+ const childElement = openMenu?.querySelector(SELECTOR_TREEVIEW_MENU) as HTMLElement | undefined
69
+ if (childElement) {
70
+ slideUp(childElement, this._config.animationSpeed)
71
+ }
72
+ }
73
+ })
74
+ }
75
+
60
76
  this._element.classList.add(CLASS_NAME_MENU_OPEN)
61
77
 
62
- if (this._childNavItem) {
63
- slideDown(this._childNavItem, this._config.animationSpeed)
78
+ const childElement = this._element?.querySelector(SELECTOR_TREEVIEW_MENU) as HTMLElement | undefined
79
+ if (childElement) {
80
+ slideDown(childElement, this._config.animationSpeed)
64
81
  }
65
82
 
66
83
  this._element.dispatchEvent(event)
@@ -71,8 +88,9 @@ class Treeview {
71
88
 
72
89
  this._element.classList.remove(CLASS_NAME_MENU_OPEN)
73
90
 
74
- if (this._childNavItem) {
75
- slideUp(this._childNavItem, this._config.animationSpeed)
91
+ const childElement = this._element?.querySelector(SELECTOR_TREEVIEW_MENU) as HTMLElement | undefined
92
+ if (childElement) {
93
+ slideUp(childElement, this._config.animationSpeed)
76
94
  }
77
95
 
78
96
  this._element.dispatchEvent(event)
@@ -93,13 +111,18 @@ class Treeview {
93
111
  * ------------------------------------------------------------------------
94
112
  */
95
113
 
96
- domReady(() => {
114
+ onDOMContentLoaded(() => {
97
115
  const button = document.querySelectorAll(SELECTOR_DATA_TOGGLE)
98
116
 
99
117
  button.forEach(btn => {
100
118
  btn.addEventListener('click', event => {
101
119
  const target = event.target as HTMLElement
102
120
  const targetItem = target.closest(SELECTOR_NAV_ITEM) as HTMLElement | undefined
121
+ const targetLink = target.closest(SELECTOR_NAV_LINK) as HTMLAnchorElement | undefined
122
+
123
+ if (target?.getAttribute('href') === '#' || targetLink?.getAttribute('href') === '#') {
124
+ event.preventDefault()
125
+ }
103
126
 
104
127
  if (targetItem) {
105
128
  const data = new Treeview(targetItem, Default)
@@ -1,16 +1,19 @@
1
- const domReady = (callBack: () => void) => {
1
+ const domContentLoadedCallbacks: Array<() => void> = []
2
+
3
+ const onDOMContentLoaded = (callback: () => void): void => {
2
4
  if (document.readyState === 'loading') {
3
- document.addEventListener('DOMContentLoaded', callBack)
4
- } else {
5
- callBack()
6
- }
7
- }
5
+ // add listener on the first call when the document is in loading state
6
+ if (!domContentLoadedCallbacks.length) {
7
+ document.addEventListener('DOMContentLoaded', () => {
8
+ for (const callback of domContentLoadedCallbacks) {
9
+ callback()
10
+ }
11
+ })
12
+ }
8
13
 
9
- const windowReady = (callBack: () => void) => {
10
- if (document.readyState === 'complete') {
11
- callBack()
14
+ domContentLoadedCallbacks.push(callback)
12
15
  } else {
13
- window.addEventListener('load', callBack)
16
+ callback()
14
17
  }
15
18
  }
16
19
 
@@ -80,7 +83,7 @@ const slideDown = (target: HTMLElement, duration = 500) => {
80
83
  }, duration)
81
84
  }
82
85
 
83
- /* TOOGLE */
86
+ /* TOGGLE */
84
87
  const slideToggle = (target: HTMLElement, duration = 500) => {
85
88
  if (window.getComputedStyle(target).display === 'none') {
86
89
  slideDown(target, duration)
@@ -91,8 +94,7 @@ const slideToggle = (target: HTMLElement, duration = 500) => {
91
94
  }
92
95
 
93
96
  export {
94
- domReady,
95
- windowReady,
97
+ onDOMContentLoaded,
96
98
  slideUp,
97
99
  slideDown,
98
100
  slideToggle
@@ -1,11 +1,28 @@
1
1
  function convertPathToHtml(path) {
2
- let htmlpath = ''
2
+ let count = 0
3
+ let htmlPath = ''
3
4
  while (path.startsWith('../')) {
5
+ count++
4
6
  path = path.slice(3)
5
- htmlpath += htmlpath.length < 2 ? '.' : '/..'
6
7
  }
7
8
 
8
- return htmlpath
9
+ if (count === 2) {
10
+ htmlPath = '.'
11
+ }
12
+
13
+ if (count === 3) {
14
+ htmlPath = '..'
15
+ }
16
+
17
+ if (count === 4) {
18
+ htmlPath = '../..'
19
+ }
20
+
21
+ if (count === 5) {
22
+ htmlPath = '../../..'
23
+ }
24
+
25
+ return htmlPath
9
26
  }
10
27
 
11
28
  export { convertPathToHtml }
@@ -1,12 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <module type="WEB_MODULE" version="4">
3
- <component name="NewModuleRootManager">
4
- <content url="file://$MODULE_DIR$">
5
- <sourceFolder url="file://$MODULE_DIR$/spec" isTestSource="true" />
6
- <sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
7
- <excludeFolder url="file://$MODULE_DIR$/vendor/composer" />
8
- </content>
9
- <orderEntry type="inheritedJdk" />
10
- <orderEntry type="sourceFolder" forTests="false" />
11
- </component>
12
- </module>
@@ -1,29 +0,0 @@
1
- <component name="ProjectCodeStyleConfiguration">
2
- <code_scheme name="Project" version="173">
3
- <JSCodeStyleSettings version="0">
4
- <option name="USE_SEMICOLON_AFTER_STATEMENT" value="false" />
5
- <option name="FORCE_SEMICOLON_STYLE" value="true" />
6
- <option name="SPACE_BEFORE_GENERATOR_MULT" value="true" />
7
- <option name="USE_DOUBLE_QUOTES" value="false" />
8
- <option name="FORCE_QUOTE_STYlE" value="true" />
9
- <option name="ENFORCE_TRAILING_COMMA" value="Remove" />
10
- <option name="VAR_DECLARATION_WRAP" value="2" />
11
- <option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
12
- <option name="SPACES_WITHIN_IMPORTS" value="true" />
13
- </JSCodeStyleSettings>
14
- <codeStyleSettings language="JavaScript">
15
- <option name="BLOCK_COMMENT_ADD_SPACE" value="true" />
16
- <option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
17
- <option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
18
- <option name="ALIGN_MULTILINE_FOR" value="false" />
19
- <option name="IF_BRACE_FORCE" value="3" />
20
- <option name="DOWHILE_BRACE_FORCE" value="3" />
21
- <option name="WHILE_BRACE_FORCE" value="3" />
22
- <option name="FOR_BRACE_FORCE" value="3" />
23
- <indentOptions>
24
- <option name="INDENT_SIZE" value="2" />
25
- <option name="CONTINUATION_INDENT_SIZE" value="2" />
26
- </indentOptions>
27
- </codeStyleSettings>
28
- </code_scheme>
29
- </component>
@@ -1,5 +0,0 @@
1
- <component name="ProjectCodeStyleConfiguration">
2
- <state>
3
- <option name="USE_PER_PROJECT_SETTINGS" value="true" />
4
- </state>
5
- </component>
@@ -1,7 +0,0 @@
1
- <component name="InspectionProjectProfileManager">
2
- <profile version="1.0">
3
- <option name="myName" value="Project Default" />
4
- <inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
5
- <inspection_tool class="Stylelint" enabled="true" level="ERROR" enabled_by_default="true" />
6
- </profile>
7
- </component>
package/.idea/modules.xml DELETED
@@ -1,8 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="ProjectModuleManager">
4
- <modules>
5
- <module fileurl="file://$PROJECT_DIR$/.idea/AdminLTE.iml" filepath="$PROJECT_DIR$/.idea/AdminLTE.iml" />
6
- </modules>
7
- </component>
8
- </project>
package/.idea/php.xml DELETED
@@ -1,28 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="MessDetectorOptionsConfiguration">
4
- <option name="transferred" value="true" />
5
- </component>
6
- <component name="PHPCSFixerOptionsConfiguration">
7
- <option name="transferred" value="true" />
8
- </component>
9
- <component name="PHPCodeSnifferOptionsConfiguration">
10
- <option name="transferred" value="true" />
11
- </component>
12
- <component name="PhpIncludePathManager">
13
- <include_path>
14
- <path value="$PROJECT_DIR$/vendor/composer" />
15
- </include_path>
16
- </component>
17
- <component name="PhpStanOptionsConfiguration">
18
- <option name="transferred" value="true" />
19
- </component>
20
- <component name="PhpUnit">
21
- <phpunit_settings>
22
- <PhpUnitSettings custom_loader_path="$PROJECT_DIR$/vendor/autoload.php" />
23
- </phpunit_settings>
24
- </component>
25
- <component name="PsalmOptionsConfiguration">
26
- <option name="transferred" value="true" />
27
- </component>
28
- </project>
package/.idea/vcs.xml DELETED
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="VcsDirectoryMappings">
4
- <mapping directory="$PROJECT_DIR$" vcs="Git" />
5
- </component>
6
- </project>