Skip to content

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

Open
wants to merge 18 commits into
base: 7.x.x
Choose a base branch
from

Conversation

liatnetach
Copy link
Contributor

This PR adds the ability to configure how side drawer menus open, introducing an overlay mode in addition to the traditional push-content behavior.

… 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
Copy link

@Copilot Copilot AI left a 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',

Copy link
Collaborator

@d4vidi d4vidi left a 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 🙏🏻

Comment on lines 91 to 94
<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}
/>
Copy link
Collaborator

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) --

...

  1. Did you resort to set-root on purpose, in order to simplify?
  2. 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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  1. 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
  2. np, changing to one button with both menus :)

Copy link
Collaborator

@d4vidi d4vidi May 11, 2025

Choose a reason for hiding this comment

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

  1. 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

Copy link
Contributor Author

@liatnetach liatnetach May 15, 2025

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';
Copy link
Collaborator

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 openModelayoutType

Copy link
Collaborator

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

Copy link
Contributor Author

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..

Copy link
Contributor Author

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 🙏

Copy link
Collaborator

@d4vidi d4vidi May 12, 2025

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

https://github.com/mutualmobile/MMDrawerController

Copy link
Contributor Author

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)
Copy link
Collaborator

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)

Copy link
Contributor Author

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?

Copy link
Contributor Author

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
Copy link
Collaborator

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)

Copy link
Contributor Author

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) {
Copy link
Collaborator

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)?

Copy link
Collaborator

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 (?)....

Copy link
Contributor Author

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

Copy link
Collaborator

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.

Copy link
Contributor Author

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
🙂

@liatnetach liatnetach force-pushed the support-drawer-menu-open-mode branch from f1d3449 to 4803f82 Compare April 15, 2025 13:03
@liatnetach liatnetach requested a review from d4vidi April 15, 2025 13:28
@liatnetach
Copy link
Contributor Author

#rebuild

[self sideDrawerViewControllerForSide:self.openSide];
[sideDrawerViewController beginAppearanceTransition:NO animated:NO];
[sideDrawerViewController endAppearanceTransition];
if (openMode == MMDrawerOpenModeAboveContent) {
Copy link
Collaborator

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 😄

Copy link
Contributor Author

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
🙂

Copy link
Collaborator

@d4vidi d4vidi left a 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:

  1. Getting the side-menu thoroughly tested in the SideMenu's suite (not the SetRoot one) - "full matrix" (all tests for both modes)
  2. Massively cleaning up and reorg'ing the work in panGestureCallback
  3. 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

@liatnetach liatnetach force-pushed the support-drawer-menu-open-mode branch from 381fe1a to 465146c Compare May 15, 2025 17:36
@liatnetach liatnetach requested a review from d4vidi May 18, 2025 14:48
@liatnetach
Copy link
Contributor Author

Hey @d4vidi 🙂
I've answered and pushed everything you asked for (including the bug fix - thanks for noticing!).
Please resolve what can be resolved, and let me know if there's anything else. 🙂

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