Skip to content

Commit 62cab55

Browse files
committed
feat(drag-drop): expose native event objects in custom events
Exposes the native `MouseEvent` and `TouchEvent` objects in the various drag&drop events since they can contain useful information like which keys were pressed while dragging. Fixes #17032.
1 parent db4b0cd commit 62cab55

File tree

7 files changed

+119
-65
lines changed

7 files changed

+119
-65
lines changed

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

Lines changed: 55 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,10 @@ describe('CdkDrag', () => {
345345

346346
// Assert the event like this, rather than `toHaveBeenCalledWith`, because Jasmine will
347347
// go into an infinite loop trying to stringify the event, if the test fails.
348-
expect(event).toEqual({source: fixture.componentInstance.dragInstance});
348+
expect(event).toEqual({
349+
source: fixture.componentInstance.dragInstance,
350+
event: jasmine.anything()
351+
});
349352
}));
350353

351354
it('should dispatch an event when the user has stopped dragging', fakeAsync(() => {
@@ -362,7 +365,8 @@ describe('CdkDrag', () => {
362365
// go into an infinite loop trying to stringify the event, if the test fails.
363366
expect(event).toEqual({
364367
source: fixture.componentInstance.dragInstance,
365-
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
368+
distance: {x: jasmine.any(Number), y: jasmine.any(Number)},
369+
event: jasmine.anything()
366370
});
367371
}));
368372

@@ -375,15 +379,17 @@ describe('CdkDrag', () => {
375379

376380
expect(event).toEqual({
377381
source: jasmine.anything(),
378-
distance: {x: 25, y: 30}
382+
distance: {x: 25, y: 30},
383+
event: jasmine.anything()
379384
});
380385

381386
dragElementViaMouse(fixture, fixture.componentInstance.dragElement.nativeElement, 40, 50);
382387
event = fixture.componentInstance.endedSpy.calls.mostRecent().args[0];
383388

384389
expect(event).toEqual({
385390
source: jasmine.anything(),
386-
distance: {x: 40, y: 50}
391+
distance: {x: 40, y: 50},
392+
event: jasmine.anything()
387393
});
388394
}));
389395

@@ -1615,7 +1621,8 @@ describe('CdkDrag', () => {
16151621
container: fixture.componentInstance.dropInstance,
16161622
previousContainer: fixture.componentInstance.dropInstance,
16171623
isPointerOverContainer: true,
1618-
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
1624+
distance: {x: jasmine.any(Number), y: jasmine.any(Number)},
1625+
event: jasmine.anything()
16191626
});
16201627

16211628
expect(dragItems.map(drag => drag.element.nativeElement.textContent!.trim()))
@@ -1741,7 +1748,8 @@ describe('CdkDrag', () => {
17411748
container: fixture.componentInstance.dropInstance,
17421749
previousContainer: fixture.componentInstance.dropInstance,
17431750
isPointerOverContainer: false,
1744-
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
1751+
distance: {x: jasmine.any(Number), y: jasmine.any(Number)},
1752+
event: jasmine.anything()
17451753
});
17461754

17471755
expect(dragItems.map(drag => drag.element.nativeElement.textContent!.trim()))
@@ -1800,7 +1808,8 @@ describe('CdkDrag', () => {
18001808
container: fixture.componentInstance.dropInstance,
18011809
previousContainer: fixture.componentInstance.dropInstance,
18021810
isPointerOverContainer: true,
1803-
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
1811+
distance: {x: jasmine.any(Number), y: jasmine.any(Number)},
1812+
event: jasmine.anything()
18041813
});
18051814

18061815
expect(dragItems.map(drag => drag.element.nativeElement.textContent!.trim()))
@@ -1841,7 +1850,8 @@ describe('CdkDrag', () => {
18411850
container: fixture.componentInstance.dropInstance,
18421851
previousContainer: fixture.componentInstance.dropInstance,
18431852
isPointerOverContainer: true,
1844-
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
1853+
distance: {x: jasmine.any(Number), y: jasmine.any(Number)},
1854+
event: jasmine.anything()
18451855
});
18461856

18471857
expect(dragItems.map(drag => drag.element.nativeElement.textContent!.trim()))
@@ -1878,7 +1888,8 @@ describe('CdkDrag', () => {
18781888
container: fixture.componentInstance.dropInstance,
18791889
previousContainer: fixture.componentInstance.dropInstance,
18801890
isPointerOverContainer: false,
1881-
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
1891+
distance: {x: jasmine.any(Number), y: jasmine.any(Number)},
1892+
event: jasmine.anything()
18821893
});
18831894

18841895
expect(dragItems.map(drag => drag.element.nativeElement.textContent!.trim()))
@@ -1921,7 +1932,8 @@ describe('CdkDrag', () => {
19211932
container: fixture.componentInstance.dropInstance,
19221933
previousContainer: fixture.componentInstance.dropInstance,
19231934
isPointerOverContainer: jasmine.any(Boolean),
1924-
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
1935+
distance: {x: jasmine.any(Number), y: jasmine.any(Number)},
1936+
event: jasmine.anything()
19251937
});
19261938
}));
19271939

