admin-lte 4.0.2 → 4.1.0

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 (146) hide show
  1. package/ACCESSIBILITY-COMPLIANCE.md +60 -339
  2. package/CHANGELOG.md +66 -0
  3. package/README.md +15 -2
  4. package/dist/css/adminlte-docs.css +878 -0
  5. package/dist/css/adminlte-docs.css.map +1 -0
  6. package/dist/css/adminlte-docs.min.css +7 -0
  7. package/dist/css/adminlte-docs.min.css.map +1 -0
  8. package/dist/css/adminlte-docs.rtl.css +877 -0
  9. package/dist/css/adminlte-docs.rtl.css.map +1 -0
  10. package/dist/css/adminlte-docs.rtl.min.css +7 -0
  11. package/dist/css/adminlte-docs.rtl.min.css.map +1 -0
  12. package/dist/css/adminlte.css +1176 -2718
  13. package/dist/css/adminlte.css.map +1 -1
  14. package/dist/css/adminlte.min.css +2 -2
  15. package/dist/css/adminlte.min.css.map +1 -1
  16. package/dist/css/adminlte.rtl.css +1176 -2718
  17. package/dist/css/adminlte.rtl.css.map +1 -1
  18. package/dist/css/adminlte.rtl.min.css +2 -2
  19. package/dist/css/adminlte.rtl.min.css.map +1 -1
  20. package/dist/js/adminlte.esm.js +1365 -0
  21. package/dist/js/adminlte.esm.js.map +1 -0
  22. package/dist/js/adminlte.esm.min.js +7 -0
  23. package/dist/js/adminlte.esm.min.js.map +1 -0
  24. package/dist/js/adminlte.js +606 -310
  25. package/dist/js/adminlte.js.map +1 -1
  26. package/dist/js/adminlte.min.js +2 -2
  27. package/dist/js/adminlte.min.js.map +1 -1
  28. package/dist/js/types/accessibility.d.ts +46 -0
  29. package/dist/js/types/adminlte.d.ts +9 -0
  30. package/dist/js/types/base-component.d.ts +36 -0
  31. package/dist/js/types/card-widget.d.ts +30 -0
  32. package/dist/js/types/color-mode.d.ts +56 -0
  33. package/dist/js/types/direct-chat.d.ts +19 -0
  34. package/dist/js/types/fullscreen.d.ts +21 -0
  35. package/dist/js/types/layout.d.ts +19 -0
  36. package/dist/js/types/push-menu.d.ts +102 -0
  37. package/dist/js/types/treeview.d.ts +27 -0
  38. package/dist/js/types/util/index.d.ts +42 -0
  39. package/package.json +60 -21
  40. package/src/scss/_app-header.scss +3 -1
  41. package/src/scss/_app-main.scss +4 -0
  42. package/src/scss/_app-sidebar.scss +3 -1
  43. package/src/scss/_bootstrap-overrides.scss +60 -0
  44. package/src/scss/_callouts.scss +13 -3
  45. package/src/scss/_dropdown.scss +3 -1
  46. package/src/scss/_info-box.scss +3 -1
  47. package/src/scss/_progress-bars.scss +3 -1
  48. package/src/scss/_table.scss +4 -2
  49. package/src/scss/adminlte-docs.scss +25 -0
  50. package/src/scss/adminlte.scss +5 -4
  51. package/src/scss/pages/_login_and_register.scss +3 -1
  52. package/src/scss/parts/_core.scss +0 -1
  53. package/src/ts/accessibility.ts +129 -69
  54. package/src/ts/adminlte.ts +3 -1
  55. package/src/ts/base-component.ts +84 -0
  56. package/src/ts/card-widget.ts +134 -85
  57. package/src/ts/color-mode.ts +174 -0
  58. package/src/ts/direct-chat.ts +38 -32
  59. package/src/ts/fullscreen.ts +78 -63
  60. package/src/ts/layout.ts +2 -1
  61. package/src/ts/push-menu.ts +93 -44
  62. package/src/ts/treeview.ts +107 -47
  63. package/src/ts/util/index.ts +114 -29
  64. package/.browserslistrc +0 -17
  65. package/.prettierrc +0 -6
  66. package/CODE_OF_CONDUCT.md +0 -43
  67. package/SECURITY.md +0 -99
  68. package/dist/UI/general.html +0 -2317
  69. package/dist/UI/icons.html +0 -1126
  70. package/dist/UI/timeline.html +0 -1212
  71. package/dist/docs/browser-support.html +0 -826
  72. package/dist/docs/color-mode.html +0 -1142
  73. package/dist/docs/components/main-header.html +0 -1209
  74. package/dist/docs/components/main-sidebar.html +0 -924
  75. package/dist/docs/customization.html +0 -1080
  76. package/dist/docs/deployment.html +0 -1145
  77. package/dist/docs/faq.html +0 -1392
  78. package/dist/docs/getting-started.html +0 -991
  79. package/dist/docs/how-to-contribute.html +0 -890
  80. package/dist/docs/index.html +0 -16
  81. package/dist/docs/integrations.html +0 -1231
  82. package/dist/docs/introduction.html +0 -1008
  83. package/dist/docs/javascript/accessibility.html +0 -949
  84. package/dist/docs/javascript/card-widget.html +0 -1019
  85. package/dist/docs/javascript/direct-chat.html +0 -896
  86. package/dist/docs/javascript/fullscreen.html +0 -905
  87. package/dist/docs/javascript/layout.html +0 -908
  88. package/dist/docs/javascript/plugins-overview.html +0 -1144
  89. package/dist/docs/javascript/pushmenu.html +0 -1045
  90. package/dist/docs/javascript/treeview.html +0 -1024
  91. package/dist/docs/layout-blueprint.html +0 -1087
  92. package/dist/docs/layout.html +0 -842
  93. package/dist/docs/license.html +0 -807
  94. package/dist/docs/migration.html +0 -1149
  95. package/dist/docs/recipes.html +0 -1185
  96. package/dist/docs/rtl.html +0 -957
  97. package/dist/examples/lockscreen.html +0 -249
  98. package/dist/examples/login-v2.html +0 -282
  99. package/dist/examples/login.html +0 -272
  100. package/dist/examples/register-v2.html +0 -291
  101. package/dist/examples/register.html +0 -277
  102. package/dist/forms/elements.html +0 -1405
  103. package/dist/forms/layout.html +0 -1267
  104. package/dist/forms/validation.html +0 -1275
  105. package/dist/forms/wizard.html +0 -1410
  106. package/dist/generate/theme.html +0 -1082
  107. package/dist/index.html +0 -1745
  108. package/dist/index2.html +0 -2277
  109. package/dist/index3.html +0 -1532
  110. package/dist/layout/collapsed-sidebar-without-hover.html +0 -1144
  111. package/dist/layout/collapsed-sidebar.html +0 -1137
  112. package/dist/layout/fixed-complete.html +0 -1138
  113. package/dist/layout/fixed-footer.html +0 -1136
  114. package/dist/layout/fixed-header.html +0 -1136
  115. package/dist/layout/fixed-sidebar.html +0 -1138
  116. package/dist/layout/layout-custom-area.html +0 -1177
  117. package/dist/layout/layout-rtl.html +0 -1137
  118. package/dist/layout/logo-switch.html +0 -683
  119. package/dist/layout/sidebar-mini.html +0 -1137
  120. package/dist/layout/unfixed-sidebar.html +0 -1136
  121. package/dist/mailbox/compose.html +0 -1151
  122. package/dist/mailbox/inbox.html +0 -1509
  123. package/dist/mailbox/read.html +0 -1202
  124. package/dist/pages/404.html +0 -239
  125. package/dist/pages/500.html +0 -227
  126. package/dist/pages/calendar.html +0 -1266
  127. package/dist/pages/chat.html +0 -1427
  128. package/dist/pages/faq.html +0 -1383
  129. package/dist/pages/file-manager.html +0 -1835
  130. package/dist/pages/invoice.html +0 -1199
  131. package/dist/pages/kanban.html +0 -1439
  132. package/dist/pages/maintenance.html +0 -230
  133. package/dist/pages/pricing.html +0 -1279
  134. package/dist/pages/profile.html +0 -1382
  135. package/dist/pages/projects.html +0 -1644
  136. package/dist/pages/settings.html +0 -1387
  137. package/dist/tables/data.html +0 -1319
  138. package/dist/tables/simple.html +0 -1435
  139. package/dist/widgets/cards.html +0 -1356
  140. package/dist/widgets/info-box.html +0 -1429
  141. package/dist/widgets/small-box.html +0 -1225
  142. package/eslint.config.js +0 -82
  143. package/github-issue-response.md +0 -40
  144. package/index.html +0 -12
  145. package/netlify.toml +0 -16
  146. package/src/scss/_bootstrap-variables.scss +0 -1766
