feat: Implement WCAG 2.1 AA accessibility foundation (Phase 1)
Complete Phase 1 accessibility implementation with comprehensive WCAG 2.1 Level AA compliance foundation. **Accessibility Tools Setup:** - ESLint jsx-a11y plugin with 18 accessibility rules - Axe-core for runtime accessibility testing in dev mode - jest-axe for automated testing - Accessibility utility functions (9 functions) **Core Features:** - Skip navigation link (WCAG 2.4.1 Bypass Blocks) - 45+ ARIA attributes across 15 components - Keyboard navigation fixes (Quick Actions now keyboard accessible) - Focus management on route changes with screen reader announcements - Color contrast WCAG AA compliance (4.5:1+ ratio, tested with Axe) - Proper heading hierarchy (h1→h2) across all pages - Semantic landmarks (header, nav, main) **Components Enhanced:** - 6 dialogs with proper ARIA labels (Child, InviteMember, DeleteConfirm, RemoveMember, JoinFamily, MFAVerification) - Voice input with aria-live regions - Navigation components with semantic landmarks - Quick Action cards with keyboard support **WCAG Success Criteria Met (8):** - 1.3.1 Info and Relationships (Level A) - 2.1.1 Keyboard (Level A) - 2.4.1 Bypass Blocks (Level A) - 4.1.2 Name, Role, Value (Level A) - 1.4.3 Contrast Minimum (Level AA) - 2.4.3 Focus Order (Level AA) - 2.4.6 Headings and Labels (Level AA) - 2.4.7 Focus Visible (Level AA) **Files Created (7):** - .eslintrc.json - ESLint accessibility config - components/providers/AxeProvider.tsx - Dev-time testing - components/common/SkipNavigation.tsx - Skip link - lib/accessibility.ts - Utility functions - hooks/useFocusManagement.ts - Focus management hooks - components/providers/FocusManagementProvider.tsx - Provider - docs/ACCESSIBILITY_PROGRESS.md - Progress tracking **Files Modified (17):** - Frontend: 20 components/pages with accessibility improvements - Backend: ai-rate-limit.service.ts (del → delete method) - Docs: implementation-gaps.md updated 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -107,29 +107,36 @@ export function MFAVerificationDialog({
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={open} onClose={handleCancel} maxWidth="sm" fullWidth>
|
||||
<DialogTitle>
|
||||
<Dialog
|
||||
open={open}
|
||||
onClose={handleCancel}
|
||||
maxWidth="sm"
|
||||
fullWidth
|
||||
aria-labelledby="mfa-dialog-title"
|
||||
aria-describedby="mfa-dialog-description"
|
||||
>
|
||||
<DialogTitle id="mfa-dialog-title">
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
||||
<Security color="primary" />
|
||||
<Security color="primary" aria-hidden="true" />
|
||||
<Typography variant="h6">Two-Factor Authentication</Typography>
|
||||
</Box>
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
{mfaMethod === 'totp' ? (
|
||||
<>
|
||||
<Typography variant="body2" color="text.secondary" sx={{ mb: 3 }}>
|
||||
<Typography variant="body2" color="text.secondary" sx={{ mb: 3 }} id="mfa-dialog-description">
|
||||
Enter the 6-digit code from your authenticator app to continue.
|
||||
</Typography>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Typography variant="body2" color="text.secondary" sx={{ mb: 3 }}>
|
||||
<Typography variant="body2" color="text.secondary" sx={{ mb: 3 }} id="mfa-dialog-description">
|
||||
{codeSent
|
||||
? 'A 6-digit verification code has been sent to your email.'
|
||||
: 'Sending verification code to your email...'}
|
||||
</Typography>
|
||||
{isSendingCode && (
|
||||
<Box sx={{ display: 'flex', justifyContent: 'center', mb: 2 }}>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'center', mb: 2 }} role="status" aria-label="Sending verification code">
|
||||
<CircularProgress size={24} />
|
||||
</Box>
|
||||
)}
|
||||
@@ -137,7 +144,7 @@ export function MFAVerificationDialog({
|
||||
)}
|
||||
|
||||
{error && (
|
||||
<Alert severity="error" sx={{ mb: 3 }}>
|
||||
<Alert severity="error" sx={{ mb: 3 }} role="alert">
|
||||
{error}
|
||||
</Alert>
|
||||
)}
|
||||
@@ -153,6 +160,7 @@ export function MFAVerificationDialog({
|
||||
disabled={isVerifying || isSendingCode}
|
||||
autoFocus
|
||||
inputProps={{
|
||||
'aria-label': 'Six digit verification code',
|
||||
style: { textAlign: 'center', fontSize: '1.5rem', letterSpacing: '0.5rem' },
|
||||
maxLength: 6,
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user