fix(bottom-sheet): stop keyboard disappearing after sheet dismissal - #21471
fix(bottom-sheet): stop keyboard disappearing after sheet dismissal#21471claudiiafg wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
🟢 Approval recommended
The behavioral change is narrowly scoped, matches the described root cause, and is covered by targeted regression tests for both relevant branches.
Pull request overview
This PR fixes a Mobile keyboard race where a QueuedBottomSheet could dismiss the keyboard twice: once at close-start and again later when Gorhom’s onDismiss callback finally fires, unintentionally hiding the keyboard that a newly opened sheet just raised.
Changes:
- Update
handleDismissto only retract the keyboard when the dismissal bypasses the close animation (i.e., when the sheet is still"open"). - Add regression tests covering both the “bypass close animation” branch and the “orderly close then late onDismiss” branch.
- Add a changeset to publish the fix as a patch for the shared package and Mobile app.
File summaries
| File | Description |
|---|---|
| shared/ui-queued-bottom-sheet/src/internals/useQueuedBottomSheet.native.ts | Avoids late onDismiss keyboard dismissal after an orderly close to prevent stealing focus from the next sheet. |
| shared/ui-queued-bottom-sheet/src/internals/useQueuedBottomSheet.native.test.ts | Adds tests to pin keyboard-dismiss behavior for bypassed-close vs orderly-close scenarios. |
| .changeset/LIVE-36689-edit-contact-keyboard.md | Declares patch releases for the shared bottom-sheet package and live-mobile. |
Review details
- Files reviewed: 3/3 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Web Tools Build Status
|
Rsdoctor Bundle Diff AnalysisFound 7 projects in monorepo, 1 project with changes. 📊 Quick Summary
📋 Detailed Reports (Click to expand)📁 mobilePath:
📦 Download Diff Report: mobile Bundle Diff Generated by Rsdoctor GitHub Action |
|



📝 Description
Previous behaviour: on Mobile, tapping
Edit contact > Edit Nameopened the rename drawer with the keyboard, and the keyboard then vanished instantly. The sheet stayed open and correctly sized; tapping the name field brought the keyboard back and it stayed.Cause: a
QueuedBottomSheetretracted the keyboard twice on its way out — once when the close animation starts (handleClose/handleAnimate) and again unconditionally when gorhom'sonDismisslanded.Keyboard.dismiss()is global, not scoped to the calling sheet.Tapping "Edit name" closes the actions-menu sheet and opens the rename drawer in the same React commit. The actions menu retracted the keyboard at close-start (a no-op — nothing was focused yet), the rename drawer then opened and focused its field so the keyboard rose, and only afterwards did the actions menu's
onDismissarrive and pull that keyboard down. That callback can land hundreds of milliseconds late, which is why the hook already carries a 600 msDISMISS_FALLBACK_DELAY_MSfor the case where it never arrives at all.Fix:
handleDismissnow retracts the keyboard only when the dismissal bypassed the close animation, the one case where nothing has retracted it yet. A dismissal that follows an orderly close leaves the keyboard alone, so it can no longer steal focus from the sheet that replaced it.This is the same class of bug the legacy drawer fixed with its
preventKeyboardDismissOnCloseopt-out; the shared queued-sheet package had no equivalent guard. Fixing it in the shared hook covers every sheet-to-sheet hand-off rather than just this flow, and needs no opt-in from callers.Regression cover: two tests in
useQueuedBottomSheet.native.test.tspin both branches — a dismissal that bypasses the close still retracts the keyboard, and one landing after an orderly close leaves it alone.Checked against the earlier LIVE-35853 fix, where retracting the keyboard as an edit-address sheet closes is needed so the sheet underneath lays out correctly: that retraction happens at close-start and is untouched.
I deliberately did not add a focus retry to
ContactNameInput— that would paper over the race rather than remove it.🔗 Context