Skip to content

Commit e8f6091

Browse files
authored
Merge pull request #420 from zjffun/feature/drag-stoped-event
feature: add a drag stopped event
2 parents 4e1e1bc + 9f4933d commit e8f6091

File tree

8 files changed

+121
-1
lines changed

8 files changed

+121
-1
lines changed

index.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ declare module '@shopify/draggable' {
4242
? DragOutContainerEvent
4343
: eventName extends 'drag:stop'
4444
? DragStopEvent
45+
: eventName extends 'drag:stopped'
46+
? DragStoppedEvent
4547
: eventName extends 'drag:pressure'
4648
? DragPressureEvent
4749
: eventName extends 'mirror:create'
@@ -124,6 +126,8 @@ declare module '@shopify/draggable' {
124126

125127
export class DragStopEvent extends DragEvent { }
126128

129+
export class DragStoppedEvent extends DragEvent { }
130+
127131
/**
128132
* DraggableEvent
129133
*/

src/Draggable/DragEvent/DragEvent.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,3 +225,13 @@ export class DragPressureEvent extends DragEvent {
225225
export class DragStopEvent extends DragEvent {
226226
static type = 'drag:stop';
227227
}
228+
229+
/**
230+
* Drag stopped event
231+
* @class DragStoppedEvent
232+
* @module DragStoppedEvent
233+
* @extends DragEvent
234+
*/
235+
export class DragStoppedEvent extends DragEvent {
236+
static type = 'drag:stopped';
237+
}

src/Draggable/DragEvent/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,3 +163,16 @@ Read-only property for pressure applied on a draggable element. Value ranges fro
163163
| **Cancelable** | false |
164164
| **Cancel action** | - |
165165
| **type** | `drag:stop` |
166+
167+
## DragStoppedEvent
168+
169+
`DragStoppedEvent` gets triggered after `DragStopEvent`. This event fires after `drag:stop` listeners have finished running,
170+
the source element removed from the document and draggable classes are removed.
171+
172+
| | |
173+
| ----------------- | ------------------ |
174+
| **Specification** | `DragEvent` |
175+
| **Interface** | `DragStoppedEvent` |
176+
| **Cancelable** | false |
177+
| **Cancel action** | - |
178+
| **type** | `drag:stopped` |

src/Draggable/DragEvent/tests/DragEvent.test.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
DragPressureEvent,
99
DragStartEvent,
1010
DragStopEvent,
11+
DragStoppedEvent,
1112
} from '../DragEvent';
1213

1314
describe('DragEvent', () => {
@@ -259,3 +260,19 @@ describe('DragStopEvent', () => {
259260
});
260261
});
261262
});
263+
264+
describe('DragStoppedEvent', () => {
265+
describe('#constructor', () => {
266+
it('should be instance of DragStoppedEvent', () => {
267+
const event = new DragStoppedEvent();
268+
269+
expect(event).toBeInstanceOf(DragStoppedEvent);
270+
});
271+
272+
it('should initialize with `type` of `drag:stopped`', () => {
273+
const event = new DragStoppedEvent();
274+
275+
expect(event.type).toBe('drag:stopped');
276+
});
277+
});
278+
});

src/Draggable/Draggable.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
DragOverEvent,
1616
DragStopEvent,
1717
DragPressureEvent,
18+
DragStoppedEvent,
1819
} from './DragEvent';
1920

2021
const onDragStart = Symbol('onDragStart');
@@ -590,6 +591,15 @@ export default class Draggable {
590591
this.lastPlacedContainer = null;
591592
}, this.options.placedTimeout);
592593

594+
const dragStoppedEvent = new DragStoppedEvent({
595+
source: this.source,
596+
originalSource: this.originalSource,
597+
sensorEvent: event.sensorEvent,
598+
sourceContainer: this.sourceContainer,
599+
});
600+
601+
this.trigger(dragStoppedEvent);
602+
593603
this.source = null;
594604
this.originalSource = null;
595605
this.currentOverContainer = null;

