feat(i18n): accessibility - per-field form errors, landmark aria-labels, tests (closes #76)

This commit is contained in:
Hermes
2026-06-04 11:04:06 +00:00
parent 0186de90ec
commit 13a25aded2
10 changed files with 421 additions and 26 deletions

View File

@@ -275,29 +275,41 @@ $gridItems = [
<div class="form-field">
<label for="fname"><?= htmlspecialchars($t('contact.fname'), ENT_QUOTES) ?></label>
<input type="text" id="fname" name="fname" required maxlength="80" autocomplete="given-name"
value="<?= $escapeContactValue($formData['fname'] ?? '') ?>">
value="<?= $escapeContactValue($formData['fname'] ?? '') ?>"
<?= !empty($formFieldErrors['fname']) ? 'aria-invalid="true" aria-describedby="err-fname"' : '' ?>>
<?php if (!empty($formFieldErrors['fname'])): ?>
<p id="err-fname" class="form-field-error"><?= htmlspecialchars($t($formFieldErrors['fname'][0]), ENT_QUOTES) ?></p>
<?php endif; ?>
</div>
<div class="form-field">
<label for="lname"><?= htmlspecialchars($t('contact.lname'), ENT_QUOTES) ?></label>
<input type="text" id="lname" name="lname" required maxlength="80" autocomplete="family-name"
value="<?= $escapeContactValue($formData['lname'] ?? '') ?>">
value="<?= $escapeContactValue($formData['lname'] ?? '') ?>"
<?= !empty($formFieldErrors['lname']) ? 'aria-invalid="true" aria-describedby="err-lname"' : '' ?>>
<?php if (!empty($formFieldErrors['lname'])): ?>
<p id="err-lname" class="form-field-error"><?= htmlspecialchars($t($formFieldErrors['lname'][0]), ENT_QUOTES) ?></p>
<?php endif; ?>
</div>
</div>
</div>
<div class="form-row">
<div class="form-row">
<div class="form-field">
<label for="email"><?= htmlspecialchars($t('contact.email'), ENT_QUOTES) ?></label>
<input type="email" id="email" name="email" required maxlength="120" autocomplete="email"
value="<?= $escapeContactValue($formData['email'] ?? '') ?>">
value="<?= $escapeContactValue($formData['email'] ?? '') ?>"
<?= !empty($formFieldErrors['email']) ? 'aria-invalid="true" aria-describedby="err-email"' : '' ?>>
<?php if (!empty($formFieldErrors['email'])): ?>
<p id="err-email" class="form-field-error"><?= htmlspecialchars($t($formFieldErrors['email'][0]), ENT_QUOTES) ?></p>
<?php endif; ?>
</div>
<div class="form-field">
<label for="phone"><?= htmlspecialchars($t('contact.phone'), ENT_QUOTES) ?></label>
<input type="tel" id="phone" name="phone" maxlength="40" autocomplete="tel"
value="<?= $escapeContactValue($formData['phone'] ?? '') ?>">
</div>
</div>
</div>
<div class="form-field">
<div class="form-field">
<label for="interest"><?= htmlspecialchars($t('contact.interest'), ENT_QUOTES) ?></label>
<select id="interest" name="interest" required>
<?php
@@ -314,13 +326,18 @@ $gridItems = [
</option>
<?php endforeach; ?>
</select>
</div>
</div>
<div class="form-field">
<div class="form-field">
<label for="message"><?= htmlspecialchars($t('contact.message'), ENT_QUOTES) ?></label>
<textarea id="message" name="message" required rows="6" maxlength="2000"
placeholder="<?= htmlspecialchars($t('contact.message'), ENT_QUOTES) ?>"><?= $escapeContactValue($formData['message'] ?? '') ?></textarea>
</div>
placeholder="<?= htmlspecialchars($t('contact.message'), ENT_QUOTES) ?>"
<?= !empty($formFieldErrors['message']) ? 'aria-invalid="true" aria-describedby="err-message"' : ''
?>><?= $escapeContactValue($formData['message'] ?? '') ?></textarea>
<?php if (!empty($formFieldErrors['message'])): ?>
<p id="err-message" class="form-field-error"><?= htmlspecialchars($t($formFieldErrors['message'][0]), ENT_QUOTES) ?></p>
<?php endif; ?>
</div>
<button type="submit" class="form-submit"><?= htmlspecialchars($t('contact.submit'), ENT_QUOTES) ?></button>