fix(reorder): items animate once in firefox (#26326)

resolves #21182

Co-authored-by: dan-rp1 <dan-rp1@users.noreply.github.com>
This commit is contained in:
Liam DeBeasi
2022-11-22 11:38:42 -05:00
committed by GitHub
parent c46ef91f46
commit 7ae8117284

View File

@@ -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<any> {
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;