Skip to content

Commit ebbe8d7

Browse files
crisbetojelbourn
authored andcommitted
fix(drag-drop): update free drag position on scroll (#19648)
Initially we didn't handle updating the item position if scrolling happens during a drag, because dragging was blocked. Eventually we unblocked dragging and added auto scrolling, but we only managed the dragged position when an item is inside a drop list. These changes add some code to also manage scrolling inside a freely draggable item.
1 parent 6ae9741 commit ebbe8d7

File tree

2 files changed

+65
-4
lines changed

2 files changed

+65
-4
lines changed

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

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,6 +1208,54 @@ describe('CdkDrag', () => {
12081208
}).not.toThrow();
12091209
}));
12101210

1211+
it('should update the free drag position if the page is scrolled', fakeAsync(() => {
1212+
const fixture = createComponent(StandaloneDraggable);
1213+
fixture.detectChanges();
1214+
1215+
const cleanup = makeScrollable();
1216+
const dragElement = fixture.componentInstance.dragElement.nativeElement;
1217+
1218+
expect(dragElement.style.transform).toBeFalsy();
1219+
startDraggingViaMouse(fixture, dragElement, 0, 0);
1220+
dispatchMouseEvent(document, 'mousemove', 50, 100);
1221+
fixture.detectChanges();
1222+
1223+
expect(dragElement.style.transform).toBe('translate3d(50px, 100px, 0px)');
1224+
1225+
scrollTo(0, 500);
1226+
dispatchFakeEvent(document, 'scroll');
1227+
fixture.detectChanges();
1228+
expect(dragElement.style.transform).toBe('translate3d(50px, 600px, 0px)');
1229+
1230+
cleanup();
1231+
}));
1232+
1233+
it('should update the free drag position if the user moves their pointer after the page ' +
1234+
'is scrolled', fakeAsync(() => {
1235+
const fixture = createComponent(StandaloneDraggable);
1236+
fixture.detectChanges();
1237+
1238+
const cleanup = makeScrollable();
1239+
const dragElement = fixture.componentInstance.dragElement.nativeElement;
1240+
1241+
expect(dragElement.style.transform).toBeFalsy();
1242+
startDraggingViaMouse(fixture, dragElement, 0, 0);
1243+
dispatchMouseEvent(document, 'mousemove', 50, 100);
1244+
fixture.detectChanges();
1245+
1246+
expect(dragElement.style.transform).toBe('translate3d(50px, 100px, 0px)');
1247+
1248+
scrollTo(0, 500);
1249+
dispatchFakeEvent(document, 'scroll');
1250+
fixture.detectChanges();
1251+
dispatchMouseEvent(document, 'mousemove', 50, 200);
1252+
fixture.detectChanges();
1253+
1254+
expect(dragElement.style.transform).toBe('translate3d(50px, 700px, 0px)');
1255+
1256+
cleanup();
1257+
}));
1258+
12111259
});
12121260

12131261
describe('draggable with a handle', () => {

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

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,10 +1244,23 @@ export class DragRef<T = any> {
12441244
private _updateOnScroll(event: Event) {
12451245
const scrollDifference = this._parentPositions.handleScroll(event);
12461246

1247-
// ClientRect dimensions are based on the page's scroll position so
1248-
// we have to update the cached boundary ClientRect if the user has scrolled.
1249-
if (this._boundaryRect && scrollDifference) {
1250-
adjustClientRect(this._boundaryRect, scrollDifference.top, scrollDifference.left);
1247+
if (scrollDifference) {
1248+
// ClientRect dimensions are based on the page's scroll position so
1249+
// we have to update the cached boundary ClientRect if the user has scrolled.
1250+
if (this._boundaryRect) {
1251+
adjustClientRect(this._boundaryRect, scrollDifference.top, scrollDifference.left);
1252+
}
1253+
1254+
this._pickupPositionOnPage.x += scrollDifference.left;
1255+
this._pickupPositionOnPage.y += scrollDifference.top;
1256+
1257+
// If we're in free drag mode, we have to update the active transform, because
1258+
// it isn't relative to the viewport like the preview inside a drop list.
1259+
if (!this._dropContainer) {
1260+
this._activeTransform.x -= scrollDifference.left;
1261+
this._activeTransform.y -= scrollDifference.top;
1262+
this._applyRootElementTransform(this._activeTransform.x, this._activeTransform.y);
1263+
}
12511264
}
12521265
}
12531266

0 commit comments

Comments
 (0)