diff --git a/src/cdk/drag-drop/directives/drag.spec.ts b/src/cdk/drag-drop/directives/drag.spec.ts index f912d8bc60b2..7e6dcadc5eb1 100644 --- a/src/cdk/drag-drop/directives/drag.spec.ts +++ b/src/cdk/drag-drop/directives/drag.spec.ts @@ -4331,6 +4331,29 @@ describe('CdkDrag', () => { dispatchMouseEvent(document, 'mouseup'); })); + it('should not throw when entering from the top with an intermediate sibling present', + fakeAsync(() => { + const fixture = createComponent(ConnectedDropZonesWithIntermediateSibling); + + // Make sure there's only one item in the first list. + fixture.componentInstance.todo = ['things']; + fixture.detectChanges(); + + const groups = fixture.componentInstance.groupedDragItems; + const dropZones = fixture.componentInstance.dropInstances.map(d => d.element.nativeElement); + const item = groups[0][0]; + + // Add some initial padding as the target drop zone + dropZones[1].style.paddingTop = '10px'; + const targetRect = dropZones[1].getBoundingClientRect(); + + expect(() => { + dragElementViaMouse(fixture, item.element.nativeElement, targetRect.left, targetRect.top); + flush(); + fixture.detectChanges(); + }).not.toThrow(); + })); + it('should assign a default id on each drop zone', fakeAsync(() => { const fixture = createComponent(ConnectedDropZones); fixture.detectChanges(); @@ -6051,6 +6074,46 @@ class DraggableInHorizontalFlexDropZoneWithMatchSizePreview { } +@Component({ + styles: CONNECTED_DROP_ZONES_STYLES, + template: ` +
+
{{item}}
+
+ +
+ +
Hello there
+
+
{{item}}
+
+
+ ` +}) +class ConnectedDropZonesWithIntermediateSibling extends ConnectedDropZones { +} + + /** * Drags an element to a position on the page using the mouse. * @param fixture Fixture on which to run change detection. diff --git a/src/cdk/drag-drop/drop-list-ref.ts b/src/cdk/drag-drop/drop-list-ref.ts index 3e24e21f64e1..a33302fa9cdf 100644 --- a/src/cdk/drag-drop/drop-list-ref.ts +++ b/src/cdk/drag-drop/drop-list-ref.ts @@ -302,15 +302,13 @@ export class DropListRef { const element = newPositionReference.getRootElement(); element.parentElement!.insertBefore(placeholder, element); activeDraggables.splice(newIndex, 0, item); + } else if (this._shouldEnterAsFirstChild(pointerX, pointerY)) { + const reference = activeDraggables[0].getRootElement(); + reference.parentNode!.insertBefore(placeholder, reference); + activeDraggables.unshift(item); } else { - const element = coerceElement(this.element); - if (this._shouldEnterAsFirstChild(pointerX, pointerY)) { - element.insertBefore(placeholder, activeDraggables[0].getRootElement()); - activeDraggables.unshift(item); - } else { - element.appendChild(placeholder); - activeDraggables.push(item); - } + coerceElement(this.element).appendChild(placeholder); + activeDraggables.push(item); } // The transform needs to be cleared so it doesn't throw off the measurements.