feat: Complete form accessibility enhancement (WCAG 2.1 AA)
Some checks failed
CI/CD Pipeline / Lint and Test (push) Has been cancelled
CI/CD Pipeline / E2E Tests (push) Has been cancelled
CI/CD Pipeline / Build Application (push) Has been cancelled

Implemented comprehensive form accessibility improvements across all critical forms:

**Accessibility Attributes Added:**
- aria-required="true" on all required form fields
- aria-invalid on fields with validation errors
- aria-describedby linking error messages to inputs
- Unique id attributes on FormHelperText for error association
- role="alert" on error messages for screen reader announcements
- labelId on Select components for proper label association
- noValidate on forms to use custom validation

**Forms Updated:**
1. Login Form (app/(auth)/login/page.tsx)
   - Email and password fields with full ARIA support
   - Error message association with aria-describedby

2. Registration Form (app/(auth)/register/page.tsx)
   - All text fields: name, email, password, DOB, parental email
   - Checkbox fields: Terms, Privacy, COPPA consent
   - Conditional required fields for minors

3. Child Dialog (components/children/ChildDialog.tsx)
   - Name, birthdate, gender fields
   - Dynamic aria-invalid based on validation state

4. Tracking Forms:
   - Feeding form (app/track/feeding/page.tsx)
     - Child selector, side selector, bottle type
     - Food description with required validation
   - Sleep form (app/track/sleep/page.tsx)
     - Child selector, start/end time fields
     - Quality and location selectors

**WCAG 2.1 Compliance:**
-  3.3.2 Labels or Instructions (AA)
-  4.1.3 Status Messages (AA)
-  1.3.1 Info and Relationships (A)
-  3.3.1 Error Identification (A)

**Documentation:**
- Updated REMAINING_FEATURES.md
- Marked Form Accessibility Enhancement as complete
- Status: 79 features completed (57%)

🎉 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-04 13:24:40 +00:00
parent 2110359307
commit 4e5f1c849e
7 changed files with 231 additions and 43 deletions

View File

@@ -414,11 +414,16 @@ function FeedingTrackPage() {
{children.length > 1 && (
<Paper sx={{ p: 2, mb: 3 }}>
<FormControl fullWidth>
<InputLabel>{t('common.selectChild')}</InputLabel>
<InputLabel id="child-select-label">{t('common.selectChild')}</InputLabel>
<Select
labelId="child-select-label"
value={selectedChild}
onChange={(e) => setSelectedChild(e.target.value)}
label={t('common.selectChild')}
required
inputProps={{
'aria-required': 'true',
}}
>
{children.map((child) => (
<MenuItem key={child.id} value={child.id}>
@@ -486,11 +491,16 @@ function FeedingTrackPage() {
{/* Side Selector */}
<FormControl fullWidth sx={{ mb: 3 }}>
<InputLabel>{t('feeding.side')}</InputLabel>
<InputLabel id="side-select-label">{t('feeding.side')}</InputLabel>
<Select
labelId="side-select-label"
value={side}
onChange={(e) => setSide(e.target.value as 'left' | 'right' | 'both')}
label={t('feeding.side')}
required
inputProps={{
'aria-required': 'true',
}}
>
<MenuItem value="left">{t('feeding.sides.left')}</MenuItem>
<MenuItem value="right">{t('feeding.sides.right')}</MenuItem>
@@ -507,6 +517,13 @@ function FeedingTrackPage() {
onChange={(e) => setDuration(parseInt(e.target.value) || 0)}
sx={{ mb: 3 }}
helperText={t('feeding.placeholders.duration')}
inputProps={{
'aria-describedby': 'duration-helper',
min: 0,
}}
FormHelperTextProps={{
id: 'duration-helper',
}}
/>
</Box>
)}
@@ -524,11 +541,16 @@ function FeedingTrackPage() {
/>
<FormControl fullWidth sx={{ mb: 3 }}>
<InputLabel>{t('feeding.bottleType')}</InputLabel>
<InputLabel id="bottle-type-label">{t('feeding.bottleType')}</InputLabel>
<Select
labelId="bottle-type-label"
value={bottleType}
onChange={(e) => setBottleType(e.target.value as 'formula' | 'breastmilk' | 'other')}
label={t('feeding.bottleType')}
required
inputProps={{
'aria-required': 'true',
}}
>
<MenuItem value="formula">{t('feeding.bottleTypes.formula')}</MenuItem>
<MenuItem value="breastmilk">{t('feeding.bottleTypes.breastmilk')}</MenuItem>
@@ -548,6 +570,11 @@ function FeedingTrackPage() {
onChange={(e) => setFoodDescription(e.target.value)}
sx={{ mb: 3 }}
placeholder={t('feeding.placeholders.foodDescription')}
required
inputProps={{
'aria-required': 'true',
'aria-invalid': !foodDescription && error ? 'true' : 'false',
}}
/>
<TextField
@@ -557,6 +584,12 @@ function FeedingTrackPage() {
onChange={(e) => setAmountDescription(e.target.value)}
sx={{ mb: 3 }}
placeholder={t('feeding.placeholders.amountDescription')}
inputProps={{
'aria-describedby': 'amount-description-helper',
}}
FormHelperTextProps={{
id: 'amount-description-helper',
}}
/>
</Box>
)}
@@ -571,6 +604,12 @@ function FeedingTrackPage() {
onChange={(e) => setNotes(e.target.value)}
sx={{ mb: 3 }}
placeholder={t('feeding.placeholders.notes')}
inputProps={{
'aria-describedby': 'notes-helper',
}}
FormHelperTextProps={{
id: 'notes-helper',
}}
/>
{/* Submit Button */}