Skip to content

Match RN TextInput keyboard-dismiss behavior on taps outside the input #577

Description

@ArnoldsManguzis

Is your feature request related to a problem? Please describe.

With a stock React Native TextInput inside a ScrollView/FlatList, the default keyboardShouldPersistTaps="never" behavior comes for free: tapping outside the focused input dismisses the keyboard, while scrolling behaves according to keyboardDismissMode. EnrichedMarkdownTextInput doesn't participate in this — when it's focused and the user taps elsewhere on the screen (e.g. on the message list above a chat composer), the input keeps focus and the keyboard stays up. RN's responder system can't auto-blur it the way it does the built-in TextInput, presumably because focus/first-responder handling lives entirely in the custom native view and isn't registered with RN's TextInputState tracking.

Describe the solution you'd like

Parity with the built-in TextInput: register the input's focus state with React Native's text-input state tracking (TextInputState / the Fabric focus registry) so that scroll containers' existing keyboardShouldPersistTaps logic treats it exactly like a native TextInput. Plain taps outside the input should blur it and dismiss the keyboard, scrolling should remain possible without dismissing (unless keyboardDismissMode says otherwise), and keyboardShouldPersistTaps="always"/"handled" should keep their usual meaning.

Describe alternatives you've considered

App-level workaround (what we do now): hold the input ref in a provider, expose a dismissKeyboard() action that calls ref.blur(), and wire a tap-gesture handler on the surrounding message list that calls it — while carefully not stealing scroll or item-press gestures. It works, but it's boilerplate every consumer embedding the input in a chat-style screen will need, and it's easy to get subtly wrong (taps on interactive children, tap-vs-scroll discrimination).
An opt-in prop (e.g. blurOnOutsideTap / dismissKeyboardOnTapOutside) implementing the same semantics natively would cover the common case, if full TextInputState integration isn't feasible.

Additional context

Observed with v0.7.4 in an Expo 55 / RN 0.83.6 chat screen where the input sits below a message list. Happy to provide a repro or test builds if useful.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions