-
Notifications
You must be signed in to change notification settings - Fork 7
Frontend/enhance form input accessibility #927
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Frontend/enhance form input accessibility #927
Conversation
## Walkthrough
This update introduces enhanced accessibility features across multiple form input components by adding ARIA attributes and improving error message semantics. It also centralizes date format validation patterns, applies stricter date validation with user-friendly error messages, and updates relevant tests, localization files, and submit button behavior for improved feedback and compliance.
## Changes
| Files/Groups | Change Summary |
|-------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Input components: InputCheckbox.vue, InputDate.vue, InputEmailList.vue, InputFile.vue, InputPassword.vue, InputPhone.vue, InputRange.vue, InputSelect.vue, InputText.vue, InputTextarea.vue | Added ARIA attributes (`aria-describedby`, `aria-errormessage`, `aria-invalid`) and improved error message spans with IDs, `role="alert"`, and `aria-live="assertive"` for better accessibility. |
| InputSubmit/InputSubmit.vue | Refined conditional rendering of success/error messages; added ARIA roles and dynamic IDs; linked submit input to messages via ARIA attributes for accessibility. |
| Forms/InputDate/InputDate.ts | Centralized validation logic, improved keyboard focus handling, added escape key handler, and reorganized code for clarity. |
| Forms/_mixins/form.mixin.ts | Added `dateWithFormat` to `joiMessages` for localized, format-specific date validation errors. |
| LicenseCard.ts, PrivilegeCard.ts, RegisterLicensee.ts | Applied stricter date format validation for relevant form inputs using centralized regex patterns and format-specific error messages; updated mockPopulate to use `await nextTick()` before validation. |
| RegisterLicensee.vue | Switched form submit buttons from `InputButton` to `InputSubmit` and updated bindings accordingly. |
| app.config.ts | Introduced exported `dateFormatPatterns` object with regexes for `MM/DD/YYYY` and `YYYY-MM-DD` formats. |
| locales/en.json, locales/es.json | Added new localized error message key for invalid date with format. |
| Forms/InputDate/InputDate.spec.ts | Added test to verify validation uses `localValue` and correct error messages for date input. |
## Sequence Diagram(s)
```mermaid
sequenceDiagram
participant User
participant InputComponent
participant ScreenReader
User->>InputComponent: Enter value (e.g., date, email, etc.)
InputComponent->>InputComponent: Validate input (using centralized patterns/messages)
alt Error detected
InputComponent->>ScreenReader: Announce error via aria attributes (role="alert", aria-live="assertive")
else Valid input
InputComponent->>ScreenReader: Announce success or no error
endEstimated code review effort3 (~45 minutes) Assessment against linked issues
Suggested reviewers
Poem
|
jsandoval81
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice job - I like the extra focus on a11y 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
webroot/src/models/FormInput/FormInput.model.ts (1)
142-142: Improve type safety for the altValue parameter.The
altValueparameter is typed asany, which reduces type safety. Consider using a more specific type that matches the expected value types for form inputs.- public validate(altValue?: any): void { + public validate(altValue?: string | number | boolean | null | Array<File> | Array<string>): void {This aligns with the
valueproperty type defined in theInterfaceFormInputinterface (line 22).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
webroot/src/components/Forms/InputDate/InputDate.ts(6 hunks)webroot/src/models/FormInput/FormInput.model.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- webroot/src/components/Forms/InputDate/InputDate.ts
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: landonshumway-ia
PR: csg-org/CompactConnect#848
File: backend/compact-connect/lambdas/python/provider-data-v1/handlers/registration.py:111-117
Timestamp: 2025-06-17T19:05:36.255Z
Learning: In CompactConnect PR #848, the user landonshumway-ia decided to leave timezone handling code in _should_allow_reregistration function as-is after testing in sandbox environment confirmed it works correctly. The user's reasoning was that reregistration is an edge case, the code has been tested and verified, and AWS is unlikely to change behavior that would break many clients. This represents a pragmatic engineering decision based on testing and risk assessment.
Learnt from: jsandoval81
PR: csg-org/CompactConnect#873
File: webroot/src/styles.common/_inputs.less:115-118
Timestamp: 2025-06-24T00:17:31.188Z
Learning: The team intentionally uses broad CSS selectors like `.dp__input_wrap div { position: static; }` to fix styling issues with the Vue Date-Picker library. They have experience with these styles working well, keep the library version pinned in yarn.lock, and have established processes to re-test everything when updating the library version. This approach is acceptable given their testing discipline and version control.
Learnt from: rmolinares
PR: csg-org/CompactConnect#843
File: webroot/src/components/Forms/InputDate/InputDate.ts:0-0
Timestamp: 2025-06-04T22:04:14.373Z
Learning: In the InputDate component (webroot/src/components/Forms/InputDate/InputDate.ts), immediate validation on every keystroke is intentional design behavior. The team prefers to alert users to encourage expected date format completion rather than deferring validation until the date is complete. This provides immediate feedback to guide users toward proper MM/dd/yyyy format completion.
Learnt from: jsandoval81
PR: csg-org/CompactConnect#922
File: webroot/src/components/UserAccount/UserAccount.ts:0-0
Timestamp: 2025-07-10T19:50:56.706Z
Learning: In the UserAccount component (webroot/src/components/UserAccount/UserAccount.ts), the email field should be disabled for staff users (`isDisabled: this.isStaff`) to maintain existing restrictions, while licensees should be able to change their email address through the new verification process. This is the intended behavior per PR #922 requirements.
Learnt from: jsandoval81
PR: csg-org/CompactConnect#873
File: webroot/src/components/PrivilegeCard/PrivilegeCard.ts:0-0
Timestamp: 2025-06-19T23:43:25.512Z
Learning: In Vue form components, when programmatically setting form input values, it's more efficient to validate just the specific form element being updated (e.g., `formInput.validate()`) rather than calling `validateAll()` on the entire form.
webroot/src/models/FormInput/FormInput.model.ts (2)
Learnt from: jsandoval81
PR: csg-org/CompactConnect#873
File: webroot/src/components/PrivilegeCard/PrivilegeCard.ts:0-0
Timestamp: 2025-06-19T23:43:25.512Z
Learning: In Vue form components, when programmatically setting form input values, it's more efficient to validate just the specific form element being updated (e.g., `formInput.validate()`) rather than calling `validateAll()` on the entire form.
Learnt from: rmolinares
PR: csg-org/CompactConnect#843
File: webroot/src/components/Forms/InputDate/InputDate.ts:0-0
Timestamp: 2025-06-04T22:04:14.373Z
Learning: In the InputDate component (webroot/src/components/Forms/InputDate/InputDate.ts), immediate validation on every keystroke is intentional design behavior. The team prefers to alert users to encourage expected date format completion rather than deferring validation until the date is complete. This provides immediate feedback to guide users toward proper MM/dd/yyyy format completion.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: CheckWebroot
🔇 Additional comments (2)
webroot/src/models/FormInput/FormInput.model.ts (2)
145-145: Logic implementation looks correct.The conditional logic properly determines which value to use for validation - the provided
altValuewhen defined, otherwise falling back to the instance'svalueproperty.
148-148: Validation logic correctly uses the determined value.The validation now properly uses the
valuevariable (which contains eitheraltValueorthis.value) instead of always usingthis.value.
jsandoval81
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm getting some odd results in UI testing:
- When I pick an initial date using the calendar picker, the date populates but the field is marked as error with "Required field"
- When I manually enter an invalid date format and correctly trigger the validation error, then use the calendar picker to select a valid date, the error of "Date must be of required format MM/DD/YYYY" remains
Not sure if it's something with the blur event and / or the value change event. The issue happens in both places I tested (registration DOB and encumbrance dates).
|
@jsandoval81 I had to adjust the It also turns out the solution we came up with to modify existing generic input validation needed a similar but different approach. The solution was working when we were validating individual date inputs but upon form submission the It's essentially the same except leveraging the model property itself versus a param. It can also be reused in the future by other inputs if needed. I've also updated the tests and improved the mock data for exists date inputs. |
|
@jlkravitz This is ready for your review. |
jlkravitz
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! Thanks for working on this.
While testing, I noticed that voiceover/screen readers don't seem to read out the state options on this page:
Out of scope here, but just flagging.
@isabeleliassen good to merge!
Requirements List
Description List
Testing List
yarn test:unit:allshould run without errors or warningsyarn serveshould run without errors or warningsyarn buildshould run without errors or warningstype="submit"escon the keyboardtabonce to begin focus on the first element of the UICloses #900
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Tests
Chores