Skip to content

Input component renders an error message that is never linked to the field #35

Description

@royalpinto007

What is wrong

components/ui/Input.tsx accepts an error prop and renders it, but nothing connects the message to the field:

{error && <p className="mt-1 text-xs text-accent">{error}</p>}

The <input> gets a red border and that is all. There is no aria-invalid, and no aria-describedby pointing at the error text. A screen reader user tabbing into a failed field hears the label and nothing else, and the error paragraph is only reachable by arrowing past the input in browse mode. The colour-only border is also the sole visual signal, which is exactly the pattern WCAG 1.4.1 rules out.

The same applies to the prefix and suffix spans: they render meaningful text such as a currency or unit marker but are not part of the field's accessible name or description.

What to change

In components/ui/Input.tsx:

  1. Generate a stable id for the component. React 18 is already a dependency, so const reactId = useId(); is the right tool. Respect a caller-supplied props.id when there is one, and fall back to the generated value.
  2. Derive const errorId = ${id}-error; and put it on the error <p>.
  3. On the <input>, add aria-invalid={error ? true : undefined} and aria-describedby set to errorId when there is an error. Merge rather than clobber any aria-describedby the caller passed in.
  4. Give the error paragraph role="alert" so it is announced when it appears after a submit attempt.
  5. Mark the prefix and suffix spans aria-hidden="true" if they are decorative, or fold them into the description if they carry meaning. Pick one and say which in the PR.

Input is a forwardRef component, so keep the existing signature and ref forwarding intact.

Where it shows up

components/post/SubmitForm.tsx and components/post/EditCaseForm.tsx are the main consumers, so this fixes the accessibility of the submission flow, which is the single most important form on the site. No visual change should result.

Verify

npx tsc --noEmit
npm run lint
npm run format

Then trigger a validation error on /submit and confirm with a screen reader, or with the browser accessibility inspector, that the input is marked invalid and describes the error text.

Comment here to claim it and ask anything you are unsure about. You will usually get a reply within a day.

Metadata

Metadata

Assignees

No one assigned

    Labels

    claimedSomeone asked first and is working on thisenhancementNew feature or requestgood first issueGood for newcomers

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions