feat(a11y): WCAG 2.2 accessibility fixes across four areas

- modal/_validateField: set aria-invalid on invalid inputs so screen readers
  announce field errors; login.js mirrors this for username/password fields
- color pickers (notes, calendar): wrap swatches in role="radiogroup" with
  aria-labelledby, add aria-checked per swatch, localized aria-labels instead
  of hex values, roving tabindex with Arrow/Enter/Space keyboard navigation
- nav badges: badge spans get aria-hidden="true"; nav link aria-label updated
  to include overdue count (tasks) or pending reminder count (reminders)
- router: remove aria-live from <main> (caused full page re-reads on nav);
  add dedicated #route-announcer sr-only region with aria-live=polite +
  aria-atomic, announces page label 50ms after render completes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Ulas Kalayci
2026-04-27 00:38:50 +02:00
parent ca5208341b
commit efd4e8c924
8 changed files with 153 additions and 27 deletions
+7
View File
@@ -69,8 +69,15 @@ function showBrowserNotification(title, body) {
* @param {number} count
*/
function updateBellBadge(count) {
const navLabel = count > 0
? t(count === 1 ? 'reminders.pendingBadgeTitle' : 'reminders.pendingBadgeTitlePlural', { count })
: t('nav.reminders');
document.querySelectorAll('[data-route="/reminders"]').forEach((navItem) => {
navItem.setAttribute('aria-label', navLabel);
});
document.querySelectorAll('.reminder-bell-badge').forEach((badge) => {
if (count > 0) {
badge.setAttribute('aria-hidden', 'true');
badge.textContent = count > 9 ? '9+' : String(count);
badge.hidden = false;
} else {