Skip to content

Commit db7491c

Browse files
crisbetojelbourn
authored andcommitted
fix(drag-drop): only add top-level drop lists to drop group (#14130)
Currently all drop lists will add themselves to the closest group that is resolved through DI. This can lead to some weird results where a parent list and a list inside it will be grouped automatically. These changes rework the way the group is provided in order to prevent it from bleeding into child lists.
1 parent d8cd6a7 commit db7491c

File tree

3 files changed

+34
-2
lines changed

3 files changed

+34
-2
lines changed

src/cdk/drag-drop/drag.spec.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {CdkDragDrop} from './drag-events';
2626
import {moveItemInArray} from './drag-utils';
2727
import {CdkDropList} from './drop-list';
2828
import {CdkDragHandle} from './drag-handle';
29+
import {CdkDropListGroup} from './drop-list-group';
2930

3031
const ITEM_HEIGHT = 25;
3132
const ITEM_WIDTH = 75;
@@ -2218,6 +2219,14 @@ describe('CdkDrag', () => {
22182219
expect(fixture.componentInstance.droppedSpy).not.toHaveBeenCalled();
22192220
}));
22202221

2222+
it('should not add child drop lists to the same group as their parents', fakeAsync(() => {
2223+
const fixture = createComponent(NestedDropListGroups);
2224+
const component = fixture.componentInstance;
2225+
fixture.detectChanges();
2226+
2227+
expect(Array.from(component.group._items)).toEqual([component.listOne, component.listTwo]);
2228+
}));
2229+
22212230
});
22222231

22232232
});
@@ -2603,6 +2612,25 @@ class ConnectedDropZonesWithSingleItems {
26032612
droppedSpy = jasmine.createSpy('dropped spy');
26042613
}
26052614

2615+
@Component({
2616+
template: `
2617+
<div cdkDropListGroup #group="cdkDropListGroup">
2618+
<div cdkDropList #listOne="cdkDropList">
2619+
<div cdkDropList #listThree="cdkDropList"></div>
2620+
<div cdkDropList #listFour="cdkDropList"></div>
2621+
</div>
2622+
2623+
<div cdkDropList #listTwo="cdkDropList"></div>
2624+
</div>
2625+
`
2626+
})
2627+
class NestedDropListGroups {
2628+
@ViewChild('group') group: CdkDropListGroup<CdkDropList>;
2629+
@ViewChild('listOne') listOne: CdkDropList;
2630+
@ViewChild('listTwo') listTwo: CdkDropList;
2631+
}
2632+
2633+
26062634
/**
26072635
* Component that passes through whatever content is projected into it.
26082636
* Used to test having drag elements being projected into a component.

src/cdk/drag-drop/drop-list-group.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ import {Directive, OnDestroy} from '@angular/core';
1515
* from `cdkDropList`.
1616
*/
1717
@Directive({
18-
selector: '[cdkDropListGroup]'
18+
selector: '[cdkDropListGroup]',
19+
exportAs: 'cdkDropListGroup',
1920
})
2021
export class CdkDropListGroup<T> implements OnDestroy {
2122
/** Drop lists registered inside the group. */

src/cdk/drag-drop/drop-list.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
Optional,
2121
Directive,
2222
ChangeDetectorRef,
23+
SkipSelf,
2324
} from '@angular/core';
2425
import {Directionality} from '@angular/cdk/bidi';
2526
import {CdkDrag} from './drag';
@@ -81,6 +82,8 @@ interface ListPositionCacheEntry {
8182
selector: '[cdkDropList], cdk-drop-list',
8283
exportAs: 'cdkDropList',
8384
providers: [
85+
// Prevent child drop lists from picking up the same group as their parent.
86+
{provide: CdkDropListGroup, useValue: undefined},
8487
{provide: CDK_DROP_LIST_CONTAINER, useExisting: CdkDropList},
8588
],
8689
host: {
@@ -157,7 +160,7 @@ export class CdkDropList<T = any> implements OnInit, OnDestroy {
157160
private _dragDropRegistry: DragDropRegistry<CdkDrag, CdkDropList<T>>,
158161
private _changeDetectorRef: ChangeDetectorRef,
159162
@Optional() private _dir?: Directionality,
160-
@Optional() private _group?: CdkDropListGroup<CdkDropList>) {}
163+
@Optional() @SkipSelf() private _group?: CdkDropListGroup<CdkDropList>) {}
161164

162165
ngOnInit() {
163166
this._dragDropRegistry.registerDropContainer(this);

0 commit comments

Comments
 (0)