From 7ae81172844659d7f4581956ce17e5324f73beef Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Tue, 22 Nov 2022 11:38:42 -0500 Subject: [PATCH] fix(reorder): items animate once in firefox (#26326) resolves #21182 Co-authored-by: dan-rp1 --- .../reorder-group/reorder-group.tsx | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/core/src/components/reorder-group/reorder-group.tsx b/core/src/components/reorder-group/reorder-group.tsx index 09888e5c90..8855ee6854 100644 --- a/core/src/components/reorder-group/reorder-group.tsx +++ b/core/src/components/reorder-group/reorder-group.tsx @@ -4,6 +4,7 @@ import { Component, Element, Event, Host, Method, Prop, State, Watch, h } from ' import { getIonMode } from '../../global/ionic-global'; import type { Gesture, GestureDetail, ItemReorderEventDetail } from '../../interface'; import { findClosestIonContent, getScrollElement } from '../../utils/content'; +import { raf } from '../../utils/helpers'; import { hapticSelectionChanged, hapticSelectionEnd, hapticSelectionStart } from '../../utils/native/haptic'; const enum ReorderGroupState { @@ -97,7 +98,7 @@ export class ReorderGroup implements ComponentInterface { */ @Method() complete(listOrReorder?: boolean | any[]): Promise { - return Promise.resolve(this.completeSync(listOrReorder)); + return Promise.resolve(this.completeReorder(listOrReorder)); } private canStart(ev: GestureDetail): boolean { @@ -200,19 +201,19 @@ export class ReorderGroup implements ComponentInterface { const fromIndex = indexForItem(selectedItemEl); if (toIndex === fromIndex) { - this.completeSync(); + this.completeReorder(); } else { this.ionItemReorder.emit({ from: fromIndex, to: toIndex, - complete: this.completeSync.bind(this), + complete: this.completeReorder.bind(this), }); } hapticSelectionEnd(); } - private completeSync(listOrReorder?: boolean | any[]): any { + private completeReorder(listOrReorder?: boolean | any[]): any { const selectedItemEl = this.selectedItemEl; if (selectedItemEl && this.state === ReorderGroupState.Complete) { const children = this.el.children as any; @@ -220,20 +221,29 @@ export class ReorderGroup implements ComponentInterface { const toIndex = this.lastToIndex; const fromIndex = indexForItem(selectedItemEl); - if (toIndex !== fromIndex && (listOrReorder === undefined || listOrReorder === true)) { - const ref = fromIndex < toIndex ? children[toIndex + 1] : children[toIndex]; + /** + * 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); - } + 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); } - for (let i = 0; i < len; i++) { - children[i].style['transform'] = ''; - } - selectedItemEl.style.transition = ''; selectedItemEl.classList.remove(ITEM_REORDER_SELECTED); this.selectedItemEl = undefined;