UNPKG

ionic-angular

Version:

A powerful framework for building mobile and progressive web apps with JavaScript and Angular 2

577 lines 18.8 kB
import { ChangeDetectionStrategy, Component, ContentChildren, ContentChild, Directive, ElementRef, EventEmitter, Input, Optional, Output, Renderer, ViewEncapsulation, NgZone } from '@angular/core'; import { isPresent, swipeShouldReset } from '../../util/util'; import { Item } from './item'; import { List } from '../list/list'; import { Platform } from '../../platform/platform'; import { DomController } from '../../platform/dom-controller'; var /** @type {?} */ SWIPE_MARGIN = 30; var /** @type {?} */ ELASTIC_FACTOR = 0.55; /** * \@name ItemOptions * \@description * The option buttons for an `ion-item-sliding`. These buttons can be placed either on the left or right side. * You can combine the `(ionSwipe)` event plus the `expandable` directive to create a full swipe action for the item. * * \@usage * * ```html * <ion-item-sliding> * <ion-item> * Item 1 * </ion-item> * <ion-item-options side="right" (ionSwipe)="saveItem(item)"> * <button ion-button expandable (click)="saveItem(item)"> * <ion-icon name="star"></ion-icon> * </button> * </ion-item-options> * </ion-item-sliding> * ``` */ export var ItemOptions = (function () { /** * @param {?} _elementRef * @param {?} _renderer */ function ItemOptions(_elementRef, _renderer) { this._elementRef = _elementRef; this._renderer = _renderer; /** * @output {event} Emitted when the item has been fully swiped. */ this.ionSwipe = new EventEmitter(); } /** * @return {?} */ ItemOptions.prototype.getSides = function () { if (isPresent(this.side) && this.side === 'left') { return 1 /* Left */; } else { return 2 /* Right */; } }; /** * @return {?} */ ItemOptions.prototype.width = function () { return this._elementRef.nativeElement.offsetWidth; }; ItemOptions.decorators = [ { type: Directive, args: [{ selector: 'ion-item-options', },] }, ]; /** @nocollapse */ ItemOptions.ctorParameters = function () { return [ { type: ElementRef, }, { type: Renderer, }, ]; }; ItemOptions.propDecorators = { 'side': [{ type: Input },], 'ionSwipe': [{ type: Output },], }; return ItemOptions; }()); function ItemOptions_tsickle_Closure_declarations() { /** @type {?} */ ItemOptions.decorators; /** * @nocollapse * @type {?} */ ItemOptions.ctorParameters; /** @type {?} */ ItemOptions.propDecorators; /** * \@input {string} The side the option button should be on. Defaults to `"right"`. * If you have multiple `ion-item-options`, a side must be provided for each. * @type {?} */ ItemOptions.prototype.side; /** * \@output {event} Emitted when the item has been fully swiped. * @type {?} */ ItemOptions.prototype.ionSwipe; /** @type {?} */ ItemOptions.prototype._elementRef; /** @type {?} */ ItemOptions.prototype._renderer; } /** * \@name ItemSliding * \@description * A sliding item is a list item that can be swiped to reveal buttons. It requires * an [Item](../Item) component as a child and a [List](../../list/List) component as * a parent. All buttons to reveal can be placed in the `<ion-item-options>` element. * * \@usage * ```html * <ion-list> * <ion-item-sliding #item> * <ion-item> * Item * </ion-item> * <ion-item-options side="left"> * <button ion-button (click)="favorite(item)">Favorite</button> * <button ion-button color="danger" (click)="share(item)">Share</button> * </ion-item-options> * * <ion-item-options side="right"> * <button ion-button (click)="unread(item)">Unread</button> * </ion-item-options> * </ion-item-sliding> * </ion-list> * ``` * * ### Swipe Direction * By default, the buttons are revealed when the sliding item is swiped from right to left, * so the buttons are placed in the right side. But it's also possible to reveal them * in the right side (sliding from left to right) by setting the `side` attribute * on the `ion-item-options` element. Up to 2 `ion-item-options` can used at the same time * in order to reveal two different sets of buttons depending the swipping direction. * * ```html * <ion-item-options side="right"> * <button ion-button (click)="archive(item)"> * <ion-icon name="archive"></ion-icon> * Archive * </button> * </ion-item-options> * * <ion-item-options side="left"> * <button ion-button (click)="archive(item)"> * <ion-icon name="archive"></ion-icon> * Archive * </button> * </ion-item-options> * ``` * * ### Listening for events (ionDrag) and (ionSwipe) * It's possible to know the current relative position of the sliding item by subscribing * to the (ionDrag)` event. * * ```html * <ion-item-sliding (ionDrag)="logDrag($event)"> * <ion-item>Item</ion-item> * <ion-item-options> * <button ion-button>Favorite</button> * </ion-item-options> * </ion-item-sliding> * ``` * * ### Button Layout * If an icon is placed with text in the option button, by default it will * display the icon on top of the text. This can be changed to display the icon * to the left of the text by setting `icon-left` as an attribute on the * `<ion-item-options>` element. * * ```html * <ion-item-options icon-left> * <button ion-button (click)="archive(item)"> * <ion-icon name="archive"></ion-icon> * Archive * </button> * </ion-item-options> * * ``` * * * \@demo /docs/v2/demos/src/item-sliding/ * @see {\@link /docs/v2/components#lists List Component Docs} * @see {\@link ../Item Item API Docs} * @see {\@link ../../list/List List API Docs} */ export var ItemSliding = (function () { /** * @param {?} list * @param {?} _plt * @param {?} _dom * @param {?} _renderer * @param {?} _elementRef * @param {?} _zone */ function ItemSliding(list, _plt, _dom, _renderer, _elementRef, _zone) { this._plt = _plt; this._dom = _dom; this._renderer = _renderer; this._elementRef = _elementRef; this._zone = _zone; this._openAmount = 0; this._startX = 0; this._optsWidthRightSide = 0; this._optsWidthLeftSide = 0; this._tmr = null; this._optsDirty = true; this._state = 2 /* Disabled */; /** * @output {event} Emitted when the sliding position changes. * It reports the relative position. * * ```ts * ondrag(item) { * let percent = item.getSlidingPercent(); * if (percent > 0) { * // positive * console.log('right side'); * } else { * // negative * console.log('left side'); * } * if (Math.abs(percent) > 1) { * console.log('overscroll'); * } * } * ``` * */ this.ionDrag = new EventEmitter(); list && list.containsSlidingItem(true); _elementRef.nativeElement.$ionComponent = this; this.setElementClass('item-wrapper', true); } Object.defineProperty(ItemSliding.prototype, "_itemOptions", { /** * @param {?} itemOptions * @return {?} */ set: function (itemOptions) { var /** @type {?} */ sides = 0; // Reset left and right options in case they were removed this._leftOptions = this._rightOptions = null; for (var _i = 0, _a = itemOptions.toArray(); _i < _a.length; _i++) { var item = _a[_i]; var /** @type {?} */ side = item.getSides(); if (side === 1 /* Left */) { this._leftOptions = item; } else { this._rightOptions = item; } sides |= item.getSides(); } this._optsDirty = true; this._sides = sides; }, enumerable: true, configurable: true }); /** * @return {?} */ ItemSliding.prototype.getOpenAmount = function () { return this._openAmount; }; /** * @return {?} */ ItemSliding.prototype.getSlidingPercent = function () { var /** @type {?} */ openAmount = this._openAmount; if (openAmount > 0) { return openAmount / this._optsWidthRightSide; } else if (openAmount < 0) { return openAmount / this._optsWidthLeftSide; } else { return 0; } }; /** * @param {?} startX * @return {?} */ ItemSliding.prototype.startSliding = function (startX) { if (this._tmr) { this._plt.cancelTimeout(this._tmr); this._tmr = null; } if (this._openAmount === 0) { this._optsDirty = true; this._setState(4 /* Enabled */); } this._startX = startX + this._openAmount; this.item.setElementStyle(this._plt.Css.transition, 'none'); }; /** * @param {?} x * @return {?} */ ItemSliding.prototype.moveSliding = function (x) { if (this._optsDirty) { this.calculateOptsWidth(); return; } var /** @type {?} */ openAmount = (this._startX - x); switch (this._sides) { case 2 /* Right */: openAmount = Math.max(0, openAmount); break; case 1 /* Left */: openAmount = Math.min(0, openAmount); break; case 3 /* Both */: break; case 0 /* None */: return; default: (void 0) /* assert */; break; } if (openAmount > this._optsWidthRightSide) { var /** @type {?} */ optsWidth = this._optsWidthRightSide; openAmount = optsWidth + (openAmount - optsWidth) * ELASTIC_FACTOR; } else if (openAmount < -this._optsWidthLeftSide) { var /** @type {?} */ optsWidth = -this._optsWidthLeftSide; openAmount = optsWidth + (openAmount - optsWidth) * ELASTIC_FACTOR; } this._setOpenAmount(openAmount, false); return openAmount; }; /** * @param {?} velocity * @return {?} */ ItemSliding.prototype.endSliding = function (velocity) { var /** @type {?} */ restingPoint = (this._openAmount > 0) ? this._optsWidthRightSide : -this._optsWidthLeftSide; // Check if the drag didn't clear the buttons mid-point // and we aren't moving fast enough to swipe open var /** @type {?} */ isResetDirection = (this._openAmount > 0) === !(velocity < 0); var /** @type {?} */ isMovingFast = Math.abs(velocity) > 0.3; var /** @type {?} */ isOnCloseZone = Math.abs(this._openAmount) < Math.abs(restingPoint / 2); if (swipeShouldReset(isResetDirection, isMovingFast, isOnCloseZone)) { restingPoint = 0; } this._setOpenAmount(restingPoint, true); this.fireSwipeEvent(); return restingPoint; }; /** * @return {?} */ ItemSliding.prototype.fireSwipeEvent = function () { var _this = this; if (this._state & 32 /* SwipeRight */) { this._zone.run(function () { return _this._rightOptions.ionSwipe.emit(_this); }); } else if (this._state & 64 /* SwipeLeft */) { this._zone.run(function () { return _this._leftOptions.ionSwipe.emit(_this); }); } }; /** * @return {?} */ ItemSliding.prototype.calculateOptsWidth = function () { if (!this._optsDirty) { return; } this._optsWidthRightSide = 0; if (this._rightOptions) { this._optsWidthRightSide = this._rightOptions.width(); (void 0) /* assert */; } this._optsWidthLeftSide = 0; if (this._leftOptions) { this._optsWidthLeftSide = this._leftOptions.width(); (void 0) /* assert */; } this._optsDirty = false; }; /** * @param {?} openAmount * @param {?} isFinal * @return {?} */ ItemSliding.prototype._setOpenAmount = function (openAmount, isFinal) { var _this = this; var /** @type {?} */ platform = this._plt; if (this._tmr) { platform.cancelTimeout(this._tmr); this._tmr = null; } this._openAmount = openAmount; if (isFinal) { this.item.setElementStyle(platform.Css.transition, ''); } else { if (openAmount > 0) { var /** @type {?} */ state = (openAmount >= (this._optsWidthRightSide + SWIPE_MARGIN)) ? 8 /* Right */ | 32 /* SwipeRight */ : 8 /* Right */; this._setState(state); } else if (openAmount < 0) { var /** @type {?} */ state = (openAmount <= (-this._optsWidthLeftSide - SWIPE_MARGIN)) ? 16 /* Left */ | 64 /* SwipeLeft */ : 16 /* Left */; this._setState(state); } } if (openAmount === 0) { this._tmr = platform.timeout(function () { _this._setState(2 /* Disabled */); _this._tmr = null; }, 600); this.item.setElementStyle(platform.Css.transform, ''); return; } this.item.setElementStyle(platform.Css.transform, "translate3d(" + -openAmount + "px,0,0)"); var /** @type {?} */ ionDrag = this.ionDrag; if (ionDrag.observers.length > 0) { ionDrag.emit(this); } }; /** * @param {?} state * @return {?} */ ItemSliding.prototype._setState = function (state) { if (state === this._state) { return; } this.setElementClass('active-slide', (state !== 2 /* Disabled */)); this.setElementClass('active-options-right', !!(state & 8 /* Right */)); this.setElementClass('active-options-left', !!(state & 16 /* Left */)); this.setElementClass('active-swipe-right', !!(state & 32 /* SwipeRight */)); this.setElementClass('active-swipe-left', !!(state & 64 /* SwipeLeft */)); this._state = state; }; /** * Close the sliding item. Items can also be closed from the [List](../../list/List). * * The sliding item can be closed by grabbing a reference to `ItemSliding`. In the * below example, the template reference variable `slidingItem` is placed on the element * and passed to the `share` method. * * ```html * <ion-list> * <ion-item-sliding #slidingItem> * <ion-item> * Item * </ion-item> * <ion-item-options> * <button ion-button (click)="share(slidingItem)">Share</button> * </ion-item-options> * </ion-item-sliding> * </ion-list> * ``` * * ```ts * import { Component } from '\@angular/core'; * import { ItemSliding } from 'ionic-angular'; * * \@Component({...}) * export class MyClass { * constructor() { } * * share(slidingItem: ItemSliding) { * slidingItem.close(); * } * } * ``` * @return {?} */ ItemSliding.prototype.close = function () { this._setOpenAmount(0, true); }; /** * @param {?} cssClass * @param {?} shouldAdd * @return {?} */ ItemSliding.prototype.setElementClass = function (cssClass, shouldAdd) { this._renderer.setElementClass(this._elementRef.nativeElement, cssClass, shouldAdd); }; ItemSliding.decorators = [ { type: Component, args: [{ selector: 'ion-item-sliding', template: "\n <ng-content select=\"ion-item,[ion-item]\"></ng-content>\n <ng-content select=\"ion-item-options\"></ng-content>\n ", changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None },] }, ]; /** @nocollapse */ ItemSliding.ctorParameters = function () { return [ { type: List, decorators: [{ type: Optional },] }, { type: Platform, }, { type: DomController, }, { type: Renderer, }, { type: ElementRef, }, { type: NgZone, }, ]; }; ItemSliding.propDecorators = { 'item': [{ type: ContentChild, args: [Item,] },], 'ionDrag': [{ type: Output },], '_itemOptions': [{ type: ContentChildren, args: [ItemOptions,] },], }; return ItemSliding; }()); function ItemSliding_tsickle_Closure_declarations() { /** @type {?} */ ItemSliding.decorators; /** * @nocollapse * @type {?} */ ItemSliding.ctorParameters; /** @type {?} */ ItemSliding.propDecorators; /** @type {?} */ ItemSliding.prototype._openAmount; /** @type {?} */ ItemSliding.prototype._startX; /** @type {?} */ ItemSliding.prototype._optsWidthRightSide; /** @type {?} */ ItemSliding.prototype._optsWidthLeftSide; /** @type {?} */ ItemSliding.prototype._sides; /** @type {?} */ ItemSliding.prototype._tmr; /** @type {?} */ ItemSliding.prototype._leftOptions; /** @type {?} */ ItemSliding.prototype._rightOptions; /** @type {?} */ ItemSliding.prototype._optsDirty; /** @type {?} */ ItemSliding.prototype._state; /** @type {?} */ ItemSliding.prototype.item; /** * \@output {event} Emitted when the sliding position changes. * It reports the relative position. * * ```ts * ondrag(item) { * let percent = item.getSlidingPercent(); * if (percent > 0) { * // positive * console.log('right side'); * } else { * // negative * console.log('left side'); * } * if (Math.abs(percent) > 1) { * console.log('overscroll'); * } * } * ``` * * @type {?} */ ItemSliding.prototype.ionDrag; /** @type {?} */ ItemSliding.prototype._plt; /** @type {?} */ ItemSliding.prototype._dom; /** @type {?} */ ItemSliding.prototype._renderer; /** @type {?} */ ItemSliding.prototype._elementRef; /** @type {?} */ ItemSliding.prototype._zone; } //# sourceMappingURL=item-sliding.js.map