Skip to content

Commit 7ae8117

Browse files
liamdebeasidan-rp1
andauthoredNov 22, 2022
fix(reorder): items animate once in firefox (#26326)
resolves #21182 Co-authored-by: dan-rp1 <dan-rp1@users.noreply.github.com>
1 parent c46ef91 commit 7ae8117

File tree

1 file changed

+23
-13
lines changed

1 file changed

+23
-13
lines changed
 

‎core/src/components/reorder-group/reorder-group.tsx

+23-13
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Component, Element, Event, Host, Method, Prop, State, Watch, h } from '
44
import { getIonMode } from '../../global/ionic-global';
55
import type { Gesture, GestureDetail, ItemReorderEventDetail } from '../../interface';
66
import { findClosestIonContent, getScrollElement } from '../../utils/content';
7+
import { raf } from '../../utils/helpers';
78
import { hapticSelectionChanged, hapticSelectionEnd, hapticSelectionStart } from '../../utils/native/haptic';
89

910
const enum ReorderGroupState {
@@ -97,7 +98,7 @@ export class ReorderGroup implements ComponentInterface {
9798
*/
9899
@Method()
99100
complete(listOrReorder?: boolean | any[]): Promise<any> {
100-
return Promise.resolve(this.completeSync(listOrReorder));
101+
return Promise.resolve(this.completeReorder(listOrReorder));
101102
}
102103

103104
private canStart(ev: GestureDetail): boolean {
@@ -200,40 +201,49 @@ export class ReorderGroup implements ComponentInterface {
200201
const fromIndex = indexForItem(selectedItemEl);
201202

202203
if (toIndex === fromIndex) {
203-
this.completeSync();
204+
this.completeReorder();
204205
} else {
205206
this.ionItemReorder.emit({
206207
from: fromIndex,
207208
to: toIndex,
208-
complete: this.completeSync.bind(this),
209+
complete: this.completeReorder.bind(this),
209210
});
210211
}
211212

212213
hapticSelectionEnd();
213214
}
214215

215-
private completeSync(listOrReorder?: boolean | any[]): any {
216+
private completeReorder(listOrReorder?: boolean | any[]): any {
216217
const selectedItemEl = this.selectedItemEl;
217218
if (selectedItemEl && this.state === ReorderGroupState.Complete) {
218219
const children = this.el.children as any;
219220
const len = children.length;
220221
const toIndex = this.lastToIndex;
221222
const fromIndex = indexForItem(selectedItemEl);
222223

223-
if (toIndex !== fromIndex && (listOrReorder === undefined || listOrReorder === true)) {
224-
const ref = fromIndex < toIndex ? children[toIndex + 1] : children[toIndex];
225-
226-
this.el.insertBefore(selectedItemEl, ref);
227-
}
224+
/**
225+
* insertBefore and setting the transform
226+
* needs to happen in the same frame otherwise
227+
* there will be a duplicate transition. This primarily
228+
* impacts Firefox where insertBefore and transform operations
229+
* are happening in two separate frames.
230+
*/
231+
raf(() => {
232+
if (toIndex !== fromIndex && (listOrReorder === undefined || listOrReorder === true)) {
233+
const ref = fromIndex < toIndex ? children[toIndex + 1] : children[toIndex];
234+
235+
this.el.insertBefore(selectedItemEl, ref);
236+
}
237+
238+
for (let i = 0; i < len; i++) {
239+
children[i].style['transform'] = '';
240+
}
241+
});
228242

229243
if (Array.isArray(listOrReorder)) {
230244
listOrReorder = reorderArray(listOrReorder, fromIndex, toIndex);
231245
}
232246

233-
for (let i = 0; i < len; i++) {
234-
children[i].style['transform'] = '';
235-
}
236-
237247
selectedItemEl.style.transition = '';
238248
selectedItemEl.classList.remove(ITEM_REORDER_SELECTED);
239249
this.selectedItemEl = undefined;

0 commit comments

Comments
 (0)
Please sign in to comment.