Skip to content

fix(core): wire aria-describedby and aria-busy on DateTimeInput time input#3716

Open
bhamodi wants to merge 1 commit into
facebook:mainfrom
bhamodi:a11y/datetimeinput-time-describedby
Open

fix(core): wire aria-describedby and aria-busy on DateTimeInput time input#3716
bhamodi wants to merge 1 commit into
facebook:mainfrom
bhamodi:a11y/datetimeinput-time-describedby

Conversation

@bhamodi

@bhamodi bhamodi commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Summary

In packages/core/src/DateTimeInput/DateTimeInput.tsx the field's description, status message, and disabled-reason are collected into a single ariaDescribedBy string (around line 478), and the field's busy state into isBusy (line 444). The date input wires both: aria-describedby={ariaDescribedBy} (line 911) and aria-busy={isBusy || undefined} (line 916). The embedded time input (around lines 973-999) set aria-label, aria-required, aria-invalid, and aria-disabled — but neither aria-describedby nor aria-busy.

Both halves live under one Field label, so the description, status message, and disabled message describe the whole control. Because only the date input carried aria-describedby, a screen-reader user who tabbed into the time half lost access to all three, and never heard the field announced as busy during an async change. This is a WCAG 1.3.1 Info and Relationships gap for the time input.

The fix adds the same two attributes to the time input, reusing the existing ariaDescribedBy and isBusy values so the two halves stay in parity.

Changes

  • packages/core/src/DateTimeInput/DateTimeInput.tsx: add aria-describedby={ariaDescribedBy} and aria-busy={isBusy || undefined} to the time <input>.
  • packages/core/src/DateTimeInput/DateTimeInput.test.tsx: added tests asserting the time input's aria-describedby resolves to the description, the status message, and the disabled reason, plus aria-busy parity with the date input (set when isLoading, absent otherwise).

Test plan

  • node_modules/.bin/vitest run --root . packages/core/src/DateTimeInput62 pass (was 58), including the 5 new tests.
  • Confirmed failing-first: ran the new tests before the fix — the three aria-describedby tests and the aria-busy time-input test all failed (aria-describedby/aria-busy was null on the time input), proving they catch the gap.
  • node_modules/.bin/tsc --project packages/core/tsconfig.json --noEmit — clean.
  • node_modules/.bin/eslint packages/core/src/DateTimeInput/DateTimeInput.tsx packages/core/src/DateTimeInput/DateTimeInput.test.tsx — clean.

Notes

Found during a broader a11y audit of the DateTimeInput component. Scoped to these two attributes on the time input plus tests. DateTimeInput.doc.mjs doesn't document aria-describedby/aria-busy, so no doc change was needed.

@vercel

vercel Bot commented Jul 9, 2026

Copy link
Copy Markdown

@bhamodi is attempting to deploy a commit to the Meta Open Source Team on Vercel.

A member of the Team first needs to authorize it.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Jul 9, 2026
@bhamodi bhamodi force-pushed the a11y/datetimeinput-time-describedby branch from 2b4070e to 6d7e9f2 Compare July 9, 2026 05:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant