From 73162d9a9ba7a503b35cdfae88b3220729900644 Mon Sep 17 00:00:00 2001 From: Jared Vititoe Date: Sat, 31 Jan 2026 00:15:11 -0500 Subject: [PATCH] Add comprehensive accessibility improvements HTML Accessibility: - Add ARIA roles to tab navigation (role="tablist", role="tab", role="tabpanel") - Add aria-selected to tab buttons with JS toggle - Add aria-controls and aria-labelledby for tab/panel relationships - Add aria-label to emoji icon buttons (settings, reply, edit, delete) - Add aria-pressed to view toggle buttons - Add labels for form inputs (comment textarea, dependency inputs, file input) - Add .sr-only utility class for screen-reader-only content CSS Accessibility: - Add .sr-only class (visually hidden, accessible to screen readers) JavaScript: - Update showTab() to toggle aria-selected on tab buttons Co-Authored-By: Claude Opus 4.5 --- assets/css/dashboard.css | 13 ++++++++++++ assets/js/ticket.js | 7 +++++-- views/DashboardView.php | 6 +++--- views/TicketView.php | 43 +++++++++++++++++++++------------------- 4 files changed, 44 insertions(+), 25 deletions(-) diff --git a/assets/css/dashboard.css b/assets/css/dashboard.css index ff80eef..0e95408 100644 --- a/assets/css/dashboard.css +++ b/assets/css/dashboard.css @@ -201,6 +201,19 @@ select:focus { outline-offset: 2px; } +/* Screen reader only - visually hidden but accessible */ +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + /* Reduced motion for accessibility */ @media (prefers-reduced-motion: reduce) { *, diff --git a/assets/js/ticket.js b/assets/js/ticket.js index dbbd415..16519ca 100644 --- a/assets/js/ticket.js +++ b/assets/js/ticket.js @@ -566,14 +566,17 @@ function showTab(tabName) { activityTab.style.display = 'none'; } - // Remove active class from all buttons + // Remove active class and aria-selected from all buttons document.querySelectorAll('.tab-btn').forEach(btn => { btn.classList.remove('active'); + btn.setAttribute('aria-selected', 'false'); }); // Show selected tab and activate its button document.getElementById(`${tabName}-tab`).style.display = 'block'; - document.querySelector(`.tab-btn[data-tab="${tabName}"]`).classList.add('active'); + const activeBtn = document.querySelector(`.tab-btn[data-tab="${tabName}"]`); + activeBtn.classList.add('active'); + activeBtn.setAttribute('aria-selected', 'true'); // Load attachments when tab is shown if (tabName === 'attachments') { diff --git a/views/DashboardView.php b/views/DashboardView.php index 30766a6..ef9dcf6 100644 --- a/views/DashboardView.php +++ b/views/DashboardView.php @@ -96,7 +96,7 @@ $nonce = SecurityHeadersMiddleware::getNonce(); - + @@ -284,8 +284,8 @@ $nonce = SecurityHeadersMiddleware::getNonce();
- - + +
@@ -268,13 +268,13 @@ $nonce = SecurityHeadersMiddleware::getNonce();
Content Sections
-
- - - - - -
+
@@ -285,7 +285,7 @@ $nonce = SecurityHeadersMiddleware::getNonce();
-
+
Description
@@ -293,13 +293,14 @@ $nonce = SecurityHeadersMiddleware::getNonce();
-
+
Comments Section

Add Comment

- + +
@@ -362,12 +363,12 @@ $nonce = SecurityHeadersMiddleware::getNonce(); echo "
"; // Reply button (max depth of 3) if ($threadDepth < 3) { - echo ""; + echo ""; } // Edit/Delete buttons for owner or admin if ($canModify) { - echo ""; - echo ""; + echo ""; + echo ""; } echo "
"; @@ -408,7 +409,7 @@ $nonce = SecurityHeadersMiddleware::getNonce();
-
+
File Attachments
@@ -419,7 +420,7 @@ $nonce = SecurityHeadersMiddleware::getNonce();
📁

Drag and drop files here or click to browse

Max file size:

- +
@@ -441,16 +442,18 @@ $nonce = SecurityHeadersMiddleware::getNonce();
-
+
Ticket Dependencies

Add Dependency

- Ticket ID for dependency + - @@ -478,7 +481,7 @@ $nonce = SecurityHeadersMiddleware::getNonce();
-
+
Activity Timeline