123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306 |
- /*!
- * (C) Ionic http://ionicframework.com - MIT License
- */
- import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/core/internal/client';
- import { a as findClosestIonContent, g as getScrollElement } from './index8.js';
- import { r as raf } from './helpers.js';
- import { a as hapticSelectionStart, b as hapticSelectionChanged, h as hapticSelectionEnd } from './haptic.js';
- import { b as getIonMode } from './ionic-global.js';
- const reorderGroupCss = ".reorder-list-active>*{display:block;-webkit-transition:-webkit-transform 300ms;transition:-webkit-transform 300ms;transition:transform 300ms;transition:transform 300ms, -webkit-transform 300ms;will-change:transform}.reorder-enabled{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.reorder-enabled ion-reorder{display:block;cursor:-webkit-grab;cursor:grab;pointer-events:all;-ms-touch-action:none;touch-action:none}.reorder-selected,.reorder-selected ion-reorder{cursor:-webkit-grabbing;cursor:grabbing}.reorder-selected{position:relative;-webkit-transition:none !important;transition:none !important;-webkit-box-shadow:0 0 10px rgba(0, 0, 0, 0.4);box-shadow:0 0 10px rgba(0, 0, 0, 0.4);opacity:0.8;z-index:100}.reorder-visible ion-reorder .reorder-icon{-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0)}";
- const IonReorderGroupStyle0 = reorderGroupCss;
- const ReorderGroup = /*@__PURE__*/ proxyCustomElement(class ReorderGroup extends HTMLElement {
- constructor() {
- super();
- this.__registerHost();
- this.ionItemReorder = createEvent(this, "ionItemReorder", 7);
- this.lastToIndex = -1;
- this.cachedHeights = [];
- this.scrollElTop = 0;
- this.scrollElBottom = 0;
- this.scrollElInitial = 0;
- this.containerTop = 0;
- this.containerBottom = 0;
- this.state = 0 /* ReorderGroupState.Idle */;
- this.disabled = true;
- }
- disabledChanged() {
- if (this.gesture) {
- this.gesture.enable(!this.disabled);
- }
- }
- async connectedCallback() {
- const contentEl = findClosestIonContent(this.el);
- if (contentEl) {
- this.scrollEl = await getScrollElement(contentEl);
- }
- this.gesture = (await import('./index3.js')).createGesture({
- el: this.el,
- gestureName: 'reorder',
- gesturePriority: 110,
- threshold: 0,
- direction: 'y',
- passive: false,
- canStart: (detail) => this.canStart(detail),
- onStart: (ev) => this.onStart(ev),
- onMove: (ev) => this.onMove(ev),
- onEnd: () => this.onEnd(),
- });
- this.disabledChanged();
- }
- disconnectedCallback() {
- this.onEnd();
- if (this.gesture) {
- this.gesture.destroy();
- this.gesture = undefined;
- }
- }
- /**
- * Completes the reorder operation. Must be called by the `ionItemReorder` event.
- *
- * If a list of items is passed, the list will be reordered and returned in the
- * proper order.
- *
- * If no parameters are passed or if `true` is passed in, the reorder will complete
- * and the item will remain in the position it was dragged to. If `false` is passed,
- * the reorder will complete and the item will bounce back to its original position.
- *
- * @param listOrReorder A list of items to be sorted and returned in the new order or a
- * boolean of whether or not the reorder should reposition the item.
- */
- complete(listOrReorder) {
- return Promise.resolve(this.completeReorder(listOrReorder));
- }
- canStart(ev) {
- if (this.selectedItemEl || this.state !== 0 /* ReorderGroupState.Idle */) {
- return false;
- }
- const target = ev.event.target;
- const reorderEl = target.closest('ion-reorder');
- if (!reorderEl) {
- return false;
- }
- const item = findReorderItem(reorderEl, this.el);
- if (!item) {
- return false;
- }
- ev.data = item;
- return true;
- }
- onStart(ev) {
- ev.event.preventDefault();
- const item = (this.selectedItemEl = ev.data);
- const heights = this.cachedHeights;
- heights.length = 0;
- const el = this.el;
- const children = el.children;
- if (!children || children.length === 0) {
- return;
- }
- let sum = 0;
- for (let i = 0; i < children.length; i++) {
- const child = children[i];
- sum += child.offsetHeight;
- heights.push(sum);
- child.$ionIndex = i;
- }
- const box = el.getBoundingClientRect();
- this.containerTop = box.top;
- this.containerBottom = box.bottom;
- if (this.scrollEl) {
- const scrollBox = this.scrollEl.getBoundingClientRect();
- this.scrollElInitial = this.scrollEl.scrollTop;
- this.scrollElTop = scrollBox.top + AUTO_SCROLL_MARGIN;
- this.scrollElBottom = scrollBox.bottom - AUTO_SCROLL_MARGIN;
- }
- else {
- this.scrollElInitial = 0;
- this.scrollElTop = 0;
- this.scrollElBottom = 0;
- }
- this.lastToIndex = indexForItem(item);
- this.selectedItemHeight = item.offsetHeight;
- this.state = 1 /* ReorderGroupState.Active */;
- item.classList.add(ITEM_REORDER_SELECTED);
- hapticSelectionStart();
- }
- onMove(ev) {
- const selectedItem = this.selectedItemEl;
- if (!selectedItem) {
- return;
- }
- // Scroll if we reach the scroll margins
- const scroll = this.autoscroll(ev.currentY);
- // // Get coordinate
- const top = this.containerTop - scroll;
- const bottom = this.containerBottom - scroll;
- const currentY = Math.max(top, Math.min(ev.currentY, bottom));
- const deltaY = scroll + currentY - ev.startY;
- const normalizedY = currentY - top;
- const toIndex = this.itemIndexForTop(normalizedY);
- if (toIndex !== this.lastToIndex) {
- const fromIndex = indexForItem(selectedItem);
- this.lastToIndex = toIndex;
- hapticSelectionChanged();
- this.reorderMove(fromIndex, toIndex);
- }
- // Update selected item position
- selectedItem.style.transform = `translateY(${deltaY}px)`;
- }
- onEnd() {
- const selectedItemEl = this.selectedItemEl;
- this.state = 2 /* ReorderGroupState.Complete */;
- if (!selectedItemEl) {
- this.state = 0 /* ReorderGroupState.Idle */;
- return;
- }
- const toIndex = this.lastToIndex;
- const fromIndex = indexForItem(selectedItemEl);
- if (toIndex === fromIndex) {
- this.completeReorder();
- }
- else {
- this.ionItemReorder.emit({
- from: fromIndex,
- to: toIndex,
- complete: this.completeReorder.bind(this),
- });
- }
- hapticSelectionEnd();
- }
- completeReorder(listOrReorder) {
- const selectedItemEl = this.selectedItemEl;
- if (selectedItemEl && this.state === 2 /* ReorderGroupState.Complete */) {
- const children = this.el.children;
- const len = children.length;
- const toIndex = this.lastToIndex;
- const fromIndex = indexForItem(selectedItemEl);
- /**
- * insertBefore and setting the transform
- * needs to happen in the same frame otherwise
- * there will be a duplicate transition. This primarily
- * impacts Firefox where insertBefore and transform operations
- * are happening in two separate frames.
- */
- raf(() => {
- if (toIndex !== fromIndex && (listOrReorder === undefined || listOrReorder === true)) {
- const ref = fromIndex < toIndex ? children[toIndex + 1] : children[toIndex];
- this.el.insertBefore(selectedItemEl, ref);
- }
- for (let i = 0; i < len; i++) {
- children[i].style['transform'] = '';
- }
- });
- if (Array.isArray(listOrReorder)) {
- listOrReorder = reorderArray(listOrReorder, fromIndex, toIndex);
- }
- selectedItemEl.style.transition = '';
- selectedItemEl.classList.remove(ITEM_REORDER_SELECTED);
- this.selectedItemEl = undefined;
- this.state = 0 /* ReorderGroupState.Idle */;
- }
- return listOrReorder;
- }
- itemIndexForTop(deltaY) {
- const heights = this.cachedHeights;
- for (let i = 0; i < heights.length; i++) {
- if (heights[i] > deltaY) {
- return i;
- }
- }
- return heights.length - 1;
- }
- /********* DOM WRITE ********* */
- reorderMove(fromIndex, toIndex) {
- const itemHeight = this.selectedItemHeight;
- const children = this.el.children;
- for (let i = 0; i < children.length; i++) {
- const style = children[i].style;
- let value = '';
- if (i > fromIndex && i <= toIndex) {
- value = `translateY(${-itemHeight}px)`;
- }
- else if (i < fromIndex && i >= toIndex) {
- value = `translateY(${itemHeight}px)`;
- }
- style['transform'] = value;
- }
- }
- autoscroll(posY) {
- if (!this.scrollEl) {
- return 0;
- }
- let amount = 0;
- if (posY < this.scrollElTop) {
- amount = -SCROLL_JUMP;
- }
- else if (posY > this.scrollElBottom) {
- amount = SCROLL_JUMP;
- }
- if (amount !== 0) {
- this.scrollEl.scrollBy(0, amount);
- }
- return this.scrollEl.scrollTop - this.scrollElInitial;
- }
- render() {
- const mode = getIonMode(this);
- return (h(Host, { key: '6ca009dd65302a914d459aec638e62977440db20', class: {
- [mode]: true,
- 'reorder-enabled': !this.disabled,
- 'reorder-list-active': this.state !== 0 /* ReorderGroupState.Idle */,
- } }));
- }
- get el() { return this; }
- static get watchers() { return {
- "disabled": ["disabledChanged"]
- }; }
- static get style() { return IonReorderGroupStyle0; }
- }, [0, "ion-reorder-group", {
- "disabled": [4],
- "state": [32],
- "complete": [64]
- }, undefined, {
- "disabled": ["disabledChanged"]
- }]);
- const indexForItem = (element) => {
- return element['$ionIndex'];
- };
- const findReorderItem = (node, container) => {
- let parent;
- while (node) {
- parent = node.parentElement;
- if (parent === container) {
- return node;
- }
- node = parent;
- }
- return undefined;
- };
- const AUTO_SCROLL_MARGIN = 60;
- const SCROLL_JUMP = 10;
- const ITEM_REORDER_SELECTED = 'reorder-selected';
- const reorderArray = (array, from, to) => {
- const element = array[from];
- array.splice(from, 1);
- array.splice(to, 0, element);
- return array.slice();
- };
- function defineCustomElement$1() {
- if (typeof customElements === "undefined") {
- return;
- }
- const components = ["ion-reorder-group"];
- components.forEach(tagName => { switch (tagName) {
- case "ion-reorder-group":
- if (!customElements.get(tagName)) {
- customElements.define(tagName, ReorderGroup);
- }
- break;
- } });
- }
- const IonReorderGroup = ReorderGroup;
- const defineCustomElement = defineCustomElement$1;
- export { IonReorderGroup, defineCustomElement };
|