-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Support drawer menus opening as overlay instead of pushing content in ios #7986
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: 7.x.x
Are you sure you want to change the base?
Conversation
… ios (#7984) * add example in playground and some animations changes with Yogi * fix drag animations (open+close) in left drawer and add overlay on center * support all features in right drawer * supoprt both old and new opening mode using openAboveScreen param * connect the new parameter to rnn platform * update param from boolean to enum * clean * install * update lock * fix unit
0a1937a
to
f1d3449
Compare
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.
Pull Request Overview
This PR introduces overlay mode for side drawer menus on iOS, allowing the drawer to open above the content rather than pushing it.
- Added new test IDs for left and right menus.
- Added new functions and UI buttons in SetRootScreen to configure left and right menus with overlay behavior.
- Updated the Options interface to support the new openMode property.
Reviewed Changes
Copilot reviewed 5 out of 10 changed files in this pull request and generated no comments.
File | Description |
---|---|
playground/src/testIDs.ts | Added new test IDs for the left and right side menus. |
playground/src/screens/SetRootScreen.tsx | Added buttons and functions to configure side menus in overlay mode for iOS. |
lib/src/interfaces/Options.ts | Extended the Options interface with an openMode property for side menus. |
Files not reviewed (5)
- lib/ios/RNNSideMenu/MMDrawerController/MMDrawerController.h: Language not supported
- lib/ios/RNNSideMenuPresenter.m: Language not supported
- lib/ios/RNNSideMenuSideOptions.h: Language not supported
- lib/ios/RNNSideMenuSideOptions.m: Language not supported
- playground/ios/NavigationTests/RNNSideMenuPresenterTest.m: Language not supported
Comments suppressed due to low confidence (2)
playground/src/screens/SetRootScreen.tsx:336
- [nitpick] The component id 'sideMenu' is used for the left menu configuration; consider renaming it to 'leftSideMenu' for clarity and to avoid confusion with the right menu configuration.
id: 'sideMenu',
playground/src/screens/SetRootScreen.tsx:376
- [nitpick] The component id 'sideMenu' is used for the right menu configuration; consider renaming it to 'rightSideMenu' for clearer distinction between the left and right menus.
id: 'sideMenu',
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.
Impressive overall, but needs to be seriously improved before we can merge this in. Please see notes 🙏🏻
<Button | ||
label="Set Root with left menu" | ||
testID={SET_ROOT_WITH_LEFT_MENU} | ||
onPress={this.setRootWithLeftMenu} | ||
/> | ||
<Button | ||
label="Set Root with right menu" | ||
testID={SET_ROOT_WITH_RIGHT_MENU} | ||
onPress={this.setRootWithRightMenu} | ||
/> |
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.
I think better place for this would be the side-menu modal (Layouts > SideMenu btn) --

...
- Did you resort to set-root on purpose, in order to simplify?
- If so, why split the left-menu and right-menu into 2 different sub-screens, rather than having 1 screen with both? It's work quirky this way, with the "right menu" button breaking the app when set with the left-menu only
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.
- it's in root and not modal cause it shows our actual use case, we set the drawer in the root hierarchy - modal is different case
- np, changing to one button with both menus :)
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.
- For RNNav there's no difference. Please align this with the existing side-menus test. It needs to pass all existing tests there - including device rotation and drawer width changes; Please go as far as putting this under a
test.each
for both open modes (new and old).
1.1. We must add a screenshot test for both cases
1.2 If you're really concerned about this working as a root, we can add just 1 simple, happy-flow test covering exactly that
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.
@d4vidi Where can I find the existing screenshot tests? can you please add a reference?
or maybe did you meant the side menu e2e file?
* @default 'pushContent' | ||
*/ | ||
openMode?: 'pushContent' | 'aboveContent'; |
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.
openMode
- to me, sounds like a configuration of which animation to use when opening the drawer.
Suggestion: Rename openMode
→ layoutType
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.
BTW is shouldStretchDrawer
applicable with aboveContent
? If not, need to specify that too in the description
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.
what shouldStretchDrawer
is for? it should be default true but I can't see any indication to something like stretching content..
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.
regarding the renaming layoutType sounds to general to me, I will prefer to keep the openMode naming 🙏
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.
Stretchy Drawer By default, the side drawer will stretch if the user pans past the maximum drawer width. This gives a playful stretch effect. You can disable this by setting shouldStretchDrawer to NO, or you can make your own overshoot animation by creating a custom visual state block and setting up custom transforms for when percentVisible is greater than 1.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.
thanks, Ill document that it is not supported with above content mode :)
NSTimeInterval duration = MAX(distance / ABS(velocity), MMDrawerMinimumAnimationDuration); | ||
|
||
// Animate opening | ||
[UIView animateWithDuration:(animated ? duration : 0.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.
This call needs to be extracted onto a function and reused in all modes (overlay/push)
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.
in each call the settings are different we can't share this code, it's not really exactly the same 🤔 maybe I'm missing something?
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.
@d4vidi can be resolved?
self.rightDrawerOpenMode; | ||
|
||
if (openMode == MMDrawerOpenModeAboveContent) { | ||
// OVERLAY MODE |
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.
2 dedicated sub-functions: One for each mode (overlay, push-content)
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.
@d4vidi can be resolved?
self.leftDrawerOpenMode : | ||
self.rightDrawerOpenMode; | ||
|
||
if (openMode == MMDrawerOpenModeAboveContent) { |
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.
Really nice, but why is this custom handling needed just for the overlay mode (but not push mode)?
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.
Anyways it would be impossible to merge this code as-is. It needs to be extracted onto a separate module, to handle all cases - UIGestureRecognizerStateBegan, UIGestureRecognizerStateChanged and UIGestureRecognizerStateEnded. Preferably, it should be delegated to the original mode's code which I assume already has this (?)....
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.
@d4vidi I don't understand the second comment, can you please clarify? 🙏
regarding the first question the whole calculation is different between the modes cause in the original mode we calculate the center view position and in the new mode we needs the drawer itself
the actual element who moves is different
thats why there are many differences between the two regarding the animation calculations
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.
I see, thanks. Well we need to improve the code here. The function (panGestureCallback) is already massive, let's try to extract what we can onto sub-functions, at least. See 9c9834b#diff-a32c08640d39c005d4c2d2ad17f75707ab7286e61ed5b286fbf4dbb04541ba07R1409 as an example.
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.
Ive split panGestureCallback
method into small methods, you can see this commit
🙂
f1d3449
to
4803f82
Compare
#rebuild |
[self sideDrawerViewControllerForSide:self.openSide]; | ||
[sideDrawerViewController beginAppearanceTransition:NO animated:NO]; | ||
[sideDrawerViewController endAppearanceTransition]; | ||
if (openMode == MMDrawerOpenModeAboveContent) { |
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.
... Same here. The change here is massive, you need to find a way to elegantly extract this massive amount of logic onto several sub-methods. Also, please minimize the extra-comments = fluff 😄
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.
Ive split panGestureCallback
method into small methods, you can see this commit
🙂
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.
Hey @liatnetach, some further discussion - above. Still a lot to be done but please keep up the good work. It's mainly about:
- Getting the side-menu thoroughly tested in the SideMenu's suite (not the SetRoot one) - "full matrix" (all tests for both modes)
- Massively cleaning up and reorg'ing the work in panGestureCallback
- Fix an odd bug - the drawer disappears unexpectedly when panning out
Simulator.Screen.Recording.-.iPhone.13.Pro.Max.-.2025-05-13.at.13.30.11.mp4
381fe1a
to
465146c
Compare
Hey @d4vidi 🙂 |
This PR adds the ability to configure how side drawer menus open, introducing an overlay mode in addition to the traditional push-content behavior.