Skip to content
This repository was archived by the owner on May 4, 2022. It is now read-only.

feat(sidemenu): overlay content #175

Open
wants to merge 3 commits into
base: master
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
77 changes: 56 additions & 21 deletions js/angular/controller/sideMenuController.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ IonicModule
'$rootScope',
function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform, $ionicBody, $ionicHistory, $ionicScrollDelegate, IONIC_BACK_PRIORITY, $rootScope) {
var self = this;
var rightShowing, leftShowing, isDragging;
var isDragging;
var startX, lastX, offsetX, isAsideExposed;
var enableMenuWithBackViews = true;

Expand Down Expand Up @@ -61,7 +61,11 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform, $ionicBody, $io
if (arguments.length === 0) {
shouldOpen = openAmount <= 0;
}
self.content.enableAnimation();
if (self.left.displayType == 'overlay') {
self.left.enableAnimation();
} else {
self.content.enableAnimation();
}
if (!shouldOpen) {
self.openPercentage(0);
$rootScope.$emit('$ionicSideMenuClose', 'left');
Expand All @@ -80,7 +84,11 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform, $ionicBody, $io
if (arguments.length === 0) {
shouldOpen = openAmount >= 0;
}
self.content.enableAnimation();
if (self.right.displayType == 'overlay') {
self.right.enableAnimation();
} else {
self.content.enableAnimation();
}
if (!shouldOpen) {
self.openPercentage(0);
$rootScope.$emit('$ionicSideMenuClose', 'right');
Expand Down Expand Up @@ -111,7 +119,17 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform, $ionicBody, $io
* @return {float} The amount the side menu is open, either positive or negative for left (positive), or right (negative)
*/
self.getOpenAmount = function() {
return self.content && self.content.getTranslateX() || 0;
var retOpenAmount = 0;
if ((isNaN(retOpenAmount) || retOpenAmount === 0) && self.right && self.right.displayType == 'overlay') {
retOpenAmount = self.right.getTranslateX();
}
if ((isNaN(retOpenAmount) || retOpenAmount === 0) && self.left && self.left.displayType == 'overlay') {
retOpenAmount = self.left.getTranslateX();
}
if ((isNaN(retOpenAmount) || retOpenAmount === 0) && self.content) {
retOpenAmount = self.content.getTranslateX();
}
return retOpenAmount;
};

/**
Expand Down Expand Up @@ -181,6 +199,18 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform, $ionicBody, $io
var maxLeft = self.left && self.left.width || 0;
var maxRight = self.right && self.right.width || 0;

var overlayLeft = self.left && self.left.displayType == 'overlay' || false;
var overlayRight = self.right && self.right.displayType == 'overlay' || false;
var openLeft = overlayLeft && self.left.getTranslateX() || 0;
var openRight = overlayRight && self.right.getTranslateX() || 0;
var openContent = self.content.getTranslateX() || 0;

if (amount > maxLeft) {
amount = maxLeft;
} else if (amount < -maxRight) {
amount = -maxRight;
}

// Check if we can move to that side, depending if the left/right panel is enabled
if (!(self.left && self.left.isEnabled) && amount > 0) {
self.content.setTranslateX(0);
Expand All @@ -192,31 +222,30 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform, $ionicBody, $io
return;
}

if (leftShowing && amount > maxLeft) {
self.content.setTranslateX(maxLeft);
return;
}

if (rightShowing && amount < -maxRight) {
self.content.setTranslateX(-maxRight);
return;
if (amount > 0) {
if (overlayLeft) { self.left.setTranslateX(amount); }
if (overlayRight && openRight) { self.right.setTranslateX(0); }
if (!(overlayLeft && openLeft)) { self.content.setTranslateX(overlayLeft ? 0 : amount); }
} else if (amount < 0) {
if (overlayRight) { self.right.setTranslateX(amount); }
if (overlayLeft && openLeft) { self.left.setTranslateX(0); }
if (!(overlayRight && openRight)) { self.content.setTranslateX(overlayRight ? 0 : amount); }
} else /* if (amount === 0) */ {
if (overlayLeft && openLeft) { self.left.setTranslateX(amount); }
if (overlayRight && openRight) { self.right.setTranslateX(amount); }
if (!(overlayRight && openRight) && openContent) { self.content.setTranslateX(amount); }
}

self.content.setTranslateX(amount);

leftShowing = amount > 0;
rightShowing = amount < 0;

if (amount > 0) {
// Push the z-index of the right menu down
self.right && self.right.pushDown && self.right.pushDown();
self.right && self.right.displayType != 'overlay' && self.right.pushDown && self.right.pushDown();
// Bring the z-index of the left menu up
self.left && self.left.bringUp && self.left.bringUp();
self.left && self.left.displayType != 'overlay' && self.left.bringUp && self.left.bringUp();
} else {
// Bring the z-index of the right menu up
self.right && self.right.bringUp && self.right.bringUp();
self.right && self.right.displayType != 'overlay' && self.right.bringUp && self.right.bringUp();
// Push the z-index of the left menu down
self.left && self.left.pushDown && self.left.pushDown();
self.left && self.left.displayType != 'overlay' && self.left.pushDown && self.left.pushDown();
}
};

Expand Down Expand Up @@ -348,6 +377,12 @@ function($scope, $attrs, $ionicSideMenuDelegate, $ionicPlatform, $ionicBody, $io
isDragging = true;
// Initialize dragging
self.content.disableAnimation();
if (self.left.displayType == 'overlay') {
self.left.disableAnimation();
}
if (self.right.displayType == 'overlay') {
self.right.disableAnimation();
}
offsetX = self.getOpenAmount();
}

Expand Down
19 changes: 16 additions & 3 deletions js/angular/directive/sideMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
* <ion-side-menu
* side="left"
* width="myWidthValue + 20"
* is-enabled="shouldLeftSideMenuBeEnabled()">
* is-enabled="shouldLeftSideMenuBeEnabled()"
* display-type="push">
* </ion-side-menu>
* ```
* For a complete side menu example, see the
Expand All @@ -22,6 +23,7 @@
* @param {string} side Which side the side menu is currently on. Allowed values: 'left' or 'right'.
* @param {boolean=} is-enabled Whether this side menu is enabled.
* @param {number=} width How many pixels wide the side menu should be. Defaults to 275.
* @param {string} display-type Which type of display the menu should have. Allowed values: 'push' or 'overlay'. Defaults to 'push'.
*/
IonicModule
.directive('ionSideMenu', function() {
Expand All @@ -32,16 +34,23 @@ IonicModule
compile: function(element, attr) {
angular.isUndefined(attr.isEnabled) && attr.$set('isEnabled', 'true');
angular.isUndefined(attr.width) && attr.$set('width', '275');
angular.isUndefined(attr.displayType) && attr.$set('displayType', 'push');

element.addClass('menu menu-' + attr.side);
if (attr.displayType == 'overlay') {
element.addClass('menu-animated');
element[0].style[attr.side] = '-' + attr.width + 'px';
element[0].style.zIndex = 2147483647; // top most, maximum zIndex value
}

return function($scope, $element, $attr, sideMenuCtrl) {
$scope.side = $attr.side || 'left';

var sideMenu = sideMenuCtrl[$scope.side] = new ionic.views.SideMenu({
width: attr.width,
el: $element[0],
isEnabled: true
isEnabled: true,
displayType: attr.displayType
});

$scope.$watch($attr.width, function(val) {
Expand All @@ -53,8 +62,12 @@ IonicModule
$scope.$watch($attr.isEnabled, function(val) {
sideMenu.setIsEnabled(!!val);
});
$scope.$watch($attr.displayType, function(val) {
if (val == 'push' || val == 'overlay') {
sideMenu.setDisplayType(val);
}
});
};
}
};
});

20 changes: 19 additions & 1 deletion js/views/sideMenuView.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
this.el = opts.el;
this.isEnabled = (typeof opts.isEnabled === 'undefined') ? true : opts.isEnabled;
this.setWidth(opts.width);
this.displayType = (typeof opts.displayType === 'undefined') ? 'push' : opts.displayType;
},
getFullWidth: function() {
return this.width;
Expand All @@ -31,7 +32,24 @@
if(this.el.style.zIndex !== '-1') {
this.el.style.zIndex = '-1';
}
}
},
setDisplayType: function(displayType) {
this.displayType = displayType;
},
enableAnimation: function() {
this.animationEnabled = true;
this.el.classList.add('menu-animated');
},
disableAnimation: function() {
this.animationEnabled = false;
this.el.classList.remove('menu-animated');
},
getTranslateX: function() {
return parseFloat(this.el.style[ionic.CSS.TRANSFORM].replace('translate3d(', '').split(',')[0]);
},
setTranslateX: ionic.animationFrameThrottle(function(x) {
this.el.style[ionic.CSS.TRANSFORM] = 'translate3d(' + x + 'px, 0, 0)';
})
});

ionic.views.SideMenuContent = ionic.views.View.inherit({
Expand Down
12 changes: 12 additions & 0 deletions test/unit/angular/controller/sideMenuController.unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,18 @@ describe('$ionicSideMenus controller', function() {
expect(ctrl.right.isEnabled).toEqual(true);
});

// Menu displayType
it('should set displayType', function() {
ctrl.left.setDisplayType('overlay');
ctrl.right.setDisplayType('overlay');
expect(ctrl.left.displayType).toEqual('overlay');
expect(ctrl.right.displayType).toEqual('overlay');
ctrl.left.setDisplayType('push');
ctrl.right.setDisplayType('push');
expect(ctrl.left.displayType).toEqual('push');
expect(ctrl.right.displayType).toEqual('push');
});

// Menu widths
it('should init widths', function() {
expect(ctrl.left.width).toEqual(270);
Expand Down
1 change: 1 addition & 0 deletions test/unit/views/sideMenu.unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ describe('SideMenu', function() {
it('Should init', function() {
expect(menu.width).toEqual(270);
expect(menu.isEnabled).toEqual(true);
expect(menu.displayType).toEqual('push');
});
});