src/Draggable/Plugins/Mirror/tests/Mirror.test.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,4 +494,23 @@ describe('Mirror', () => {
494494

495495
releaseMouse(draggable.source);
496496
});
497+
498+
describe('when `drag:stopped`', () => {
499+
it('mirror element was removed from document', async () => {
500+
draggable = new Draggable(container, draggableOptions);
501+
502+
clickMouse(draggableElement);
503+
waitForDragDelay();
504+
505+
await waitForPromisesToResolve();
506+
507+
const mirrorElement = document.querySelector('.draggable-mirror');
508+
509+
draggable.on('drag:stopped', () => {
510+
expect(mirrorElement.parentNode).toBeNull();
511+
});
512+
513+
releaseMouse(draggable.source);
514+
});
515+
});
497516
});

src/Draggable/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ Allow excluding default plugins and default sensors. Use with caution as it may
112112
| [`drag:out`][dragout] | Gets fired when dragging out of other draggable | false | - |
113113
| [`drag:out:container`][dragoutcontainer] | Gets fired when dragging out of other draggable container | false | - |
114114
| [`drag:stop`][dragstop] | Gets fired when draggable has been released | false | - |
115+
| [`drag:stopped`][dragstopped] | Gets fired when draggable finished | false | - |
115116
| [`drag:pressure`][dragpressure] | Gets fired when using force touch on draggable element | false | - |
116117

117118
[draggableinit]: DraggableEvent#draggableinitializedevent
@@ -123,6 +124,7 @@ Allow excluding default plugins and default sensors. Use with caution as it may
123124
[dragout]: DragEvent#dragoutevent
124125
[dragoutcontainer]: DragEvent#dragoutcontainerevent
125126
[dragstop]: DragEvent#dragstopevent
127+
[dragstopped]: DragEvent#dragstoppedevent
126128
[dragpressure]: DragEvent#dragpressureevent
127129

128130
### Classes

src/Draggable/tests/Draggable.test.js

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
waitForRequestAnimationFrame,
1010
} from 'helper';
1111
import Draggable, {defaultOptions} from '../Draggable';
12-
import {DragStartEvent, DragMoveEvent, DragStopEvent} from '../DragEvent';
12+
import {DragStartEvent, DragMoveEvent, DragStopEvent, DragStoppedEvent} from '../DragEvent';
1313
import {DraggableInitializedEvent, DraggableDestroyEvent} from '../DraggableEvent';
1414
import {Focusable, Mirror, Scrollable, Announcement} from '../Plugins';
1515
import {MouseSensor, TouchSensor} from '../Sensors';
@@ -607,6 +607,30 @@ describe('Draggable', () => {
607607
expect(call).toBeInstanceOf(DragStopEvent);
608608
});
609609

610+
it('triggers `drag:stopped` drag event on mouseup', () => {
611+
const newInstance = new Draggable(containers, {
612+
draggable: 'li',
613+
});
614+
const draggableElement = sandbox.querySelector('li');
615+
document.elementFromPoint = () => draggableElement;
616+
617+
triggerEvent(draggableElement, 'mousedown', {button: 0});
618+
619+
// Wait for delay
620+
waitForDragDelay();
621+
622+
const callback = jest.fn();
623+
newInstance.on('drag:stopped', callback);
624+
625+
triggerEvent(draggableElement, 'mouseup', {button: 0});
626+
627+
const call = callback.mock.calls[0][0];
628+
629+
expect(call.type).toBe('drag:stopped');
630+
631+
expect(call).toBeInstanceOf(DragStoppedEvent);
632+
});
633+
610634
it('adds `source:dragging` classname to draggable element on mousedown', () => {
611635
const newInstance = new Draggable(containers, {
612636
draggable: 'li',
@@ -881,4 +905,25 @@ describe('Draggable', () => {
881905

882906
triggerEvent(document.body, 'mouseup', {button: 0});
883907
});
908+
909+
describe('when `drag:stopped`', () => {
910+
it('source element was removed from document', () => {
911+
const newInstance = new Draggable(containers, {
912+
draggable: 'li',
913+
});
914+
const draggableElement = sandbox.querySelector('li');
915+
document.elementFromPoint = () => draggableElement;
916+
917+
newInstance.on('drag:stopped', (event) => {
918+
expect(event.source.parentNode).toBeNull();
919+
});
920+
921+
clickMouse(draggableElement);
922+
923+
// Wait for delay
924+
waitForDragDelay();
925+
926+
releaseMouse(newInstance.source);
927+
});
928+
});
884929
});

0 commit comments

Comments
 (0)