@@ -1969,7 +1981,8 @@ describe('CdkDrag', () => {
19691981
container: fixture.componentInstance.dropInstance,
19701982
previousContainer: fixture.componentInstance.dropInstance,
19711983
isPointerOverContainer: jasmine.any(Boolean),
1972-
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
1984+
distance: {x: jasmine.any(Number), y: jasmine.any(Number)},
1985+
event: jasmine.anything()
19731986
});
19741987

19751988
scrollTo(0, 0);
@@ -3455,7 +3468,8 @@ describe('CdkDrag', () => {
34553468
container: dropInstance,
34563469
previousContainer: dropInstance,
34573470
isPointerOverContainer: true,
3458-
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
3471+
distance: {x: jasmine.any(Number), y: jasmine.any(Number)},
3472+
event: jasmine.anything()
34593473
});
34603474

34613475
expect(dragItems.map(drag => drag.element.nativeElement.textContent!.trim()))
@@ -3849,7 +3863,8 @@ describe('CdkDrag', () => {
38493863
container: fixture.componentInstance.dropInstance,
38503864
previousContainer: fixture.componentInstance.dropInstance,
38513865
isPointerOverContainer: true,
3852-
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
3866+
distance: {x: jasmine.any(Number), y: jasmine.any(Number)},
3867+
event: jasmine.anything()
38533868
});
38543869
}));
38553870

@@ -4064,7 +4079,8 @@ describe('CdkDrag', () => {
40644079
container: fixture.componentInstance.dropInstances.toArray()[1],
40654080
previousContainer: fixture.componentInstance.dropInstances.first,
40664081
isPointerOverContainer: true,
4067-
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
4082+
distance: {x: jasmine.any(Number), y: jasmine.any(Number)},
4083+
event: jasmine.anything()
40684084
});
40694085
}));
40704086

@@ -4169,7 +4185,8 @@ describe('CdkDrag', () => {
41694185
container: dropInstances[1],
41704186
previousContainer: dropInstances[0],
41714187
isPointerOverContainer: true,
4172-
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
4188+
distance: {x: jasmine.any(Number), y: jasmine.any(Number)},
4189+
event: jasmine.anything()
41734190
});
41744191
}));
41754192

@@ -4200,7 +4217,8 @@ describe('CdkDrag', () => {
42004217
container: dropInstances[0],
42014218
previousContainer: dropInstances[0],
42024219
isPointerOverContainer: false,
4203-
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
4220+
distance: {x: jasmine.any(Number), y: jasmine.any(Number)},
4221+
event: jasmine.anything()
42044222
});
42054223
}));
42064224

@@ -4231,7 +4249,8 @@ describe('CdkDrag', () => {
42314249
container: dropInstances[0],
42324250
previousContainer: dropInstances[0],
42334251
isPointerOverContainer: false,
4234-
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
4252+
distance: {x: jasmine.any(Number), y: jasmine.any(Number)},
4253+
event: jasmine.anything()
42354254
});
42364255
}));
42374256

@@ -4394,6 +4413,7 @@ describe('CdkDrag', () => {
43944413
container: dropInstances[1],
43954414
previousContainer: dropInstances[0],
43964415
isPointerOverContainer: true,
4416+
event: jasmine.anything(),
43974417
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
43984418
});
43994419
}));
@@ -4531,7 +4551,8 @@ describe('CdkDrag', () => {
45314551
container: dropInstances[1],
45324552
previousContainer: dropInstances[0],
45334553
isPointerOverContainer: true,
4534-
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
4554+
distance: {x: jasmine.any(Number), y: jasmine.any(Number)},
4555+
event: jasmine.anything()
45354556
});
45364557
}));
45374558

@@ -4558,7 +4579,8 @@ describe('CdkDrag', () => {
45584579
container: dropInstances[1],
45594580
previousContainer: dropInstances[0],
45604581
isPointerOverContainer: true,
4561-
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
4582+
distance: {x: jasmine.any(Number), y: jasmine.any(Number)},
4583+
event: jasmine.anything()
45624584
});
45634585
}));
45644586

@@ -4590,7 +4612,8 @@ describe('CdkDrag', () => {
45904612
container: dropInstances[1],
45914613
previousContainer: dropInstances[0],
45924614
isPointerOverContainer: true,
4593-
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
4615+
distance: {x: jasmine.any(Number), y: jasmine.any(Number)},
4616+
event: jasmine.anything()
45944617
});
45954618
}));
45964619

@@ -4626,7 +4649,8 @@ describe('CdkDrag', () => {
46264649
container: fixture.componentInstance.dropInstances.toArray()[1],
46274650
previousContainer: fixture.componentInstance.dropInstances.first,
46284651
isPointerOverContainer: true,
4629-
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
4652+
distance: {x: jasmine.any(Number), y: jasmine.any(Number)},
4653+
event: jasmine.anything()
46304654
});
46314655

46324656
expect(dropContainers[0].contains(item.element.nativeElement)).toBe(true,
@@ -4723,7 +4747,8 @@ describe('CdkDrag', () => {
47234747
container: dropInstances[0],
47244748
previousContainer: dropInstances[0],
47254749
isPointerOverContainer: false,
4726-
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
4750+
distance: {x: jasmine.any(Number), y: jasmine.any(Number)},
4751+
event: jasmine.anything()
47274752
});
47284753
}));
47294754

@@ -4844,7 +4869,8 @@ describe('CdkDrag', () => {
48444869
container: dropInstances[2],
48454870
previousContainer: dropInstances[0],
48464871
isPointerOverContainer: false,
4847-
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
4872+
distance: {x: jasmine.any(Number), y: jasmine.any(Number)},
4873+
event: jasmine.anything()
48484874
}));
48494875

48504876
}));
@@ -5103,7 +5129,8 @@ describe('CdkDrag', () => {
51035129
container: fixture.componentInstance.dropInstances.toArray()[1],
51045130
previousContainer: fixture.componentInstance.dropInstances.first,
51055131
isPointerOverContainer: true,
5106-
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
5132+
distance: {x: jasmine.any(Number), y: jasmine.any(Number)},
5133+
event: jasmine.anything()
51075134
});
51085135

51095136
cleanup();
@@ -5138,7 +5165,8 @@ describe('CdkDrag', () => {
51385165
container: fixture.componentInstance.dropInstances.toArray()[1],
51395166
previousContainer: fixture.componentInstance.dropInstances.first,
51405167
isPointerOverContainer: true,
5141-
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
5168+
distance: {x: jasmine.any(Number), y: jasmine.any(Number)},
5169+
event: jasmine.anything()
51425170
});
51435171
}));
51445172

