Skip to content

feat(components-native): Replace react-native-keyboard-aware-scroll-view with react-native-keyboard-controller#2901

Merged
edison-cy-yang merged 12 commits intomasterfrom
JOB-150289-find-and-replace-the-library-in-atlantis
Mar 12, 2026
Merged

feat(components-native): Replace react-native-keyboard-aware-scroll-view with react-native-keyboard-controller#2901
edison-cy-yang merged 12 commits intomasterfrom
JOB-150289-find-and-replace-the-library-in-atlantis

Conversation

@edison-cy-yang
Copy link
Copy Markdown
Contributor

@edison-cy-yang edison-cy-yang commented Feb 7, 2026

Motivations

react-native-keyboard-aware-scroll-view has not been maintained nor updated in a long time, we are replacing it with react-native-keyboard-controller

Changes

react-native-keyboard-aware-scrollp-view is replaced with react-native-keyboard-controller in Form internal implementation. There should be no changes to existing functionality.

Props

  • enableResetScrollToCoords={false} -> disableScrollOnKeyboardHide={true}. Same behavior — prevent auto-reset of scroll position when keyboard hides
  • enableAutomaticScroll={!disableKeyboardAwareScroll} -> enabled={!disableKeyboardAwareScroll}. Same behavior — toggles auto-scroll to focused inputs
  • enableOnAndroid={edgeToEdgeEnabled} removed. Not needed; the new library handles Android by default
  • keyboardOpeningTime={...} removed New library handles animation timing internally
  • keyboardShouldPersistTaps={"handled"} unchanged Standard ScrollView prop, passed through as-is
  • extraScrollHeight -> extraKeyboardSpace

bottomOffset — behavior difference
The old library's extraHeight (equivalent to bottomOffset ) was set to headerHeight, which is the navigation header height + a 20px constant (KEYBOARD_TOP_PADDING_AUTO_SCROLL) from useScreenInformation.

I am not sure how this was exactly working with the old library. However, the two libraries compute this offset differently internally.

Setting bottomOffset={headerHeight} in the new library produced an oversized gap between the keyboard and the focused input. After testing, bottomOffset={KEYBOARD_TOP_PADDING_AUTO_SCROLL} (the 20px constant alone) gives the correct behavior — keeping the focused input just above the keyboard without the extra header height offset that is no longer needed.

Keyboard event listeners
The old library forwarded keyboard events via props (onKeyboardWillShow, onKeyboardDidShow, etc.) directly on KeyboardAwareScrollView. The new library doesn't expose those props, so listeners are now registered using KeyboardEvents.addListener from react-native-keyboard-controller, which provides cross-platform keyboard events (keyboardWillShow/Hide on both iOS and Android).

The event payload changed: the old RN Keyboard event exposed endCoordinates.height and endCoordinates.screenY, while the new library's KeyboardEventData only provides height. screenY is now derived as windowHeight - height.

Scroll ref API
The old library's ref exposed scrollToPosition(x, y, animated). The new library's ref uses the standard RN ScrollView method scrollTo({ x, y, animated }).

Added

Changed

Deprecated

Removed

Fixed

Security

Testing

Changes can be
tested via Pre-release


In Atlantis we use Github's built in pull request reviews.

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Feb 7, 2026

Deploying atlantis with  Cloudflare Pages  Cloudflare Pages

Latest commit: 23c7863
Status: ✅  Deploy successful!
Preview URL: https://ba62a055.atlantis.pages.dev
Branch Preview URL: https://job-150289-find-and-replace.atlantis.pages.dev

View logs

Comment thread package-lock.json
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This was done manually to resolve issue with how Cloudflare installs packages. We've had to do something similar in 4c8f8f2

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 7, 2026

Published Pre-release for a97fab0 with versions:

  - @jobber/components-native@0.95.5-JOB-150289-a97fab0.18+a97fab075

To install the new version(s) for Mobile run:

npm install @jobber/components-native@0.95.5-JOB-150289-a97fab0.18+a97fab075

{...keyboardProps}
extraHeight={headerHeight}
extraScrollHeight={edgeToEdgeEnabled ? tokens["space-large"] : 0}
bottomOffset={headerHeight}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

According to documentation, bottomOffset is equivalent to extraHeight prop from react-native-keyboard-aware-scroll-view and it's supposed to be The distance between the keyboard and the caret inside a focused TextInput when the keyboard is shown. However I'm seeing a bigger margin than before 🧐. But I'm also not sure why headerHeight was used as the bottom offset in the old implementation.

Image


const handleOfflineSubmit = useOfflineHandler();

const keyboardProps = Platform.select({
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The old KeyboardAwareScrollView forwarded keyboard events directly as props.

The new KeyboardAwareScrollView does not expose keyboard event props. Instead, we use KeyboardEvents.addListener from react-native-keyboard-controller, which provides cross-platform keyboard lifecycle events.

The new library's KeyboardEventData only provides height — there is no endCoordinates.screenY. Since screenY is the Y coordinate of the top of the keyboard (measured from the top of the screen), it is derived as: keyboardScreenY = windowHeight - event.height

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

With that said, I have not tested that this is still working. Still trying to figure out how to navigate to the components that need sticky form save button above the keyboard.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I thought I had an update to this, not sure where it went.

I tried a few places in the consuming app with production atlantis where the Form is short, and the keyboard is open, saveButtonPosition becomes sticky, but the button does not render above the keyboard. This behavior may have changed over time even before we swap out the library. So although these handleKeyboard listeners are equivalent with the old implementation, it's not actually affecting the keyboard position.

[windowHeight],
);

const handleKeyboardHide = useCallback(() => {
Copy link
Copy Markdown
Contributor Author

@edison-cy-yang edison-cy-yang Mar 10, 2026

Choose a reason for hiding this comment

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

This handler remains the same as the previous implementation.

@edison-cy-yang edison-cy-yang marked this pull request as ready for review March 10, 2026 23:02
@edison-cy-yang edison-cy-yang requested a review from a team as a code owner March 10, 2026 23:02
Copy link
Copy Markdown
Contributor

@MichaelParadis MichaelParadis left a comment

Choose a reason for hiding this comment

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

LGTM!

@edison-cy-yang edison-cy-yang merged commit f2adedb into master Mar 12, 2026
14 checks passed
@edison-cy-yang edison-cy-yang deleted the JOB-150289-find-and-replace-the-library-in-atlantis branch March 12, 2026 21:20
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.

2 participants