Skip to content

Commit 700fef1

Browse files
committed
fix: allow draggable elements insider other draggable elements to be dragged
Fixes #61
1 parent 62eb8b6 commit 700fef1

File tree

2 files changed

+72
-4
lines changed

2 files changed

+72
-4
lines changed

projects/angular-draggable-droppable/src/lib/draggable.directive.spec.ts

+66-4
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,51 @@ describe('draggable directive', () => {
9898
scrollContainer: DraggableScrollContainerDirective;
9999
}
100100

101+
@Component({
102+
// tslint:disable-line max-classes-per-file
103+
template: `
104+
<div
105+
mwlDraggable
106+
[dragAxis]="{x: true, y: true}"
107+
(dragPointerDown)="outerDrag($event)"
108+
(dragStart)="outerDrag($event)"
109+
(ghostElementCreated)="outerDrag($event)"
110+
(dragging)="outerDrag($event)"
111+
(dragEnd)="outerDrag($event)"
112+
>
113+
<button
114+
#draggableElement
115+
mwlDraggable
116+
[dragAxis]="{x: true, y: true}"
117+
(dragPointerDown)="dragPointerDown($event)"
118+
(dragStart)="dragStart($event)"
119+
(ghostElementCreated)="ghostElementCreated($event)"
120+
(dragging)="dragging($event)"
121+
(dragEnd)="dragEnd($event)"
122+
>
123+
Drag me as well
124+
</button>
125+
</div>
126+
`,
127+
styles: [
128+
`
129+
div[mwlDraggable] {
130+
position: relative;
131+
width: 50px;
132+
height: 50px;
133+
z-index: 1;
134+
}
135+
`
136+
]
137+
})
138+
class InnerDragTestComponent extends TestComponent {
139+
outerDrag = sinon.spy();
140+
}
141+
101142
beforeEach(() => {
102143
TestBed.configureTestingModule({
103144
imports: [DragAndDropModule],
104-
declarations: [TestComponent, ScrollTestComponent]
145+
declarations: [TestComponent, ScrollTestComponent, InnerDragTestComponent]
105146
});
106147
});
107148

@@ -496,9 +537,11 @@ describe('draggable directive', () => {
496537
it('should work with touch events', () => {
497538
const draggableElement =
498539
fixture.componentInstance.draggableElement.nativeElement;
499-
triggerDomEvent('touchstart', draggableElement, {
500-
touches: [{ clientX: 5, clientY: 10 }]
501-
});
540+
fixture.debugElement
541+
.query(By.directive(DraggableDirective))
542+
.triggerEventHandler('touchstart', {
543+
touches: [{ clientX: 5, clientY: 10 }]
544+
});
502545
triggerDomEvent('touchmove', draggableElement, {
503546
targetTouches: [{ clientX: 7, clientY: 10 }]
504547
});
@@ -819,4 +862,23 @@ describe('draggable directive', () => {
819862
triggerDomEvent('mouseup', draggableElement, { clientX: 5, clientY: 10 });
820863
expect(getComputedStyle(tmp).userSelect).to.equal('auto');
821864
});
865+
866+
it('should allow for draggable elements to be inside other draggable elements', () => {
867+
const innerDragFixture = TestBed.createComponent(InnerDragTestComponent);
868+
innerDragFixture.detectChanges();
869+
document.body.appendChild(innerDragFixture.nativeElement);
870+
const draggableElement =
871+
innerDragFixture.componentInstance.draggableElement.nativeElement;
872+
triggerDomEvent('mousedown', draggableElement, { clientX: 5, clientY: 10 });
873+
expect(innerDragFixture.componentInstance.dragPointerDown).to.have.been
874+
.calledOnce;
875+
triggerDomEvent('mousemove', draggableElement, { clientX: 5, clientY: 12 });
876+
expect(innerDragFixture.componentInstance.dragStart).to.have.been
877+
.calledOnce;
878+
expect(innerDragFixture.componentInstance.dragging).to.have.been.calledOnce;
879+
triggerDomEvent('mouseup', draggableElement, { clientX: 5, clientY: 14 });
880+
expect(innerDragFixture.componentInstance.dragEnd).to.have.been.calledOnce;
881+
expect(innerDragFixture.componentInstance.outerDrag).not.to.have.been
882+
.called;
883+
});
822884
});

projects/angular-draggable-droppable/src/lib/draggable.directive.ts

+6
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,12 @@ export class DraggableDirective implements OnInit, OnChanges, OnDestroy {
213213
const pointerDragged$: Observable<any> = this.pointerDown$.pipe(
214214
filter(() => this.canDrag()),
215215
mergeMap((pointerDownEvent: PointerEvent) => {
216+
// fix for https://github.com/mattlewis92/angular-draggable-droppable/issues/61
217+
// stop mouse events propagating up the chain
218+
if (pointerDownEvent.event.stopPropagation) {
219+
pointerDownEvent.event.stopPropagation();
220+
}
221+
216222
// hack to prevent text getting selected in safari while dragging
217223
const globalDragStyle: HTMLStyleElement = this.renderer.createElement(
218224
'style'

0 commit comments

Comments
 (0)