UNPKG

ionic-framework

Version:
402 lines 14.2 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'); /** * _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. * * 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]="contentRef"> * <ion-content> * <ion-list> * ... * </ion-list> * </ion-content> * </ion-menu> * * <ion-nav #content-ref [root]="rootPage"></ion-nav> * ``` * * By default, Menus are on the left, but this can be overriden with the `side` * property: * ```html * <ion-menu [content]="contentRef" 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 menu-toggle and * menu-close 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]="contentRef" type="overlay"></ion-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(app, elementRef, config, platform, keyboard) { _super.call(this, elementRef, config); this.app = app; this.platform = platform; this.keyboard = keyboard; this.opening = new core_1.EventEmitter('opening'); this.isOpen = false; this._preventTime = 0; this.isEnabled = true; } /** * @private */ Menu.prototype.ngOnInit = function () { _super.prototype.ngOnInit.call(this); var self = this; var content = self.content; self._cntEle = (content instanceof Node) ? content : content && content.getNativeElement && content.getNativeElement(); if (!self._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-nav #content></ion-nav>'); } if (self.side !== 'left' && self.side !== 'right') { self.side = 'left'; } 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 () { 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; }; /** * @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} TODO */ 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 menu-toggle 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) return; this._before(); this._getType().setProgressStart(this.isOpen); }; /** * @private */ Menu.prototype.setProgess = function (value) { // user actively dragging the menu if (this.isEnabled) { 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._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 menu-toggle this._preventTime = Date.now() + 20; }; /** * @private */ Menu.prototype._isPrevented = function () { return this._preventTime > Date.now(); }; /** * TODO * @return {TODO} TODO */ Menu.prototype.open = function () { return this.setOpen(true); }; /** * TODO * @return {TODO} TODO */ Menu.prototype.close = function () { return this.setOpen(false); }; /** * TODO * @return {TODO} TODO */ 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; }; /** * @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; }; /** * @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) { console.error('Menu with id "' + menuId + '" cannot be found for menu-toggle'); return; } } else { menu = app.getComponent('leftMenu'); if (!menu) { menu = app.getComponent('rightMenu'); } if (!menu) { console.error('Menu with id "leftMenu" or "rightMenu" cannot be found for menu-toggle'); return; } } return menu; }; Menu = __decorate([ core_1.Component({ selector: 'ion-menu', inputs: [ 'content', 'dragThreshold', 'id', 'side', 'type' ], defaultInputs: { 'side': 'left', 'menuType': 'reveal' }, outputs: ['opening'], host: { 'role': 'navigation', '[attr.side]': 'side', '[attr.type]': 'type' }, template: '<ng-content></ng-content><div tappable disable-activated class="backdrop"></div>', directives: [core_1.forwardRef(function () { return MenuBackdrop; })] }), __metadata('design:paramtypes', [(typeof (_a = typeof app_1.IonicApp !== 'undefined' && app_1.IonicApp) === 'function' && _a) || Object, (typeof (_b = typeof core_1.ElementRef !== 'undefined' && core_1.ElementRef) === 'function' && _b) || Object, (typeof (_c = typeof config_1.Config !== 'undefined' && config_1.Config) === 'function' && _c) || Object, (typeof (_d = typeof platform_1.Platform !== 'undefined' && platform_1.Platform) === 'function' && _d) || Object, (typeof (_e = typeof keyboard_1.Keyboard !== 'undefined' && keyboard_1.Keyboard) === 'function' && _e) || Object]) ], Menu); return Menu; var _a, _b, _c, _d, _e; })(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) { console.debug('backdrop clicked'); 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, (typeof (_a = typeof core_1.ElementRef !== 'undefined' && core_1.ElementRef) === 'function' && _a) || Object]) ], MenuBackdrop); return MenuBackdrop; var _a; })();