feat(menu): right side menus

This commit is contained in:
Adam Bradley
2015-09-22 12:36:42 -05:00
parent 3b7d261290
commit 1a60540f2b
9 changed files with 88 additions and 33 deletions

View File

@ -35,3 +35,7 @@ ion-menu[type=overlay] {
} }
} }
} }
ion-menu[type=overlay][side=right] {
left: 8px;
}

View File

@ -10,7 +10,7 @@ import {Animation} from 'ionic/animations/animation';
*/ */
export class MenuType { export class MenuType {
constructor(menu: Menu) { constructor() {
this.open = new Animation(); this.open = new Animation();
this.close = new Animation(); this.close = new Animation();
} }
@ -88,16 +88,17 @@ class MenuRevealType extends MenuType {
let duration = 250; let duration = 250;
let openedX = (menu.width() * (menu.side == 'right' ? -1 : 1)) + 'px'; let openedX = (menu.width() * (menu.side == 'right' ? -1 : 1)) + 'px';
let closedX = '0px'
this.open.easing(easing).duration(duration); this.open.easing(easing).duration(duration);
this.close.easing(easing).duration(duration); this.close.easing(easing).duration(duration);
let contentOpen = new Animation(menu.getContentElement()); let contentOpen = new Animation(menu.getContentElement());
contentOpen.fromTo(TRANSLATE_X, CENTER, openedX); contentOpen.fromTo(TRANSLATE_X, closedX, openedX);
this.open.add(contentOpen); this.open.add(contentOpen);
let contentClose = new Animation(menu.getContentElement()); let contentClose = new Animation(menu.getContentElement());
contentClose.fromTo(TRANSLATE_X, openedX, CENTER); contentClose.fromTo(TRANSLATE_X, openedX, closedX);
this.close.add(contentClose); this.close.add(contentClose);
} }
} }
@ -117,13 +118,23 @@ class MenuOverlayType extends MenuType {
let duration = 250; let duration = 250;
let backdropOpacity = 0.5; let backdropOpacity = 0.5;
let closedX = (menu.width() * (menu.side == 'right' ? 1 : -1)) + 'px'; let closedX, openedX;
if (menu.side == 'right') {
// right side
closedX = menu.platform.width() + 'px';
openedX = (menu.platform.width() - menu.width() - 8) + 'px';
} else {
// left side
closedX = -menu.width() + 'px';
openedX = '8px';
}
this.open.easing(easing).duration(duration); this.open.easing(easing).duration(duration);
this.close.easing(easing).duration(duration); this.close.easing(easing).duration(duration);
let menuOpen = new Animation(menu.getMenuElement()); let menuOpen = new Animation(menu.getMenuElement());
menuOpen.fromTo(TRANSLATE_X, closedX, '8px'); menuOpen.fromTo(TRANSLATE_X, closedX, openedX);
this.open.add(menuOpen); this.open.add(menuOpen);
let backdropOpen = new Animation(menu.getBackdropElement()); let backdropOpen = new Animation(menu.getBackdropElement());
@ -131,7 +142,7 @@ class MenuOverlayType extends MenuType {
this.open.add(backdropOpen); this.open.add(backdropOpen);
let menuClose = new Animation(menu.getMenuElement()); let menuClose = new Animation(menu.getMenuElement());
menuClose.fromTo(TRANSLATE_X, '8px', closedX); menuClose.fromTo(TRANSLATE_X, openedX, closedX);
this.close.add(menuClose); this.close.add(menuClose);
let backdropClose = new Animation(menu.getBackdropElement()); let backdropClose = new Animation(menu.getBackdropElement());
@ -144,4 +155,3 @@ Menu.register('overlay', MenuOverlayType);
const OPACITY = 'opacity'; const OPACITY = 'opacity';
const TRANSLATE_X = 'translateX'; const TRANSLATE_X = 'translateX';
const CENTER = '0px';

View File

@ -4,6 +4,7 @@ import {Ion} from '../ion';
import {IonicApp} from '../app/app'; import {IonicApp} from '../app/app';
import {IonicConfig} from '../../config/config'; import {IonicConfig} from '../../config/config';
import {IonicComponent} from '../../config/annotations'; import {IonicComponent} from '../../config/annotations';
import {IonicPlatform} from '../../platform/platform';
import * as gestures from './menu-gestures'; import * as gestures from './menu-gestures';
@ -35,10 +36,16 @@ import * as gestures from './menu-gestures';
}) })
export class Menu extends Ion { export class Menu extends Ion {
constructor(app: IonicApp, elementRef: ElementRef, config: IonicConfig) { constructor(
app: IonicApp,
elementRef: ElementRef,
config: IonicConfig,
platform: IonicPlatform
) {
super(elementRef, config); super(elementRef, config);
this.app = app; this.app = app;
this.platform = platform;
this.opening = new EventEmitter('opening'); this.opening = new EventEmitter('opening');
this.isOpen = false; this.isOpen = false;
this._disableTime = 0; this._disableTime = 0;
@ -46,9 +53,9 @@ export class Menu extends Ion {
onInit() { onInit() {
super.onInit(); super.onInit();
this.contentElement = (this.content instanceof Node) ? this.content : this.content.getNativeElement(); this._cntEle = (this.content instanceof Node) ? this.content : this.content.getNativeElement();
if (!this.contentElement) { if (!this._cntEle) {
return console.error('Menu: must have a [content] element to listen for drag events on. Example:\n\n<ion-menu [content]="content"></ion-menu>\n\n<ion-content #content></ion-content>'); return console.error('Menu: must have a [content] element to listen for drag events on. Example:\n\n<ion-menu [content]="content"></ion-menu>\n\n<ion-content #content></ion-content>');
} }
@ -61,8 +68,8 @@ export class Menu extends Ion {
this._initGesture(); this._initGesture();
this._initType(this.type); this._initType(this.type);
this.contentElement.classList.add('menu-content'); this._cntEle.classList.add('menu-content');
this.contentElement.classList.add('menu-content-' + this.type); this._cntEle.classList.add('menu-content-' + this.type);
let self = this; let self = this;
this.onContentClick = function(ev) { this.onContentClick = function(ev) {
@ -161,11 +168,11 @@ export class Menu extends Ion {
this.isOpen = isOpen; this.isOpen = isOpen;
this.contentElement.classList[isOpen ? 'add' : 'remove']('menu-content-open'); this._cntEle.classList[isOpen ? 'add' : 'remove']('menu-content-open');
this.contentElement.removeEventListener('click', this.onContentClick); this._cntEle.removeEventListener('click', this.onContentClick);
if (isOpen) { if (isOpen) {
this.contentElement.addEventListener('click', this.onContentClick); this._cntEle.addEventListener('click', this.onContentClick);
} else { } else {
this.getNativeElement().classList.remove('show-menu'); this.getNativeElement().classList.remove('show-menu');
@ -220,7 +227,7 @@ export class Menu extends Ion {
* @return {Element} The Menu's associated content element. * @return {Element} The Menu's associated content element.
*/ */
getContentElement() { getContentElement() {
return this.contentElement; return this._cntEle;
} }
/** /**
@ -239,7 +246,7 @@ export class Menu extends Ion {
this.app.unregister(this.id); this.app.unregister(this.id);
this._gesture && this._gesture.destroy(); this._gesture && this._gesture.destroy();
this._type && this._type.onDestroy(); this._type && this._type.onDestroy();
this.contentElement = null; this._cntEle = null;
} }
} }

View File

@ -36,9 +36,9 @@ class E2EApp {
]; ];
} }
openPage(menu, page) { openPage(page) {
// close the menu when clicking a link from the menu // close the menu when clicking a link from the menu
menu.close(); this.app.getComponent('leftMenu').close();
// Reset the content nav to have just this page // Reset the content nav to have just this page
// we wouldn't want the back button to show in this scenario // we wouldn't want the back button to show in this scenario

View File

@ -1,4 +1,4 @@
<ion-menu #menu [content]="content"> <ion-menu [content]="content" id="leftMenu">
<ion-toolbar secondary> <ion-toolbar secondary>
<ion-title>Left Menu</ion-title> <ion-title>Left Menu</ion-title>
@ -8,11 +8,35 @@
<ion-list> <ion-list>
<button ion-item *ng-for="#p of pages" (click)="openPage(menu, p)"> <button ion-item *ng-for="#p of pages" (click)="openPage(p)">
{{p.title}} {{p.title}}
</button> </button>
<button ion-item menu-toggle no-forward-icon class="e2eCloseMenu"> <button ion-item menu-toggle="leftMenu" no-forward-icon class="e2eCloseMenu">
Close Menu
</button>
</ion-list>
</ion-content>
</ion-menu>
<ion-menu side="right" [content]="content" id="rightMenu">
<ion-toolbar secondary>
<ion-title>Right Menu</ion-title>
</ion-toolbar>
<ion-content>
<ion-list>
<button ion-item *ng-for="#p of pages" (click)="openPage(p)">
{{p.title}}
</button>
<button ion-item menu-toggle="rightMenu" no-forward-icon class="e2eCloseMenu">
Close Menu Close Menu
</button> </button>

View File

@ -1,7 +1,7 @@
<ion-navbar *navbar> <ion-navbar *navbar>
<a menu-toggle> <a menu-toggle="leftMenu">
<icon menu></icon> <icon menu></icon>
</a> </a>
@ -21,19 +21,23 @@
</button> </button>
</ion-nav-items> </ion-nav-items>
<a menu-toggle secondary> <a menu-toggle="rightMenu" secondary>
<icon menu></icon> <icon menu></icon>
</a> </a>
</ion-navbar> </ion-navbar>
<ion-content #content padding> <ion-content padding>
<h3>Page 1</h3> <h3>Page 1</h3>
<p> <p>
<button class="e2eContentToggleMenu" menu-toggle>Toggle Menu</button> <button class="e2eContentToggleMenu" menu-toggle="leftMenu">Toggle Left Menu</button>
</p>
<p>
<button class="e2eContentToggleMenu" menu-toggle="rightMenu">Toggle Right Menu</button>
</p> </p>
<f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f> <f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f>

View File

@ -1,7 +1,7 @@
<ion-navbar *navbar> <ion-navbar *navbar>
<a menu-toggle> <a menu-toggle="leftMenu">
<icon menu></icon> <icon menu></icon>
</a> </a>
@ -11,12 +11,12 @@
</ion-navbar> </ion-navbar>
<ion-content #content padding> <ion-content padding>
<h3>Page 2</h3> <h3>Page 2</h3>
<p> <p>
<button menu-toggle class="e2eContentToggleMenu">Toggle Menu</button> <button menu-toggle="leftMenu" class="e2eContentToggleMenu">Toggle Left Menu</button>
</p> </p>
<p> <p>

View File

@ -1,7 +1,7 @@
<ion-navbar *navbar> <ion-navbar *navbar>
<a menu-toggle> <a menu-toggle="leftMenu">
<icon menu></icon> <icon menu></icon>
</a> </a>
@ -12,12 +12,12 @@
</ion-navbar> </ion-navbar>
<ion-content #content padding> <ion-content padding>
<h3>Page 3</h3> <h3>Page 3</h3>
<p> <p>
<button menu-toggle>Toggle Menu</button> <button menu-toggle="leftMenu">Toggle Left Menu</button>
</p> </p>
<f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f> <f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f>

View File

@ -43,6 +43,12 @@ $toolbar-md-button-font-size: 1.4rem !default;
} }
} }
[menu-toggle][secondary],
[menu-toggle][secondary].activated {
margin: 0 2px;
min-width: 28px;
}
} }
ion-title { ion-title {