fix(client): focused TextInput is hidden by the soft keyboard on android #254

Closed
opened 2026-06-23 16:13:32 +00:00 by james · 0 comments
Owner

Context

On Android, when the soft keyboard opens to focus a TextInput, the keyboard covers the bottom half of the screen and the user can't scroll the UI to see the field they're typing in. The focused input is obscured, and ScrollView's content area doesn't account for the keyboard's height.

This is the classic React Native keyboard-avoidance gap — RN doesn't automatically push the focused field into view on Android (iOS has more native plumbing for this). The standard fix is to wrap form screens in KeyboardAvoidingView with behavior="padding" (or "height" on Android), or to use react-native-keyboard-aware-scroll-view which handles the inset + auto-scroll-to-focused-input in one shot.

Affected screens (any with TextInput at or below the middle of the viewport):

  • /login
  • /register
  • /server-setup
  • /(app)/profile (Basics card, contacts add row)
  • /(app)/notes (create form)
  • /(app)/skills (add-section, add-skill, rename inputs)
  • /(app)/experience (Jobs, Education, Contracts edit forms)
  • /(app)/account (PAT create form)

Source

User-reported (June 2026).

Approach

Two options:

A. KeyboardAvoidingView on each screen. RN built-in, no new dep. Per-screen wrapping adds boilerplate.

B. react-native-keyboard-controller or react-native-keyboard-aware-scroll-view. Third-party libs that handle the cross-platform quirks + auto-scroll the focused input into view. Drop-in replacement for ScrollView.

Recommendation: B with react-native-keyboard-controller — modern, actively maintained, ships with KeyboardAwareScrollView that handles iOS + Android consistently and auto-scrolls. The legacy react-native-keyboard-aware-scroll-view is also fine but less actively maintained. Bundle cost is acceptable for a load-bearing UX gap.

Scope

  • Add react-native-keyboard-controller (or chosen lib) to apps/client/.
  • Wrap each form-bearing screen's outer ScrollView with KeyboardAwareScrollView (or equivalent).
  • Verify on Android via Expo Go: focus each TextInput on each screen, confirm the field stays visible above the keyboard.
  • No web regression — react-native-keyboard-controller ships a no-op web shim per its docs.

Acceptance criteria

  • Focusing any TextInput on Android scrolls the field into view above the keyboard.
  • Web behaviour unchanged.
  • No new manifest permissions.
  • Manual smoke on Android via Expo Go for each affected screen.

Out of scope

  • iOS-specific tuning (out of scope per idea.md).
  • A bottom-anchored submit button that lifts with the keyboard — separate UX polish.
  • Replacing every ScrollView in the app — only form-bearing screens need the treatment.

Composes with

  • #176 — universal client work.
  • #234 — native E2E smoke. Adding a "type into a field below the fold" step to the Maestro flow would catch this class of regression.
## Context On Android, when the soft keyboard opens to focus a `TextInput`, the keyboard covers the bottom half of the screen and the user can't scroll the UI to see the field they're typing in. The focused input is obscured, and ScrollView's content area doesn't account for the keyboard's height. This is the classic React Native keyboard-avoidance gap — RN doesn't automatically push the focused field into view on Android (iOS has more native plumbing for this). The standard fix is to wrap form screens in `KeyboardAvoidingView` with `behavior="padding"` (or `"height"` on Android), or to use `react-native-keyboard-aware-scroll-view` which handles the inset + auto-scroll-to-focused-input in one shot. Affected screens (any with TextInput at or below the middle of the viewport): - `/login` - `/register` - `/server-setup` - `/(app)/profile` (Basics card, contacts add row) - `/(app)/notes` (create form) - `/(app)/skills` (add-section, add-skill, rename inputs) - `/(app)/experience` (Jobs, Education, Contracts edit forms) - `/(app)/account` (PAT create form) ## Source User-reported (June 2026). ## Approach Two options: A. **`KeyboardAvoidingView` on each screen.** RN built-in, no new dep. Per-screen wrapping adds boilerplate. B. **`react-native-keyboard-controller` or `react-native-keyboard-aware-scroll-view`.** Third-party libs that handle the cross-platform quirks + auto-scroll the focused input into view. Drop-in replacement for `ScrollView`. **Recommendation: B with `react-native-keyboard-controller`** — modern, actively maintained, ships with `KeyboardAwareScrollView` that handles iOS + Android consistently and auto-scrolls. The legacy `react-native-keyboard-aware-scroll-view` is also fine but less actively maintained. Bundle cost is acceptable for a load-bearing UX gap. ## Scope - Add `react-native-keyboard-controller` (or chosen lib) to `apps/client/`. - Wrap each form-bearing screen's outer `ScrollView` with `KeyboardAwareScrollView` (or equivalent). - Verify on Android via Expo Go: focus each TextInput on each screen, confirm the field stays visible above the keyboard. - No web regression — `react-native-keyboard-controller` ships a no-op web shim per its docs. ## Acceptance criteria - [ ] Focusing any `TextInput` on Android scrolls the field into view above the keyboard. - [ ] Web behaviour unchanged. - [ ] No new manifest permissions. - [ ] Manual smoke on Android via Expo Go for each affected screen. ## Out of scope - iOS-specific tuning (out of scope per `idea.md`). - A bottom-anchored submit button that lifts with the keyboard — separate UX polish. - Replacing every ScrollView in the app — only form-bearing screens need the treatment. ## Composes with - [#176](https://forge.wynning.tech/james/carol/issues/176) — universal client work. - [#234](https://forge.wynning.tech/james/carol/issues/234) — native E2E smoke. Adding a "type into a field below the fold" step to the Maestro flow would catch this class of regression.
james closed this issue 2026-06-23 16:51:27 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
james/carol#254
No description provided.