UNPKG

ionic-framework

Version:

The ionic-framework package comes with both Javascript and Sass frontend dependencies, located in the root of the package, and a Node API, located in `tooling/`.

475 lines (474 loc) 16.1 kB
var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; var core_1 = require('angular2/core'); var ion_1 = require('../ion'); var app_1 = require('../app/app'); var config_1 = require('../../config/config'); var platform_1 = require('../../platform/platform'); var keyboard_1 = require('../../util/keyboard'); var gestures = require('./menu-gestures'); /** * @name Menu * @description * _For basic Menu usage, see the [Menu section](../../../../components/#menus) * of the Component docs._ * * Menu is a side-menu navigation that can be dragged out or toggled to show. * * @usage * In order to use Menu, you must specify a [reference](https://angular.io/docs/ts/latest/guide/user-input.html#local-variables) * to the content element that Menu should listen on for drag events, using the `content` property: * * ```html * <ion-menu [content]="mycontent"> * <ion-content> * <ion-list> * ... * </ion-list> * </ion-content> * </ion-menu> * * <ion-nav #mycontent [root]="rootPage"></ion-nav> * ``` * * By default, Menus are on the left, but this can be overriden with the `side` * property: * ```html * <ion-menu [content]="mycontent" side="right"></ion-menu> * ``` * * Menus can optionally be given an `id` attribute which allows the app to * to get ahold of menu references. If no `id` is given then the menu * automatically receives an `id` created from the side it is on, such as * `leftMenu` or `rightMenu`. When using more than one menu it is always * recommended to give each menu a unique `id`. Additionally menuToggle and * menuClose directives should be given menu id values of their respective * menu. * * Menu supports two display styles: overlay, and reveal. Overlay * is the traditional Android drawer style, and Reveal is the traditional iOS * style. By default, Menu will adjust to the correct style for the platform, * but this can be overriden using the `type` property: * ```html * <ion-menu [content]="mycontent" type="overlay"></ion-menu> * ``` * * To programatically interact with the menu, you first get the menu component. * * ```ts * @Page({ * `<ion-menu [content]="mycontent" id="leftMenu"></ion-menu> * <ion-nav #mycontent [root]="rootPage"></ion-nav>` * )} * export class MyClass{ * constructor(app: IonicApp){ * this.app = app; * this.menu; * } * * // Wait until the page is ready * ngAfterViewInit(){ * this.menu = this.app.getComponent('leftMenu'); * } * * // Open the menu programatically * openMenu(){ * this.menu.open(); * } * * } * ``` * * If you want to use any of the APIs down below, make sure to grabe the menu component by it's ID * * @demo /docs/v2/demos/menu/ * * @see {@link /docs/v2/components#menus Menu Component Docs} * @see {@link /docs/v2/components#navigation Navigation Component Docs} * @see {@link ../../nav/Nav Nav API Docs} * */ var Menu = (function (_super) { __extends(Menu, _super); function Menu(_elementRef, _config, _app, _platform, _renderer, _keyboard, _zone) { _super.call(this, _elementRef); this._elementRef = _elementRef; this._config = _config; this._app = _app; this._platform = _platform; this._renderer = _renderer; this._keyboard = _keyboard; this._zone = _zone; this._preventTime = 0; this.isOpen = false; this.isEnabled = true; this.isSwipeEnabled = true; this.opening = new core_1.EventEmitter(); } /** * @private */ Menu.prototype.ngOnInit = function () { var self = this; var content = self.content; self._cntEle = (content instanceof Node) ? content : content && content.getNativeElement && content.getNativeElement(); if (!self._cntEle) { return void 0; } if (self.side !== 'left' && self.side !== 'right') { self.side = 'left'; } self._renderer.setElementAttribute(self._elementRef.nativeElement, 'side', self.side); if (self.swipeEnabled === 'false') { self.isSwipeEnabled = false; } if (!self.id) { // Auto register self.id = self.side + 'Menu'; if (self._app.getComponent(self.id)) { // id already exists, make sure this one is unique self.id += (++menuIds); } self._app.register(self.id, self); } self._initGesture(); self._initType(self.type); self._cntEle.classList.add('menu-content'); self._cntEle.classList.add('menu-content-' + self.type); self.onContentClick = function (ev) { if (self.isEnabled) { ev.preventDefault(); ev.stopPropagation(); self.close(); } }; }; /** * @private */ Menu.prototype._initGesture = function () { var _this = this; this._zone.runOutsideAngular(function () { switch (_this.side) { case 'right': _this._gesture = new gestures.RightMenuGesture(_this); break; case 'left': _this._gesture = new gestures.LeftMenuGesture(_this); break; } _this._targetGesture = new gestures.TargetGesture(_this); }); }; /** * @private */ Menu.prototype._initType = function (type) { type = type && type.trim().toLowerCase(); if (!type) { type = this._config.get('menuType'); } this.type = type; this._renderer.setElementAttribute(this._elementRef.nativeElement, 'menuType', type); }; /** * @private */ Menu.prototype._getType = function () { if (!this._type) { this._type = new menuTypes[this.type](this); if (this._config.get('animate') === false) { this._type.open.duration(33); this._type.close.duration(33); } } return this._type; }; /** * Sets the state of the Menu to open or not. * @param {boolean} isOpen If the Menu is open or not. * @return {Promise} returns a promise once set */ Menu.prototype.setOpen = function (shouldOpen) { var _this = this; // _isPrevented is used to prevent unwanted opening/closing after swiping open/close // or swiping open the menu while pressing down on the menuToggle button if (shouldOpen === this.isOpen || this._isPrevented()) { return Promise.resolve(); } this._before(); return this._getType().setOpen(shouldOpen).then(function () { _this._after(shouldOpen); }); }; /** * @private */ Menu.prototype.setProgressStart = function () { // user started swiping the menu open/close if (this._isPrevented() || !this.isEnabled || !this.isSwipeEnabled) return; this._before(); this._getType().setProgressStart(this.isOpen); }; /** * @private */ Menu.prototype.setProgess = function (value) { // user actively dragging the menu if (this.isEnabled && this.isSwipeEnabled) { this._prevent(); this._getType().setProgess(value); this.opening.next(value); } }; /** * @private */ Menu.prototype.setProgressEnd = function (shouldComplete) { var _this = this; // user has finished dragging the menu if (this.isEnabled && this.isSwipeEnabled) { this._prevent(); this._getType().setProgressEnd(shouldComplete).then(function (isOpen) { _this._after(isOpen); }); } }; /** * @private */ Menu.prototype._before = function () { // this places the menu into the correct location before it animates in // this css class doesn't actually kick off any animations if (this.isEnabled) { this.getNativeElement().classList.add('show-menu'); this.getBackdropElement().classList.add('show-backdrop'); this._prevent(); this._keyboard.close(); } }; /** * @private */ Menu.prototype._after = function (isOpen) { // keep opening/closing the menu disabled for a touch more yet // only add listeners/css if it's enabled and isOpen // and only remove listeners/css if it's not open if ((this.isEnabled && isOpen) || !isOpen) { this._prevent(); this.isOpen = isOpen; this._cntEle.classList[isOpen ? 'add' : 'remove']('menu-content-open'); this._cntEle.removeEventListener('click', this.onContentClick); if (isOpen) { this._cntEle.addEventListener('click', this.onContentClick); } else { this.getNativeElement().classList.remove('show-menu'); this.getBackdropElement().classList.remove('show-backdrop'); } } }; /** * @private */ Menu.prototype._prevent = function () { // used to prevent unwanted opening/closing after swiping open/close // or swiping open the menu while pressing down on the menuToggle this._preventTime = Date.now() + 20; }; /** * @private */ Menu.prototype._isPrevented = function () { return this._preventTime > Date.now(); }; /** * Progamatically open the Menu * @return {Promise} returns a promise when the menu is fully opened */ Menu.prototype.open = function () { return this.setOpen(true); }; /** * Progamatically close the Menu * @return {Promise} returns a promise when the menu is fully closed */ Menu.prototype.close = function () { return this.setOpen(false); }; /** * Toggle the menu. If it's closed, it will open, and if opened, it will close * @return {Promise} returns a promise when the menu has been toggled */ Menu.prototype.toggle = function () { return this.setOpen(!this.isOpen); }; /** * Used to enable or disable a menu. For example, there could be multiple * left menus, but only one of them should be able to be dragged open. * @param {boolean} shouldEnable True if it should be enabled, false if not. * @return {Menu} Returns the instance of the menu, which is useful for chaining. */ Menu.prototype.enable = function (shouldEnable) { this.isEnabled = shouldEnable; if (!shouldEnable) { this.close(); } return this; }; /** * Used to enable or disable the ability to swipe open the menu. * @param {boolean} shouldEnable True if it should be swipe-able, false if not. * @return {Menu} Returns the instance of the menu, which is useful for chaining. */ Menu.prototype.swipeEnable = function (shouldEnable) { this.isSwipeEnabled = shouldEnable; return this; }; /** * @private */ Menu.prototype.getMenuElement = function () { return this.getNativeElement(); }; /** * @private */ Menu.prototype.getContentElement = function () { return this._cntEle; }; /** * @private */ Menu.prototype.getBackdropElement = function () { return this.backdrop.elementRef.nativeElement; }; /** * @private */ Menu.register = function (name, cls) { menuTypes[name] = cls; }; //static register(name:string , cls: typeof MenuType) { /** * @private */ Menu.prototype.ngOnDestroy = function () { this._app.unregister(this.id); this._gesture && this._gesture.destroy(); this._targetGesture && this._targetGesture.destroy(); this._type && this._type.ngOnDestroy(); this._cntEle = null; }; Menu.getById = function (app, menuId) { var menu = null; if (menuId) { menu = app.getComponent(menuId); if (!menu) { void 0; return; } } else { menu = app.getComponent('leftMenu'); if (!menu) { menu = app.getComponent('rightMenu'); } if (!menu) { void 0; return; } } return menu; }; __decorate([ core_1.Input(), __metadata('design:type', Object) ], Menu.prototype, "content", void 0); __decorate([ core_1.Input(), __metadata('design:type', String) ], Menu.prototype, "id", void 0); __decorate([ core_1.Input(), __metadata('design:type', String) ], Menu.prototype, "side", void 0); __decorate([ core_1.Input(), __metadata('design:type', String) ], Menu.prototype, "type", void 0); __decorate([ core_1.Input(), __metadata('design:type', String) ], Menu.prototype, "swipeEnabled", void 0); __decorate([ core_1.Input(), __metadata('design:type', Object) ], Menu.prototype, "maxEdgeStart", void 0); __decorate([ core_1.Output(), __metadata('design:type', core_1.EventEmitter) ], Menu.prototype, "opening", void 0); Menu = __decorate([ core_1.Component({ selector: 'ion-menu', host: { 'role': 'navigation', '[attr.side]': 'side', '[attr.type]': 'type', '[attr.swipeEnabled]': 'swipeEnabled' }, template: '<ng-content></ng-content><div tappable disable-activated class="backdrop"></div>', directives: [core_1.forwardRef(function () { return MenuBackdrop; })] }), __metadata('design:paramtypes', [core_1.ElementRef, config_1.Config, app_1.IonicApp, platform_1.Platform, core_1.Renderer, keyboard_1.Keyboard, core_1.NgZone]) ], Menu); return Menu; })(ion_1.Ion); exports.Menu = Menu; var menuTypes = {}; var menuIds = 0; var MenuBackdrop = (function () { function MenuBackdrop(menu, elementRef) { this.menu = menu; this.elementRef = elementRef; menu.backdrop = this; } /** * @private */ MenuBackdrop.prototype.clicked = function (ev) { void 0; ev.preventDefault(); ev.stopPropagation(); this.menu.close(); }; MenuBackdrop = __decorate([ core_1.Directive({ selector: '.backdrop', host: { '(click)': 'clicked($event)' } }), __param(0, core_1.Host()), __metadata('design:paramtypes', [Menu, core_1.ElementRef]) ], MenuBackdrop); return MenuBackdrop; })(); exports.MenuBackdrop = MenuBackdrop;