@@ -1,369 +1,90 @@
1
- # AdminLTE Accessibility Compliance - WCAG 2.1 AA
1
+ # AdminLTE Accessibility Statement
2
2
 
3
3
  ## Overview
4
4
 
5
- AdminLTE has been enhanced with comprehensive accessibility features to meet **WCAG 2.1 AA** standards. This implementation ensures the template is usable by all users, including those with disabilities who may use assistive technologies like screen readers, keyboard navigation, or voice control software.
5
+ AdminLTE 4 is built with accessibility in mind and aims for **WCAG 2.1 AA** conformance. This document describes honestly what is implemented today, what is partially implemented, and what is still on the roadmap — so you know exactly what you get and what your application still needs to provide.
6
6
 
7
- ## 🎯 WCAG 2.1 AA Compliance Features
7
+ > **Important:** a template can only ever be a starting point. Accessible markup in the demo pages does not make your application compliant — you remain responsible for testing the pages you build.
8
8
 
9
- ### **Principle 1: Perceivable**
9
+ ## ✅ Implemented
10
10
 
11
- #### 1.1 Text Alternatives
12
- - ✅ **All decorative icons have `aria-hidden="true"`**
13
- - ✅ **Meaningful images have appropriate `alt` text**
14
- - ✅ **Icon fonts use screen reader friendly approaches**
11
+ ### Markup (demo pages)
15
12
 
