fix: Improve form error feedback accessibility#1120
Conversation
|
@web3blind is attempting to deploy a commit to the vetswhocode-web-app Team on Vercel. A member of the Team first needs to authorize it. |
There was a problem hiding this comment.
Pull request overview
This PR improves accessibility of shared form elements by ensuring validation errors are programmatically associated with their corresponding inputs/textareas and announced by assistive technology.
Changes:
- Add
feedbackIdsupport and generate stable error-message IDs for form elements. - Mark error feedback as
role="alert"and wirearia-invalid/aria-describedbyonInputandTextarea. - Add unit tests validating the default error ID/linking behavior for
InputandTextarea.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
src/components/ui/form-elements/types.ts |
Adds a new feedbackId prop to shared input props to support stable error message IDs. |
src/components/ui/form-elements/input.tsx |
Sets aria-invalid/aria-describedby and assigns an ID to the rendered error feedback. |
src/components/ui/form-elements/textarea.tsx |
Mirrors Input accessibility wiring for textarea error feedback. |
src/components/ui/form-elements/feedback.tsx |
Adds optional id and announces error feedback via role="alert". |
src/components/ui/form-elements/__tests__/accessible-feedback.test.tsx |
Adds tests asserting default ${id}-error linkage and alert role behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| export interface IInputProps extends IFeedback { | ||
| className?: string; | ||
| disabled?: boolean; | ||
| readonly?: boolean; | ||
| feedbackText?: string; | ||
| feedbackId?: string; | ||
| id: string; |
| describe("form element error feedback accessibility", () => { | ||
| it("connects input errors with aria-describedby and alert feedback", () => { | ||
| render( | ||
| <Input | ||
| id="email" | ||
| name="email" | ||
| state="error" | ||
| feedbackText="Enter a valid email address" | ||
| /> | ||
| ); | ||
|
|
||
| const input = screen.getByRole("textbox"); | ||
| const alert = screen.getByRole("alert"); | ||
|
|
||
| expect(input).toHaveAttribute("aria-invalid", "true"); | ||
| expect(input).toHaveAttribute("aria-describedby", "email-error"); | ||
| expect(alert).toHaveAttribute("id", "email-error"); | ||
| expect(alert).toHaveTextContent("Enter a valid email address"); | ||
| }); |
|
Updated the PR to address the Copilot feedback around
Local validation:
Note: the Vercel status is still blocked by the existing Vercel team authorization gate, not by a build log from this change. |
|
Withdrawing this stale accessibility PR as part of fork cleanup. Thanks for the consideration. |
Summary
role="alert"so screen readers announce validation errors.aria-describedbyandaria-invalid.InputandTextareacomponents.Accessibility impact
This improves the shared form components used across application forms. When a field has validation feedback, assistive technology can now identify the field as invalid and read the matching error message.
Relates to #895.
Validation
npm test -- src/components/ui/form-elements/__tests__/accessible-feedback.test.tsx— passednpx biome check src/components/ui/form-elements/__tests__/accessible-feedback.test.tsx src/components/ui/form-elements/feedback.tsx src/components/ui/form-elements/input.tsx src/components/ui/form-elements/textarea.tsx src/components/ui/form-elements/types.ts— passed with existing complexity warnings ininput.tsxandtextarea.tsxnpm run typecheck— blocked by pre-existing unrelated test typing errors in__tests__/lib/j0di3and__tests__/pages/api/j0di3