Skip to content

Commit a606bc1

Browse files
Merge pull request #562 from mkszepp/fix-drag-start-and-test-helper
Fix: Block drag start while any item is busy & add wait for transition end in test helper `drop`
2 parents 8f1e124 + 836d255 commit a606bc1

File tree

2 files changed

+54
-3
lines changed

2 files changed

+54
-3
lines changed

addon/src/modifiers/sortable-item.js

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,10 @@ export default class SortableItemModifier extends Modifier {
366366
* @private
367367
*/
368368
_prepareDrag(startEvent, event) {
369+
// Block drag start while any item has busy state
370+
if (this.sortableGroup.sortedItems.some((x) => x.isBusy)) {
371+
return;
372+
}
369373
let distance = this.distance;
370374
let dx = Math.abs(getX(startEvent) - getX(event));
371375
let dy = Math.abs(getY(startEvent) - getY(event));
@@ -618,7 +622,10 @@ export default class SortableItemModifier extends Modifier {
618622
set(this, 'isDropping', true);
619623

620624
this.sortableGroup.update();
621-
transitionPromise.then(() => this._complete());
625+
626+
let allTransitionPromise = this._waitForAllTransitions();
627+
628+
Promise.all([transitionPromise, allTransitionPromise]).then(() => this._complete());
622629
}
623630

624631
/**
@@ -678,6 +685,42 @@ export default class SortableItemModifier extends Modifier {
678685
return transitionPromise;
679686
}
680687

688+
/**
689+
@method _waitForTransitions
690+
@private
691+
@return Promise
692+
*/
693+
_waitForAllTransitions() {
694+
let waiterToken;
695+
696+
if (DEBUG) {
697+
waiterToken = sortableItemWaiter.beginAsync();
698+
}
699+
700+
let transitionPromise;
701+
702+
if (this.isAnimated) {
703+
const animations = this.sortableGroup.sortedItems.map((x) => x.element.getAnimations());
704+
705+
const animationPromises = animations.map((animation) => {
706+
return animation.finished;
707+
});
708+
709+
transitionPromise = Promise.all(animationPromises);
710+
} else {
711+
const duration = this.isAnimated ? this.transitionDuration : 200;
712+
transitionPromise = new Promise((resolve) => later(resolve, duration));
713+
}
714+
715+
if (DEBUG) {
716+
transitionPromise = transitionPromise.finally(() => {
717+
sortableItemWaiter.endAsync(waiterToken);
718+
});
719+
}
720+
721+
return transitionPromise;
722+
}
723+
681724
/**
682725
@method _complete
683726
@private
@@ -706,7 +749,8 @@ export default class SortableItemModifier extends Modifier {
706749
@type Number
707750
*/
708751
get transitionDuration() {
709-
let el = this.element;
752+
const items = this.sortableGroup.sortedItems.filter((x) => !x.isDragging && !x.isDropping);
753+
let el = items[0].element ?? this.element; // Fallback when only one element is present in list
710754
let rule = getComputedStyle(el).transitionDuration;
711755
let match = rule.match(/([\d.]+)([ms]*)/);
712756

addon/src/test-support/helpers/drag.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { triggerEvent, find, settled } from '@ember/test-helpers';
1+
import { triggerEvent, find, settled, waitUntil } from '@ember/test-helpers';
22
import { getOffset } from '../utils/offset';
33

44
/**
@@ -108,4 +108,11 @@ export async function drag(mode, itemSelector, offsetFn, callbacks = {}) {
108108
await callbacks.dragend();
109109
await settled();
110110
}
111+
112+
await waitUntil(
113+
() => {
114+
return !find('.is-dropping');
115+
},
116+
{ timeout: 2000 }
117+
);
111118
}

0 commit comments

Comments
 (0)