Skip to content

React 19 upgrade#4428

Open
lbwexler wants to merge 20 commits into
developfrom
react-19-upgrade
Open

React 19 upgrade#4428
lbwexler wants to merge 20 commits into
developfrom
react-19-upgrade

Conversation

@lbwexler

Copy link
Copy Markdown
Member

Hoist P/R Checklist

Pull request authors: Review and check off the below. Items that do not apply can also be
checked off to indicate they have been considered. If unclear if a step is relevant, please leave
unchecked and note in comments.

  • Caught up with develop branch as of last change.
  • Added CHANGELOG entry, or determined not required.
  • Reviewed for breaking changes, added breaking-change label + CHANGELOG if so.
  • Updated doc comments / prop-types, or determined not required.
  • Reviewed and tested on Mobile, or determined not required.
  • Created Toolbox branch / PR, or determined not required.

If your change is still a WIP, please use the "Create draft pull request" option in the split
button below to indicate it is not ready yet for a final review.

Pull request reviewers: when merging this P/R, please consider using a squash commit to
collapse multiple intermediate commits into a single commit representing the overall feature
change. This helps keep the commit log clean and easy to scan across releases. PRs containing a
single commit should be rebased when possible.

lbwexler added 15 commits June 5, 2026 17:25
findDOMNode is removed in React 19. HoistInputModel.domEl used it as a
fallback for the case where domRef.current resolved to a class-component
instance rather than a DOM element. A trace of all 25 desktop + mobile
HoistInput implementations confirms every one roots domRef on a DOM
element (host element, Blueprint forwardRef control, or react-onsenui's
forwardRef-to-host chain), so the fallback was defensive legacy and is
never exercised. domEl now resolves the element directly from the ref.

Behavior-preserving on React 18; forward-compatible with React 19.
…19 prep)

The legacy Blueprint Popover relies on the removed findDOMNode and breaks
under React 19. PopoverNext (Floating UI based) is its React-19-compatible
replacement, shipped in the same Blueprint build and running on React 18 -
the same approach already used for Overlay2.

The kit Popover wrapper now renders PopoverNext, converting our existing
legacy PopoverProps API via Blueprint's popoverPropsToNextProps helper
(maps position/modifiers/minimal/boundary and preserves the legacy
shouldReturnFocusOnClose=false default). The public popover factory API is
unchanged, so none of the ~20 call sites need edits. Verified no call site
uses an unmappable legacy-only prop (modifiersCustom,
portalStopPropagationEvents, wrapperTagName, targetClassName).
…ct 19 prep)

react-popper (Popper.js) is deprecated, its repo archived, and its peer dep
caps at React 18 - a genuine code incompatibility with React 19. The mobile
Popover was its only consumer.

Swapped usePopper for @floating-ui/react's useFloating, reusing the same
Floating UI library Blueprint's PopoverNext already pulls in (deduped to a
single 0.27.x copy) rather than adding a separate dependency. Placement names
are shared between the two libraries so menuPositionToPlacement is unchanged;
the preventOverflow modifier maps to shift({padding: 10}), 'auto' position
maps to autoPlacement(), and scroll/resize tracking uses autoUpdate.

Removed react-popper as a direct dependency (it remains transitively via
Blueprint's legacy Popover until Blueprint v7) and removed the now-obsolete
Popper.js-specific popperOptions prop from the mobile Popover.
Moves the @types/react@19 code fixes (the non-dependency portion of the
React 19 upgrade) onto this prep branch, since all are forward-compatible -
they compile and lint clean under @types/react@18 and behave identically on
React 18:

- useRef<HTMLDivElement>(null) explicit initial arg (DynamicTabSwitcher)
- cast element props access, now 'unknown' under @types 19 (DashCanvasWidgetChooser)
- type cloneElement child as ReactElement<any> (UseHotkeys, UseContextMenu)
- wrap async ref handler to return void (CodeInput)
- narrow render-fn results to ReactElement (Column editor, Scroller content)

Verified: tsc + eslint clean under @types/react@18.
Bumps react/react-dom (dev) and @types/react/@types/react-dom to 19, widens
the react/react-dom peer range to '~18.2.0 || ^19.0.0', and notes React 19
support in the changelog.

The forward-compatible code fixes this upgrade requires now live on the
react-19 prep branch (this branch is stacked on it), so this commit is the
dependency bump alone. tsc clean under @types/react@19.
Comment thread mobile/cmp/popover/Popover.ts Outdated
backdrop = false,
position = 'auto',
popoverClassName,
popperOptions

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we using popperOptions anywhere? I doubt it, but worth it to confirm?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will check with team

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or just look at our flagship mobile apps directly

Comment thread kit/onsen/index.ts
const elemRef = useRef(null);
const boolProps = mapKeys(
pickBy(props, it => typeof it === 'boolean'),
(_v, key) => ONSEN_BOOL_ALIASES[key] ?? key

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try to reason about this... I'm probably missing something, but wouldn't it be enough to iterate all props (i.e. lose the pickBy), fix the ONSEN_BOOL_ALIASES, and then use those modified props as the input for childProps? Why do we need to apply them after render?

Comment thread kit/blueprint/Wrappers.ts
@amcclain amcclain added this to the v87 milestone Jun 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants