-
Notifications
You must be signed in to change notification settings - Fork 30
feat(components-native): Replace react-native-modalize with react-native-bottom-sheet for ContentOverlay #2819
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
feat(components-native): Replace react-native-modalize with react-native-bottom-sheet for ContentOverlay #2819
Conversation
…ttom sheet and keyboard positioning
…rop in BottomSheet
The `null` handleComponent was a problem. Using `opacity:0` works better
The shadow around the header, combined with the border radius fix, resulted in visible shadow around the top corners of the header. Moving the shadow to a pseudo/empty element positioned below the header prevents this.
Very buggy problem with the scrollview. If the modal is at the top/fullscreen, and you drag it downwards then upwards, it rapidly fluctuates nativeEvent.contentOffset.y as if you're scrolling... but you're not.. the modal is just moving its position back to the top. This solution doesn't fully cover it, so perhaps we need a ticket to track a followup improvement here.
Very buggy problem with the scrollview. If the modal is at the top/fullscreen, and you drag it downwards then upwards, it rapidly fluctuates nativeEvent.contentOffset.y as if you're scrolling... but you're not.. the modal is just moving its position back to the top. My previous commit attempted to reduce this flicker, but it wasn't working great. RN offers scrollTop on ScrollView (https://reactnative.dev/docs/element-nodes#web-compatible-api) and BottomSheetScrollView wraps ScrollView, so we have access to it. Accessing scrollTop appears to be way more reliable than nativeEvent.contentOffset.y which is constantly fluctuating as you're moving the modal upwards.
| style: (isOpen ? undefined : { display: "none" }) as any, | ||
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
| ...(props as any), | ||
| style: isOpen ? undefined : { display: "none" }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noticed a bunch of any casting and props passing appeared to be unnecessary, so removed until we determine a need for that.
| const handleOnScroll = () => { | ||
| const scrollTop = scrollViewRef.current?.scrollTop || 0; | ||
| setShowHeaderShadow(scrollTop > 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The old code (further down below) was using this:
setShowHeaderShadow(nativeEvent.contentOffset.y > 0);However, with the new modal library.. that value was constantly fluctuating in the case shown below. For some reason, it triggers this scroll event when you're moving the modal upwards:
Screen.Recording.2025-12-04.at.2.39.58.PM.mov
After a bit of digging, I found that RN supports scrollTop on the native ScrollView which is what BottomSheetScrollView uses internally. This allows us to use a much more stable/reliable value which seems to work great:
Screen.Recording.2025-12-04.at.2.34.45.PM.mov
…ative-bottom-sheet-and-replace-react-native-modalize
f7128c0 to
6a9a82d
Compare
…bottom-sheet-and-replace-react-native-modalize' into JOB-140606-implement-it-in-content-overlay
No longer needed
…bottom-sheet-and-replace-react-native-modalize' into JOB-140606-implement-it-in-content-overlay
Historically we've mocked these libraries, but that doesn't seem required anymore? https://docs.swmansion.com/react-native-reanimated/docs/3.x/guides/testing/ The only case we need to mock is isFabricInstalled because of a current bug in @gorhom/bottom-sheet
…bottom-sheet-and-replace-react-native-modalize' into JOB-140606-implement-it-in-content-overlay
We realized this file is actually exported as part of our package, so that's why reanimated's mock was duplicated between this file and __mocks.ts.
Restored that and moved `require("react-native-reanimated").setUpTests()` to our __mocks.ts file.
| if (reactTag) { | ||
| AccessibilityInfo.setAccessibilityFocus(reactTag); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just something from my todo list, we should double check this logic works, maybe add a test if possible.
| // TODO: Add large screen styles? | ||
| // windowWidth > 640 ? styles.modalForLargeScreens : undefined, | ||
| { backgroundColor: getModalBackgroundColor(modalBackgroundColor, tokens) }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO: handle large screen modals. We have a "modalForLargeScreens" subtask for this.
Remaining tasks
keyboardAvoidingBehaviorprop not implementedavoidKeyboardLikeIOSprop not implementedmodalForLargeScreensstyle not appliedBottomSheetModalandBottomSheetScrollViewinMockBottomSheetContentOverlay, there should be no rebuilt.We also need to go through existing ContentOverlay usages and find out what kind of inputs are currently being used. I realized
BottomSheet.InputTextmay not be the only wrapper input component we need. To recap,BottomSheet.InputTextis a wrapper aroundInputTextthat implementsonFocusandonBlurto properly position keyboard against these inputs. If we do indeed need more wrapper inputs, we will need to follow the pattern inBottomSheet.InputTextfor every input component, and replace each existing instance 🥲This PR targets #2803, but does not depend on it.
Motivations
Changes
Added
Changed
Deprecated
Removed
Fixed
Security
Testing
ContentOverlay.rebuilt.tsxis created for the sake of testing the old version and compare against the new one in simulator. This should not be a rebuilt and should completely replaceContentOverlay.tsxTo test with live linking:
meta.jsonChanges can be
tested via Pre-release
In Atlantis we use Github's built in pull request reviews.