UNPKG

admin-lte

Version:

Responsive open source admin dashboard and control panel.

91 lines (65 loc) 5.99 kB
# AdminLTE Accessibility Statement ## Overview 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. > **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. ## ✅ Implemented ### Markup (demo pages) - Semantic landmark structure on the app shell (`<nav>`, `<main>`, `<aside>`, `<footer>`) — non-list `.nav` containers receive `role="navigation"` automatically (#6038) - Exactly one `<h1>` per page (the page title in the content header) - Breadcrumbs wrapped in `<nav aria-label="breadcrumb">` with `aria-current="page"` - `aria-label` on all icon-only controls (card tools, topbar toggles, sidebar toggle) - Form inputs associated with `<label>` elements (visually hidden where the design is placeholder-driven, floating labels on the v2 auth pages) - Table headers with `scope` attributes - `lang="en"` declared, descriptive page titles, `meta name="color-scheme"` ### Behavior (`accessibility.ts` and components) - **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 - **Skip links** to main content and navigation, injected once and reused across Turbo navigations (WCAG 2.4.1) - **Treeview state exposure** — sidebar submenu toggles carry `aria-expanded`, kept in sync by the Treeview component - **Modal focus restoration** — the triggering element is captured on `show.bs.modal` and restored on close (skipped if it has left the document) - **Escape** closes open dropdowns; Bootstrap's own modal keyboard handling is left untouched - **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 - **Reduced motion**`prefers-reduced-motion` disables smooth scrolling and shortens animations; `prefers-contrast: more` styles in the CSS - **Theme-flash prevention** and dark mode via Bootstrap color modes, respecting `prefers-color-scheme` (#6043) - **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 ### Explicit non-goals - **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. ## ⚠️ Partial / known gaps These are known, tracked limitations — pull requests welcome: - **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. - **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). - **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`. - **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. - **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. ## 🔧 JavaScript API ```typescript import { initAccessibility, accessibilityUtils } from 'admin-lte' const accessibility = initAccessibility({ announcements: true, // live region + automatic alert announcements skipLinks: true, // inject skip links focusManagement: true, // modal focus restore, Escape handling keyboardNavigation: true, // arrow keys in menus reducedMotion: true // respect prefers-reduced-motion }) accessibility.announce('Data saved successfully', 'polite') accessibility.focusElement('#error-summary') accessibility.trapFocus(customDialogElement) // for non-Bootstrap dialogs // Contrast checking (rgb() and hex supported) accessibilityUtils.checkColorContrast('#000000', '#ffffff') // { ratio: 21, passes: true } ``` 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. ## 🧪 How to test your pages - **Automated:** [axe-core](https://github.com/dequelabs/axe-core), [WAVE](https://wave.webaim.org/), Lighthouse accessibility audit - **Keyboard:** navigate your entire flow with Tab/Shift+Tab/Enter/Escape only; confirm focus is always visible and never trapped - **Screen readers:** [NVDA](https://www.nvaccess.org/) (Windows, free), VoiceOver (macOS/iOS), JAWS - **Zoom:** verify layouts at 200% zoom and 320px viewport width - **Motion:** enable "reduce motion" in your OS and confirm animations calm down ## 🗺️ Roadmap - axe/pa11y checks in CI against the built demo pages - Keyboard interaction pattern (roving tabindex) for the sidebar treeview - `aria-expanded`/`aria-controls` in the static demo markup (not only JS-stamped) - Audit and document contrast for all shipped color variants - RTL accessibility review ## 📚 Resources - [WCAG 2.1 Guidelines](https://www.w3.org/WAI/WCAG21/quickref/) - [ARIA Authoring Practices Guide](https://www.w3.org/WAI/ARIA/apg/) - [WebAIM](https://webaim.org/)