Skip to content

fix(DatePicker): error handling & a11y polish - #3395

Open
aresnik11 wants to merge 4 commits into
mainfrom
ajr-datepicker-polish-new
Open

fix(DatePicker): error handling & a11y polish#3395
aresnik11 wants to merge 4 commits into
mainfrom
ajr-datepicker-polish-new

Conversation

@aresnik11

@aresnik11 aresnik11 commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Overview

Adds per-input validation error messages to DatePicker:

  • Per-input errors — each DatePickerInput manages its own error, so range mode shows independent messages for the start and end inputs. Typed dates are validated on change and blur; invalid input stays visible until corrected.
  • No-shift input layout — the error renders via FormError's absolute variant so the input never changes height: the range-mode arrow stays aligned and no space is reserved when there's no error.
  • Calendar offset — the popover shifts down only when it's open and an error exists (via a hasError context flag); closed-state spacing is unchanged.
  • Validation util — detects incomplete entries, invalid month/day, date rollover (e.g. Feb 30), and disabled dates, range with disabled dates.
  • Localizable strings — new DatePickerTranslations keys for each error message, with English defaults.

Also adds some calendar/input accessibility refinements:

  • Announce full weekday names in calendar headers instead of abbreviations
  • Associate the field label with the segment shell via aria-labelledby
  • Convert the presentational calendar icon to an IconButton with an openCalendarLabel translation

There are definitely some bugs so let me know what you find! Also lmk what the error messages should be and if we want any more generic.

PR Checklist

  • Related to designs:
  • Related to JIRA ticket: GMT-1650, [GMT-1651], [GMT-1652], [GMT-1646]
  • Version plan added/updated (or not needed)
  • I have run this code to verify it works
  • This PR includes unit tests for the code change
  • This PR includes testing instructions tests for the code change
  • The alpha package of this PR is passing end-to-end tests in all relevant Codecademy repositories

Testing Instructions

Single mode

  1. Type 2/30/2024 and blur → shows "February does not have 30 days".
  2. Correct to 2/28/2024 → error clears and the date commits.
  3. Open/close the calendar several times → spacing above it stays consistent.
  4. With a disableDate prop, type a disabled date → shows "This date is not available".

Range mode

  1. Start input: type 2/30/2024 → error appears under the start input only.
  2. End input: type an invalid date → a separate error appears under the end input.
  3. Confirm the arrow separator does not move when errors appear/disappear.
  4. Correct the start date → start error clears while the end error (if any) remains.
  5. In a story with disabled dates, type a start date before the blocked date and an end date after it (a range that spans the disabled day).
  6. Confirm the error message "This date range contains unavailable dates" appears under the input; the previously committed selection is left unchanged (not silently cleared).
  7. Change the end date so the range no longer crosses the blocked date.
  8. Confirm error clears

Calendar + spacing

  1. Open the calendar with no error and note the spacing above it.
  2. Trigger an error while it's open → the calendar shifts down so the error is visible.
  3. Close and reopen → spacing matches step 9 (no drift).

Accessibility

  1. Each error announces via its role="alert" region; start/end errors announce independently.
  2. aria-invalid toggles on each input as its error state changes.
  3. Calendar weekday headers announce full weekday names (e.g. "Monday").

PR Links and Envs

Repository PR Link
Monolith Monolith PR
Mono Mono PR

… button

- Announce full weekday names in calendar headers instead of abbreviations
- Associate the field label with the segment shell via aria-labelledby
- Convert the presentational calendar icon to an IconButton with an
  openCalendarLabel translation

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@nx-cloud

nx-cloud Bot commented Jul 7, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit 6e5803a


☁️ Nx Cloud last updated this comment at 2026-08-05 17:31:00 UTC

@nx-cloud

nx-cloud Bot commented Jul 7, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit 81bac52


☁️ Nx Cloud last updated this comment at 2026-07-07 19:14:44 UTC

@codecov

codecov Bot commented Jul 7, 2026

Copy link
Copy Markdown

⚠️ JUnit XML file not found

The CLI was unable to find any JUnit XML files to upload.
For more help, visit our troubleshooting guide.

Move error state to each DatePickerInput so start/end inputs in range
mode surface independent messages. Render the error via FormError's
`absolute` variant so it sits out of layout flow — the input never
changes height, keeping the range-mode arrow aligned and reserving no
space when there is no error. The calendar popover still shifts down
(y=0) only when open and an error exists, via a boolean `hasError`
context signal.

Validate typed dates (incomplete, invalid month/day, rollover, disabled
dates) through a shared validateSegments util and localizable
translation keys.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@aresnik11 aresnik11 changed the title fix(DatePicker): a11y polish for weekday headers, label, and calendar… fix(DatePicker): error handling & a11y polish Jul 13, 2026
Wire validateDateRange into the typed-commit path so a range spanning a
disabled date shows an error instead of silently resetting; dedupe its
span check onto rangeContainsDisabled. Also clean up pre-existing lint.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@aresnik11
aresnik11 marked this pull request as ready for review August 5, 2026 17:28
@aresnik11
aresnik11 requested a review from a team as a code owner August 5, 2026 17:28
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

@codecademydev

Copy link
Copy Markdown
Collaborator

📬 Published Alpha Packages:

Package Version npm Diff
@codecademy/gamut 72.5.1-alpha.7ca70c.0 npm diff
@codecademy/gamut-icons 9.57.12-alpha.7ca70c.0 npm diff
@codecademy/gamut-illustrations 0.58.17-alpha.7ca70c.0 npm diff
@codecademy/gamut-kit 3.0.14-alpha.7ca70c.0 npm diff
@codecademy/gamut-patterns 0.10.36-alpha.7ca70c.0 npm diff
@codecademy/gamut-styles 20.1.1-alpha.7ca70c.0 npm diff
@codecademy/gamut-tests 6.0.7-alpha.7ca70c.0 npm diff
@codecademy/variance 0.26.2-alpha.7ca70c.0 npm diff
eslint-plugin-gamut 2.4.4-alpha.7ca70c.0 npm diff

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants