Skip to content

Commit 778e182

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 31d8819 commit 778e182

File tree

6 files changed

+63
-37
lines changed

6 files changed

+63
-37
lines changed

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

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

365365
/** Handles the events from the underlying `DragRef`. */
366366
private _handleEvents(ref: DragRef<CdkDrag<T>>) {
367-
ref.started.subscribe(() => {
368-
this.started.emit({source: this});
367+
ref.started.subscribe(startEvent => {
368+
this.started.emit({source: this, event: startEvent.event});
369369

370370
// Since all of these events run outside of change detection,
371371
// we need to ensure that everything is marked correctly.
372372
this._changeDetectorRef.markForCheck();
373373
});
374374

375-
ref.released.subscribe(() => {
376-
this.released.emit({source: this});
375+
ref.released.subscribe(releaseEvent => {
376+
this.released.emit({source: this, event: releaseEvent.event});
377377
});
378378

379-
ref.ended.subscribe(event => {
380-
this.ended.emit({source: this, distance: event.distance});
379+
ref.ended.subscribe(endEvent => {
380+
this.ended.emit({source: this, distance: endEvent.distance, event: endEvent.event});
381381

382382
// Since all of these events run outside of change detection,
383383
// we need to ensure that everything is marked correctly.
384384
this._changeDetectorRef.markForCheck();
385385
});
386386

387-
ref.entered.subscribe(event => {
387+
ref.entered.subscribe(enterEvent => {
388388
this.entered.emit({
389-
container: event.container.data,
389+
container: enterEvent.container.data,
390390
item: this,
391-
currentIndex: event.currentIndex
391+
currentIndex: enterEvent.currentIndex
392392
});
393393
});
394394

395-
ref.exited.subscribe(event => {
395+
ref.exited.subscribe(exitEvent => {
396396
this.exited.emit({
397-
container: event.container.data,
397+
container: exitEvent.container.data,
398398
item: this
399399
});
400400
});
401401

402-
ref.dropped.subscribe(event => {
402+
ref.dropped.subscribe(dropEvent => {
403403
this.dropped.emit({
404-
previousIndex: event.previousIndex,
405-
currentIndex: event.currentIndex,
406-
previousContainer: event.previousContainer.data,
407-
container: event.container.data,
408-
isPointerOverContainer: event.isPointerOverContainer,
404+
previousIndex: dropEvent.previousIndex,
405+
currentIndex: dropEvent.currentIndex,
406+
previousContainer: dropEvent.previousContainer.data,
407+
container: dropEvent.container.data,
408+
isPointerOverContainer: dropEvent.isPointerOverContainer,
409409
item: this,
410-
distance: event.distance
410+
distance: dropEvent.distance,
411+
event: dropEvent.event
411412
});
412413
});
413414
}

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

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -340,15 +340,16 @@ export class CdkDropList<T = any> implements CdkDropListContainer, AfterContentI
340340
});
341341
});
342342

343-
ref.dropped.subscribe(event => {
343+
ref.dropped.subscribe(dropEvent => {
344344
this.dropped.emit({
345-
previousIndex: event.previousIndex,
346-
currentIndex: event.currentIndex,
347-
previousContainer: event.previousContainer.data,
348-
container: event.container.data,
349-
item: event.item.data,
350-
isPointerOverContainer: event.isPointerOverContainer,
351-
distance: event.distance
345+
previousIndex: dropEvent.previousIndex,
346+
currentIndex: dropEvent.currentIndex,
347+
previousContainer: dropEvent.previousContainer.data,
348+
container: dropEvent.container.data,
349+
item: dropEvent.item.data,
350+
isPointerOverContainer: dropEvent.isPointerOverContainer,
351+
distance: dropEvent.distance,
352+
event: dropEvent.event
352353
});
353354

354355
// 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. */

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

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -228,13 +228,13 @@ export class DragRef<T = any> {
228228
beforeStarted = new Subject<void>();
229229

230230
/** Emits when the user starts dragging the item. */
231-
started = new Subject<{source: DragRef}>();
231+
started = new Subject<{source: DragRef, event: MouseEvent | TouchEvent}>();
232232

233233
/** Emits when the user has released a drag item, before any animations have started. */
234-
released = new Subject<{source: DragRef}>();
234+
released = new Subject<{source: DragRef, event: MouseEvent | TouchEvent}>();
235235

236236
/** Emits when the user stops dragging an item in the container. */
237-
ended = new Subject<{source: DragRef, distance: Point}>();
237+
ended = new Subject<{source: DragRef, distance: Point, event: MouseEvent | TouchEvent}>();
238238

239239
/** Emits when the user has moved the item into a new container. */
240240
entered = new Subject<{container: DropListRef, item: DragRef, currentIndex: number}>();
@@ -251,6 +251,7 @@ export class DragRef<T = any> {
251251
previousContainer: DropListRef;
252252
distance: Point;
253253
isPointerOverContainer: boolean;
254+
event: MouseEvent | TouchEvent;
254255
}>();
255256

256257
/**
@@ -628,7 +629,7 @@ export class DragRef<T = any> {
628629
return;
629630
}
630631

631-
this.released.next({source: this});
632+
this.released.next({source: this, event});
632633

633634
if (this._dropContainer) {
634635
// Stop scrolling immediately, instead of waiting for the animation to finish.
@@ -647,7 +648,8 @@ export class DragRef<T = any> {
647648
this._ngZone.run(() => {
648649
this.ended.next({
649650
source: this,
650-
distance: this._getDragDistance(this._getPointerPositionOnPage(event))
651+
distance: this._getDragDistance(this._getPointerPositionOnPage(event)),
652+
event
651653
});
652654
});
653655
this._cleanupCachedDimensions();
@@ -658,7 +660,7 @@ export class DragRef<T = any> {
658660
/** Starts the dragging sequence. */
659661
private _startDragSequence(event: MouseEvent | TouchEvent) {
660662
// Emit the event on the item before the one on the container.
661-
this.started.next({source: this});
663+
this.started.next({source: this, event});
662664

663665
if (isTouchEvent(event)) {
664666
this._lastTouchEventTime = Date.now();
@@ -783,15 +785,16 @@ export class DragRef<T = any> {
783785
const isPointerOverContainer = container._isOverContainer(
784786
pointerPosition.x, pointerPosition.y);
785787

786-
this.ended.next({source: this, distance});
788+
this.ended.next({source: this, distance, event});
787789
this.dropped.next({
788790
item: this,
789791
currentIndex,
790792
previousIndex: this._initialContainer.getItemIndex(this),
791793
container: container,
792794
previousContainer: this._initialContainer,
793795
isPointerOverContainer,
794-
distance
796+
distance,
797+
event
795798
});
796799
container.drop(this, currentIndex, this._initialContainer, isPointerOverContainer, distance);
797800
this._dropContainer = this._initialContainer;

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ export class DropListRef<T = any> {
129129
previousContainer: DropListRef,
130130
isPointerOverContainer: boolean,
131131
distance: Point;
132+
event: MouseEvent | TouchEvent;
132133
}>();
133134

134135
/** Emits as the user is swapping items while actively dragging. */
@@ -335,9 +336,11 @@ export class DropListRef<T = any> {
335336
* container when the item was dropped.
336337
* @param distance Distance the user has dragged since the start of the dragging sequence.
337338
* @breaking-change 9.0.0 `distance` parameter to become required.
339+
* @breaking-change 10.0.0 `event` parameter to become required.
338340
*/
339341
drop(item: DragRef, currentIndex: number, previousContainer: DropListRef,
340-
isPointerOverContainer: boolean, distance: Point = {x: 0, y: 0}): void {
342+
isPointerOverContainer: boolean, distance: Point = {x: 0, y: 0},
343+
event: MouseEvent | TouchEvent = {} as any): void {
341344
this._reset();
342345
this.dropped.next({
343346
item,
@@ -346,7 +349,8 @@ export class DropListRef<T = any> {
346349
container: this,
347350
previousContainer,
348351
isPointerOverContainer,
349-
distance
352+
distance,
353+
event
350354
});
351355
}
352356

tools/public_api_guard/cdk/drag-drop.d.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export interface CdkDragDrop<T, O = T> {
5757
x: number;
5858
y: number;
5959
};
60+
event: MouseEvent | TouchEvent;
6061
isPointerOverContainer: boolean;
6162
item: CdkDrag;
6263
previousContainer: CdkDropList<O>;
@@ -68,6 +69,7 @@ export interface CdkDragEnd<T = any> {
6869
x: number;
6970
y: number;
7071
};
72+
event: MouseEvent | TouchEvent;
7173
source: CdkDrag<T>;
7274
}
7375

@@ -121,6 +123,7 @@ export declare class CdkDragPreview<T = any> {
121123
}
122124

123125
export interface CdkDragRelease<T = any> {
126+
event: MouseEvent | TouchEvent;
124127
source: CdkDrag<T>;
125128
}
126129

@@ -132,6 +135,7 @@ export interface CdkDragSortEvent<T = any, I = T> {
132135
}
133136

134137
export interface CdkDragStart<T = any> {
138+
event: MouseEvent | TouchEvent;
135139
source: CdkDrag<T>;
136140
}
137141

@@ -239,10 +243,12 @@ export declare class DragRef<T = any> {
239243
previousContainer: DropListRef;
240244
distance: Point;
241245
isPointerOverContainer: boolean;
246+
event: TouchEvent | MouseEvent;
242247
}>;
243248
ended: Subject<{
244249
source: DragRef<any>;
245250
distance: Point;
251+
event: TouchEvent | MouseEvent;
246252
}>;
247253
entered: Subject<{
248254
container: DropListRef;
@@ -269,9 +275,11 @@ export declare class DragRef<T = any> {
269275
}>;
270276
released: Subject<{
271277
source: DragRef<any>;
278+
event: TouchEvent | MouseEvent;
272279
}>;
273280
started: Subject<{
274281
source: DragRef<any>;
282+
event: TouchEvent | MouseEvent;
275283
}>;
276284
constructor(element: ElementRef<HTMLElement> | HTMLElement, _config: DragRefConfig, _document: Document, _ngZone: NgZone, _viewportRuler: ViewportRuler, _dragDropRegistry: DragDropRegistry<DragRef, DropListRef>);
277285
_sortFromLastPointerPosition(): void;
@@ -311,6 +319,7 @@ export declare class DropListRef<T = any> {
311319
previousContainer: DropListRef<any>;
312320
isPointerOverContainer: boolean;
313321
distance: Point;
322+
event: TouchEvent | MouseEvent;
314323
}>;
315324
element: HTMLElement | ElementRef<HTMLElement>;
316325
enterPredicate: (drag: DragRef, drop: DropListRef) => boolean;
@@ -347,7 +356,7 @@ export declare class DropListRef<T = any> {
347356
_stopScrolling(): void;
348357
connectedTo(connectedTo: DropListRef[]): this;
349358
dispose(): void;
350-
drop(item: DragRef, currentIndex: number, previousContainer: DropListRef, isPointerOverContainer: boolean, distance?: Point): void;
359+
drop(item: DragRef, currentIndex: number, previousContainer: DropListRef, isPointerOverContainer: boolean, distance?: Point, event?: MouseEvent | TouchEvent): void;
351360
enter(item: DragRef, pointerX: number, pointerY: number): void;
352361
exit(item: DragRef): void;
353362
getItemIndex(item: DragRef): number;

0 commit comments

Comments
 (0)