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
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion e2e/SetRoot.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ describe('SetRoot', () => {
await elementById(TestIDs.SET_ROOT_WITH_TWO_CHILDREN_HIDES_BOTTOM_TABS_BTN).tap();
await expect(elementById(TestIDs.LAYOUTS_TAB)).toBeNotVisible();
});

it('set root should not override props for component with identical id', async () => {
await expect(elementByLabel('Two')).toBeVisible();
await elementById(TestIDs.ROUND_BUTTON).tap();
Expand All @@ -51,3 +51,13 @@ describe('SetRoot', () => {
await elementById(TestIDs.OK_BUTTON).tap();
});
});

it.e2e(':ios: set root with left and right side menus - menu visibility', async () => {
await elementById(TestIDs.SET_ROOT_WITH_MENUS).tap();
await elementById(TestIDs.OPEN_LEFT_SIDE_MENU_BTN).tap();
await elementById(TestIDs.CLOSE_LEFT_SIDE_MENU_BTN).tap();
await expect(elementById(TestIDs.CLOSE_LEFT_SIDE_MENU_BTN)).toBeNotVisible();
await elementById(TestIDs.OPEN_RIGHT_SIDE_MENU_BTN).tap();
await elementById(TestIDs.CLOSE_RIGHT_SIDE_MENU_BTN).tap();
await expect(elementById(TestIDs.CLOSE_RIGHT_SIDE_MENU_BTN)).toBeNotVisible();
});
133 changes: 76 additions & 57 deletions e2e/SideMenu.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,76 +3,95 @@ import TestIDs from '../playground/src/testIDs';

const { elementByLabel, elementById } = Utils;

