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

Choose a reason for hiding this comment

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

Definitely need to add this to at least one or more e2e test case, with screenshot comparison.

* Configure the opening mode of the side menu
* #### (iOS specific)
* @default 'pushContent'
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change

* @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 🙏

Comment on lines 35 to 40
MMDrawerOpenMode MMDrawerOpenModeFromString(NSString *openModeString) {
if (!openModeString) {
return MMDrawerOpenModePushContent; // Default
}

if ([openModeString isEqualToString:@"aboveContent"]) {
return MMDrawerOpenModeAboveContent;
} else {
// Default or explicit "pushContent"
return MMDrawerOpenModePushContent;
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

MMDrawerOpenMode MMDrawerOpenModeFromString(NSString *openModeString) {
    if ([openModeString isEqualToString:@"aboveContent"]) {
        return MMDrawerOpenModeAboveContent;
    } 
    return MMDrawerOpenModePushContent;
}

(isEqualToString should be checking implicitly for non-nullability)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good to know :)

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?

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)

NSTimeInterval duration = MAX(distance / ABS(velocity), MMDrawerMinimumAnimationDuration);

// Animate closure
[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 code needs to be extracted onto a function and shared across all mode

Copy link
Contributor Author

@liatnetach liatnetach Apr 15, 2025

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 🤔 maybe I'm missing something?

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 separate functions for closing the overlay in each mode (maybe even just 1 closing logic func can be enough?...)

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

@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

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