@@ -146,7 +146,7 @@ export class DropListRef<T = any> {
146146 private _parentPositions : ParentPositionTracker ;
147147
148148 /** Cached `ClientRect` of the drop list. */
149- private _clientRect : ClientRect ;
149+ private _clientRect : ClientRect | undefined ;
150150
151151 /**
152152 * Draggable items that are currently active inside the container. Includes the items
@@ -163,7 +163,7 @@ export class DropListRef<T = any> {
163163 private _previousSwap = { drag : null as DragRef | null , delta : 0 , overlaps : false } ;
164164
165165 /** Draggable items in the container. */
166- private _draggables : ReadonlyArray < DragRef > ;
166+ private _draggables : ReadonlyArray < DragRef > = [ ] ;
167167
168168 /** Drop lists that are connected to the current one. */
169169 private _siblings : ReadonlyArray < DropListRef > = [ ] ;
@@ -240,19 +240,8 @@ export class DropListRef<T = any> {
240240
241241 /** Starts dragging an item. */
242242 start ( ) : void {
243- const styles = coerceElement ( this . element ) . style as DragCSSStyleDeclaration ;
244- this . beforeStarted . next ( ) ;
245- this . _isDragging = true ;
246-
247- // We need to disable scroll snapping while the user is dragging, because it breaks automatic
248- // scrolling. The browser seems to round the value based on the snapping points which means
249- // that we can't increment/decrement the scroll position.
250- this . _initialScrollSnap = styles . msScrollSnapType || styles . scrollSnapType || '' ;
251- styles . scrollSnapType = styles . msScrollSnapType = 'none' ;
252- this . _cacheItems ( ) ;
253- this . _siblings . forEach ( sibling => sibling . _startReceiving ( this ) ) ;
254- this . _viewportScrollSubscription . unsubscribe ( ) ;
255- this . _listenToScrollEvents ( ) ;
243+ this . _draggingStarted ( ) ;
244+ this . _notifyReceivingSiblings ( ) ;
256245 }
257246
258247 /**
@@ -264,7 +253,7 @@ export class DropListRef<T = any> {
264253 * out automatically.
265254 */
266255 enter ( item : DragRef , pointerX : number , pointerY : number , index ?: number ) : void {
267- this . start ( ) ;
256+ this . _draggingStarted ( ) ;
268257
269258 // If sorting is disabled, we want the item to return to its starting
270259 // position if the user is returning it to its initial container.
@@ -323,6 +312,8 @@ export class DropListRef<T = any> {
323312 this . _cacheItemPositions ( ) ;
324313 this . _cacheParentPositions ( ) ;
325314
315+ // Notify siblings at the end so that the item has been inserted into the `activeDraggables`.
316+ this . _notifyReceivingSiblings ( ) ;
326317 this . entered . next ( { item, container : this , currentIndex : this . getItemIndex ( item ) } ) ;
327318 }
328319
@@ -463,7 +454,7 @@ export class DropListRef<T = any> {
463454 _sortItem ( item : DragRef , pointerX : number , pointerY : number ,
464455 pointerDelta : { x : number , y : number } ) : void {
465456 // Don't sort the item if sorting is disabled or it's out of range.
466- if ( this . sortingDisabled ||
457+ if ( this . sortingDisabled || ! this . _clientRect ||
467458 ! isPointerNearClientRect ( this . _clientRect , DROP_PROXIMITY_THRESHOLD , pointerX , pointerY ) ) {
468459 return ;
469460 }
@@ -600,6 +591,22 @@ export class DropListRef<T = any> {
600591 this . _stopScrollTimers . next ( ) ;
601592 }
602593
594+ /** Starts the dragging sequence within the list. */
595+ private _draggingStarted ( ) {
596+ const styles = coerceElement ( this . element ) . style as DragCSSStyleDeclaration ;
597+ this . beforeStarted . next ( ) ;
598+ this . _isDragging = true ;
599+
600+ // We need to disable scroll snapping while the user is dragging, because it breaks automatic
601+ // scrolling. The browser seems to round the value based on the snapping points which means
602+ // that we can't increment/decrement the scroll position.
603+ this . _initialScrollSnap = styles . msScrollSnapType || styles . scrollSnapType || '' ;
604+ styles . scrollSnapType = styles . msScrollSnapType = 'none' ;
605+ this . _cacheItems ( ) ;
606+ this . _viewportScrollSubscription . unsubscribe ( ) ;
607+ this . _listenToScrollEvents ( ) ;
608+ }
609+
603610 /** Caches the positions of the configured scrollable parents. */
604611 private _cacheParentPositions ( ) {
605612 const element = coerceElement ( this . element ) ;
@@ -802,7 +809,7 @@ export class DropListRef<T = any> {
802809 * @param y Pointer position along the Y axis.
803810 */
804811 _isOverContainer ( x : number , y : number ) : boolean {
805- return isInsideClientRect ( this . _clientRect , x , y ) ;
812+ return this . _clientRect != null && isInsideClientRect ( this . _clientRect , x , y ) ;
806813 }
807814
808815 /**
@@ -823,7 +830,8 @@ export class DropListRef<T = any> {
823830 * @param y Position of the item along the Y axis.
824831 */
825832 _canReceive ( item : DragRef , x : number , y : number ) : boolean {
826- if ( ! isInsideClientRect ( this . _clientRect , x , y ) || ! this . enterPredicate ( item , this ) ) {
833+ if ( ! this . _clientRect || ! isInsideClientRect ( this . _clientRect , x , y ) ||
834+ ! this . enterPredicate ( item , this ) ) {
827835 return false ;
828836 }
829837
@@ -850,10 +858,16 @@ export class DropListRef<T = any> {
850858 * Called by one of the connected drop lists when a dragging sequence has started.
851859 * @param sibling Sibling in which dragging has started.
852860 */
853- _startReceiving ( sibling : DropListRef ) {
861+ _startReceiving ( sibling : DropListRef , items : DragRef [ ] ) {
854862 const activeSiblings = this . _activeSiblings ;
855863
856- if ( ! activeSiblings . has ( sibling ) ) {
864+ if ( ! activeSiblings . has ( sibling ) && items . every ( item => {
865+ // Note that we have to add an exception to the `enterPredicate` for items that started off
866+ // in this drop list. The drag ref has logic that allows an item to return to its initial
867+ // container, if it has left the initial container and none of the connected containers
868+ // allow it to enter. See `DragRef._updateActiveDropContainer` for more context.
869+ return this . enterPredicate ( item , this ) || this . _draggables . indexOf ( item ) > - 1 ;
870+ } ) ) {
857871 activeSiblings . add ( sibling ) ;
858872 this . _cacheParentPositions ( ) ;
859873 this . _listenToScrollEvents ( ) ;
@@ -917,6 +931,12 @@ export class DropListRef<T = any> {
917931
918932 return this . _cachedShadowRoot ;
919933 }
934+
935+ /** Notifies any siblings that may potentially receive the item. */
936+ private _notifyReceivingSiblings ( ) {
937+ const draggedItems = this . _activeDraggables . filter ( item => item . isDragging ( ) ) ;
938+ this . _siblings . forEach ( sibling => sibling . _startReceiving ( this , draggedItems ) ) ;
939+ }
920940}
921941
922942
0 commit comments