Package
@carbon/react
Browser
Chrome, Firefox, Edge, Safari
Package version
1.106.0
React version
19.2.8
Description
What happens
DatePicker (datePickerType="single", allowInput defaulting to true) shows a typed date in the text field, but onChange on DatePicker is not called. A surrounding controlled form therefore still has undefined / null and shows a required/invalid error even though the field looks filled.
Selecting the same date from the calendar calls onChange immediately and the form is valid.
This is the opposite of other Carbon inputs (TextInput, NumberInput, Select), which update the consumer as soon as the value is complete.
How we hit it
We use DatePicker as a controlled field (React Hook Form Controller + Zod z.date()). The submit action is a Carbon Modal primary button (onRequestSubmit), i.e. outside the input.
- User types a valid date (we use
dateFormat="d.m.Y", e.g. 15.07.2026).
- User clicks the modal primary button without pressing Enter.
- The input still shows the typed date.
- Form validation fails with “required” because
onChange never updated form state.
Picking the date from the calendar does not reproduce this.
Why this looks like a Carbon bug
DatePicker forwards onChange to flatpickr’s onChange hook. That hook fires for calendar selection, and for typed input only after blur or Enter. It does not fire when the typed string becomes a valid date.
Two consequences follow from that:
- Typed vs picked is inconsistent. Calendar selection notifies the parent immediately. Keyboard entry does not, even when the visible value is already a complete, valid date.
- Modal submit races the blur commit. Clicking a Carbon Modal primary button blurs the field and submits in the same turn. React applies the blur
onChange after the submit handler has already run, so validation still sees an empty value. This is the recommended Carbon form+modal pattern, so it is easy to hit.
A second gap makes keyboard entry worse for any non-US format:
Carbon’s built-in parseDate is only installed when dateFormat === "m/d/Y" (source). For d.m.Y / d/m/Y, typed input falls through to flatpickr’s lenient parser, which can invent or reject dates (see #15432, #18931, #21065). #18931 was closed with “pass parseDate yourself”, but:
parseDate is now marked deprecated as a flatpickr passthrough.
- Even with a correct
parseDate, onChange still only fires on blur/Enter, so the modal-submit case remains broken.
Expected behavior
- Typing a complete, valid date should call
DatePicker onChange with that Date, the same way a calendar click does.
- A custom
dateFormat should parse typed input without requiring every consumer to reimplement parseDate.
- Invalid typed input should not silently become a different date.
Workaround we use today (application-level)
We wrap DatePicker and:
- supply our own
parseDate for d.m.Y;
- commit a valid in-range date from
DatePickerInput onInput so the form has the value before submit;
- dedupe the extra
onChange that then arrives from Carbon on blur/Enter.
That works, but it is compensating for DatePicker not treating typed input as a first-class value change.
Related
Reproduction/example
https://stackblitz.com/edit/github-xmshnwfx-lzqictoe?file=src%2FApp.jsx
Steps to reproduce
A. Storybook (no app code)
- Open https://react.carbondesignsystem.com/?path=/story/components-datepicker--single-with-calendar
- Open the Actions panel.
- Click the text field and type a complete valid date with the keyboard. Do not use the calendar. Do not press Enter or blur yet.
- Observe: the input shows the date, but
onChange is not logged.
- Press Enter or click outside the field.
onChange may fire only now.
- Clear the field, then pick the same date from the calendar.
onChange fires immediately.
B. Controlled form + Modal (the failure we see)
Use the StackBlitz snippet https://stackblitz.com/edit/github-xmshnwfx-lzqictoe?file=src%2FApp.jsx.
Then:
- Type
15.07.2026 into Date Picker. Do not use the calendar and do not press Enter.
- Click Submit.
- The input still shows
15.07.2026.
- The page reports
onChange was never called and the submitted value is empty.
- Repeat, but pick the date from the calendar, then Submit.
onChange has the date and submit succeeds.
Optional: change dateFormat to "m/d/Y" and type 07/15/2026. Without a consumer parseDate, blur/Enter is also unreliable.
Suggested Severity
Medium (Severity 3) = User can complete task, and/or has a workaround within the user experience of a given component.
Project name
Swissgrid AG grid management project
Code of Conduct
Package
@carbon/react
Browser
Chrome, Firefox, Edge, Safari
Package version
1.106.0
React version
19.2.8
Description
What happens
DatePicker(datePickerType="single",allowInputdefaulting totrue) shows a typed date in the text field, butonChangeonDatePickeris not called. A surrounding controlled form therefore still hasundefined/nulland shows a required/invalid error even though the field looks filled.Selecting the same date from the calendar calls
onChangeimmediately and the form is valid.This is the opposite of other Carbon inputs (
TextInput,NumberInput,Select), which update the consumer as soon as the value is complete.How we hit it
We use DatePicker as a controlled field (React Hook Form
Controller+ Zodz.date()). The submit action is a CarbonModalprimary button (onRequestSubmit), i.e. outside the input.dateFormat="d.m.Y", e.g.15.07.2026).onChangenever updated form state.Picking the date from the calendar does not reproduce this.
Why this looks like a Carbon bug
DatePickerforwardsonChangeto flatpickr’sonChangehook. That hook fires for calendar selection, and for typed input only after blur or Enter. It does not fire when the typed string becomes a valid date.Two consequences follow from that:
onChangeafter the submit handler has already run, so validation still sees an empty value. This is the recommended Carbon form+modal pattern, so it is easy to hit.A second gap makes keyboard entry worse for any non-US format:
Carbon’s built-in
parseDateis only installed whendateFormat === "m/d/Y"(source). Ford.m.Y/d/m/Y, typed input falls through to flatpickr’s lenient parser, which can invent or reject dates (see #15432, #18931, #21065).#18931was closed with “passparseDateyourself”, but:parseDateis now marked deprecated as a flatpickr passthrough.parseDate,onChangestill only fires on blur/Enter, so the modal-submit case remains broken.Expected behavior
DatePickeronChangewith thatDate, the same way a calendar click does.dateFormatshould parse typed input without requiring every consumer to reimplementparseDate.Workaround we use today (application-level)
We wrap DatePicker and:
parseDateford.m.Y;DatePickerInputonInputso the form has the value before submit;onChangethat then arrives from Carbon on blur/Enter.That works, but it is compensating for DatePicker not treating typed input as a first-class value change.
Related
parseDate”onChangenot firing (calendar path; different from this)onChangefiring twice (we also have to guard for this)Reproduction/example
https://stackblitz.com/edit/github-xmshnwfx-lzqictoe?file=src%2FApp.jsx
Steps to reproduce
A. Storybook (no app code)
onChangeis not logged.onChangemay fire only now.onChangefires immediately.B. Controlled form + Modal (the failure we see)
Use the StackBlitz snippet https://stackblitz.com/edit/github-xmshnwfx-lzqictoe?file=src%2FApp.jsx.
Then:
15.07.2026into Date Picker. Do not use the calendar and do not press Enter.15.07.2026.onChangewas never called and the submitted value is empty.onChangehas the date and submit succeeds.Optional: change
dateFormatto"m/d/Y"and type07/15/2026. Without a consumerparseDate, blur/Enter is also unreliable.Suggested Severity
Medium (Severity 3) = User can complete task, and/or has a workaround within the user experience of a given component.
Project name
Swissgrid AG grid management project
Code of Conduct