16
- #### 1.3 Adaptable
17
- - ✅ **Semantic HTML structure with proper landmarks**
18
- - ✅ **Form labels properly associated with inputs**
19
- - ✅ **Table headers have correct `scope` attributes**
20
- - ✅ **Lists use proper `<ul>`, `<ol>`, `<li>` structure**
21
- - ✅ **Heading hierarchy follows logical order (h1 → h2 → h3)**
13
+ - Semantic landmark structure on the app shell (`<nav>`, `<main>`, `<aside>`, `<footer>`) — non-list `.nav` containers receive `role="navigation"` automatically (#6038)
14
+ - Exactly one `<h1>` per page (the page title in the content header)
15
+ - Breadcrumbs wrapped in `<nav aria-label="breadcrumb">` with `aria-current="page"`
16
+ - `aria-label` on all icon-only controls (card tools, topbar toggles, sidebar toggle)
17
+ - Form inputs associated with `<label>` elements (visually hidden where the design is placeholder-driven, floating labels on the v2 auth pages)
18
+ - Table headers with `scope` attributes
19
+ - `lang="en"` declared, descriptive page titles, `meta name="color-scheme"`
22
20
 
23
- #### 1.4 Distinguishable
24
- - ✅ **Color contrast ratios meet 4.5:1 minimum for normal text**
25
- - ✅ **Color contrast ratios meet 3:1 minimum for large text**
26
- - ✅ **Information not conveyed by color alone**
27
- - ✅ **Text can be resized up to 200% without loss of functionality**
28
- - ✅ **Focus indicators are clearly visible**
21
+ ### Behavior (`accessibility.ts` and components)
29
22
 
30
- ### **Principle 2: Operable**
23
+ - **Live region announcements** (WCAG 4.1.3) — a single polite `#live-region`, with a public `announce()` API; alerts inserted into the DOM are announced automatically
24
+ - **Skip links** to main content and navigation, injected once and reused across Turbo navigations (WCAG 2.4.1)
25
+ - **Treeview state exposure** — sidebar submenu toggles carry `aria-expanded`, kept in sync by the Treeview component
26
+ - **Modal focus restoration** — the triggering element is captured on `show.bs.modal` and restored on close (skipped if it has left the document)
27
+ - **Escape** closes open dropdowns; Bootstrap's own modal keyboard handling is left untouched
28
+ - **Arrow-key navigation** in menus and dropdowns — only when focus is on a menu item; never intercepts keys inside inputs, textareas, selects, or contenteditable elements
29
+ - **Reduced motion** — `prefers-reduced-motion` disables smooth scrolling and shortens animations; `prefers-contrast: more` styles in the CSS
30
+ - **Theme-flash prevention** and dark mode via Bootstrap color modes, respecting `prefers-color-scheme` (#6043)
31
+ - **Form error identification** (WCAG 3.3.1/3.3.2) — validation errors get an `invalid-feedback` node wired via `aria-describedby` (appended to existing descriptions, not replacing them) and are announced assertively
31
32
 
32
- #### 2.1 Keyboard Accessible
33
- - ✅ **All interactive elements are keyboard accessible**
34
- - ✅ **Tab order is logical and predictable**
35
- - ✅ **No keyboard traps exist**
36
- - ✅ **Skip links to bypass repetitive content**
37
- - ✅ **Arrow key navigation for menus**
38
- - ✅ **Escape key closes modals and dropdowns**
33
+ ### Explicit non-goals
39
34
 
40
- #### 2.2 Enough Time
41
- - ✅ **No time limits on user interactions**
42
- - ✅ **Animations can be paused or disabled**
35
+ - **No global focus wrapping.** Focus is deliberately *not* trapped at the page edges — wrapping Tab at the document boundary would itself violate WCAG 2.1.2 (No Keyboard Trap). Focus trapping is applied only inside modal dialogs.
43
36
 
44
- #### 2.3 Seizures and Physical Reactions
45
- - ✅ **No content flashes more than 3 times per second**
46
- - ✅ **Respects `prefers-reduced-motion` user preference**
47
- - ✅ **Animation duration can be controlled**
37
+ ## ⚠️ Partial / known gaps
48
38
 
49
- #### 2.4 Navigable
50
- - ✅ **Skip links to main content and navigation**
51
- - ✅ **Descriptive page titles**
52
- - ✅ **Meaningful link text (no "click here")**
53
- - ✅ **Focus order matches visual order**
54
- - ✅ **Focus is clearly visible**
55
- - ✅ **Multiple ways to navigate (menus, breadcrumbs, search)**
39
+ These are known, tracked limitations — pull requests welcome:
56
40
 
57
- #### 2.5 Input Modalities
58
- - ✅ **Touch targets are at least 44×44 pixels**
59
- - ✅ **Drag operations have keyboard alternatives**
60
- - ✅ **Touch gestures have alternatives**
41
+ - **Treeview and push-menu have no dedicated keyboard interaction pattern** beyond normal Tab/Enter link behavior (no roving tabindex, no Home/End within the tree). `aria-expanded` is stamped by JS; static markup without JS does not carry it.
42
+ - **Drag-and-drop demos (kanban, sortable dashboard cards) have no keyboard alternative.** SortableJS does not provide one; treat these demos as visual examples only (WCAG 2.5.7 gap).
43
+ - **Touch target sizes are not enforced globally.** Card tool buttons are smaller than 44×44 px; an opt-in `.touch-target` utility class exists in `_accessibility.scss`.
44
+ - **Color contrast is not guaranteed for every Bootstrap color utility combination** you may compose. The `accessibilityUtils.checkColorContrast()` helper (supports `rgb()`/hex) can verify your combinations.
45
+ - **No automated accessibility tests run in CI yet** (axe/pa11y integration is on the roadmap). Claims in this document are verified manually and are point-in-time.
61
46
 
62
- ### **Principle 3: Understandable**
47
+ ## 🔧 JavaScript API
63
48
 
64
- #### 3.1 Readable
65
- - ✅ **Language of page is declared (`lang="en"`)**
66
- - ✅ **Language changes are marked up**
67
- - ✅ **Unusual words have definitions or explanations**
68
-
69
- #### 3.2 Predictable
70
- - ✅ **Navigation is consistent across pages**
71
- - ✅ **Components behave predictably**
72
- - ✅ **Form submission doesn't cause unexpected context changes**
73
-
74
- #### 3.3 Input Assistance
75
- - ✅ **Error messages are clearly identified**
76
- - ✅ **Form field requirements are indicated**
77
- - ✅ **Error suggestions are provided when possible**
78
- - ✅ **Form validation messages are announced to screen readers**
79
-
80
- ### **Principle 4: Robust**
81
-
82
- #### 4.1 Compatible
83
- - ✅ **Valid HTML markup**
84
- - ✅ **Proper ARIA attributes and roles**
85
- - ✅ **Compatible with assistive technologies**
86
- - ✅ **Status messages are announced (`aria-live` regions)**
87
-
88
- ## 🛠️ Implementation Details
89
-
90
- ### **Skip Links Implementation**
91
- ```html
92
- <!-- Automatically added by accessibility.js -->
93
- <div class="skip-links">
94
- <a href="#main" class="skip-link">Skip to main content</a>
95
- <a href="#navigation" class="skip-link">Skip to navigation</a>
96
- </div>
97
- ```
98
-
99
- ### **ARIA Live Regions**
100
- ```html
101
- <!-- Automatically created for status announcements -->
102
- <div id="live-region" class="live-region" aria-live="polite" aria-atomic="true" role="status"></div>
103
- ```
104
-
105
- ### **Enhanced Focus Management**
106
- - **Modal Focus Trap**: Focus is contained within modals
107
- - **Dropdown Navigation**: Arrow keys navigate menu items
108
- - **Focus Restoration**: Previous focus restored when modals close
109
- - **Escape Key Support**: ESC closes modals and dropdowns
110
-
111
- ### **Form Accessibility**
112
- ```html
113
- <!-- Example of accessible form with error handling -->
114
- <div class="mb-3">
115
- <label for="email" class="form-label">
116
- Email address <span class="required-indicator sr-only">(required)</span>
117
- </label>
118
- <input type="email" class="form-control" id="email" required aria-describedby="email-help email-error">
119
- <div id="email-help" class="form-text">We'll never share your email with anyone else.</div>
120
- <div id="email-error" class="invalid-feedback" role="alert"></div>
121
- </div>
122
- ```
123
-
124
- ### **Table Accessibility**
125
- ```html
126
- <!-- Accessible table structure -->
127
- <table class="table table-accessible" role="table">
128
- <caption>Monthly Sales Data</caption>
129
- <thead>
130
- <tr>
131
- <th scope="col">Month</th>
132
- <th scope="col">Sales</th>
133
- <th scope="col">Growth</th>
134
- </tr>
135
- </thead>
136
- <tbody>
137
- <tr>
138
- <th scope="row">January</th>
139
- <td>$10,000</td>
140
- <td>+5%</td>
141
- </tr>
142
- </tbody>
143
- </table>
144
- ```
145
-
146
- ### **Navigation Landmarks**
147
- ```html
148
- <!-- Semantic navigation structure -->
149
- <nav role="navigation" aria-label="Main navigation" id="navigation">
150
- <ul class="navbar-nav">
151
- <li class="nav-item">
152
- <a href="#" class="nav-link"
153
- role="button"
154
- data-bs-toggle="collapse"
155
- data-bs-target="#widgets-nav"
156
- aria-expanded="false"
157
- aria-controls="widgets-nav"
158
- aria-label="Toggle widgets menu">
159
- <i class="nav-icon bi bi-box-seam" aria-hidden="true"></i>
160
- <p>Widgets <i class="nav-arrow bi bi-chevron-right" aria-hidden="true"></i></p>
161
- </a>
162
- <ul id="widgets-nav" class="nav nav-treeview collapse" role="group" aria-labelledby="widgets-nav">
163
- <!-- Submenu items -->
164
- </ul>
165
- </li>
166
- </ul>
167
- </nav>
168
- ```
169
-
170
- ## 🎨 Accessible Color Palette
171
-
172
- ### **High Contrast Colors (4.5:1 ratio minimum)**
173
- - **Primary Accessible**: `#003d82` (4.5:1 on white)
174
- - **Success Accessible**: `#0f5132` (4.5:1 on white)
175
- - **Danger Accessible**: `#842029` (4.5:1 on white)
176
- - **Warning Accessible**: `#664d03` (4.5:1 on white)
177
-
178
- ### **Dark Mode Support**
179
- ```css
180
- [data-bs-theme="dark"] {
181
- .text-accessible-primary { color: #6ea8fe; }
182
- .text-accessible-success { color: #75b798; }
183
- .text-accessible-danger { color: #f1aeb5; }
184
- .text-accessible-warning { color: #ffda6a; }
185
- }
186
- ```
187
-
188
- ## 📱 Responsive & Touch Accessibility
189
-
190
- ### **Touch Target Sizes**
191
- - **Standard buttons**: Minimum 44×44 pixels
192
- - **Icon buttons**: Minimum 44×44 pixels touch area
193
- - **Small interactive elements**: Minimum 24×24 pixels (when grouped)
194
-
195
- ### **Responsive Considerations**
196
- - **Zoom support**: Up to 200% zoom without horizontal scrolling
197
- - **Mobile navigation**: Touch-friendly collapsible menus
198
- - **Orientation support**: Works in both portrait and landscape
199
-
200
- ## 🔧 JavaScript Accessibility API
201
-
202
- ### **AccessibilityManager Class**
203
49
  ```typescript
204
- import { initAccessibility } from './accessibility.js'
50
+ import { initAccessibility, accessibilityUtils } from 'admin-lte'
205
51
 
206
- // Initialize with full features
207
- const accessibilityManager = initAccessibility({
208
- announcements: true,
209
- skipLinks: true,
210
- focusManagement: true,
211
- keyboardNavigation: true,
212
- reducedMotion: true
213
- })
214
-
215
- // Public API methods
216
- accessibilityManager.announce("Form submitted successfully", "polite")
217
- accessibilityManager.focusElement("#main-content")
218
- accessibilityManager.trapFocus(modalElement)
219
- ```
220
-
221
- ### **Utility Functions**
222
- ```typescript
223
- import { accessibilityUtils } from './accessibility.js'
224
-
225
- // Check color contrast
226
- const contrast = accessibilityUtils.checkColorContrast("#000000", "#ffffff")
227
- console.log(contrast) // { ratio: 21, passes: true }
228
-
229
- // Generate unique IDs
230
- const id = accessibilityUtils.generateId("form-field") // "form-field-abc123def"
231
-
232
- // Check if element is focusable
233
- const isFocusable = accessibilityUtils.isFocusable(element) // true/false
234
- ```
235
-
236
- ## 🧪 Testing & Validation
237
-
238
- ### **Automated Testing Tools**
239
- - **axe-core**: Automated accessibility testing
240
- - **WAVE**: Web accessibility evaluation
241
- - **Lighthouse**: Accessibility audit included
242
-
243
- ### **Manual Testing Checklist**
244
- - [ ] Navigate entire interface using only keyboard
245
- - [ ] Test with screen reader (NVDA, JAWS, VoiceOver)
246
- - [ ] Verify color contrast ratios
247
- - [ ] Test with 200% zoom
248
- - [ ] Verify reduced motion preferences
249
- - [ ] Test touch interactions on mobile
250
-
251
- ### **Screen Reader Testing**
252
- ```bash
253
- # Test announcements
254
- accessibilityManager.announce("New message received", "assertive")
255
-
256
- # Test form errors
257
- <input type="email" required aria-describedby="email-error">
258
- <div id="email-error" role="alert">Please enter a valid email address</div>
259
- ```
260
-
261
- ## 📚 Browser Support
262
-
263
- ### **Modern Browser Support (ES2022 Compatible)**
264
- - **Chrome**: 97+ (97% coverage)
265
- - **Firefox**: 104+ (95% coverage)
266
- - **Safari**: 15.4+ (92% coverage)
267
- - **Edge**: 97+ (94% coverage)
268
-
269
- ### **Assistive Technology Support**
270
- - **JAWS**: 2020+
271
- - **NVDA**: 2020+
272
- - **VoiceOver**: macOS 10.15+, iOS 13+
273
- - **Dragon NaturallySpeaking**: 15+
274
-
275
- ## 🚀 Performance Impact
276
-
277
- ### **Bundle Size Impact**
278
- - **CSS**: +12KB (compressed)
279
- - **JavaScript**: +8KB (compressed)
280
- - **Total Impact**: ~20KB additional payload
281
-
282
- ### **Runtime Performance**
283
- - **Initialization**: ~5ms on modern devices
284
- - **Focus Management**: <1ms per interaction
285
- - **Announcements**: <1ms per message
286
-
287
- ## 📖 Usage Examples
288
-
289
- ### **Basic Setup**
290
- ```html
291
- <!DOCTYPE html>
292
- <html lang="en">
293
- <head>
294
- <!-- Enhanced accessibility meta tags -->
295
- <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
296
- <meta name="color-scheme" content="light dark">
297
- <!-- AdminLTE CSS with accessibility styles -->
298
- <link rel="stylesheet" href="dist/css/adminlte.css">
299
- </head>
300
- <body>
301
- <!-- Skip links automatically added -->
302
- <!-- Main content with proper landmarks -->
303
- <main id="main" role="main">
304
- <!-- Your content -->
305
- </main>
306
-
307
- <!-- AdminLTE JS with accessibility features -->
308
- <script src="dist/js/adminlte.js"></script>
309
- </body>
310
- </html>
311
- ```
312
-
313
- ### **Custom Configuration**
314
- ```javascript
315
- // Initialize with custom settings
316
52
  const accessibility = initAccessibility({
317
- announcements: true, // Enable screen reader announcements
318
- skipLinks: true, // Add skip navigation links
319
- focusManagement: true, // Enhanced focus handling
320
- keyboardNavigation: true, // Arrow key navigation
321
- reducedMotion: false // Disable if animations are critical
53
+ announcements: true, // live region + automatic alert announcements
54
+ skipLinks: true, // inject skip links
55
+ focusManagement: true, // modal focus restore, Escape handling
56
+ keyboardNavigation: true, // arrow keys in menus
57
+ reducedMotion: true // respect prefers-reduced-motion
322
58
  })
323
59
 
324
- // Add custom announcements
325
- accessibility.announce("Data saved successfully", "polite")
60
+ accessibility.announce('Data saved successfully', 'polite')
61
+ accessibility.focusElement('#error-summary')
62
+ accessibility.trapFocus(customDialogElement) // for non-Bootstrap dialogs
326
63
 
327
- // Focus specific elements
328
- accessibility.focusElement("#error-summary")
64
+ // Contrast checking (rgb() and hex supported)
65
+ accessibilityUtils.checkColorContrast('#000000', '#ffffff') // { ratio: 21, passes: true }
329
66
  ```
330
67
 
331
- ## 🔄 Future Enhancements
332
-
333
- ### **Roadmap for Additional Features**
334
- - [ ] Voice navigation support
335
- - [ ] Enhanced keyboard shortcuts
336
- - [ ] Customizable contrast themes
337
- - [ ] Advanced screen reader optimization
338
- - [ ] Internationalization (i18n) support
339
- - [ ] Right-to-left (RTL) accessibility improvements
340
-
341
- ### **Community Contributions**
342
- We welcome contributions to improve accessibility further. Please:
343
- 1. Follow WCAG 2.1 AA guidelines
344
- 2. Test with multiple assistive technologies
345
- 3. Document any new features thoroughly
346
- 4. Include automated tests where possible
68
+ The module is initialized automatically by `adminlte.js`. All document-level listeners are registered against the Turbo lifecycle signal, so Hotwired Turbo navigations neither leak listeners nor duplicate injected nodes.
347
69
 
348
- ---
70
+ ## 🧪 How to test your pages
349
71
 
350
- ## 📞 Support & Resources
72
+ - **Automated:** [axe-core](https://github.com/dequelabs/axe-core), [WAVE](https://wave.webaim.org/), Lighthouse accessibility audit
73
+ - **Keyboard:** navigate your entire flow with Tab/Shift+Tab/Enter/Escape only; confirm focus is always visible and never trapped
74
+ - **Screen readers:** [NVDA](https://www.nvaccess.org/) (Windows, free), VoiceOver (macOS/iOS), JAWS
75
+ - **Zoom:** verify layouts at 200% zoom and 320px viewport width
76
+ - **Motion:** enable "reduce motion" in your OS and confirm animations calm down
351
77
 
352
- ### **Documentation**
353
- - [WCAG 2.1 Guidelines](https://www.w3.org/WAI/WCAG21/quickref/)
354
- - [ARIA Authoring Practices](https://www.w3.org/WAI/ARIA/apg/)
355
- - [WebAIM Resources](https://webaim.org/)
356
-
357
- ### **Testing Tools**
358
- - [axe-core](https://github.com/dequelabs/axe-core)
359
- - [WAVE Web Accessibility Evaluator](https://wave.webaim.org/)
360
- - [Lighthouse Accessibility](https://developers.google.com/web/tools/lighthouse/)
78
+ ## 🗺️ Roadmap
361
79
 
362
- ### **Screen Readers**
363
- - [NVDA (Free)](https://www.nvaccess.org/)
364
- - [JAWS (Commercial)](https://www.freedomscientific.com/products/software/jaws/)
365
- - [VoiceOver (Built-in on macOS/iOS)](https://support.apple.com/guide/voiceover/)
80
+ - axe/pa11y checks in CI against the built demo pages
81
+ - Keyboard interaction pattern (roving tabindex) for the sidebar treeview
82
+ - `aria-expanded`/`aria-controls` in the static demo markup (not only JS-stamped)
83
+ - Audit and document contrast for all shipped color variants
84
+ - RTL accessibility review
366
85
 
367
- ---
86
+ ## 📚 Resources
368
87
 
369
- **AdminLTE v4.0.0** - Now with comprehensive WCAG 2.1 AA accessibility compliance! 🎉
88
+ - [WCAG 2.1 Guidelines](https://www.w3.org/WAI/WCAG21/quickref/)
89
+ - [ARIA Authoring Practices Guide](https://www.w3.org/WAI/ARIA/apg/)
90
+ - [WebAIM](https://webaim.org/)
package/CHANGELOG.md CHANGED
@@ -7,6 +7,72 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [4.1.0] - 2026-07-02
11
+
12
+ ### Added
13
+
14
+ - **ESM bundle and TypeScript declarations on npm:** `dist/js/adminlte.esm.js` (+ `.min`) ships alongside the UMD build, generated `.d.ts` files ship under `dist/js/types/`, and package.json gains `module`, `types`, and a full `exports` map (with `sass`/`style` conditions and `./dist/*` + `./src/scss/*` subpaths). `import { PushMenu } from "admin-lte"` now resolves natively in Vite/webpack and type-checks out of the box — previously the package shipped a single minified UMD file with no typings at all.
15
+ - **Component lifecycle API (Bootstrap-style):** every JS component now has `getInstance(element)`, `getOrCreateInstance(element, config?)` and `dispose()`, backed by a per-element WeakMap registry (instances are garbage-collected with their elements — Turbo-safe). The data API now uses **delegated document-level listeners**, so toggles inside content inserted after page load (AJAX partials, Turbo Frames) work without re-initialisation. `PushMenu` is finally controllable programmatically via `PushMenu.getInstance(sidebar)`.
16
+ - **`ColorMode` module in the bundle:** the light/dark/auto switcher (persisted in `lte-theme`, OS-preference aware, `[data-bs-theme-value]` data-API, `changed.lte.color-mode` event) is now part of `adminlte.js`. Applications no longer need to copy the demo's inline script; the demo pages now use the bundled module. Only the tiny no-flash snippet in `<head>` remains inline, by design.
17
+ - **`bootstrap` declared as a peer dependency** — the Sass source imports it, so `@use "admin-lte/src/scss/adminlte"` now works after a plain `npm install admin-lte` (npm installs the peer automatically). Documented the required Sass load-path setup.
18
+ - **New demo pages:** a blank **starter page** (the most-requested v3 page, absent from v4), a dedicated **ApexCharts** page with six chart types, and a **Users** management page (searchable directory table, add-user and delete-confirmation modals, pagination). All linked from the sidebar.
19
+ - **Test baseline:** a vitest + happy-dom unit suite (30 tests across the component lifecycle, card/treeview/push-menu behavior, ColorMode, and slide animations) wired into `npm run production`; plus `npm run test-a11y` — an axe-core check over key built demo pages that fails on serious/critical WCAG violations, with a dedicated GitHub workflow.
20
+
21
+ ### Fixed
22
+
23
+ - First findings of the new axe gate, fixed at the source: breadcrumb links now use the darker link shade (Bootstrap's default blue was 4.26:1 against the content-header's gray background — below WCAG AA's 4.5:1), the direct-chat message pane is keyboard-focusable (`tabindex="0"` + `role="log"`), and muted footnote text uses `text-body-secondary` instead of the failing `text-secondary`.
24
+
25
+ ### Changed
26
+
27
+ - **Component events overhauled (behavior change):** all plugin events are now bubbling `CustomEvent`s dispatched on the component's root element (the card, the nav item, the sidebar) — previously most were non-bubbling and card events fired on whatever was clicked, including the `<i>` icon. Animated actions gained cancelable "before" events (`collapse`/`expand`/`remove.lte.card-widget`, `expand`/`collapse.lte.treeview`, `open`/`collapse.lte.push-menu`) and their "after" events (`collapsed`, `expanded`, `removed`, `opened`, …) now fire when the animation completes, not when it starts. If you listened for card events on the tool buttons themselves, listen on the card or on `document` instead.
28
+ - **Docs styles split out of the production CSS:** the documentation/FAQ styling now compiles to a separate `adminlte-docs.css`, loaded only by the docs pages. Together with the 4.0.4 dedup, `adminlte.min.css` is down to ~40.4 KB gzip (from 46.7 KB in 4.0.3); bundlewatch budgets tightened accordingly.
29
+ - **Vendored Bootstrap variables fork replaced:** the 1,766-line `_bootstrap-variables.scss` copy (which had to be re-synced by hand every Bootstrap release) is gone; AdminLTE's ~10 actual changes now live in a small `_bootstrap-overrides.scss` loaded before Bootstrap's own variables. Compiled CSS is byte-identical.
30
+ - **Sass deprecation policy:** the build no longer silences all warnings (`--quiet`); it silences only dependency warnings and the known `@import` deprecation (`--quiet-deps --silence-deprecation=import`), so new deprecations in AdminLTE's own code surface at build time. All deprecated global built-ins (`map-get`, `map-keys`) migrated to the `sass:map` module. The full `@use` module-system migration is intentionally deferred until Bootstrap ships module-system Sass (Bootstrap 6) — Bootstrap 5's partials are designed around `@import`'s shared global namespace and cannot be loaded individually via `@use`.
31
+ - Rewrote the color-mode docs page around the bundled `ColorMode` module (the old copy-paste script it showed used a stale storage key); tsconfig.json no longer carries the invalid `"root": true` option.
32
+
33
+ ## [4.0.4] - 2026-07-02
34
+
35
+ ### Added
36
+
37
+ - **Forgot-password example page** — both login pages have linked `forgot-password.html` since 4.0.0, but the page didn't exist (dead link in every deployed demo). Now shipped and listed in the sidebar under Examples › Version 1.
38
+ - **Treeview exposes its state to assistive tech:** submenu toggle links now carry `aria-expanded`, stamped on init and kept in sync on open/close.
39
+
40
+ ### Fixed
41
+
42
+ - **npm packaging:** the package is now built from a `files` allowlist instead of the `.npmignore` denylist. Stray local files can no longer leak into the tarball (4.0.2 shipped an untracked working file this way), and the demo/docs HTML — which SECURITY.md advises never to deploy — is no longer published to npm. Unpacked size drops from 12.7 MB to 9.0 MB (177 → 95 files). Also declares `engines: node >= 20`.
43
+ - **CSS bundles shipped the docs-site styles twice:** `_docs.scss` was imported from both `adminlte.scss` and `parts/_core.scss`, and Sass `@import` duplicates output — ~23 KB of dead weight in each of the four dist stylesheets.
44
+ - **Accessibility module keyboard handling:**
45
+ - removed the document-edge Tab wrap — it acted as a page-level keyboard trap (WCAG 2.1.2), preventing keyboard users from ever tabbing out to the browser chrome
46
+ - arrow keys are no longer intercepted inside inputs, textareas, selects, or contenteditable elements (typing in a navbar search field used to yank focus into the menu), and menu arrow-navigation only engages when focus is actually on a menu item
47
+ - modal focus restore now captures the triggering element on `show.bs.modal` (capturing on `shown` stored an element inside the modal, so closing dropped focus to `<body>`); `[autofocus]` is respected
48
+ - **Hotwired Turbo no longer duplicates injected DOM:** the skip links, `#live-region`, and sidebar overlay are now reused when a restored `<body>` snapshot already contains them — previously they accumulated one copy per navigation.
49
+ - **Card widget:** `remove()` now actually removes the card from the DOM after the animation (it only hid it, so hidden form fields kept submitting); clicking the collapse toggle mid-animation reverses it instead of being swallowed; widget events now dispatch on the toggle button itself rather than a clicked `<i>` icon; `minimize()` cleans up its inline styles.
50
+ - **Slide animations are cancelable:** rapid-toggling a treeview or card no longer lets a stale animation timer strip styles mid-flight and desync display state.
51
+ - **Treeview accordion guard** compared each open item against the parent `<ul>` (never true), so `open()` on an already-open item slid its own menu shut.
52
+ - **PushMenu** reacts to viewport changes via `matchMedia` on the actual breakpoint crossing — mobile URL-bar/keyboard resizes and same-side width changes no longer re-expand a sidebar the user collapsed; the default breakpoint (991.98) now matches the CSS convention, fixing a 992px off-by-one.
53
+ - **Callout variants** referenced two custom properties that were never defined, so links and inline code inside callouts never recolored; the user-menu footer used `--bs-light-bg`, which doesn't exist in Bootstrap 5.3 (now `--bs-tertiary-bg`).
54
+ - **Demo pages:** Bootstrap JS CDN pin updated 5.3.7 → 5.3.8 to match the compiled CSS; removed the dead navbar-search button (`data-widget="navbar-search"` has no implementation in v4); every page now has exactly one `<h1>` (page titles were `<h3>`); breadcrumbs are wrapped in `<nav aria-label="breadcrumb">`; all icon-only buttons (card tools, topbar toggles) have `aria-label`s; auth forms have real `<label>`s and `<main>` landmarks; dated "Google+" copy updated.
55
+
56
+ ### Changed
57
+
58
+ - **ACCESSIBILITY-COMPLIANCE.md rewritten as an accurate accessibility statement** — what's implemented, what's partial (treeview keyboard pattern, drag-and-drop alternatives, touch-target sizes), and what's on the roadmap — replacing the aspirational all-checked WCAG checklist. Demo meta descriptions updated to match.
59
+ - **bundlewatch budgets recalibrated:** CSS budgets tightened (46 → 44 kB min+gzip) to lock in the docs-dedup win; JS budget raised (5.8 → 6.5 kB) for the behavior fixes above.
60
+
61
+ ## [4.0.3] - 2026-07-01
62
+
63
+ ### Added
64
+
65
+ - **Hotwired Turbo / Turbo Drive support:** plugins now re-initialise on `turbo:load`, so PushMenu, TreeView and the other JS components keep working after Turbo swaps the `<body>` on in-app navigation (previously they went dead after the first link click). Each init cycle uses an `AbortController` whose signal is aborted on `turbo:before-render`, so the `window`/`document`-level listeners are torn down before re-init instead of stacking up on every navigation. (#563, #5890 — diagnosed and prototyped by @MarkDaleman in #6058)
66
+
67
+ ### Fixed
68
+
69
+ - **Fullscreen state sync:** the fullscreen icons and the `maximized`/`minimized` events are now driven by the native `fullscreenchange` event instead of the request/exit calls. The UI no longer flips when a fullscreen request is denied (permissions policy, missing `allowfullscreen`, lost user gesture), and it now stays in sync when the user exits with `ESC` or `F11`. (builds on @webgo-oss's report in #6055)
70
+ - **Accessibility:** form inputs lacking both an `id` and a `name` now receive a stable, generated error-message id instead of colliding on a shared `-error` id and appending a new orphaned error node on every re-validation. (#6055, reported by @webgo-oss)
71
+
72
+ ### Updated
73
+
74
+ - All dependencies bumped to their latest releases, including four majors — **Astro 6 → 7** (which pulls in Vite 8), **@astrojs/mdx 6 → 7**, **eslint-plugin-astro 1 → 2**, and **eslint-plugin-unicorn 68 → 69** — plus ESLint, Prettier, Stylelint, PostCSS, Rollup and typescript-eslint. No source changes were required; the full `npm run production` pipeline (lint + Astro build + bundlewatch) passes and `npm audit` remains at **0 vulnerabilities**. (supersedes Dependabot PRs #6065–#6074)
75
+
10
76
  ## [4.0.2] - 2026-06-11
11
77
 
12
78
  ### Fixed
package/README.md CHANGED
@@ -31,14 +31,22 @@ large desktops, and it's MIT-licensed.
31
31
  The same AdminLTE 4 dashboard, officially integrated for the framework you know best —
32
32
  you're looking at the **HTML / Bootstrap** core:
33
33
 
34
- <p align="center">
34
+ <!-- ADMINLTE-ECOSYSTEM:START -->
35
+ <div align="center">
36
+ <a href="https://github.com/ColorlibHQ/AdminLTE"><img height="36" alt="HTML" src="https://img.shields.io/badge/HTML-0D6EFD?style=for-the-badge&logo=html5&logoColor=white"></a>
35
37
  <a href="https://github.com/ColorlibHQ/adminlte-react"><img height="36" alt="React" src="https://img.shields.io/badge/React-20232A?style=for-the-badge&logo=react&logoColor=61DAFB"></a>
36
38
  <a href="https://github.com/ColorlibHQ/adminlte-react"><img height="36" alt="Next.js" src="https://img.shields.io/badge/Next.js-000000?style=for-the-badge&logo=nextdotjs&logoColor=white"></a>
37
39
  <a href="https://github.com/ColorlibHQ/adminlte-vue"><img height="36" alt="Vue" src="https://img.shields.io/badge/Vue.js-35495E?style=for-the-badge&logo=vuedotjs&logoColor=4FC08D"></a>
38
40
  <a href="https://github.com/ColorlibHQ/adminlte-vue"><img height="36" alt="Nuxt" src="https://img.shields.io/badge/Nuxt-00DC82?style=for-the-badge&logo=nuxt&logoColor=white"></a>
41
+ <a href="https://github.com/ColorlibHQ/adminlte-angular"><img height="36" alt="Angular" src="https://img.shields.io/badge/Angular-DD0031?style=for-the-badge&logo=angular&logoColor=white"></a>
39
42
  <a href="https://github.com/ColorlibHQ/adminlte-laravel"><img height="36" alt="Laravel" src="https://img.shields.io/badge/Laravel-FF2D20?style=for-the-badge&logo=laravel&logoColor=white"></a>
43
+ <a href="https://github.com/ColorlibHQ/adminlte-symfony"><img height="36" alt="Symfony" src="https://img.shields.io/badge/Symfony-000000?style=for-the-badge&logo=symfony&logoColor=white"></a>
40
44
  <a href="https://github.com/ColorlibHQ/adminlte-django"><img height="36" alt="Django" src="https://img.shields.io/badge/Django-092E20?style=for-the-badge&logo=django&logoColor=white"></a>
41
- </p>
45
+ <a href="https://github.com/ColorlibHQ/adminlte-aspnet"><img height="36" alt="ASP.NET" src="https://img.shields.io/badge/ASP.NET-512BD4?style=for-the-badge&logo=dotnet&logoColor=white"></a>
46
+ <a href="https://github.com/ColorlibHQ/adminlte-drupal"><img height="36" alt="Drupal" src="https://img.shields.io/badge/Drupal-0678BE?style=for-the-badge&logo=drupal&logoColor=white"></a>
47
+ <a href="https://docs.adminlte.io"><img height="36" alt="Docs" src="https://img.shields.io/badge/Docs-adminlte.io-0EA5E9?style=for-the-badge&logo=readthedocs&logoColor=white"></a>
48
+ </div>
49
+ <!-- ADMINLTE-ECOSYSTEM:END -->
42
50
 
43
51
  | Edition | Repository | Live demo | Install |
44
52
  |---|---|---|---|
@@ -47,6 +55,11 @@ you're looking at the **HTML / Bootstrap** core:
47
55
  | **Vue 3 & Nuxt** — 45+ typed components, composables, SSR-safe theming | [adminlte-vue](https://github.com/ColorlibHQ/adminlte-vue) | [themes/vue-nuxt](https://adminlte.io/themes/vue-nuxt/) | see repo |
48
56
  | **Laravel** — Blade components, config-driven menu, auth scaffolding | [adminlte-laravel](https://github.com/ColorlibHQ/adminlte-laravel) | [laravel.adminlte.io](https://laravel.adminlte.io/) | `composer require colorlibhq/adminlte-laravel` |
49
57
  | **Django** — reusable app, menu filter pipeline, themed admin | [adminlte-django](https://github.com/ColorlibHQ/adminlte-django) | [django.adminlte.io](https://django.adminlte.io/) | `pip install django-adminlte4` |
58
+ | **Symfony** — Twig Components, AssetMapper, config-driven menu, EasyAdmin theme | [adminlte-symfony](https://github.com/ColorlibHQ/adminlte-symfony) | see repo | `composer require colorlibhq/adminlte-symfony` |
59
+ | **Angular 22** — 44 standalone signal components, dark mode, ⌘K palette | [adminlte-angular](https://github.com/ColorlibHQ/adminlte-angular) | see repo | `npm i @adminlte/angular` |
60
+ | **ASP.NET Core (.NET 10)** — Blazor components + MVC/Razor Pages Tag Helpers | [adminlte-aspnet](https://github.com/ColorlibHQ/adminlte-aspnet) | see repo | `dotnet add package ColorlibHQ.AdminLTE.AspNetCore` |
61
+ | **Drupal** — admin theme for Drupal 10.3+/11, themed admin UI | [adminlte-drupal](https://github.com/ColorlibHQ/adminlte-drupal) | see repo | see repo |
62
+ | **Docs** — guides, components, and API reference for every edition | [docs.adminlte.io](https://docs.adminlte.io) | [docs.adminlte.io](https://docs.adminlte.io) | — |
50
63
 
51
64
  Every edition ships the full AdminLTE 4 design — Bootstrap 5.3, dark mode, RTL — with
52
65
  idiomatic integrations for its stack (components, routing, auth, theming).