describe('SideMenu', () => {
describe.each([true, false])('SideMenu', (shouldTestAboveContent) => {
let openLeftMenuTestId;
let openRightMenuTestId;

beforeEach(async () => {
await device.launchApp({ newInstance: true });
await elementById(TestIDs.SIDE_MENU_BTN).tap();
openLeftMenuTestId = shouldTestAboveContent ? TestIDs.OPEN_LEFT_SIDE_MENU_ABOVE_CONTENT_BTN : TestIDs.OPEN_LEFT_SIDE_MENU_BTN;
openRightMenuTestId = shouldTestAboveContent ? TestIDs.OPEN_RIGHT_SIDE_MENU_ABOVE_CONTENT_BTN : TestIDs.OPEN_RIGHT_SIDE_MENU_BTN;
});

it('close SideMenu and push to stack with static id', async () => {
await elementById(TestIDs.OPEN_LEFT_SIDE_MENU_BTN).tap();
await elementById(TestIDs.LEFT_SIDE_MENU_PUSH_BTN).tap();
await elementById(TestIDs.CLOSE_LEFT_SIDE_MENU_BTN).tap();
await expect(elementById(TestIDs.PUSHED_SCREEN_HEADER)).toBeVisible();
await elementById(TestIDs.POP_BTN).tap();
await expect(elementById(TestIDs.CENTER_SCREEN_HEADER)).toBeVisible();
});
describe(`${shouldTestAboveContent ? 'Above Content' : 'Push Screen'}`, () => {
it.e2e(':ios: close SideMenu and push to stack with static id', async () => {
await elementById(openLeftMenuTestId).tap();
await elementById(TestIDs.LEFT_SIDE_MENU_PUSH_BTN).tap();
if(shouldTestAboveContent) {
await expect(elementById(TestIDs.PUSHED_SCREEN_HEADER)).toBeVisible();
await expect(elementById(TestIDs.CLOSE_LEFT_SIDE_MENU_BTN)).toBeNotVisible();
} else {
await elementById(TestIDs.CLOSE_LEFT_SIDE_MENU_BTN).tap();
await elementById(TestIDs.POP_BTN).tap();
await expect(elementById(TestIDs.CENTER_SCREEN_HEADER)).toBeVisible();
}
});

it('Push to stack with static id and close SideMenu with screen options', async () => {
await elementById(TestIDs.OPEN_LEFT_SIDE_MENU_BTN).tap();
await elementById(TestIDs.LEFT_SIDE_MENU_PUSH_AND_CLOSE_BTN).tap();
await expect(elementById(TestIDs.PUSHED_SCREEN_HEADER)).toBeVisible();
await elementById(TestIDs.POP_BTN).tap();
await expect(elementById(TestIDs.CENTER_SCREEN_HEADER)).toBeVisible();
});
it(':android: close SideMenu and push to stack with static id', async () => {
await elementById(openLeftMenuTestId).tap();
await elementById(TestIDs.LEFT_SIDE_MENU_PUSH_BTN).tap();
await elementById(TestIDs.CLOSE_LEFT_SIDE_MENU_BTN).tap();
await elementById(TestIDs.POP_BTN).tap();
await expect(elementById(TestIDs.CENTER_SCREEN_HEADER)).toBeVisible();
});

it('side menu visibility - left', async () => {
await elementById(TestIDs.OPEN_LEFT_SIDE_MENU_BTN).tap();
await elementById(TestIDs.CLOSE_LEFT_SIDE_MENU_BTN).tap();
await expect(elementById(TestIDs.CLOSE_LEFT_SIDE_MENU_BTN)).toBeNotVisible();
});
it('Push to stack with static id and close SideMenu with screen options', async () => {
await elementById(openLeftMenuTestId).tap();
await elementById(TestIDs.LEFT_SIDE_MENU_PUSH_AND_CLOSE_BTN).tap();
await expect(elementById(TestIDs.PUSHED_SCREEN_HEADER)).toBeVisible();
await elementById(TestIDs.POP_BTN).tap();
await expect(elementById(TestIDs.CENTER_SCREEN_HEADER)).toBeVisible();
});

it('side menu visibility - right', async () => {
await elementById(TestIDs.OPEN_RIGHT_SIDE_MENU_BTN).tap();
await elementById(TestIDs.CLOSE_RIGHT_SIDE_MENU_BTN).tap();
await expect(elementById(TestIDs.CLOSE_RIGHT_SIDE_MENU_BTN)).toBeNotVisible();
});
it('side menu visibility - left', async () => {
await elementById(openLeftMenuTestId).tap();
await elementById(TestIDs.CLOSE_LEFT_SIDE_MENU_BTN).tap();
await expect(elementById(TestIDs.CLOSE_LEFT_SIDE_MENU_BTN)).toBeNotVisible();
});

it.e2e('should rotate', async () => {
await elementById(TestIDs.OPEN_LEFT_SIDE_MENU_BTN).tap();
await device.setOrientation('landscape');
await expect(elementById(TestIDs.LEFT_SIDE_MENU_PUSH_BTN)).toBeVisible();
});
it('side menu visibility - right', async () => {
await elementById(openRightMenuTestId).tap();
await elementById(TestIDs.CLOSE_RIGHT_SIDE_MENU_BTN).tap();
await expect(elementById(TestIDs.CLOSE_RIGHT_SIDE_MENU_BTN)).toBeNotVisible();
});

it.e2e(':ios: rotation should update drawer height', async () => {
await elementById(TestIDs.OPEN_LEFT_SIDE_MENU_BTN).tap();
await expect(elementByLabel('left drawer height: 869')).toBeVisible();
await device.setOrientation('landscape');
await expect(elementByLabel('left drawer height: 428')).toBeVisible();
await device.setOrientation('portrait');
await expect(elementByLabel('left drawer height: 869')).toBeVisible();
});
it.e2e('should rotate', async () => {
await elementById(openLeftMenuTestId).tap();
await device.setOrientation('landscape');
await expect(elementById(TestIDs.LEFT_SIDE_MENU_PUSH_BTN)).toBeVisible();
});

it.e2e('should set left drawer width', async () => {
await elementById(TestIDs.OPEN_LEFT_SIDE_MENU_BTN).tap();
await expect(elementById(TestIDs.SIDE_MENU_LEFT_DRAWER_HEIGHT_TEXT)).toBeVisible();
await expect(elementByLabel('left drawer width: 250')).toBeVisible();
});
it.e2e(':ios: rotation should update drawer height', async () => {
await elementById(openLeftMenuTestId).tap();
await expect(elementByLabel('left drawer height: 869')).toBeVisible();
await device.setOrientation('landscape');
await expect(elementByLabel('left drawer height: 428')).toBeVisible();
await device.setOrientation('portrait');
await expect(elementByLabel('left drawer height: 869')).toBeVisible();
});

it.e2e('should change left drawer width', async () => {
await elementById(TestIDs.CHANGE_LEFT_SIDE_MENU_WIDTH_BTN).tap();
await elementById(TestIDs.OPEN_LEFT_SIDE_MENU_BTN).tap();
await expect(elementByLabel('left drawer width: 50')).toBeVisible();
});
it.e2e('should set left drawer width', async () => {
await elementById(openLeftMenuTestId).tap();
await expect(elementById(TestIDs.SIDE_MENU_LEFT_DRAWER_HEIGHT_TEXT)).toBeVisible();
await expect(elementByLabel('left drawer width: 250')).toBeVisible();
});

it.e2e('should set right drawer width', async () => {
await elementById(TestIDs.OPEN_RIGHT_SIDE_MENU_BTN).tap();
await expect(elementByLabel('right drawer width: 250')).toBeVisible();
});
it.e2e('should change left drawer width', async () => {
await elementById(TestIDs.CHANGE_LEFT_SIDE_MENU_WIDTH_BTN).tap();
await elementById(openLeftMenuTestId).tap();
await expect(elementByLabel('left drawer width: 50')).toBeVisible();
});

it.e2e('should set right drawer width', async () => {
await elementById(openRightMenuTestId).tap();
await expect(elementByLabel('right drawer width: 250')).toBeVisible();
});

it.e2e('should change right drawer width', async () => {
await elementById(TestIDs.CHANGE_RIGHT_SIDE_MENU_WIDTH_BTN).tap();
await elementById(TestIDs.OPEN_RIGHT_SIDE_MENU_BTN).tap();
await expect(elementByLabel('right drawer width: 50')).toBeVisible();
it.e2e('should change right drawer width', async () => {
await elementById(TestIDs.CHANGE_RIGHT_SIDE_MENU_WIDTH_BTN).tap();
await elementById(openRightMenuTestId).tap();
await expect(elementByLabel('right drawer width: 50')).toBeVisible();
});
});
});
22 changes: 22 additions & 0 deletions lib/ios/RNNSideMenu/MMDrawerController/MMDrawerController.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,14 @@ typedef void (^MMDrawerControllerDrawerVisualStateBlock)(MMDrawerController *dra

@interface MMDrawerController : UIViewController

/**
Enum defining how the drawer opens
*/
typedef NS_ENUM(NSInteger, MMDrawerOpenMode) {
MMDrawerOpenModePushContent = 0, // Original behavior - pushes content aside
MMDrawerOpenModeAboveContent = 1, // Overlay behavior - opens above content
};

///---------------------------------------
/// @name Accessing Drawer Container View Controller Properties
///---------------------------------------
Expand Down Expand Up @@ -213,6 +221,18 @@ typedef void (^MMDrawerControllerDrawerVisualStateBlock)(MMDrawerController *dra
@property(nonatomic, assign) BOOL shouldStretchLeftDrawer;
@property(nonatomic, assign) BOOL shouldStretchRightDrawer;

/**
* Specifies how the drawer should open relative to the center content.
*
* Possible values:
* - MMDrawerOpenModePushContent: The drawer will push the center content aside when opening (traditional behavior).
* - MMDrawerOpenModeAboveContent: The drawer will open above the center content with a semi-transparent overlay.
*
* By default, this value is set to MMDrawerOpenModePushContent.
*/
@property(nonatomic, assign) MMDrawerOpenMode leftDrawerOpenMode;
@property(nonatomic, assign) MMDrawerOpenMode rightDrawerOpenMode;

/**
The current open side of the drawer.

Expand Down Expand Up @@ -600,4 +620,6 @@ typedef void (^MMDrawerControllerDrawerVisualStateBlock)(MMDrawerController *dra
(BOOL (^)(MMDrawerController *drawerController, UIGestureRecognizer *gesture,
UITouch *touch))gestureShouldRecognizeTouchBlock;

- (void)side:(MMDrawerSide)drawerSide openMode:(MMDrawerOpenMode)openMode;

@end
Loading