@@ -4,6 +4,7 @@ import { Component, Element, Event, Host, Method, Prop, State, Watch, h } from '
4
4
import { getIonMode } from '../../global/ionic-global' ;
5
5
import type { Gesture , GestureDetail , ItemReorderEventDetail } from '../../interface' ;
6
6
import { findClosestIonContent , getScrollElement } from '../../utils/content' ;
7
+ import { raf } from '../../utils/helpers' ;
7
8
import { hapticSelectionChanged , hapticSelectionEnd , hapticSelectionStart } from '../../utils/native/haptic' ;
8
9
9
10
const enum ReorderGroupState {
@@ -97,7 +98,7 @@ export class ReorderGroup implements ComponentInterface {
97
98
*/
98
99
@Method ( )
99
100
complete ( listOrReorder ?: boolean | any [ ] ) : Promise < any > {
100
- return Promise . resolve ( this . completeSync ( listOrReorder ) ) ;
101
+ return Promise . resolve ( this . completeReorder ( listOrReorder ) ) ;
101
102
}
102
103
103
104
private canStart ( ev : GestureDetail ) : boolean {
@@ -200,40 +201,49 @@ export class ReorderGroup implements ComponentInterface {
200
201
const fromIndex = indexForItem ( selectedItemEl ) ;
201
202
202
203
if ( toIndex === fromIndex ) {
203
- this . completeSync ( ) ;
204
+ this . completeReorder ( ) ;
204
205
} else {
205
206
this . ionItemReorder . emit ( {
206
207
from : fromIndex ,
207
208
to : toIndex ,
208
- complete : this . completeSync . bind ( this ) ,
209
+ complete : this . completeReorder . bind ( this ) ,
209
210
} ) ;
210
211
}
211
212
212
213
hapticSelectionEnd ( ) ;
213
214
}
214
215
215
- private completeSync ( listOrReorder ?: boolean | any [ ] ) : any {
216
+ private completeReorder ( listOrReorder ?: boolean | any [ ] ) : any {
216
217
const selectedItemEl = this . selectedItemEl ;
217
218
if ( selectedItemEl && this . state === ReorderGroupState . Complete ) {
218
219
const children = this . el . children as any ;
219
220
const len = children . length ;
220
221
const toIndex = this . lastToIndex ;
221
222
const fromIndex = indexForItem ( selectedItemEl ) ;
222
223
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
+ } ) ;
228
242
229
243
if ( Array . isArray ( listOrReorder ) ) {
230
244
listOrReorder = reorderArray ( listOrReorder , fromIndex , toIndex ) ;
231
245
}
232
246
233
- for ( let i = 0 ; i < len ; i ++ ) {
234
- children [ i ] . style [ 'transform' ] = '' ;
235
- }
236
-
237
247
selectedItemEl . style . transition = '' ;
238
248
selectedItemEl . classList . remove ( ITEM_REORDER_SELECTED ) ;
239
249
this . selectedItemEl = undefined ;
0 commit comments