Skip to content

[EuiDatePicker] Remove legacy string refs from react-datepicker dropdowns - #9960

Open
ChrisJamesC wants to merge 1 commit into
elastic:mainfrom
ChrisJamesC:fix/react19-datepicker-string-refs
Open

[EuiDatePicker] Remove legacy string refs from react-datepicker dropdowns#9960
ChrisJamesC wants to merge 1 commit into
elastic:mainfrom
ChrisJamesC:fix/react19-datepicker-string-refs

Conversation

@ChrisJamesC

Copy link
Copy Markdown

Summary

What: Removes three legacy string refs (ref="options") from the vendored react-datepicker dropdown components.

Why: Fixes #9009. On React 19, opening the month, year, or month/year dropdown throws during render:

Uncaught Error: Expected ref to be a function, an object returned by React.createRef(), or undefined/null.

React 19 removed legacy string refs. Because the throw happens in markRef during updateClassComponent, React unmounts the whole tree — so this takes down the consuming application, not just the date picker.

How: The offending props are in packages/eui/src/components/date_picker/react-datepicker/src/:

File Element
month_dropdown.js <MonthDropdownOptions ref="options">
year_dropdown.js <YearDropdownOptions ref="options">
month_year_dropdown.js <MonthYearDropdownOptions ref="options">

All three are dead code rather than something needing migration to callback refs — this.refs is not read anywhere in the package:

$ grep -rn 'this\.refs' packages/eui/src/
(no matches)

They appear to be residue from the upstream fork in #5339. Deleting them is therefore behaviour-preserving, which is why this is a deletion rather than a useRef/callback-ref migration.

Worth noting for reviewers: these files match an ESLint ignore pattern, so react/no-string-refs never had a chance to flag them. That's likely why they survived this long.

API Changes

None — no public prop, type, or token changes.

component / parent prop / child change description
No public API change

Screenshots

Not applicable — no visual change. On React 16–18 the rendered output is byte-identical (all 42 existing date_picker snapshots pass unmodified). On React 19 the difference is "throws" vs. "works", which isn't meaningfully screenshottable.

Impact Assessment

  • 🔴 Breaking changes — None. No public API surface is touched.
  • 💅 Visual changes — None. Snapshots unchanged.
  • 🧪 Test impact — None. No HTML structure, class name, or default value changes.
  • 🔧 Hard to integrate — No Kibana changes required.

Impact level: 🟢 None

Release Readiness

  • Documentation — no documented behaviour changes.
  • Figma — no design changes.
  • Migration guide — no breaking or visual changes.
  • Adoption plan — bug fix, not a new feature.

QA instructions for reviewer

On React 16–18 (current supported range), this should be a no-op:

  • Open the EuiDatePicker docs or Storybook.
  • Confirm the month and year dropdowns still open, scroll, and select correctly (dropdownMode="scroll", the default).
  • Confirm dropdownMode="select" is unaffected.
  • Confirm EuiSuperDatePicker's absolute tab still works.

To verify the actual fix, a React 19 environment is required: render <EuiDatePicker showMonthDropdown showYearDropdown /> and open either dropdown. Before this change it throws; after, it behaves normally.

Checklist before marking Ready for Review

  • Filled out all sections above

  • QA: Tested light/dark modes, high contrast, mobile, Chrome/Safari/Edge/Firefox, keyboard-only, screen reader — not done; deletion of an unread ref with no rendered-output change

  • QA: Tested in CodeSandbox and Kibana — not done, happy to if the team wants it

  • QA: Tested docs changes — no docs changes

  • Tests: yarn test-unit src/components/date_picker — 18/18 suites, 188 passed, 1 skipped, 42 snapshots unchanged

    No new regression test: EUI's Jest environment runs React 18, where string refs still work, so the failure this fixes cannot be reproduced in the current test setup. A meaningful regression test depends on the React 19 test environment tracked in [Epic] React 19 support #8720.

  • Changelog: Added

  • Breaking changes: Added breaking change label — not applicable


Scope note: this does not make EUI React 19 compatible overall (#8720, #7774). It removes one hard crash. EuiFieldSearch (#9587) is still open, and the <StrictMode> work in #7774 is unaffected by this change.

@ChrisJamesC
ChrisJamesC requested a review from a team as a code owner August 27, 2026 09:11
@github-actions

Copy link
Copy Markdown

👋 Since this is a community submitted pull request, a Buildkite build has not been started automatically. Would an Elastic organization member please verify the contents of this pull request and kick off a build manually?

@github-actions github-actions Bot added the community contribution (Don't delete - used for automation) label Aug 27, 2026
ChrisJamesC added a commit to ChrisJamesC/eui that referenced this pull request Aug 27, 2026
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…owns

React 19 removed support for legacy string refs. Rendering the month,
year, or month-year dropdown therefore throws "Expected ref to be a
function, an object returned by React.createRef(), or undefined/null"
and unmounts the surrounding tree, making EuiDatePicker unusable on
React 19 whenever showMonthDropdown / showYearDropdown is enabled.

The `ref="options"` props are dead code: `this.refs` is not read
anywhere in packages/eui/src, so removing them is behaviour-preserving.
Existing date_picker snapshots are unchanged.

Fixes elastic#9009

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@ChrisJamesC
ChrisJamesC force-pushed the fix/react19-datepicker-string-refs branch from bd1259b to 24fee02 Compare August 27, 2026 10:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community contribution (Don't delete - used for automation)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[React 19][EuiDatepicker] Errors out in React 19

1 participant