123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410 |
- import { ChangeDetectionStrategy, Component, ContentChild, ContentChildren, ElementRef, EventEmitter, NgZone, Optional, Output, Renderer, ViewEncapsulation, forwardRef } from '@angular/core';
- import { swipeShouldReset } from '../../util/util';
- import { Item } from './item';
- import { List } from '../list/list';
- import { Platform } from '../../platform/platform';
- import { ItemOptions } from './item-options';
- var SWIPE_MARGIN = 30;
- var ELASTIC_FACTOR = 0.55;
- var ITEM_SIDE_FLAG_NONE = 0;
- var ITEM_SIDE_FLAG_LEFT = 1 << 0;
- var ITEM_SIDE_FLAG_RIGHT = 1 << 1;
- var ITEM_SIDE_FLAG_BOTH = ITEM_SIDE_FLAG_LEFT | ITEM_SIDE_FLAG_RIGHT;
- /**
- * @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-start` as an attribute on the
- * `<ion-item-options>` element.
- *
- * ```html
- * <ion-item-options icon-start>
- * <button ion-button (click)="archive(item)">
- * <ion-icon name="archive"></ion-icon>
- * Archive
- * </button>
- * </ion-item-options>
- *
- * ```
- *
- * ### Expandable Options
- *
- * Options can be expanded to take up the full width of the item if you swipe past
- * a certain point. This can be combined with the `ionSwipe` event to call methods
- * on the class.
- *
- * ```html
- *
- * <ion-item-sliding (ionSwipe)="delete(item)">
- * <ion-item>Item</ion-item>
- * <ion-item-options>
- * <button ion-button expandable (click)="delete(item)">Delete</button>
- * </ion-item-options>
- * </ion-item-sliding>
- * ```
- *
- * We can call `delete` by either clicking the button, or by doing a full swipe on the item.
- *
- * @demo /docs/demos/src/item-sliding/
- * @see {@link /docs/components#lists List Component Docs}
- * @see {@link ../Item Item API Docs}
- * @see {@link ../../list/List List API Docs}
- */
- var ItemSliding = (function () {
- function ItemSliding(list, _plt, _renderer, _elementRef, _zone) {
- this._plt = _plt;
- 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", {
- set: function (itemOptions) {
- var 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];
- if (item.isRightSide()) {
- this._rightOptions = item;
- sides |= ITEM_SIDE_FLAG_RIGHT;
- }
- else {
- this._leftOptions = item;
- sides |= ITEM_SIDE_FLAG_LEFT;
- }
- }
- this._optsDirty = true;
- this._sides = sides;
- },
- enumerable: true,
- configurable: true
- });
- /**
- * @hidden
- */
- ItemSliding.prototype.getOpenAmount = function () {
- return this._openAmount;
- };
- /**
- * @hidden
- */
- ItemSliding.prototype.getSlidingPercent = function () {
- var openAmount = this._openAmount;
- if (openAmount > 0) {
- return openAmount / this._optsWidthRightSide;
- }
- else if (openAmount < 0) {
- return openAmount / this._optsWidthLeftSide;
- }
- else {
- return 0;
- }
- };
- /**
- * @hidden
- */
- 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');
- };
- /**
- * @hidden
- */
- ItemSliding.prototype.moveSliding = function (x) {
- if (this._optsDirty) {
- this.calculateOptsWidth();
- return;
- }
- var openAmount = (this._startX - x);
- switch (this._sides) {
- case ITEM_SIDE_FLAG_RIGHT:
- openAmount = Math.max(0, openAmount);
- break;
- case ITEM_SIDE_FLAG_LEFT:
- openAmount = Math.min(0, openAmount);
- break;
- case ITEM_SIDE_FLAG_BOTH: break;
- case ITEM_SIDE_FLAG_NONE: return;
- default:
- (void 0) /* assert */;
- break;
- }
- if (openAmount > this._optsWidthRightSide) {
- var optsWidth = this._optsWidthRightSide;
- openAmount = optsWidth + (openAmount - optsWidth) * ELASTIC_FACTOR;
- }
- else if (openAmount < -this._optsWidthLeftSide) {
- var optsWidth = -this._optsWidthLeftSide;
- openAmount = optsWidth + (openAmount - optsWidth) * ELASTIC_FACTOR;
- }
- this._setOpenAmount(openAmount, false);
- return openAmount;
- };
- /**
- * @hidden
- */
- ItemSliding.prototype.endSliding = function (velocity) {
- var 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 isResetDirection = (this._openAmount > 0) === !(velocity < 0);
- var isMovingFast = Math.abs(velocity) > 0.3;
- var isOnCloseZone = Math.abs(this._openAmount) < Math.abs(restingPoint / 2);
- if (swipeShouldReset(isResetDirection, isMovingFast, isOnCloseZone)) {
- restingPoint = 0;
- }
- this.fireSwipeEvent();
- this._setOpenAmount(restingPoint, true);
- return restingPoint;
- };
- /**
- * @hidden
- */
- 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); });
- }
- };
- /**
- * @hidden
- */
- 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;
- };
- ItemSliding.prototype._setOpenAmount = function (openAmount, isFinal) {
- var _this = this;
- var platform = this._plt;
- if (this._tmr) {
- platform.cancelTimeout(this._tmr);
- this._tmr = null;
- }
- this._openAmount = openAmount;
- if (isFinal) {
- this.item.setElementStyle(platform.Css.transition, '');
- }
- if (openAmount > 0) {
- var state = (openAmount >= (this._optsWidthRightSide + SWIPE_MARGIN))
- ? 8 /* Right */ | 32 /* SwipeRight */
- : 8 /* Right */;
- this._setState(state);
- }
- else if (openAmount < 0) {
- var state_1 = (openAmount <= (-this._optsWidthLeftSide - SWIPE_MARGIN))
- ? 16 /* Left */ | 64 /* SwipeLeft */
- : 16 /* Left */;
- this._setState(state_1);
- }
- else {
- (void 0) /* assert */;
- 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 ionDrag = this.ionDrag;
- if (ionDrag.observers.length > 0) {
- ionDrag.emit(this);
- }
- };
- 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();
- * }
- * }
- * ```
- */
- ItemSliding.prototype.close = function () {
- this._setOpenAmount(0, true);
- };
- /**
- * @hidden
- */
- 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: Renderer, },
- { type: ElementRef, },
- { type: NgZone, },
- ]; };
- ItemSliding.propDecorators = {
- 'item': [{ type: ContentChild, args: [Item,] },],
- 'ionDrag': [{ type: Output },],
- '_itemOptions': [{ type: ContentChildren, args: [forwardRef(function () { return ItemOptions; }),] },],
- };
- return ItemSliding;
- }());
- export { ItemSliding };
- //# sourceMappingURL=item-sliding.js.map
|