Accessibility Issue: Dynamic Content Without ARIA Live Regions
WCAG Level: A
Severity: Medium
Category: Dynamic Content (WCAG 4.1.3)
Issue Description
Several areas of the application update dynamically (sync status, loading states, success/error messages, recommendations) without using ARIA live regions to announce changes to screen reader users.
User Impact
- Affected Users: Screen reader users
- Severity: Medium - users miss important status updates and feedback
Violations Found
File: src/pages/Settings.tsx
Lines: 145-156
<!-- Current Code -->
{message && (
<div className="card" style={{ background: 'var(--color-success-dim)', ... }}>
<span style={{ color: 'var(--color-success)', fontWeight: 600 }}>{message}</span>
</div>
)}
{error && (
<div className="card" style={{ background: 'var(--color-error-dim)', ... }}>
<span style={{ color: 'var(--color-error)', fontWeight: 600 }}>Error:</span> {error}
</div>
)}
Issue: Success and error messages appear but are not announced to screen readers.
File: src/pages/Activities.tsx
Lines: 92-97
<!-- Current Code (loading state) -->
{loading ? (
<div className="card" style={{ textAlign: 'center', padding: '2rem' }}>
<div>⚡</div>
<p style={{ color: 'var(--text-muted)', margin: 0 }}>Loading your victories…</p>
</div>
) : ( ... )}
Issue: Loading state not announced; completion not announced.
File: src/components/AdaptiveRecommendations.tsx
Lines: 254-274
<!-- Current Code -->
{analyzing && (
<span style={{ fontSize: '0.78rem', color: 'var(--text-muted)' }}>Analyzing…</span>
)}
Issue: Analysis status not announced.
Recommended Fix
<!-- Fixed Code - Settings.tsx -->
{message && (
<div
className="card"
role="status"
aria-live="polite"
style={{ background: 'var(--color-success-dim)', ... }}
>
<span style={{ color: 'var(--color-success)', fontWeight: 600 }}>{message}</span>
</div>
)}
{error && (
<div
className="card"
role="alert"
aria-live="assertive"
style={{ background: 'var(--color-error-dim)', ... }}
>
<span style={{ color: 'var(--color-error)', fontWeight: 600 }}>Error:</span> {error}
</div>
)}
<!-- Fixed Code - Loading states -->
<div
className="card"
role="status"
aria-live="polite"
aria-busy={loading}
style={{ textAlign: 'center', padding: '2rem' }}
>
{loading ? (
<>
<div aria-hidden="true">⚡</div>
<p style={{ color: 'var(--text-muted)', margin: 0 }}>Loading your activities…</p>
</>
) : (
<p style={{ color: 'var(--text-muted)', margin: 0 }}>
{activities.length} activities loaded
</p>
)}
</div>
Changes Made:
- Add
role="status" and aria-live="polite" for non-critical updates
- Add
role="alert" and aria-live="assertive" for errors
- Add
aria-busy attribute for loading states
- Announce completion states, not just loading
Additional Instances
src/pages/Dashboard.tsx - Sync results, daily recap appearance
src/pages/Training.tsx - Sync status messages
src/components/LoadingScreen.tsx - Loading spinner
src/pages/Analytics.tsx - Data loading states
src/pages/Insights.tsx - Score updates
Testing Instructions
- Use screen reader to navigate application
- Trigger actions that show messages (save settings, sync)
- Verify success/error messages are announced
- Verify loading states announce start and completion
- Test with NVDA/VoiceOver in different modes
Resources
Acceptance Criteria
Accessibility Issue: Dynamic Content Without ARIA Live Regions
WCAG Level: A
Severity: Medium
Category: Dynamic Content (WCAG 4.1.3)
Issue Description
Several areas of the application update dynamically (sync status, loading states, success/error messages, recommendations) without using ARIA live regions to announce changes to screen reader users.
User Impact
Violations Found
File:
src/pages/Settings.tsxLines: 145-156
Issue: Success and error messages appear but are not announced to screen readers.
File:
src/pages/Activities.tsxLines: 92-97
Issue: Loading state not announced; completion not announced.
File:
src/components/AdaptiveRecommendations.tsxLines: 254-274
Issue: Analysis status not announced.
Recommended Fix
Changes Made:
role="status"andaria-live="polite"for non-critical updatesrole="alert"andaria-live="assertive"for errorsaria-busyattribute for loading statesAdditional Instances
src/pages/Dashboard.tsx- Sync results, daily recap appearancesrc/pages/Training.tsx- Sync status messagessrc/components/LoadingScreen.tsx- Loading spinnersrc/pages/Analytics.tsx- Data loading statessrc/pages/Insights.tsx- Score updatesTesting Instructions
Resources
Acceptance Criteria
role="status"witharia-live="polite"role="alert"witharia-live="assertive"aria-busyattribute