mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-19 03:32:21 +08:00
feat(menu): right side menus
This commit is contained in:
@ -35,3 +35,7 @@ ion-menu[type=overlay] {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ion-menu[type=overlay][side=right] {
|
||||
left: 8px;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import {Animation} from 'ionic/animations/animation';
|
||||
*/
|
||||
export class MenuType {
|
||||
|
||||
constructor(menu: Menu) {
|
||||
constructor() {
|
||||
this.open = new Animation();
|
||||
this.close = new Animation();
|
||||
}
|
||||
@ -88,16 +88,17 @@ class MenuRevealType extends MenuType {
|
||||
let duration = 250;
|
||||
|
||||
let openedX = (menu.width() * (menu.side == 'right' ? -1 : 1)) + 'px';
|
||||
let closedX = '0px'
|
||||
|
||||
this.open.easing(easing).duration(duration);
|
||||
this.close.easing(easing).duration(duration);
|
||||
|
||||
let contentOpen = new Animation(menu.getContentElement());
|
||||
contentOpen.fromTo(TRANSLATE_X, CENTER, openedX);
|
||||
contentOpen.fromTo(TRANSLATE_X, closedX, openedX);
|
||||
this.open.add(contentOpen);
|
||||
|
||||
let contentClose = new Animation(menu.getContentElement());
|
||||
contentClose.fromTo(TRANSLATE_X, openedX, CENTER);
|
||||
contentClose.fromTo(TRANSLATE_X, openedX, closedX);
|
||||
this.close.add(contentClose);
|
||||
}
|
||||
}
|
||||
@ -117,13 +118,23 @@ class MenuOverlayType extends MenuType {
|
||||
let duration = 250;
|
||||
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.close.easing(easing).duration(duration);
|
||||
|
||||
let menuOpen = new Animation(menu.getMenuElement());
|
||||
menuOpen.fromTo(TRANSLATE_X, closedX, '8px');
|
||||
menuOpen.fromTo(TRANSLATE_X, closedX, openedX);
|
||||
this.open.add(menuOpen);
|
||||
|
||||
let backdropOpen = new Animation(menu.getBackdropElement());
|
||||
@ -131,7 +142,7 @@ class MenuOverlayType extends MenuType {
|
||||
this.open.add(backdropOpen);
|
||||
|
||||
let menuClose = new Animation(menu.getMenuElement());
|
||||
menuClose.fromTo(TRANSLATE_X, '8px', closedX);
|
||||
menuClose.fromTo(TRANSLATE_X, openedX, closedX);
|
||||
this.close.add(menuClose);
|
||||
|
||||
let backdropClose = new Animation(menu.getBackdropElement());
|
||||
@ -144,4 +155,3 @@ Menu.register('overlay', MenuOverlayType);
|
||||
|
||||
const OPACITY = 'opacity';
|
||||
const TRANSLATE_X = 'translateX';
|
||||
const CENTER = '0px';
|
||||
|
@ -4,6 +4,7 @@ import {Ion} from '../ion';
|
||||
import {IonicApp} from '../app/app';
|
||||
import {IonicConfig} from '../../config/config';
|
||||
import {IonicComponent} from '../../config/annotations';
|
||||
import {IonicPlatform} from '../../platform/platform';
|
||||
import * as gestures from './menu-gestures';
|
||||
|
||||
|
||||
@ -35,10 +36,16 @@ import * as gestures from './menu-gestures';
|
||||
})
|
||||
export class Menu extends Ion {
|
||||
|
||||
constructor(app: IonicApp, elementRef: ElementRef, config: IonicConfig) {
|
||||
constructor(
|
||||
app: IonicApp,
|
||||
elementRef: ElementRef,
|
||||
config: IonicConfig,
|
||||
platform: IonicPlatform
|
||||
) {
|
||||
super(elementRef, config);
|
||||
|
||||
this.app = app;
|
||||
this.platform = platform;
|
||||
|
||||
this.opening = new EventEmitter('opening');
|
||||
this.isOpen = false;
|
||||
this._disableTime = 0;
|
||||
@ -46,9 +53,9 @@ export class Menu extends Ion {
|
||||
|
||||
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>');
|
||||
}
|
||||
|
||||
@ -61,8 +68,8 @@ export class Menu extends Ion {
|
||||
this._initGesture();
|
||||
this._initType(this.type);
|
||||
|
||||
this.contentElement.classList.add('menu-content');
|
||||
this.contentElement.classList.add('menu-content-' + this.type);
|
||||
this._cntEle.classList.add('menu-content');
|
||||
this._cntEle.classList.add('menu-content-' + this.type);
|
||||
|
||||
let self = this;
|
||||
this.onContentClick = function(ev) {
|
||||
@ -161,11 +168,11 @@ export class Menu extends Ion {
|
||||
|
||||
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) {
|
||||
this.contentElement.addEventListener('click', this.onContentClick);
|
||||
this._cntEle.addEventListener('click', this.onContentClick);
|
||||
|
||||
} else {
|
||||
this.getNativeElement().classList.remove('show-menu');
|
||||
@ -220,7 +227,7 @@ export class Menu extends Ion {
|
||||
* @return {Element} The Menu's associated content element.
|
||||
*/
|
||||
getContentElement() {
|
||||
return this.contentElement;
|
||||
return this._cntEle;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -239,7 +246,7 @@ export class Menu extends Ion {
|
||||
this.app.unregister(this.id);
|
||||
this._gesture && this._gesture.destroy();
|
||||
this._type && this._type.onDestroy();
|
||||
this.contentElement = null;
|
||||
this._cntEle = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -36,9 +36,9 @@ class E2EApp {
|
||||
];
|
||||
}
|
||||
|
||||
openPage(menu, page) {
|
||||
openPage(page) {
|
||||
// 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
|
||||
// we wouldn't want the back button to show in this scenario
|
||||
|
@ -1,4 +1,4 @@
|
||||
<ion-menu #menu [content]="content">
|
||||
<ion-menu [content]="content" id="leftMenu">
|
||||
|
||||
<ion-toolbar secondary>
|
||||
<ion-title>Left Menu</ion-title>
|
||||
@ -8,11 +8,35 @@
|
||||
|
||||
<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}}
|
||||
</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
|
||||
</button>
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
<ion-navbar *navbar>
|
||||
|
||||
<a menu-toggle>
|
||||
<a menu-toggle="leftMenu">
|
||||
<icon menu></icon>
|
||||
</a>
|
||||
|
||||
@ -21,19 +21,23 @@
|
||||
</button>
|
||||
</ion-nav-items>
|
||||
|
||||
<a menu-toggle secondary>
|
||||
<a menu-toggle="rightMenu" secondary>
|
||||
<icon menu></icon>
|
||||
</a>
|
||||
|
||||
</ion-navbar>
|
||||
|
||||
|
||||
<ion-content #content padding>
|
||||
<ion-content padding>
|
||||
|
||||
<h3>Page 1</h3>
|
||||
|
||||
<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>
|
||||
|
||||
<f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f>
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
<ion-navbar *navbar>
|
||||
|
||||
<a menu-toggle>
|
||||
<a menu-toggle="leftMenu">
|
||||
<icon menu></icon>
|
||||
</a>
|
||||
|
||||
@ -11,12 +11,12 @@
|
||||
|
||||
</ion-navbar>
|
||||
|
||||
<ion-content #content padding>
|
||||
<ion-content padding>
|
||||
|
||||
<h3>Page 2</h3>
|
||||
|
||||
<p>
|
||||
<button menu-toggle class="e2eContentToggleMenu">Toggle Menu</button>
|
||||
<button menu-toggle="leftMenu" class="e2eContentToggleMenu">Toggle Left Menu</button>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
<ion-navbar *navbar>
|
||||
|
||||
<a menu-toggle>
|
||||
<a menu-toggle="leftMenu">
|
||||
<icon menu></icon>
|
||||
</a>
|
||||
|
||||
@ -12,12 +12,12 @@
|
||||
</ion-navbar>
|
||||
|
||||
|
||||
<ion-content #content padding>
|
||||
<ion-content padding>
|
||||
|
||||
<h3>Page 3</h3>
|
||||
|
||||
<p>
|
||||
<button menu-toggle>Toggle Menu</button>
|
||||
<button menu-toggle="leftMenu">Toggle Left Menu</button>
|
||||
</p>
|
||||
|
||||
<f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f>
|
||||
|
@ -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 {
|
||||
|
Reference in New Issue
Block a user