React 19 upgrade#4428
Open
lbwexler wants to merge 20 commits into
Open
Conversation
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.
# Conflicts: # CHANGELOG.md # package.json
# Conflicts: # CHANGELOG.md # package.json
# Conflicts: # CHANGELOG.md
TomTirapani
reviewed
Jun 19, 2026
| backdrop = false, | ||
| position = 'auto', | ||
| popoverClassName, | ||
| popperOptions |
Member
There was a problem hiding this comment.
Are we using popperOptions anywhere? I doubt it, but worth it to confirm?
Member
Author
There was a problem hiding this comment.
or just look at our flagship mobile apps directly
| const elemRef = useRef(null); | ||
| const boolProps = mapKeys( | ||
| pickBy(props, it => typeof it === 'boolean'), | ||
| (_v, key) => ONSEN_BOOL_ALIASES[key] ?? key |
Member
There was a problem hiding this comment.
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?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.
developbranch as of last change.breaking-changelabel + CHANGELOG if so.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.