@@ -5172,7 +5200,8 @@ describe('CdkDrag', () => {
51725200
container: fixture.componentInstance.dropInstances.toArray()[1],
51735201
previousContainer: fixture.componentInstance.dropInstances.first,
51745202
isPointerOverContainer: true,
5175-
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
5203+
distance: {x: jasmine.any(Number), y: jasmine.any(Number)},
5204+
event: jasmine.anything()
51765205
});
51775206
}));
51785207

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

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -383,50 +383,51 @@ export class CdkDrag<T = any> implements AfterViewInit, OnChanges, OnDestroy {
383383

384384
/** Handles the events from the underlying `DragRef`. */
385385
private _handleEvents(ref: DragRef<CdkDrag<T>>) {
386-
ref.started.subscribe(() => {
387-
this.started.emit({source: this});
386+
ref.started.subscribe(startEvent => {
387+
this.started.emit({source: this, event: startEvent.event});
388388

389389
// Since all of these events run outside of change detection,
390390
// we need to ensure that everything is marked correctly.
391391
this._changeDetectorRef.markForCheck();
392392
});
393393

394-
ref.released.subscribe(() => {
395-
this.released.emit({source: this});
394+
ref.released.subscribe(releaseEvent => {
395+
this.released.emit({source: this, event: releaseEvent.event});
396396
});
397397

398-
ref.ended.subscribe(event => {
399-
this.ended.emit({source: this, distance: event.distance});
398+
ref.ended.subscribe(endEvent => {
399+
this.ended.emit({source: this, distance: endEvent.distance, event: endEvent.event});
400400

401401
// Since all of these events run outside of change detection,
402402
// we need to ensure that everything is marked correctly.
403403
this._changeDetectorRef.markForCheck();
404404
});
405405

406-
ref.entered.subscribe(event => {
406+
ref.entered.subscribe(enterEvent => {
407407
this.entered.emit({
408-
container: event.container.data,
408+
container: enterEvent.container.data,
409409
item: this,
410-
currentIndex: event.currentIndex
410+
currentIndex: enterEvent.currentIndex
411411
});
412412
});
413413

414-
ref.exited.subscribe(event => {
414+
ref.exited.subscribe(exitEvent => {
415415
this.exited.emit({
416-
container: event.container.data,
416+
container: exitEvent.container.data,
417417
item: this
418418
});
419419
});
420420

421-
ref.dropped.subscribe(event => {
421+
ref.dropped.subscribe(dropEvent => {
422422
this.dropped.emit({
423-
previousIndex: event.previousIndex,
424-
currentIndex: event.currentIndex,
425-
previousContainer: event.previousContainer.data,
426-
container: event.container.data,
427-
isPointerOverContainer: event.isPointerOverContainer,
423+
previousIndex: dropEvent.previousIndex,
424+
currentIndex: dropEvent.currentIndex,
425+
previousContainer: dropEvent.previousContainer.data,
426+
container: dropEvent.container.data,
427+
isPointerOverContainer: dropEvent.isPointerOverContainer,
428428
item: this,
429-
distance: event.distance
429+
distance: dropEvent.distance,
430+
event: dropEvent.event
430431
});
431432
});
432433
}

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

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -320,15 +320,16 @@ export class CdkDropList<T = any> implements OnDestroy {
320320
});
321321
});
322322

323-
ref.dropped.subscribe(event => {
323+
ref.dropped.subscribe(dropEvent => {
324324
this.dropped.emit({
325-
previousIndex: event.previousIndex,
326-
currentIndex: event.currentIndex,
327-
previousContainer: event.previousContainer.data,
328-
container: event.container.data,
329-
item: event.item.data,
330-
isPointerOverContainer: event.isPointerOverContainer,
331-
distance: event.distance
325+
previousIndex: dropEvent.previousIndex,
326+
currentIndex: dropEvent.currentIndex,
327+
previousContainer: dropEvent.previousContainer.data,
328+
container: dropEvent.container.data,
329+
item: dropEvent.item.data,
330+
isPointerOverContainer: dropEvent.isPointerOverContainer,
331+
distance: dropEvent.distance,
332+
event: dropEvent.event
332333
});
333334

334335
// Mark for check since all of these events run outside of change

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,16 @@ import {CdkDropList} from './directives/drop-list';
1313
export interface CdkDragStart<T = any> {
1414
/** Draggable that emitted the event. */
1515
source: CdkDrag<T>;
16+
/** Native event that started the drag sequence. */
17+
event: MouseEvent | TouchEvent;
1618
}
1719

1820
/** Event emitted when the user releases an item, before any animations have started. */
1921
export interface CdkDragRelease<T = any> {
2022
/** Draggable that emitted the event. */
2123
source: CdkDrag<T>;
24+
/** Native event that caused the release event. */
25+
event: MouseEvent | TouchEvent;
2226
}
2327

2428
/** Event emitted when the user stops dragging a draggable. */
@@ -27,6 +31,8 @@ export interface CdkDragEnd<T = any> {
2731
source: CdkDrag<T>;
2832
/** Distance in pixels that the user has dragged since the drag sequence started. */
2933
distance: {x: number, y: number};
34+
/** Native event that caused the dragging to stop. */
35+
event: MouseEvent | TouchEvent;
3036
}
3137

3238
/** Event emitted when the user moves an item into a new drop container. */
@@ -67,6 +73,8 @@ export interface CdkDragDrop<T, O = T> {
6773
isPointerOverContainer: boolean;
6874
/** Distance in pixels that the user has dragged since the drag sequence started. */
6975
distance: {x: number, y: number};
76+
/** Native event that caused the drop event. */
77+
event: MouseEvent | TouchEvent;
7078
}
7179

7280
/** Event emitted as the user is dragging a draggable item. */

0 commit comments

Comments
 (0)