admin-lte 4.0.0-beta3 → 4.0.0-rc2
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.
- package/.browserslistrc +9 -4
- package/ACCESSIBILITY-COMPLIANCE.md +369 -0
- package/CHANGELOG.md +314 -0
- package/README.md +43 -7
- package/dist/css/adminlte.css +1412 -1264
- package/dist/css/adminlte.css.map +1 -1
- package/dist/css/adminlte.min.css +1 -1
- package/dist/css/adminlte.min.css.map +1 -1
- package/dist/css/adminlte.rtl.css +1430 -1256
- package/dist/css/adminlte.rtl.css.map +1 -1
- package/dist/css/adminlte.rtl.min.css +1 -1
- package/dist/css/adminlte.rtl.min.css.map +1 -1
- package/dist/js/adminlte.js +786 -345
- package/dist/js/adminlte.js.map +1 -1
- package/dist/js/adminlte.min.js +3 -3
- package/dist/js/adminlte.min.js.map +1 -1
- package/dist/pages/UI/general.html +41 -9
- package/dist/pages/UI/icons.html +38 -6
- package/dist/pages/UI/timeline.html +38 -6
- package/dist/pages/docs/browser-support.html +39 -25
- package/dist/pages/docs/color-mode.html +44 -31
- package/dist/pages/docs/components/main-header.html +39 -25
- package/dist/pages/docs/components/main-sidebar.html +40 -27
- package/dist/pages/docs/faq.html +38 -23
- package/dist/pages/docs/how-to-contribute.html +39 -25
- package/dist/pages/docs/introduction.html +44 -35
- package/dist/pages/docs/javascript/treeview.html +39 -25
- package/dist/pages/docs/layout.html +38 -6
- package/dist/pages/docs/license.html +38 -23
- package/dist/pages/examples/lockscreen.html +17 -5
- package/dist/pages/examples/login-v2.html +16 -4
- package/dist/pages/examples/login.html +16 -4
- package/dist/pages/examples/register-v2.html +16 -4
- package/dist/pages/examples/register.html +16 -4
- package/dist/pages/forms/general.html +38 -6
- package/dist/pages/generate/theme.html +155 -5
- package/dist/pages/index.html +42 -27
- package/dist/pages/index2.html +39 -7
- package/dist/pages/index3.html +38 -6
- package/dist/pages/layout/collapsed-sidebar.html +38 -6
- package/dist/pages/layout/fixed-complete.html +862 -0
- package/dist/pages/layout/fixed-footer.html +861 -0
- package/dist/pages/layout/fixed-header.html +861 -0
- package/dist/pages/layout/fixed-sidebar.html +38 -6
- package/dist/pages/layout/layout-custom-area.html +38 -6
- package/dist/pages/layout/layout-rtl.html +38 -6
- package/dist/pages/layout/logo-switch.html +17 -5
- package/dist/pages/layout/sidebar-mini.html +38 -6
- package/dist/pages/layout/unfixed-sidebar.html +38 -6
- package/dist/pages/tables/simple.html +38 -6
- package/dist/pages/widgets/cards.html +38 -6
- package/dist/pages/widgets/info-box.html +38 -6
- package/dist/pages/widgets/small-box.html +38 -6
- package/eslint.config.js +81 -0
- package/package.json +34 -31
- package/src/scss/_accessibility.scss +292 -0
- package/src/scss/_app-footer.scss +8 -0
- package/src/scss/_app-header.scss +8 -0
- package/src/scss/_table.scss +1 -9
- package/src/scss/_variables.scss +2 -1
- package/src/scss/adminlte.scss +3 -0
- package/src/ts/accessibility.ts +533 -0
- package/src/ts/adminlte.ts +48 -9
- package/src/ts/card-widget.ts +1 -2
- package/src/ts/push-menu.ts +1 -2
- package/src/ts/util/index.ts +39 -7
- package/.astro/content-assets.mjs +0 -1
- package/.astro/content-modules.mjs +0 -1
- package/.astro/content.d.ts +0 -166
- package/.astro/data-store.json +0 -1
- package/.astro/settings.json +0 -5
- package/.astro/types.d.ts +0 -2
- package/adminlte-v4.0.0-beta1-with-dist.zip +0 -0
- package/adminlte-v4.0.0-beta3.zip +0 -0
package/dist/js/adminlte.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* AdminLTE v4.0.0-
|
|
3
|
-
* Copyright 2014-
|
|
2
|
+
* AdminLTE v4.0.0-rc2 (https://adminlte.io)
|
|
3
|
+
* Copyright 2014-2025 Colorlib <https://colorlib.com>
|
|
4
4
|
* Licensed under MIT (https://github.com/ColorlibHQ/AdminLTE/blob/master/LICENSE)
|
|
5
5
|
*/
|
|
6
6
|
(function (global, factory) {
|
|
@@ -33,14 +33,14 @@
|
|
|
33
33
|
target.style.boxSizing = 'border-box';
|
|
34
34
|
target.style.height = `${target.offsetHeight}px`;
|
|
35
35
|
target.style.overflow = 'hidden';
|
|
36
|
-
|
|
36
|
+
globalThis.setTimeout(() => {
|
|
37
37
|
target.style.height = '0';
|
|
38
38
|
target.style.paddingTop = '0';
|
|
39
39
|
target.style.paddingBottom = '0';
|
|
40
40
|
target.style.marginTop = '0';
|
|
41
41
|
target.style.marginBottom = '0';
|
|
42
42
|
}, 1);
|
|
43
|
-
|
|
43
|
+
globalThis.setTimeout(() => {
|
|
44
44
|
target.style.display = 'none';
|
|
45
45
|
target.style.removeProperty('height');
|
|
46
46
|
target.style.removeProperty('padding-top');
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
/* SLIDE DOWN */
|
|
56
56
|
const slideDown = (target, duration = 500) => {
|
|
57
57
|
target.style.removeProperty('display');
|
|
58
|
-
let { display } =
|
|
58
|
+
let { display } = globalThis.getComputedStyle(target);
|
|
59
59
|
if (display === 'none') {
|
|
60
60
|
display = 'block';
|
|
61
61
|
}
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
target.style.paddingBottom = '0';
|
|
68
68
|
target.style.marginTop = '0';
|
|
69
69
|
target.style.marginBottom = '0';
|
|
70
|
-
|
|
70
|
+
globalThis.setTimeout(() => {
|
|
71
71
|
target.style.boxSizing = 'border-box';
|
|
72
72
|
target.style.transitionProperty = 'height, margin, padding';
|
|
73
73
|
target.style.transitionDuration = `${duration}ms`;
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
target.style.removeProperty('margin-top');
|
|
78
78
|
target.style.removeProperty('margin-bottom');
|
|
79
79
|
}, 1);
|
|
80
|
-
|
|
80
|
+
globalThis.setTimeout(() => {
|
|
81
81
|
target.style.removeProperty('height');
|
|
82
82
|
target.style.removeProperty('overflow');
|
|
83
83
|
target.style.removeProperty('transition-duration');
|
|
@@ -104,6 +104,7 @@
|
|
|
104
104
|
* ====================================================
|
|
105
105
|
*/
|
|
106
106
|
class Layout {
|
|
107
|
+
_element;
|
|
107
108
|
constructor(element) {
|
|
108
109
|
this._element = element;
|
|
109
110
|
}
|
|
@@ -128,146 +129,185 @@
|
|
|
128
129
|
|
|
129
130
|
/**
|
|
130
131
|
* --------------------------------------------
|
|
131
|
-
* @file AdminLTE
|
|
132
|
-
* @description
|
|
132
|
+
* @file AdminLTE card-widget.ts
|
|
133
|
+
* @description Card widget for AdminLTE.
|
|
133
134
|
* @license MIT
|
|
134
135
|
* --------------------------------------------
|
|
135
136
|
*/
|
|
136
137
|
/**
|
|
137
|
-
* ------------------------------------------------------------------------
|
|
138
138
|
* Constants
|
|
139
|
-
*
|
|
139
|
+
* ====================================================
|
|
140
140
|
*/
|
|
141
|
-
const DATA_KEY$4 = 'lte.
|
|
141
|
+
const DATA_KEY$4 = 'lte.card-widget';
|
|
142
142
|
const EVENT_KEY$4 = `.${DATA_KEY$4}`;
|
|
143
|
-
const
|
|
144
|
-
const
|
|
145
|
-
const
|
|
146
|
-
const
|
|
147
|
-
const
|
|
148
|
-
const
|
|
149
|
-
const
|
|
150
|
-
const
|
|
151
|
-
const
|
|
152
|
-
const
|
|
153
|
-
const
|
|
154
|
-
const
|
|
155
|
-
const
|
|
156
|
-
const
|
|
157
|
-
const
|
|
158
|
-
const
|
|
159
|
-
|
|
143
|
+
const EVENT_COLLAPSED$2 = `collapsed${EVENT_KEY$4}`;
|
|
144
|
+
const EVENT_EXPANDED$2 = `expanded${EVENT_KEY$4}`;
|
|
145
|
+
const EVENT_REMOVE = `remove${EVENT_KEY$4}`;
|
|
146
|
+
const EVENT_MAXIMIZED$1 = `maximized${EVENT_KEY$4}`;
|
|
147
|
+
const EVENT_MINIMIZED$1 = `minimized${EVENT_KEY$4}`;
|
|
148
|
+
const CLASS_NAME_CARD = 'card';
|
|
149
|
+
const CLASS_NAME_COLLAPSED = 'collapsed-card';
|
|
150
|
+
const CLASS_NAME_COLLAPSING = 'collapsing-card';
|
|
151
|
+
const CLASS_NAME_EXPANDING = 'expanding-card';
|
|
152
|
+
const CLASS_NAME_WAS_COLLAPSED = 'was-collapsed';
|
|
153
|
+
const CLASS_NAME_MAXIMIZED = 'maximized-card';
|
|
154
|
+
const SELECTOR_DATA_REMOVE = '[data-lte-toggle="card-remove"]';
|
|
155
|
+
const SELECTOR_DATA_COLLAPSE = '[data-lte-toggle="card-collapse"]';
|
|
156
|
+
const SELECTOR_DATA_MAXIMIZE = '[data-lte-toggle="card-maximize"]';
|
|
157
|
+
const SELECTOR_CARD = `.${CLASS_NAME_CARD}`;
|
|
158
|
+
const SELECTOR_CARD_BODY = '.card-body';
|
|
159
|
+
const SELECTOR_CARD_FOOTER = '.card-footer';
|
|
160
|
+
const Default$1 = {
|
|
161
|
+
animationSpeed: 500,
|
|
162
|
+
collapseTrigger: SELECTOR_DATA_COLLAPSE,
|
|
163
|
+
removeTrigger: SELECTOR_DATA_REMOVE,
|
|
164
|
+
maximizeTrigger: SELECTOR_DATA_MAXIMIZE
|
|
160
165
|
};
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
+
class CardWidget {
|
|
167
|
+
_element;
|
|
168
|
+
_parent;
|
|
169
|
+
_clone;
|
|
170
|
+
_config;
|
|
166
171
|
constructor(element, config) {
|
|
167
172
|
this._element = element;
|
|
168
|
-
this.
|
|
173
|
+
this._parent = element.closest(SELECTOR_CARD);
|
|
174
|
+
if (element.classList.contains(CLASS_NAME_CARD)) {
|
|
175
|
+
this._parent = element;
|
|
176
|
+
}
|
|
177
|
+
this._config = { ...Default$1, ...config };
|
|
169
178
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
if (navItem) {
|
|
180
|
-
navItem.forEach(navI => {
|
|
181
|
-
navI.classList.remove(CLASS_NAME_MENU_OPEN$1);
|
|
179
|
+
collapse() {
|
|
180
|
+
const event = new Event(EVENT_COLLAPSED$2);
|
|
181
|
+
if (this._parent) {
|
|
182
|
+
this._parent.classList.add(CLASS_NAME_COLLAPSING);
|
|
183
|
+
const elm = this._parent?.querySelectorAll(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`);
|
|
184
|
+
elm.forEach(el => {
|
|
185
|
+
if (el instanceof HTMLElement) {
|
|
186
|
+
slideUp(el, this._config.animationSpeed);
|
|
187
|
+
}
|
|
182
188
|
});
|
|
189
|
+
setTimeout(() => {
|
|
190
|
+
if (this._parent) {
|
|
191
|
+
this._parent.classList.add(CLASS_NAME_COLLAPSED);
|
|
192
|
+
this._parent.classList.remove(CLASS_NAME_COLLAPSING);
|
|
193
|
+
}
|
|
194
|
+
}, this._config.animationSpeed);
|
|
183
195
|
}
|
|
196
|
+
this._element?.dispatchEvent(event);
|
|
184
197
|
}
|
|
185
198
|
expand() {
|
|
186
|
-
const event = new Event(
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
const sidebarExpand = (_c = Array.from(sidebarExpandList).find(className => className.startsWith(CLASS_NAME_SIDEBAR_EXPAND))) !== null && _c !== void 0 ? _c : '';
|
|
201
|
-
const sidebar = document.getElementsByClassName(sidebarExpand)[0];
|
|
202
|
-
const sidebarContent = window.getComputedStyle(sidebar, '::before').getPropertyValue('content');
|
|
203
|
-
this._config = Object.assign(Object.assign({}, this._config), { sidebarBreakpoint: Number(sidebarContent.replace(/[^\d.-]/g, '')) });
|
|
204
|
-
if (window.innerWidth <= this._config.sidebarBreakpoint) {
|
|
205
|
-
this.collapse();
|
|
199
|
+
const event = new Event(EVENT_EXPANDED$2);
|
|
200
|
+
if (this._parent) {
|
|
201
|
+
this._parent.classList.add(CLASS_NAME_EXPANDING);
|
|
202
|
+
const elm = this._parent?.querySelectorAll(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`);
|
|
203
|
+
elm.forEach(el => {
|
|
204
|
+
if (el instanceof HTMLElement) {
|
|
205
|
+
slideDown(el, this._config.animationSpeed);
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
setTimeout(() => {
|
|
209
|
+
if (this._parent) {
|
|
210
|
+
this._parent.classList.remove(CLASS_NAME_COLLAPSED, CLASS_NAME_EXPANDING);
|
|
211
|
+
}
|
|
212
|
+
}, this._config.animationSpeed);
|
|
206
213
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
}
|
|
214
|
+
this._element?.dispatchEvent(event);
|
|
215
|
+
}
|
|
216
|
+
remove() {
|
|
217
|
+
const event = new Event(EVENT_REMOVE);
|
|
218
|
+
if (this._parent) {
|
|
219
|
+
slideUp(this._parent, this._config.animationSpeed);
|
|
214
220
|
}
|
|
221
|
+
this._element?.dispatchEvent(event);
|
|
215
222
|
}
|
|
216
223
|
toggle() {
|
|
217
|
-
if (
|
|
224
|
+
if (this._parent?.classList.contains(CLASS_NAME_COLLAPSED)) {
|
|
218
225
|
this.expand();
|
|
226
|
+
return;
|
|
219
227
|
}
|
|
220
|
-
|
|
221
|
-
|
|
228
|
+
this.collapse();
|
|
229
|
+
}
|
|
230
|
+
maximize() {
|
|
231
|
+
const event = new Event(EVENT_MAXIMIZED$1);
|
|
232
|
+
if (this._parent) {
|
|
233
|
+
this._parent.style.height = `${this._parent.offsetHeight}px`;
|
|
234
|
+
this._parent.style.width = `${this._parent.offsetWidth}px`;
|
|
235
|
+
this._parent.style.transition = 'all .15s';
|
|
236
|
+
setTimeout(() => {
|
|
237
|
+
const htmlTag = document.querySelector('html');
|
|
238
|
+
if (htmlTag) {
|
|
239
|
+
htmlTag.classList.add(CLASS_NAME_MAXIMIZED);
|
|
240
|
+
}
|
|
241
|
+
if (this._parent) {
|
|
242
|
+
this._parent.classList.add(CLASS_NAME_MAXIMIZED);
|
|
243
|
+
if (this._parent.classList.contains(CLASS_NAME_COLLAPSED)) {
|
|
244
|
+
this._parent.classList.add(CLASS_NAME_WAS_COLLAPSED);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}, 150);
|
|
222
248
|
}
|
|
249
|
+
this._element?.dispatchEvent(event);
|
|
223
250
|
}
|
|
224
|
-
|
|
225
|
-
|
|
251
|
+
minimize() {
|
|
252
|
+
const event = new Event(EVENT_MINIMIZED$1);
|
|
253
|
+
if (this._parent) {
|
|
254
|
+
this._parent.style.height = 'auto';
|
|
255
|
+
this._parent.style.width = 'auto';
|
|
256
|
+
this._parent.style.transition = 'all .15s';
|
|
257
|
+
setTimeout(() => {
|
|
258
|
+
const htmlTag = document.querySelector('html');
|
|
259
|
+
if (htmlTag) {
|
|
260
|
+
htmlTag.classList.remove(CLASS_NAME_MAXIMIZED);
|
|
261
|
+
}
|
|
262
|
+
if (this._parent) {
|
|
263
|
+
this._parent.classList.remove(CLASS_NAME_MAXIMIZED);
|
|
264
|
+
if (this._parent?.classList.contains(CLASS_NAME_WAS_COLLAPSED)) {
|
|
265
|
+
this._parent.classList.remove(CLASS_NAME_WAS_COLLAPSED);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}, 10);
|
|
269
|
+
}
|
|
270
|
+
this._element?.dispatchEvent(event);
|
|
271
|
+
}
|
|
272
|
+
toggleMaximize() {
|
|
273
|
+
if (this._parent?.classList.contains(CLASS_NAME_MAXIMIZED)) {
|
|
274
|
+
this.minimize();
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
this.maximize();
|
|
226
278
|
}
|
|
227
279
|
}
|
|
228
280
|
/**
|
|
229
|
-
*
|
|
281
|
+
*
|
|
230
282
|
* Data Api implementation
|
|
231
|
-
*
|
|
283
|
+
* ====================================================
|
|
232
284
|
*/
|
|
233
285
|
onDOMContentLoaded(() => {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
data.
|
|
286
|
+
const collapseBtn = document.querySelectorAll(SELECTOR_DATA_COLLAPSE);
|
|
287
|
+
collapseBtn.forEach(btn => {
|
|
288
|
+
btn.addEventListener('click', event => {
|
|
289
|
+
event.preventDefault();
|
|
290
|
+
const target = event.target;
|
|
291
|
+
const data = new CardWidget(target, Default$1);
|
|
292
|
+
data.toggle();
|
|
241
293
|
});
|
|
242
|
-
}
|
|
243
|
-
const sidebarOverlay = document.createElement('div');
|
|
244
|
-
sidebarOverlay.className = CLASS_NAME_SIDEBAR_OVERLAY;
|
|
245
|
-
(_a = document.querySelector(SELECTOR_APP_WRAPPER)) === null || _a === void 0 ? void 0 : _a.append(sidebarOverlay);
|
|
246
|
-
sidebarOverlay.addEventListener('touchstart', event => {
|
|
247
|
-
event.preventDefault();
|
|
248
|
-
const target = event.currentTarget;
|
|
249
|
-
const data = new PushMenu(target, Defaults);
|
|
250
|
-
data.collapse();
|
|
251
|
-
}, { passive: true });
|
|
252
|
-
sidebarOverlay.addEventListener('click', event => {
|
|
253
|
-
event.preventDefault();
|
|
254
|
-
const target = event.currentTarget;
|
|
255
|
-
const data = new PushMenu(target, Defaults);
|
|
256
|
-
data.collapse();
|
|
257
294
|
});
|
|
258
|
-
const
|
|
259
|
-
|
|
295
|
+
const removeBtn = document.querySelectorAll(SELECTOR_DATA_REMOVE);
|
|
296
|
+
removeBtn.forEach(btn => {
|
|
260
297
|
btn.addEventListener('click', event => {
|
|
261
298
|
event.preventDefault();
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
299
|
+
const target = event.target;
|
|
300
|
+
const data = new CardWidget(target, Default$1);
|
|
301
|
+
data.remove();
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
const maxBtn = document.querySelectorAll(SELECTOR_DATA_MAXIMIZE);
|
|
305
|
+
maxBtn.forEach(btn => {
|
|
306
|
+
btn.addEventListener('click', event => {
|
|
307
|
+
event.preventDefault();
|
|
308
|
+
const target = event.target;
|
|
309
|
+
const data = new CardWidget(target, Default$1);
|
|
310
|
+
data.toggleMaximize();
|
|
271
311
|
});
|
|
272
312
|
});
|
|
273
313
|
});
|
|
@@ -287,15 +327,15 @@
|
|
|
287
327
|
// const NAME = 'Treeview'
|
|
288
328
|
const DATA_KEY$3 = 'lte.treeview';
|
|
289
329
|
const EVENT_KEY$3 = `.${DATA_KEY$3}`;
|
|
290
|
-
const EVENT_EXPANDED$
|
|
291
|
-
const EVENT_COLLAPSED$
|
|
330
|
+
const EVENT_EXPANDED$1 = `expanded${EVENT_KEY$3}`;
|
|
331
|
+
const EVENT_COLLAPSED$1 = `collapsed${EVENT_KEY$3}`;
|
|
292
332
|
// const EVENT_LOAD_DATA_API = `load${EVENT_KEY}`
|
|
293
|
-
const CLASS_NAME_MENU_OPEN = 'menu-open';
|
|
294
|
-
const SELECTOR_NAV_ITEM = '.nav-item';
|
|
333
|
+
const CLASS_NAME_MENU_OPEN$1 = 'menu-open';
|
|
334
|
+
const SELECTOR_NAV_ITEM$1 = '.nav-item';
|
|
295
335
|
const SELECTOR_NAV_LINK = '.nav-link';
|
|
296
336
|
const SELECTOR_TREEVIEW_MENU = '.nav-treeview';
|
|
297
337
|
const SELECTOR_DATA_TOGGLE$1 = '[data-lte-toggle="treeview"]';
|
|
298
|
-
const Default
|
|
338
|
+
const Default = {
|
|
299
339
|
animationSpeed: 300,
|
|
300
340
|
accordion: true
|
|
301
341
|
};
|
|
@@ -304,44 +344,44 @@
|
|
|
304
344
|
* ====================================================
|
|
305
345
|
*/
|
|
306
346
|
class Treeview {
|
|
347
|
+
_element;
|
|
348
|
+
_config;
|
|
307
349
|
constructor(element, config) {
|
|
308
350
|
this._element = element;
|
|
309
|
-
this._config =
|
|
351
|
+
this._config = { ...Default, ...config };
|
|
310
352
|
}
|
|
311
353
|
open() {
|
|
312
|
-
|
|
313
|
-
const event = new Event(EVENT_EXPANDED$2);
|
|
354
|
+
const event = new Event(EVENT_EXPANDED$1);
|
|
314
355
|
if (this._config.accordion) {
|
|
315
|
-
const openMenuList =
|
|
316
|
-
openMenuList
|
|
356
|
+
const openMenuList = this._element.parentElement?.querySelectorAll(`${SELECTOR_NAV_ITEM$1}.${CLASS_NAME_MENU_OPEN$1}`);
|
|
357
|
+
openMenuList?.forEach(openMenu => {
|
|
317
358
|
if (openMenu !== this._element.parentElement) {
|
|
318
|
-
openMenu.classList.remove(CLASS_NAME_MENU_OPEN);
|
|
319
|
-
const childElement = openMenu
|
|
359
|
+
openMenu.classList.remove(CLASS_NAME_MENU_OPEN$1);
|
|
360
|
+
const childElement = openMenu?.querySelector(SELECTOR_TREEVIEW_MENU);
|
|
320
361
|
if (childElement) {
|
|
321
362
|
slideUp(childElement, this._config.animationSpeed);
|
|
322
363
|
}
|
|
323
364
|
}
|
|
324
365
|
});
|
|
325
366
|
}
|
|
326
|
-
this._element.classList.add(CLASS_NAME_MENU_OPEN);
|
|
327
|
-
const childElement =
|
|
367
|
+
this._element.classList.add(CLASS_NAME_MENU_OPEN$1);
|
|
368
|
+
const childElement = this._element?.querySelector(SELECTOR_TREEVIEW_MENU);
|
|
328
369
|
if (childElement) {
|
|
329
370
|
slideDown(childElement, this._config.animationSpeed);
|
|
330
371
|
}
|
|
331
372
|
this._element.dispatchEvent(event);
|
|
332
373
|
}
|
|
333
374
|
close() {
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
this._element
|
|
337
|
-
const childElement = (_a = this._element) === null || _a === void 0 ? void 0 : _a.querySelector(SELECTOR_TREEVIEW_MENU);
|
|
375
|
+
const event = new Event(EVENT_COLLAPSED$1);
|
|
376
|
+
this._element.classList.remove(CLASS_NAME_MENU_OPEN$1);
|
|
377
|
+
const childElement = this._element?.querySelector(SELECTOR_TREEVIEW_MENU);
|
|
338
378
|
if (childElement) {
|
|
339
379
|
slideUp(childElement, this._config.animationSpeed);
|
|
340
380
|
}
|
|
341
381
|
this._element.dispatchEvent(event);
|
|
342
382
|
}
|
|
343
383
|
toggle() {
|
|
344
|
-
if (this._element.classList.contains(CLASS_NAME_MENU_OPEN)) {
|
|
384
|
+
if (this._element.classList.contains(CLASS_NAME_MENU_OPEN$1)) {
|
|
345
385
|
this.close();
|
|
346
386
|
}
|
|
347
387
|
else {
|
|
@@ -359,13 +399,13 @@
|
|
|
359
399
|
button.forEach(btn => {
|
|
360
400
|
btn.addEventListener('click', event => {
|
|
361
401
|
const target = event.target;
|
|
362
|
-
const targetItem = target.closest(SELECTOR_NAV_ITEM);
|
|
402
|
+
const targetItem = target.closest(SELECTOR_NAV_ITEM$1);
|
|
363
403
|
const targetLink = target.closest(SELECTOR_NAV_LINK);
|
|
364
|
-
if (
|
|
404
|
+
if (target?.getAttribute('href') === '#' || targetLink?.getAttribute('href') === '#') {
|
|
365
405
|
event.preventDefault();
|
|
366
406
|
}
|
|
367
407
|
if (targetItem) {
|
|
368
|
-
const data = new Treeview(targetItem, Default
|
|
408
|
+
const data = new Treeview(targetItem, Default);
|
|
369
409
|
data.toggle();
|
|
370
410
|
}
|
|
371
411
|
});
|
|
@@ -385,8 +425,8 @@
|
|
|
385
425
|
*/
|
|
386
426
|
const DATA_KEY$2 = 'lte.direct-chat';
|
|
387
427
|
const EVENT_KEY$2 = `.${DATA_KEY$2}`;
|
|
388
|
-
const EVENT_EXPANDED
|
|
389
|
-
const EVENT_COLLAPSED
|
|
428
|
+
const EVENT_EXPANDED = `expanded${EVENT_KEY$2}`;
|
|
429
|
+
const EVENT_COLLAPSED = `collapsed${EVENT_KEY$2}`;
|
|
390
430
|
const SELECTOR_DATA_TOGGLE = '[data-lte-toggle="chat-pane"]';
|
|
391
431
|
const SELECTOR_DIRECT_CHAT = '.direct-chat';
|
|
392
432
|
const CLASS_NAME_DIRECT_CHAT_OPEN = 'direct-chat-contacts-open';
|
|
@@ -395,17 +435,18 @@
|
|
|
395
435
|
* ====================================================
|
|
396
436
|
*/
|
|
397
437
|
class DirectChat {
|
|
438
|
+
_element;
|
|
398
439
|
constructor(element) {
|
|
399
440
|
this._element = element;
|
|
400
441
|
}
|
|
401
442
|
toggle() {
|
|
402
443
|
if (this._element.classList.contains(CLASS_NAME_DIRECT_CHAT_OPEN)) {
|
|
403
|
-
const event = new Event(EVENT_COLLAPSED
|
|
444
|
+
const event = new Event(EVENT_COLLAPSED);
|
|
404
445
|
this._element.classList.remove(CLASS_NAME_DIRECT_CHAT_OPEN);
|
|
405
446
|
this._element.dispatchEvent(event);
|
|
406
447
|
}
|
|
407
448
|
else {
|
|
408
|
-
const event = new Event(EVENT_EXPANDED
|
|
449
|
+
const event = new Event(EVENT_EXPANDED);
|
|
409
450
|
this._element.classList.add(CLASS_NAME_DIRECT_CHAT_OPEN);
|
|
410
451
|
this._element.dispatchEvent(event);
|
|
411
452
|
}
|
|
@@ -433,220 +474,32 @@
|
|
|
433
474
|
|
|
434
475
|
/**
|
|
435
476
|
* --------------------------------------------
|
|
436
|
-
* @file AdminLTE
|
|
437
|
-
* @description
|
|
477
|
+
* @file AdminLTE fullscreen.ts
|
|
478
|
+
* @description Fullscreen plugin for AdminLTE.
|
|
438
479
|
* @license MIT
|
|
439
480
|
* --------------------------------------------
|
|
440
481
|
*/
|
|
441
482
|
/**
|
|
442
483
|
* Constants
|
|
443
|
-
*
|
|
484
|
+
* ============================================================================
|
|
444
485
|
*/
|
|
445
|
-
const DATA_KEY$1 = 'lte.
|
|
486
|
+
const DATA_KEY$1 = 'lte.fullscreen';
|
|
446
487
|
const EVENT_KEY$1 = `.${DATA_KEY$1}`;
|
|
447
|
-
const
|
|
448
|
-
const
|
|
449
|
-
const
|
|
450
|
-
const
|
|
451
|
-
const
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
const SELECTOR_DATA_COLLAPSE = '[data-lte-toggle="card-collapse"]';
|
|
460
|
-
const SELECTOR_DATA_MAXIMIZE = '[data-lte-toggle="card-maximize"]';
|
|
461
|
-
const SELECTOR_CARD = `.${CLASS_NAME_CARD}`;
|
|
462
|
-
const SELECTOR_CARD_BODY = '.card-body';
|
|
463
|
-
const SELECTOR_CARD_FOOTER = '.card-footer';
|
|
464
|
-
const Default = {
|
|
465
|
-
animationSpeed: 500,
|
|
466
|
-
collapseTrigger: SELECTOR_DATA_COLLAPSE,
|
|
467
|
-
removeTrigger: SELECTOR_DATA_REMOVE,
|
|
468
|
-
maximizeTrigger: SELECTOR_DATA_MAXIMIZE
|
|
469
|
-
};
|
|
470
|
-
class CardWidget {
|
|
488
|
+
const EVENT_MAXIMIZED = `maximized${EVENT_KEY$1}`;
|
|
489
|
+
const EVENT_MINIMIZED = `minimized${EVENT_KEY$1}`;
|
|
490
|
+
const SELECTOR_FULLSCREEN_TOGGLE = '[data-lte-toggle="fullscreen"]';
|
|
491
|
+
const SELECTOR_MAXIMIZE_ICON = '[data-lte-icon="maximize"]';
|
|
492
|
+
const SELECTOR_MINIMIZE_ICON = '[data-lte-icon="minimize"]';
|
|
493
|
+
/**
|
|
494
|
+
* Class Definition.
|
|
495
|
+
* ============================================================================
|
|
496
|
+
*/
|
|
497
|
+
class FullScreen {
|
|
498
|
+
_element;
|
|
499
|
+
_config;
|
|
471
500
|
constructor(element, config) {
|
|
472
501
|
this._element = element;
|
|
473
|
-
this.
|
|
474
|
-
if (element.classList.contains(CLASS_NAME_CARD)) {
|
|
475
|
-
this._parent = element;
|
|
476
|
-
}
|
|
477
|
-
this._config = Object.assign(Object.assign({}, Default), config);
|
|
478
|
-
}
|
|
479
|
-
collapse() {
|
|
480
|
-
var _a, _b;
|
|
481
|
-
const event = new Event(EVENT_COLLAPSED);
|
|
482
|
-
if (this._parent) {
|
|
483
|
-
this._parent.classList.add(CLASS_NAME_COLLAPSING);
|
|
484
|
-
const elm = (_a = this._parent) === null || _a === void 0 ? void 0 : _a.querySelectorAll(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`);
|
|
485
|
-
elm.forEach(el => {
|
|
486
|
-
if (el instanceof HTMLElement) {
|
|
487
|
-
slideUp(el, this._config.animationSpeed);
|
|
488
|
-
}
|
|
489
|
-
});
|
|
490
|
-
setTimeout(() => {
|
|
491
|
-
if (this._parent) {
|
|
492
|
-
this._parent.classList.add(CLASS_NAME_COLLAPSED);
|
|
493
|
-
this._parent.classList.remove(CLASS_NAME_COLLAPSING);
|
|
494
|
-
}
|
|
495
|
-
}, this._config.animationSpeed);
|
|
496
|
-
}
|
|
497
|
-
(_b = this._element) === null || _b === void 0 ? void 0 : _b.dispatchEvent(event);
|
|
498
|
-
}
|
|
499
|
-
expand() {
|
|
500
|
-
var _a, _b;
|
|
501
|
-
const event = new Event(EVENT_EXPANDED);
|
|
502
|
-
if (this._parent) {
|
|
503
|
-
this._parent.classList.add(CLASS_NAME_EXPANDING);
|
|
504
|
-
const elm = (_a = this._parent) === null || _a === void 0 ? void 0 : _a.querySelectorAll(`${SELECTOR_CARD_BODY}, ${SELECTOR_CARD_FOOTER}`);
|
|
505
|
-
elm.forEach(el => {
|
|
506
|
-
if (el instanceof HTMLElement) {
|
|
507
|
-
slideDown(el, this._config.animationSpeed);
|
|
508
|
-
}
|
|
509
|
-
});
|
|
510
|
-
setTimeout(() => {
|
|
511
|
-
if (this._parent) {
|
|
512
|
-
this._parent.classList.remove(CLASS_NAME_COLLAPSED);
|
|
513
|
-
this._parent.classList.remove(CLASS_NAME_EXPANDING);
|
|
514
|
-
}
|
|
515
|
-
}, this._config.animationSpeed);
|
|
516
|
-
}
|
|
517
|
-
(_b = this._element) === null || _b === void 0 ? void 0 : _b.dispatchEvent(event);
|
|
518
|
-
}
|
|
519
|
-
remove() {
|
|
520
|
-
var _a;
|
|
521
|
-
const event = new Event(EVENT_REMOVE);
|
|
522
|
-
if (this._parent) {
|
|
523
|
-
slideUp(this._parent, this._config.animationSpeed);
|
|
524
|
-
}
|
|
525
|
-
(_a = this._element) === null || _a === void 0 ? void 0 : _a.dispatchEvent(event);
|
|
526
|
-
}
|
|
527
|
-
toggle() {
|
|
528
|
-
var _a;
|
|
529
|
-
if ((_a = this._parent) === null || _a === void 0 ? void 0 : _a.classList.contains(CLASS_NAME_COLLAPSED)) {
|
|
530
|
-
this.expand();
|
|
531
|
-
return;
|
|
532
|
-
}
|
|
533
|
-
this.collapse();
|
|
534
|
-
}
|
|
535
|
-
maximize() {
|
|
536
|
-
var _a;
|
|
537
|
-
const event = new Event(EVENT_MAXIMIZED$1);
|
|
538
|
-
if (this._parent) {
|
|
539
|
-
this._parent.style.height = `${this._parent.offsetHeight}px`;
|
|
540
|
-
this._parent.style.width = `${this._parent.offsetWidth}px`;
|
|
541
|
-
this._parent.style.transition = 'all .15s';
|
|
542
|
-
setTimeout(() => {
|
|
543
|
-
const htmlTag = document.querySelector('html');
|
|
544
|
-
if (htmlTag) {
|
|
545
|
-
htmlTag.classList.add(CLASS_NAME_MAXIMIZED);
|
|
546
|
-
}
|
|
547
|
-
if (this._parent) {
|
|
548
|
-
this._parent.classList.add(CLASS_NAME_MAXIMIZED);
|
|
549
|
-
if (this._parent.classList.contains(CLASS_NAME_COLLAPSED)) {
|
|
550
|
-
this._parent.classList.add(CLASS_NAME_WAS_COLLAPSED);
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
}, 150);
|
|
554
|
-
}
|
|
555
|
-
(_a = this._element) === null || _a === void 0 ? void 0 : _a.dispatchEvent(event);
|
|
556
|
-
}
|
|
557
|
-
minimize() {
|
|
558
|
-
var _a;
|
|
559
|
-
const event = new Event(EVENT_MINIMIZED$1);
|
|
560
|
-
if (this._parent) {
|
|
561
|
-
this._parent.style.height = 'auto';
|
|
562
|
-
this._parent.style.width = 'auto';
|
|
563
|
-
this._parent.style.transition = 'all .15s';
|
|
564
|
-
setTimeout(() => {
|
|
565
|
-
var _a;
|
|
566
|
-
const htmlTag = document.querySelector('html');
|
|
567
|
-
if (htmlTag) {
|
|
568
|
-
htmlTag.classList.remove(CLASS_NAME_MAXIMIZED);
|
|
569
|
-
}
|
|
570
|
-
if (this._parent) {
|
|
571
|
-
this._parent.classList.remove(CLASS_NAME_MAXIMIZED);
|
|
572
|
-
if ((_a = this._parent) === null || _a === void 0 ? void 0 : _a.classList.contains(CLASS_NAME_WAS_COLLAPSED)) {
|
|
573
|
-
this._parent.classList.remove(CLASS_NAME_WAS_COLLAPSED);
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
}, 10);
|
|
577
|
-
}
|
|
578
|
-
(_a = this._element) === null || _a === void 0 ? void 0 : _a.dispatchEvent(event);
|
|
579
|
-
}
|
|
580
|
-
toggleMaximize() {
|
|
581
|
-
var _a;
|
|
582
|
-
if ((_a = this._parent) === null || _a === void 0 ? void 0 : _a.classList.contains(CLASS_NAME_MAXIMIZED)) {
|
|
583
|
-
this.minimize();
|
|
584
|
-
return;
|
|
585
|
-
}
|
|
586
|
-
this.maximize();
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
/**
|
|
590
|
-
*
|
|
591
|
-
* Data Api implementation
|
|
592
|
-
* ====================================================
|
|
593
|
-
*/
|
|
594
|
-
onDOMContentLoaded(() => {
|
|
595
|
-
const collapseBtn = document.querySelectorAll(SELECTOR_DATA_COLLAPSE);
|
|
596
|
-
collapseBtn.forEach(btn => {
|
|
597
|
-
btn.addEventListener('click', event => {
|
|
598
|
-
event.preventDefault();
|
|
599
|
-
const target = event.target;
|
|
600
|
-
const data = new CardWidget(target, Default);
|
|
601
|
-
data.toggle();
|
|
602
|
-
});
|
|
603
|
-
});
|
|
604
|
-
const removeBtn = document.querySelectorAll(SELECTOR_DATA_REMOVE);
|
|
605
|
-
removeBtn.forEach(btn => {
|
|
606
|
-
btn.addEventListener('click', event => {
|
|
607
|
-
event.preventDefault();
|
|
608
|
-
const target = event.target;
|
|
609
|
-
const data = new CardWidget(target, Default);
|
|
610
|
-
data.remove();
|
|
611
|
-
});
|
|
612
|
-
});
|
|
613
|
-
const maxBtn = document.querySelectorAll(SELECTOR_DATA_MAXIMIZE);
|
|
614
|
-
maxBtn.forEach(btn => {
|
|
615
|
-
btn.addEventListener('click', event => {
|
|
616
|
-
event.preventDefault();
|
|
617
|
-
const target = event.target;
|
|
618
|
-
const data = new CardWidget(target, Default);
|
|
619
|
-
data.toggleMaximize();
|
|
620
|
-
});
|
|
621
|
-
});
|
|
622
|
-
});
|
|
623
|
-
|
|
624
|
-
/**
|
|
625
|
-
* --------------------------------------------
|
|
626
|
-
* @file AdminLTE fullscreen.ts
|
|
627
|
-
* @description Fullscreen plugin for AdminLTE.
|
|
628
|
-
* @license MIT
|
|
629
|
-
* --------------------------------------------
|
|
630
|
-
*/
|
|
631
|
-
/**
|
|
632
|
-
* Constants
|
|
633
|
-
* ============================================================================
|
|
634
|
-
*/
|
|
635
|
-
const DATA_KEY = 'lte.fullscreen';
|
|
636
|
-
const EVENT_KEY = `.${DATA_KEY}`;
|
|
637
|
-
const EVENT_MAXIMIZED = `maximized${EVENT_KEY}`;
|
|
638
|
-
const EVENT_MINIMIZED = `minimized${EVENT_KEY}`;
|
|
639
|
-
const SELECTOR_FULLSCREEN_TOGGLE = '[data-lte-toggle="fullscreen"]';
|
|
640
|
-
const SELECTOR_MAXIMIZE_ICON = '[data-lte-icon="maximize"]';
|
|
641
|
-
const SELECTOR_MINIMIZE_ICON = '[data-lte-icon="minimize"]';
|
|
642
|
-
/**
|
|
643
|
-
* Class Definition.
|
|
644
|
-
* ============================================================================
|
|
645
|
-
*/
|
|
646
|
-
class FullScreen {
|
|
647
|
-
constructor(element, config) {
|
|
648
|
-
this._element = element;
|
|
649
|
-
this._config = config;
|
|
502
|
+
this._config = config;
|
|
650
503
|
}
|
|
651
504
|
inFullScreen() {
|
|
652
505
|
const event = new Event(EVENT_MAXIMIZED);
|
|
@@ -704,12 +557,600 @@
|
|
|
704
557
|
});
|
|
705
558
|
});
|
|
706
559
|
|
|
560
|
+
/**
|
|
561
|
+
* --------------------------------------------
|
|
562
|
+
* @file AdminLTE push-menu.ts
|
|
563
|
+
* @description Push menu for AdminLTE.
|
|
564
|
+
* @license MIT
|
|
565
|
+
* --------------------------------------------
|
|
566
|
+
*/
|
|
567
|
+
/**
|
|
568
|
+
* ------------------------------------------------------------------------
|
|
569
|
+
* Constants
|
|
570
|
+
* ------------------------------------------------------------------------
|
|
571
|
+
*/
|
|
572
|
+
const DATA_KEY = 'lte.push-menu';
|
|
573
|
+
const EVENT_KEY = `.${DATA_KEY}`;
|
|
574
|
+
const EVENT_OPEN = `open${EVENT_KEY}`;
|
|
575
|
+
const EVENT_COLLAPSE = `collapse${EVENT_KEY}`;
|
|
576
|
+
const CLASS_NAME_SIDEBAR_MINI = 'sidebar-mini';
|
|
577
|
+
const CLASS_NAME_SIDEBAR_COLLAPSE = 'sidebar-collapse';
|
|
578
|
+
const CLASS_NAME_SIDEBAR_OPEN = 'sidebar-open';
|
|
579
|
+
const CLASS_NAME_SIDEBAR_EXPAND = 'sidebar-expand';
|
|
580
|
+
const CLASS_NAME_SIDEBAR_OVERLAY = 'sidebar-overlay';
|
|
581
|
+
const CLASS_NAME_MENU_OPEN = 'menu-open';
|
|
582
|
+
const SELECTOR_APP_SIDEBAR = '.app-sidebar';
|
|
583
|
+
const SELECTOR_SIDEBAR_MENU = '.sidebar-menu';
|
|
584
|
+
const SELECTOR_NAV_ITEM = '.nav-item';
|
|
585
|
+
const SELECTOR_NAV_TREEVIEW = '.nav-treeview';
|
|
586
|
+
const SELECTOR_APP_WRAPPER = '.app-wrapper';
|
|
587
|
+
const SELECTOR_SIDEBAR_EXPAND = `[class*="${CLASS_NAME_SIDEBAR_EXPAND}"]`;
|
|
588
|
+
const SELECTOR_SIDEBAR_TOGGLE = '[data-lte-toggle="sidebar"]';
|
|
589
|
+
const Defaults = {
|
|
590
|
+
sidebarBreakpoint: 992
|
|
591
|
+
};
|
|
592
|
+
/**
|
|
593
|
+
* Class Definition
|
|
594
|
+
* ====================================================
|
|
595
|
+
*/
|
|
596
|
+
class PushMenu {
|
|
597
|
+
_element;
|
|
598
|
+
_config;
|
|
599
|
+
constructor(element, config) {
|
|
600
|
+
this._element = element;
|
|
601
|
+
this._config = { ...Defaults, ...config };
|
|
602
|
+
}
|
|
603
|
+
menusClose() {
|
|
604
|
+
const navTreeview = document.querySelectorAll(SELECTOR_NAV_TREEVIEW);
|
|
605
|
+
navTreeview.forEach(navTree => {
|
|
606
|
+
navTree.style.removeProperty('display');
|
|
607
|
+
navTree.style.removeProperty('height');
|
|
608
|
+
});
|
|
609
|
+
const navSidebar = document.querySelector(SELECTOR_SIDEBAR_MENU);
|
|
610
|
+
const navItem = navSidebar?.querySelectorAll(SELECTOR_NAV_ITEM);
|
|
611
|
+
if (navItem) {
|
|
612
|
+
navItem.forEach(navI => {
|
|
613
|
+
navI.classList.remove(CLASS_NAME_MENU_OPEN);
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
expand() {
|
|
618
|
+
const event = new Event(EVENT_OPEN);
|
|
619
|
+
document.body.classList.remove(CLASS_NAME_SIDEBAR_COLLAPSE);
|
|
620
|
+
document.body.classList.add(CLASS_NAME_SIDEBAR_OPEN);
|
|
621
|
+
this._element.dispatchEvent(event);
|
|
622
|
+
}
|
|
623
|
+
collapse() {
|
|
624
|
+
const event = new Event(EVENT_COLLAPSE);
|
|
625
|
+
document.body.classList.remove(CLASS_NAME_SIDEBAR_OPEN);
|
|
626
|
+
document.body.classList.add(CLASS_NAME_SIDEBAR_COLLAPSE);
|
|
627
|
+
this._element.dispatchEvent(event);
|
|
628
|
+
}
|
|
629
|
+
addSidebarBreakPoint() {
|
|
630
|
+
const sidebarExpandList = document.querySelector(SELECTOR_SIDEBAR_EXPAND)?.classList ?? [];
|
|
631
|
+
const sidebarExpand = Array.from(sidebarExpandList).find(className => className.startsWith(CLASS_NAME_SIDEBAR_EXPAND)) ?? '';
|
|
632
|
+
const sidebar = document.getElementsByClassName(sidebarExpand)[0];
|
|
633
|
+
const sidebarContent = globalThis.getComputedStyle(sidebar, '::before').getPropertyValue('content');
|
|
634
|
+
this._config = { ...this._config, sidebarBreakpoint: Number(sidebarContent.replace(/[^\d.-]/g, '')) };
|
|
635
|
+
if (window.innerWidth <= this._config.sidebarBreakpoint) {
|
|
636
|
+
this.collapse();
|
|
637
|
+
}
|
|
638
|
+
else {
|
|
639
|
+
if (!document.body.classList.contains(CLASS_NAME_SIDEBAR_MINI)) {
|
|
640
|
+
this.expand();
|
|
641
|
+
}
|
|
642
|
+
if (document.body.classList.contains(CLASS_NAME_SIDEBAR_MINI) && document.body.classList.contains(CLASS_NAME_SIDEBAR_COLLAPSE)) {
|
|
643
|
+
this.collapse();
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
toggle() {
|
|
648
|
+
if (document.body.classList.contains(CLASS_NAME_SIDEBAR_COLLAPSE)) {
|
|
649
|
+
this.expand();
|
|
650
|
+
}
|
|
651
|
+
else {
|
|
652
|
+
this.collapse();
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
init() {
|
|
656
|
+
this.addSidebarBreakPoint();
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
/**
|
|
660
|
+
* ------------------------------------------------------------------------
|
|
661
|
+
* Data Api implementation
|
|
662
|
+
* ------------------------------------------------------------------------
|
|
663
|
+
*/
|
|
664
|
+
onDOMContentLoaded(() => {
|
|
665
|
+
const sidebar = document?.querySelector(SELECTOR_APP_SIDEBAR);
|
|
666
|
+
if (sidebar) {
|
|
667
|
+
const data = new PushMenu(sidebar, Defaults);
|
|
668
|
+
data.init();
|
|
669
|
+
window.addEventListener('resize', () => {
|
|
670
|
+
data.init();
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
const sidebarOverlay = document.createElement('div');
|
|
674
|
+
sidebarOverlay.className = CLASS_NAME_SIDEBAR_OVERLAY;
|
|
675
|
+
document.querySelector(SELECTOR_APP_WRAPPER)?.append(sidebarOverlay);
|
|
676
|
+
sidebarOverlay.addEventListener('touchstart', event => {
|
|
677
|
+
event.preventDefault();
|
|
678
|
+
const target = event.currentTarget;
|
|
679
|
+
const data = new PushMenu(target, Defaults);
|
|
680
|
+
data.collapse();
|
|
681
|
+
}, { passive: true });
|
|
682
|
+
sidebarOverlay.addEventListener('click', event => {
|
|
683
|
+
event.preventDefault();
|
|
684
|
+
const target = event.currentTarget;
|
|
685
|
+
const data = new PushMenu(target, Defaults);
|
|
686
|
+
data.collapse();
|
|
687
|
+
});
|
|
688
|
+
const fullBtn = document.querySelectorAll(SELECTOR_SIDEBAR_TOGGLE);
|
|
689
|
+
fullBtn.forEach(btn => {
|
|
690
|
+
btn.addEventListener('click', event => {
|
|
691
|
+
event.preventDefault();
|
|
692
|
+
let button = event.currentTarget;
|
|
693
|
+
if (button?.dataset.lteToggle !== 'sidebar') {
|
|
694
|
+
button = button?.closest(SELECTOR_SIDEBAR_TOGGLE);
|
|
695
|
+
}
|
|
696
|
+
if (button) {
|
|
697
|
+
event?.preventDefault();
|
|
698
|
+
const data = new PushMenu(button, Defaults);
|
|
699
|
+
data.toggle();
|
|
700
|
+
}
|
|
701
|
+
});
|
|
702
|
+
});
|
|
703
|
+
});
|
|
704
|
+
|
|
705
|
+
/**
|
|
706
|
+
* AdminLTE Accessibility Module
|
|
707
|
+
* WCAG 2.1 AA Compliance Features
|
|
708
|
+
*/
|
|
709
|
+
class AccessibilityManager {
|
|
710
|
+
config;
|
|
711
|
+
liveRegion = null;
|
|
712
|
+
focusHistory = [];
|
|
713
|
+
constructor(config = {}) {
|
|
714
|
+
this.config = {
|
|
715
|
+
announcements: true,
|
|
716
|
+
skipLinks: true,
|
|
717
|
+
focusManagement: true,
|
|
718
|
+
keyboardNavigation: true,
|
|
719
|
+
reducedMotion: true,
|
|
720
|
+
...config
|
|
721
|
+
};
|
|
722
|
+
this.init();
|
|
723
|
+
}
|
|
724
|
+
init() {
|
|
725
|
+
if (this.config.announcements) {
|
|
726
|
+
this.createLiveRegion();
|
|
727
|
+
}
|
|
728
|
+
if (this.config.skipLinks) {
|
|
729
|
+
this.addSkipLinks();
|
|
730
|
+
}
|
|
731
|
+
if (this.config.focusManagement) {
|
|
732
|
+
this.initFocusManagement();
|
|
733
|
+
}
|
|
734
|
+
if (this.config.keyboardNavigation) {
|
|
735
|
+
this.initKeyboardNavigation();
|
|
736
|
+
}
|
|
737
|
+
if (this.config.reducedMotion) {
|
|
738
|
+
this.respectReducedMotion();
|
|
739
|
+
}
|
|
740
|
+
this.initErrorAnnouncements();
|
|
741
|
+
this.initTableAccessibility();
|
|
742
|
+
this.initFormAccessibility();
|
|
743
|
+
}
|
|
744
|
+
// WCAG 4.1.3: Status Messages
|
|
745
|
+
createLiveRegion() {
|
|
746
|
+
if (this.liveRegion)
|
|
747
|
+
return;
|
|
748
|
+
this.liveRegion = document.createElement('div');
|
|
749
|
+
this.liveRegion.id = 'live-region';
|
|
750
|
+
this.liveRegion.className = 'live-region';
|
|
751
|
+
this.liveRegion.setAttribute('aria-live', 'polite');
|
|
752
|
+
this.liveRegion.setAttribute('aria-atomic', 'true');
|
|
753
|
+
this.liveRegion.setAttribute('role', 'status');
|
|
754
|
+
document.body.append(this.liveRegion);
|
|
755
|
+
}
|
|
756
|
+
// WCAG 2.4.1: Bypass Blocks
|
|
757
|
+
addSkipLinks() {
|
|
758
|
+
const skipLinksContainer = document.createElement('div');
|
|
759
|
+
skipLinksContainer.className = 'skip-links';
|
|
760
|
+
const skipToMain = document.createElement('a');
|
|
761
|
+
skipToMain.href = '#main';
|
|
762
|
+
skipToMain.className = 'skip-link';
|
|
763
|
+
skipToMain.textContent = 'Skip to main content';
|
|
764
|
+
const skipToNav = document.createElement('a');
|
|
765
|
+
skipToNav.href = '#navigation';
|
|
766
|
+
skipToNav.className = 'skip-link';
|
|
767
|
+
skipToNav.textContent = 'Skip to navigation';
|
|
768
|
+
skipLinksContainer.append(skipToMain);
|
|
769
|
+
skipLinksContainer.append(skipToNav);
|
|
770
|
+
document.body.insertBefore(skipLinksContainer, document.body.firstChild);
|
|
771
|
+
// Ensure targets exist and are focusable
|
|
772
|
+
this.ensureSkipTargets();
|
|
773
|
+
}
|
|
774
|
+
ensureSkipTargets() {
|
|
775
|
+
const main = document.querySelector('#main, main, [role="main"]');
|
|
776
|
+
if (main && !main.id) {
|
|
777
|
+
main.id = 'main';
|
|
778
|
+
}
|
|
779
|
+
if (main && !main.hasAttribute('tabindex')) {
|
|
780
|
+
main.setAttribute('tabindex', '-1');
|
|
781
|
+
}
|
|
782
|
+
const nav = document.querySelector('#navigation, nav, [role="navigation"]');
|
|
783
|
+
if (nav && !nav.id) {
|
|
784
|
+
nav.id = 'navigation';
|
|
785
|
+
}
|
|
786
|
+
if (nav && !nav.hasAttribute('tabindex')) {
|
|
787
|
+
nav.setAttribute('tabindex', '-1');
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
// WCAG 2.4.3: Focus Order & 2.4.7: Focus Visible
|
|
791
|
+
initFocusManagement() {
|
|
792
|
+
document.addEventListener('keydown', (event) => {
|
|
793
|
+
if (event.key === 'Tab') {
|
|
794
|
+
this.handleTabNavigation(event);
|
|
795
|
+
}
|
|
796
|
+
if (event.key === 'Escape') {
|
|
797
|
+
this.handleEscapeKey(event);
|
|
798
|
+
}
|
|
799
|
+
});
|
|
800
|
+
// Focus management for modals and dropdowns
|
|
801
|
+
this.initModalFocusManagement();
|
|
802
|
+
this.initDropdownFocusManagement();
|
|
803
|
+
}
|
|
804
|
+
handleTabNavigation(event) {
|
|
805
|
+
const focusableElements = this.getFocusableElements();
|
|
806
|
+
const currentIndex = focusableElements.indexOf(document.activeElement);
|
|
807
|
+
if (event.shiftKey) {
|
|
808
|
+
// Shift+Tab (backward)
|
|
809
|
+
if (currentIndex <= 0) {
|
|
810
|
+
event.preventDefault();
|
|
811
|
+
focusableElements.at(-1)?.focus();
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
else if (currentIndex >= focusableElements.length - 1) {
|
|
815
|
+
// Tab (forward)
|
|
816
|
+
event.preventDefault();
|
|
817
|
+
focusableElements[0]?.focus();
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
getFocusableElements() {
|
|
821
|
+
const selector = [
|
|
822
|
+
'a[href]',
|
|
823
|
+
'button:not([disabled])',
|
|
824
|
+
'input:not([disabled])',
|
|
825
|
+
'select:not([disabled])',
|
|
826
|
+
'textarea:not([disabled])',
|
|
827
|
+
'[tabindex]:not([tabindex="-1"])',
|
|
828
|
+
'[contenteditable="true"]'
|
|
829
|
+
].join(', ');
|
|
830
|
+
return Array.from(document.querySelectorAll(selector));
|
|
831
|
+
}
|
|
832
|
+
handleEscapeKey(event) {
|
|
833
|
+
// Close modals, dropdowns, etc.
|
|
834
|
+
const activeModal = document.querySelector('.modal.show');
|
|
835
|
+
const activeDropdown = document.querySelector('.dropdown-menu.show');
|
|
836
|
+
if (activeModal) {
|
|
837
|
+
const closeButton = activeModal.querySelector('[data-bs-dismiss="modal"]');
|
|
838
|
+
closeButton?.click();
|
|
839
|
+
event.preventDefault();
|
|
840
|
+
}
|
|
841
|
+
else if (activeDropdown) {
|
|
842
|
+
const toggleButton = document.querySelector('[data-bs-toggle="dropdown"][aria-expanded="true"]');
|
|
843
|
+
toggleButton?.click();
|
|
844
|
+
event.preventDefault();
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
// WCAG 2.1.1: Keyboard Access
|
|
848
|
+
initKeyboardNavigation() {
|
|
849
|
+
// Add keyboard support for custom components
|
|
850
|
+
document.addEventListener('keydown', (event) => {
|
|
851
|
+
const target = event.target;
|
|
852
|
+
// Handle arrow key navigation for menus
|
|
853
|
+
if (target.closest('.nav, .navbar-nav, .dropdown-menu')) {
|
|
854
|
+
this.handleMenuNavigation(event);
|
|
855
|
+
}
|
|
856
|
+
// Handle Enter and Space for custom buttons
|
|
857
|
+
if ((event.key === 'Enter' || event.key === ' ') && target.hasAttribute('role') && target.getAttribute('role') === 'button' && !target.matches('button, input[type="button"], input[type="submit"]')) {
|
|
858
|
+
event.preventDefault();
|
|
859
|
+
target.click();
|
|
860
|
+
}
|
|
861
|
+
});
|
|
862
|
+
}
|
|
863
|
+
handleMenuNavigation(event) {
|
|
864
|
+
if (!['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(event.key)) {
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
867
|
+
const currentElement = event.target;
|
|
868
|
+
const menuItems = Array.from(currentElement.closest('.nav, .navbar-nav, .dropdown-menu')?.querySelectorAll('a, button') || []);
|
|
869
|
+
const currentIndex = menuItems.indexOf(currentElement);
|
|
870
|
+
let nextIndex;
|
|
871
|
+
switch (event.key) {
|
|
872
|
+
case 'ArrowDown':
|
|
873
|
+
case 'ArrowRight': {
|
|
874
|
+
nextIndex = currentIndex < menuItems.length - 1 ? currentIndex + 1 : 0;
|
|
875
|
+
break;
|
|
876
|
+
}
|
|
877
|
+
case 'ArrowUp':
|
|
878
|
+
case 'ArrowLeft': {
|
|
879
|
+
nextIndex = currentIndex > 0 ? currentIndex - 1 : menuItems.length - 1;
|
|
880
|
+
break;
|
|
881
|
+
}
|
|
882
|
+
case 'Home': {
|
|
883
|
+
nextIndex = 0;
|
|
884
|
+
break;
|
|
885
|
+
}
|
|
886
|
+
case 'End': {
|
|
887
|
+
nextIndex = menuItems.length - 1;
|
|
888
|
+
break;
|
|
889
|
+
}
|
|
890
|
+
default: {
|
|
891
|
+
return;
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
event.preventDefault();
|
|
895
|
+
menuItems[nextIndex]?.focus();
|
|
896
|
+
}
|
|
897
|
+
// WCAG 2.3.3: Animation from Interactions
|
|
898
|
+
respectReducedMotion() {
|
|
899
|
+
const prefersReducedMotion = globalThis.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
900
|
+
if (prefersReducedMotion) {
|
|
901
|
+
document.body.classList.add('reduce-motion');
|
|
902
|
+
// Disable smooth scrolling
|
|
903
|
+
document.documentElement.style.scrollBehavior = 'auto';
|
|
904
|
+
// Reduce animation duration
|
|
905
|
+
const style = document.createElement('style');
|
|
906
|
+
style.textContent = `
|
|
907
|
+
*, *::before, *::after {
|
|
908
|
+
animation-duration: 0.01ms !important;
|
|
909
|
+
animation-iteration-count: 1 !important;
|
|
910
|
+
transition-duration: 0.01ms !important;
|
|
911
|
+
}
|
|
912
|
+
`;
|
|
913
|
+
document.head.append(style);
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
// WCAG 3.3.1: Error Identification
|
|
917
|
+
initErrorAnnouncements() {
|
|
918
|
+
const observer = new MutationObserver((mutations) => {
|
|
919
|
+
mutations.forEach((mutation) => {
|
|
920
|
+
mutation.addedNodes.forEach((node) => {
|
|
921
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
922
|
+
const element = node;
|
|
923
|
+
// Check for error messages
|
|
924
|
+
if (element.matches('.alert-danger, .invalid-feedback, .error')) {
|
|
925
|
+
this.announce(element.textContent || 'Error occurred', 'assertive');
|
|
926
|
+
}
|
|
927
|
+
// Check for success messages
|
|
928
|
+
if (element.matches('.alert-success, .success')) {
|
|
929
|
+
this.announce(element.textContent || 'Success', 'polite');
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
});
|
|
933
|
+
});
|
|
934
|
+
});
|
|
935
|
+
observer.observe(document.body, {
|
|
936
|
+
childList: true,
|
|
937
|
+
subtree: true
|
|
938
|
+
});
|
|
939
|
+
}
|
|
940
|
+
// WCAG 1.3.1: Info and Relationships
|
|
941
|
+
initTableAccessibility() {
|
|
942
|
+
document.querySelectorAll('table').forEach((table) => {
|
|
943
|
+
// Add table role if missing
|
|
944
|
+
if (!table.hasAttribute('role')) {
|
|
945
|
+
table.setAttribute('role', 'table');
|
|
946
|
+
}
|
|
947
|
+
// Ensure headers have proper scope
|
|
948
|
+
table.querySelectorAll('th').forEach((th) => {
|
|
949
|
+
if (!th.hasAttribute('scope')) {
|
|
950
|
+
const isInThead = th.closest('thead');
|
|
951
|
+
const isFirstColumn = th.cellIndex === 0;
|
|
952
|
+
if (isInThead) {
|
|
953
|
+
th.setAttribute('scope', 'col');
|
|
954
|
+
}
|
|
955
|
+
else if (isFirstColumn) {
|
|
956
|
+
th.setAttribute('scope', 'row');
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
});
|
|
960
|
+
// Add caption if missing but title exists
|
|
961
|
+
if (!table.querySelector('caption') && table.hasAttribute('title')) {
|
|
962
|
+
const caption = document.createElement('caption');
|
|
963
|
+
caption.textContent = table.getAttribute('title') || '';
|
|
964
|
+
table.insertBefore(caption, table.firstChild);
|
|
965
|
+
}
|
|
966
|
+
});
|
|
967
|
+
}
|
|
968
|
+
// WCAG 3.3.2: Labels or Instructions
|
|
969
|
+
initFormAccessibility() {
|
|
970
|
+
document.querySelectorAll('input, select, textarea').forEach((input) => {
|
|
971
|
+
const htmlInput = input;
|
|
972
|
+
// Ensure all inputs have labels
|
|
973
|
+
if (!htmlInput.labels?.length && !htmlInput.hasAttribute('aria-label') && !htmlInput.hasAttribute('aria-labelledby')) {
|
|
974
|
+
const placeholder = htmlInput.getAttribute('placeholder');
|
|
975
|
+
if (placeholder) {
|
|
976
|
+
htmlInput.setAttribute('aria-label', placeholder);
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
// Add required indicators
|
|
980
|
+
if (htmlInput.hasAttribute('required')) {
|
|
981
|
+
const label = htmlInput.labels?.[0];
|
|
982
|
+
if (label && !label.querySelector('.required-indicator')) {
|
|
983
|
+
const indicator = document.createElement('span');
|
|
984
|
+
indicator.className = 'required-indicator sr-only';
|
|
985
|
+
indicator.textContent = ' (required)';
|
|
986
|
+
label.append(indicator);
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
// Handle invalid states
|
|
990
|
+
htmlInput.addEventListener('invalid', () => {
|
|
991
|
+
this.handleFormError(htmlInput);
|
|
992
|
+
});
|
|
993
|
+
});
|
|
994
|
+
}
|
|
995
|
+
handleFormError(input) {
|
|
996
|
+
const errorId = `${input.id || input.name}-error`;
|
|
997
|
+
let errorElement = document.getElementById(errorId);
|
|
998
|
+
if (!errorElement) {
|
|
999
|
+
errorElement = document.createElement('div');
|
|
1000
|
+
errorElement.id = errorId;
|
|
1001
|
+
errorElement.className = 'invalid-feedback';
|
|
1002
|
+
errorElement.setAttribute('role', 'alert');
|
|
1003
|
+
input.parentNode?.insertBefore(errorElement, input.nextSibling);
|
|
1004
|
+
}
|
|
1005
|
+
errorElement.textContent = input.validationMessage;
|
|
1006
|
+
input.setAttribute('aria-describedby', errorId);
|
|
1007
|
+
input.classList.add('is-invalid');
|
|
1008
|
+
this.announce(`Error in ${input.labels?.[0]?.textContent || input.name}: ${input.validationMessage}`, 'assertive');
|
|
1009
|
+
}
|
|
1010
|
+
// Modal focus management
|
|
1011
|
+
initModalFocusManagement() {
|
|
1012
|
+
document.addEventListener('shown.bs.modal', (event) => {
|
|
1013
|
+
const modal = event.target;
|
|
1014
|
+
const focusableElements = modal.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
|
|
1015
|
+
if (focusableElements.length > 0) {
|
|
1016
|
+
focusableElements[0].focus();
|
|
1017
|
+
}
|
|
1018
|
+
// Store previous focus
|
|
1019
|
+
this.focusHistory.push(document.activeElement);
|
|
1020
|
+
});
|
|
1021
|
+
document.addEventListener('hidden.bs.modal', () => {
|
|
1022
|
+
// Restore previous focus
|
|
1023
|
+
const previousElement = this.focusHistory.pop();
|
|
1024
|
+
if (previousElement) {
|
|
1025
|
+
previousElement.focus();
|
|
1026
|
+
}
|
|
1027
|
+
});
|
|
1028
|
+
}
|
|
1029
|
+
// Dropdown focus management
|
|
1030
|
+
initDropdownFocusManagement() {
|
|
1031
|
+
document.addEventListener('shown.bs.dropdown', (event) => {
|
|
1032
|
+
const dropdown = event.target;
|
|
1033
|
+
const menu = dropdown.querySelector('.dropdown-menu');
|
|
1034
|
+
const firstItem = menu?.querySelector('a, button');
|
|
1035
|
+
if (firstItem) {
|
|
1036
|
+
firstItem.focus();
|
|
1037
|
+
}
|
|
1038
|
+
});
|
|
1039
|
+
}
|
|
1040
|
+
// Public API methods
|
|
1041
|
+
announce(message, priority = 'polite') {
|
|
1042
|
+
if (!this.liveRegion) {
|
|
1043
|
+
this.createLiveRegion();
|
|
1044
|
+
}
|
|
1045
|
+
if (this.liveRegion) {
|
|
1046
|
+
this.liveRegion.setAttribute('aria-live', priority);
|
|
1047
|
+
this.liveRegion.textContent = message;
|
|
1048
|
+
// Clear after announcement
|
|
1049
|
+
setTimeout(() => {
|
|
1050
|
+
if (this.liveRegion) {
|
|
1051
|
+
this.liveRegion.textContent = '';
|
|
1052
|
+
}
|
|
1053
|
+
}, 1000);
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
focusElement(selector) {
|
|
1057
|
+
const element = document.querySelector(selector);
|
|
1058
|
+
if (element) {
|
|
1059
|
+
element.focus();
|
|
1060
|
+
// Ensure element is visible
|
|
1061
|
+
element.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
trapFocus(container) {
|
|
1065
|
+
const focusableElements = container.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
|
|
1066
|
+
const focusableArray = Array.from(focusableElements);
|
|
1067
|
+
const firstElement = focusableArray[0];
|
|
1068
|
+
const lastElement = focusableArray.at(-1);
|
|
1069
|
+
container.addEventListener('keydown', (event) => {
|
|
1070
|
+
if (event.key === 'Tab') {
|
|
1071
|
+
if (event.shiftKey) {
|
|
1072
|
+
if (document.activeElement === firstElement) {
|
|
1073
|
+
lastElement?.focus();
|
|
1074
|
+
event.preventDefault();
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
else if (document.activeElement === lastElement) {
|
|
1078
|
+
firstElement.focus();
|
|
1079
|
+
event.preventDefault();
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
});
|
|
1083
|
+
}
|
|
1084
|
+
addLandmarks() {
|
|
1085
|
+
// Add main landmark if missing
|
|
1086
|
+
const main = document.querySelector('main');
|
|
1087
|
+
if (!main) {
|
|
1088
|
+
const appMain = document.querySelector('.app-main');
|
|
1089
|
+
if (appMain) {
|
|
1090
|
+
appMain.setAttribute('role', 'main');
|
|
1091
|
+
appMain.id = 'main';
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
// Add navigation landmarks
|
|
1095
|
+
document.querySelectorAll('.navbar-nav, .nav').forEach((nav, index) => {
|
|
1096
|
+
if (!nav.hasAttribute('role')) {
|
|
1097
|
+
nav.setAttribute('role', 'navigation');
|
|
1098
|
+
}
|
|
1099
|
+
if (!nav.hasAttribute('aria-label')) {
|
|
1100
|
+
nav.setAttribute('aria-label', `Navigation ${index + 1}`);
|
|
1101
|
+
}
|
|
1102
|
+
});
|
|
1103
|
+
// Add search landmark
|
|
1104
|
+
const searchForm = document.querySelector('form[role="search"], .navbar-search');
|
|
1105
|
+
if (searchForm && !searchForm.hasAttribute('role')) {
|
|
1106
|
+
searchForm.setAttribute('role', 'search');
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
// Initialize accessibility when DOM is ready
|
|
1111
|
+
const initAccessibility = (config) => {
|
|
1112
|
+
return new AccessibilityManager(config);
|
|
1113
|
+
};
|
|
1114
|
+
|
|
1115
|
+
/**
|
|
1116
|
+
* AdminLTE v4.0.0-rc1
|
|
1117
|
+
* Author: Colorlib
|
|
1118
|
+
* Website: AdminLTE.io <https://adminlte.io>
|
|
1119
|
+
* License: Open source - MIT <https://opensource.org/licenses/MIT>
|
|
1120
|
+
*/
|
|
1121
|
+
onDOMContentLoaded(() => {
|
|
1122
|
+
/**
|
|
1123
|
+
* Initialize AdminLTE Core Components
|
|
1124
|
+
* -------------------------------
|
|
1125
|
+
*/
|
|
1126
|
+
const layout = new Layout(document.body);
|
|
1127
|
+
layout.holdTransition();
|
|
1128
|
+
/**
|
|
1129
|
+
* Initialize Accessibility Features - WCAG 2.1 AA Compliance
|
|
1130
|
+
* --------------------------------------------------------
|
|
1131
|
+
*/
|
|
1132
|
+
const accessibilityManager = initAccessibility({
|
|
1133
|
+
announcements: true,
|
|
1134
|
+
skipLinks: true,
|
|
1135
|
+
focusManagement: true,
|
|
1136
|
+
keyboardNavigation: true,
|
|
1137
|
+
reducedMotion: true
|
|
1138
|
+
});
|
|
1139
|
+
// Add semantic landmarks
|
|
1140
|
+
accessibilityManager.addLandmarks();
|
|
1141
|
+
// Mark app as loaded after initialization
|
|
1142
|
+
setTimeout(() => {
|
|
1143
|
+
document.body.classList.add('app-loaded');
|
|
1144
|
+
}, 400);
|
|
1145
|
+
});
|
|
1146
|
+
|
|
707
1147
|
exports.CardWidget = CardWidget;
|
|
708
1148
|
exports.DirectChat = DirectChat;
|
|
709
1149
|
exports.FullScreen = FullScreen;
|
|
710
1150
|
exports.Layout = Layout;
|
|
711
1151
|
exports.PushMenu = PushMenu;
|
|
712
1152
|
exports.Treeview = Treeview;
|
|
1153
|
+
exports.initAccessibility = initAccessibility;
|
|
713
1154
|
|
|
714
1155
|
}));
|
|
715
1156
|
//# sourceMappingURL=adminlte.js.map
|