Skip to content

Conversation

@edison-cy-yang
Copy link
Contributor

@edison-cy-yang edison-cy-yang commented Nov 19, 2025

Remaining tasks

  • keyboardAvoidingBehavior prop not implemented
  • avoidKeyboardLikeIOS prop not implemented
  • modalForLargeScreens style not applied
  • Mock BottomSheetModal and BottomSheetScrollView in MockBottomSheet
  • Make sure this builds for the doc site
  • Unit test, should be able to reuse existing test with minimal modifications
  • Copy all the changes to ContentOverlay, 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.InputText may not be the only wrapper input component we need. To recap, BottomSheet.InputText is a wrapper around InputText that implements onFocus and onBlur to properly position keyboard against these inputs. If we do indeed need more wrapper inputs, we will need to follow the pattern in BottomSheet.InputText for 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.tsx is 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 replace ContentOverlay.tsx

To test with live linking:

  • Export these from the ContentOverlay barrel
export { ContentOverlayRebuilt } from "./ContentOverlay.rebuilt";
export type { ContentOverlayRebuiltRef } from "./types";
  • Add ContentOverlayRebuilt to meta.json
  • Follow the mobile Atlantis live linking guide, so you can have ContentOverlay and ContentOverlayRebuilt side by side

Changes can be
tested via Pre-release


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

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" },
Copy link
Contributor

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.

Comment on lines +127 to +129
const handleOnScroll = () => {
const scrollTop = scrollViewRef.current?.scrollTop || 0;
setShowHeaderShadow(scrollTop > 0);
Copy link
Contributor

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

@jdeichert jdeichert force-pushed the JOB-140606-implement-it-in-content-overlay branch from f7128c0 to 6a9a82d Compare December 5, 2025 16:55
jdeichert and others added 11 commits December 5, 2025 08:59
…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
Base automatically changed from JOB-140604-install-react-native-bottom-sheet-and-replace-react-native-modalize to master December 8, 2025 21:31
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.
Comment on lines +124 to +127
if (reactTag) {
AccessibilityInfo.setAccessibilityFocus(reactTag);
}
}
Copy link
Contributor

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.

Comment on lines +143 to +145
// TODO: Add large screen styles?
// windowWidth > 640 ? styles.modalForLargeScreens : undefined,
{ backgroundColor: getModalBackgroundColor(modalBackgroundColor, tokens) },
Copy link
Contributor

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants