Skip to content

Commit 0a1937a

Browse files
committed
Support drawer menus opening as overlay instead of pushing content in 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
1 parent 9205aa0 commit 0a1937a

File tree

10 files changed

+789
-140
lines changed

10 files changed

+789
-140
lines changed

lib/ios/RNNSideMenu/MMDrawerController/MMDrawerController.h

+22
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,14 @@ typedef void (^MMDrawerControllerDrawerVisualStateBlock)(MMDrawerController *dra
127127

128128
@interface MMDrawerController : UIViewController
129129

130+
/**
131+
Enum defining how the drawer opens
132+
*/
133+
typedef NS_ENUM(NSInteger, MMDrawerOpenMode) {
134+
MMDrawerOpenModePushContent = 0, // Original behavior - pushes content aside
135+
MMDrawerOpenModeAboveContent = 1, // Overlay behavior - opens above content
136+
};
137+
130138
///---------------------------------------
131139
/// @name Accessing Drawer Container View Controller Properties
132140
///---------------------------------------
@@ -213,6 +221,18 @@ typedef void (^MMDrawerControllerDrawerVisualStateBlock)(MMDrawerController *dra
213221
@property(nonatomic, assign) BOOL shouldStretchLeftDrawer;
214222
@property(nonatomic, assign) BOOL shouldStretchRightDrawer;
215223

224+
/**
225+
* Specifies how the drawer should open relative to the center content.
226+
*
227+
* Possible values:
228+
* - MMDrawerOpenModePushContent: The drawer will push the center content aside when opening (traditional behavior).
229+
* - MMDrawerOpenModeAboveContent: The drawer will open above the center content with a semi-transparent overlay.
230+
*
231+
* By default, this value is set to MMDrawerOpenModePushContent.
232+
*/
233+
@property(nonatomic, assign) MMDrawerOpenMode leftDrawerOpenMode;
234+
@property(nonatomic, assign) MMDrawerOpenMode rightDrawerOpenMode;
235+
216236
/**
217237
The current open side of the drawer.
218238
@@ -600,4 +620,6 @@ typedef void (^MMDrawerControllerDrawerVisualStateBlock)(MMDrawerController *dra
600620
(BOOL (^)(MMDrawerController *drawerController, UIGestureRecognizer *gesture,
601621
UITouch *touch))gestureShouldRecognizeTouchBlock;
602622

623+
- (void)side:(MMDrawerSide)drawerSide openMode:(MMDrawerOpenMode)openMode;
624+
603625
@end

lib/ios/RNNSideMenu/MMDrawerController/MMDrawerController.m

+604-138
Large diffs are not rendered by default.

lib/ios/RNNSideMenuPresenter.m

+30
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#import "RNNSideMenuPresenter.h"
22
#import "RNNSideMenuController.h"
3+
#import "RNNSideMenuSideOptions.h"
34

45
@implementation RNNSideMenuPresenter
56

@@ -52,6 +53,23 @@ - (void)applyOptions:(RNNNavigationOptions *)options {
5253

5354
[self.sideMenuController.view
5455
setBackgroundColor:[withDefault.layout.backgroundColor withDefault:nil]];
56+
57+
if (withDefault.sideMenu.left.openMode.hasValue) {
58+
NSString *openModeString = withDefault.sideMenu.left.openMode.get;
59+
MMDrawerOpenMode openMode = MMDrawerOpenModeFromString(openModeString);
60+
[self.sideMenuController side:MMDrawerSideLeft openMode:openMode];
61+
} else {
62+
[self.sideMenuController side:MMDrawerSideLeft openMode:MMDrawerOpenModePushContent];
63+
}
64+
65+
if (withDefault.sideMenu.right.openMode.hasValue) {
66+
NSString *openModeString = withDefault.sideMenu.right.openMode.get;
67+
MMDrawerOpenMode openMode = MMDrawerOpenModeFromString(openModeString);
68+
[self.sideMenuController side:MMDrawerSideRight openMode:openMode];
69+
} else {
70+
[self.sideMenuController side:MMDrawerSideRight openMode:MMDrawerOpenModePushContent];
71+
}
72+
5573
}
5674

5775
- (void)applyOptionsOnInit:(RNNNavigationOptions *)initialOptions {
@@ -112,6 +130,18 @@ - (void)mergeOptions:(RNNNavigationOptions *)options
112130
options.sideMenu.right.shouldStretchDrawer.get;
113131
}
114132

133+
if (options.sideMenu.left.openMode.hasValue) {
134+
NSString *openModeString = options.sideMenu.left.openMode.get;
135+
MMDrawerOpenMode openMode = MMDrawerOpenModeFromString(openModeString);
136+
[self.sideMenuController side:MMDrawerSideLeft openMode:openMode];
137+
}
138+
139+
if (options.sideMenu.right.openMode.hasValue) {
140+
NSString *openModeString = options.sideMenu.right.openMode.get;
141+
MMDrawerOpenMode openMode = MMDrawerOpenModeFromString(openModeString);
142+
[self.sideMenuController side:MMDrawerSideRight openMode:openMode];
143+
}
144+
115145
if (options.sideMenu.left.animationVelocity.hasValue) {
116146
self.sideMenuController.animationVelocityLeft = options.sideMenu.left.animationVelocity.get;
117147
}

lib/ios/RNNSideMenuSideOptions.h

+6
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,11 @@
88
@property(nonatomic, strong) Double *width;
99
@property(nonatomic, strong) Bool *shouldStretchDrawer;
1010
@property(nonatomic, strong) Double *animationVelocity;
11+
@property (nonatomic, strong) Text *openMode;
1112

13+
/**
14+
* Converts a string open mode to the equivalent MMDrawerOpenMode enum value
15+
*/
16+
MMDrawerOpenMode MMDrawerOpenModeFromString(NSString *openModeString);
17+
1218
@end

lib/ios/RNNSideMenuSideOptions.m

+19-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ - (instancetype)initWithDict:(NSDictionary *)dict {
1010
self.width = [DoubleParser parse:dict key:@"width"];
1111
self.shouldStretchDrawer = [BoolParser parse:dict key:@"shouldStretchDrawer"];
1212
self.animationVelocity = [DoubleParser parse:dict key:@"animationVelocity"];
13-
13+
self.openMode = [TextParser parse:dict key:@"openMode"];
1414
return self;
1515
}
1616

@@ -25,6 +25,24 @@ - (void)mergeOptions:(RNNSideMenuSideOptions *)options {
2525
self.shouldStretchDrawer = options.shouldStretchDrawer;
2626
if (options.animationVelocity.hasValue)
2727
self.animationVelocity = options.animationVelocity;
28+
if (options.openMode.hasValue)
29+
self.openMode = options.openMode;
30+
}
31+
32+
/**
33+
Converts a string open mode to the equivalent MMDrawerOpenMode enum value
34+
*/
35+
MMDrawerOpenMode MMDrawerOpenModeFromString(NSString *openModeString) {
36+
if (!openModeString) {
37+
return MMDrawerOpenModePushContent; // Default
38+
}
39+
40+
if ([openModeString isEqualToString:@"aboveContent"]) {
41+
return MMDrawerOpenModeAboveContent;
42+
} else {
43+
// Default or explicit "pushContent"
44+
return MMDrawerOpenModePushContent;
45+
}
2846
}
2947

3048
@end

lib/src/interfaces/Options.ts

+7
Original file line numberDiff line numberDiff line change
@@ -1082,6 +1082,13 @@ export interface SideMenuSide {
10821082
* @default true
10831083
*/
10841084
shouldStretchDrawer?: boolean;
1085+
/**
1086+
* Configure the opening mode of the side menu
1087+
* #### (iOS specific)
1088+
* @default 'pushContent'
1089+
1090+
*/
1091+
openMode?: 'pushContent' | 'aboveContent';
10851092
}
10861093

10871094
export interface OptionsSideMenu {

package-lock.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

playground/ios/NavigationTests/RNNSideMenuPresenterTest.m

+6
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ - (void)testApplyOptionsShouldSetDefaultValues {
4747
[[self.boundViewController expect] side:MMDrawerSideRight enabled:YES];
4848
[[self.boundViewController expect] setShouldStretchLeftDrawer:YES];
4949
[[self.boundViewController expect] setShouldStretchRightDrawer:YES];
50+
[[self.boundViewController expect] side:MMDrawerSideLeft openMode:MMDrawerOpenModePushContent];
51+
[[self.boundViewController expect] side:MMDrawerSideRight openMode:MMDrawerOpenModePushContent];
5052
[[self.boundViewController expect] setAnimationVelocityLeft:840.0f];
5153
[[self.boundViewController expect] setAnimationVelocityRight:840.0f];
5254
[[self.boundViewController reject] side:MMDrawerSideLeft width:0];
@@ -63,13 +65,17 @@ - (void)testApplyOptionsShouldSetInitialValues {
6365
self.options.sideMenu.right.enabled = [[Bool alloc] initWithBOOL:NO];
6466
self.options.sideMenu.left.shouldStretchDrawer = [[Bool alloc] initWithBOOL:NO];
6567
self.options.sideMenu.right.shouldStretchDrawer = [[Bool alloc] initWithBOOL:NO];
68+
self.options.sideMenu.left.openMode = [[Text alloc] initWithValue:@"aboveContent"];
69+
self.options.sideMenu.right.openMode = [[Text alloc] initWithValue:@"aboveContent"];
6670
self.options.sideMenu.right.animationVelocity = [[Double alloc] initWithValue:@(100.0f)];
6771
self.options.sideMenu.left.animationVelocity = [[Double alloc] initWithValue:@(100.0f)];
6872

6973
[[self.boundViewController expect] side:MMDrawerSideLeft enabled:NO];
7074
[[self.boundViewController expect] side:MMDrawerSideRight enabled:NO];
7175
[[self.boundViewController expect] setShouldStretchLeftDrawer:NO];
7276
[[self.boundViewController expect] setShouldStretchRightDrawer:NO];
77+
[[self.boundViewController expect] side:MMDrawerSideLeft openMode:MMDrawerOpenModeAboveContent];
78+
[[self.boundViewController expect] side:MMDrawerSideRight openMode:MMDrawerOpenModeAboveContent];
7379
[[self.boundViewController expect] setAnimationVelocityLeft:100.0f];
7480
[[self.boundViewController expect] setAnimationVelocityRight:100.0f];
7581

playground/src/screens/SetRootScreen.tsx

+92
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ const {
1717
SET_ROOT_WITH_TWO_CHILDREN_HIDES_BOTTOM_TABS_BTN,
1818
SET_ROOT_WITHOUT_STACK_HIDES_BOTTOM_TABS_BTN,
1919
SET_ROOT_WITH_BUTTONS,
20+
SET_ROOT_WITH_RIGHT_MENU,
21+
SET_ROOT_WITH_LEFT_MENU,
2022
ROUND_BUTTON,
2123
} = testIDs;
2224

@@ -86,6 +88,16 @@ export default class SetRootScreen extends React.Component<NavigationProps> {
8688
testID={SET_ROOT_WITH_BUTTONS}
8789
onPress={this.setRootWithButtons}
8890
/>
91+
<Button
92+
label="Set Root with left menu"
93+
testID={SET_ROOT_WITH_LEFT_MENU}
94+
onPress={this.setRootWithLeftMenu}
95+
/>
96+
<Button
97+
label="Set Root with right menu"
98+
testID={SET_ROOT_WITH_RIGHT_MENU}
99+
onPress={this.setRootWithRightMenu}
100+
/>
89101
</Root>
90102
);
91103
}
@@ -314,4 +326,84 @@ export default class SetRootScreen extends React.Component<NavigationProps> {
314326
},
315327
},
316328
});
329+
330+
setRootWithLeftMenu = () =>
331+
Navigation.setRoot({
332+
root: {
333+
sideMenu: {
334+
left: {
335+
component: {
336+
id: 'sideMenu',
337+
name: Screens.SideMenuLeft,
338+
},
339+
},
340+
center: {
341+
stack: {
342+
children: [
343+
{
344+
component: {
345+
name: Screens.SideMenuCenter,
346+
id: 'SideMenuCenter',
347+
options: {
348+
animations: {
349+
setRoot: {
350+
waitForRender: true,
351+
},
352+
},
353+
},
354+
},
355+
},
356+
],
357+
},
358+
},
359+
options: {
360+
sideMenu: {
361+
left: {
362+
openMode: 'aboveContent',
363+
},
364+
},
365+
},
366+
},
367+
},
368+
});
369+
370+
setRootWithRightMenu = () =>
371+
Navigation.setRoot({
372+
root: {
373+
sideMenu: {
374+
right: {
375+
component: {
376+
id: 'sideMenu',
377+
name: Screens.SideMenuRight,
378+
},
379+
},
380+
center: {
381+
stack: {
382+
children: [
383+
{
384+
component: {
385+
name: Screens.SideMenuCenter,
386+
id: 'SideMenuCenter',
387+
options: {
388+
animations: {
389+
setRoot: {
390+
waitForRender: true,
391+
},
392+
},
393+
},
394+
},
395+
},
396+
],
397+
},
398+
},
399+
options: {
400+
sideMenu: {
401+
right: {
402+
openMode: 'aboveContent',
403+
},
404+
},
405+
},
406+
},
407+
},
408+
});
317409
}

playground/src/testIDs.ts

+2
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ const testIDs = {
120120
'SET_ROOT_WITH_TWO_CHILDREN_HIDES_BOTTOM_TABS_BTN',
121121
SET_ROOT_HIDES_BOTTOM_TABS_BTN: 'SET_ROOT_HIDES_BOTTOM_TABS_BTN',
122122
SET_ROOT_WITH_BUTTONS: 'SET_ROOT_WITH_BUTTONS',
123+
SET_ROOT_WITH_RIGHT_MENU: 'SET_ROOT_WITH_RIGHT_MENU',
124+
SET_ROOT_WITH_LEFT_MENU: 'SET_ROOT_WITH_LEFT_MENU',
123125
ADD_BACK_HANDLER: 'ADD_BACK_HANDLER',
124126
REMOVE_BACK_HANDLER: 'REMOVE_BACK_HANDLER',
125127
OPEN_LEFT_SIDE_MENU_BTN: 'OPEN_LEFT_SIDE_MENU_BTN',

0 commit comments

Comments
 (0)