Skip to content

[Bug]: DatePicker: typing a valid date fills the input but does not call onChange #23122

Description

@MartinCernikSG

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.

  1. User types a valid date (we use dateFormat="d.m.Y", e.g. 15.07.2026).
  2. User clicks the modal primary button without pressing Enter.
  3. The input still shows the typed date.
  4. 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:

  1. 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.
  2. 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)

  1. Open https://react.carbondesignsystem.com/?path=/story/components-datepicker--single-with-calendar
  2. Open the Actions panel.
  3. 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.
  4. Observe: the input shows the date, but onChange is not logged.
  5. Press Enter or click outside the field. onChange may fire only now.
  6. 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:

  1. Type 15.07.2026 into Date Picker. Do not use the calendar and do not press Enter.
  2. Click Submit.
  3. The input still shows 15.07.2026.
  4. The page reports onChange was never called and the submitted value is empty.
  5. 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

Metadata

Metadata

Assignees

No one assigned

    Type

    Fields

    Severity

    Medium

    Projects

    Status
    🕵️‍♀️ Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions