Skip to content

Commit f800900

Browse files
crisbetojelbourn
authored andcommitted
fix(drag-drop): position reset if viewport is resized while boundary is invisible (#17777)
If a dragged item is inside a boundary, we update its position on window resize to ensure that it stays inside the boundary. If a resize event happens while the boundary is hidden, we end up resetting the user's position unintentionally. These changes add a check that prevents the position from changing if the elements are hidden. Fixes #17750.
1 parent 3e98034 commit f800900

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,23 @@ describe('CdkDrag', () => {
800800
expect(dragElement.style.transform).toBe('translate3d(50px, 100px, 0px)');
801801
}));
802802

803+
it('should keep the old position if the boundary is invisible after a resize', fakeAsync(() => {
804+
const fixture = createComponent(StandaloneDraggable);
805+
const boundary: HTMLElement = fixture.nativeElement.querySelector('.wrapper');
806+
fixture.componentInstance.boundary = boundary;
807+
fixture.detectChanges();
808+
const dragElement = fixture.componentInstance.dragElement.nativeElement;
809+
810+
dragElementViaMouse(fixture, dragElement, 300, 300);
811+
expect(dragElement.style.transform).toBe('translate3d(100px, 100px, 0px)');
812+
813+
boundary.style.display = 'none';
814+
dispatchFakeEvent(window, 'resize');
815+
tick(20);
816+
817+
expect(dragElement.style.transform).toBe('translate3d(100px, 100px, 0px)');
818+
}));
819+
803820
it('should handle the element and boundary dimensions changing between drag sequences',
804821
fakeAsync(() => {
805822
const fixture = createComponent(StandaloneDraggable);

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,6 +1123,14 @@ export class DragRef<T = any> {
11231123

11241124
const boundaryRect = this._boundaryElement.getBoundingClientRect();
11251125
const elementRect = this._rootElement.getBoundingClientRect();
1126+
1127+
// It's possible that the element got hidden away after dragging (e.g. by switching to a
1128+
// different tab). Don't do anything in this case so we don't clear the user's position.
1129+
if ((boundaryRect.width === 0 && boundaryRect.height === 0) ||
1130+
(elementRect.width === 0 && elementRect.height === 0)) {
1131+
return;
1132+
}
1133+
11261134
const leftOverflow = boundaryRect.left - elementRect.left;
11271135
const rightOverflow = elementRect.right - boundaryRect.right;
11281136
const topOverflow = boundaryRect.top - elementRect.top;

0 commit comments

Comments
 (0)