Skip to content

Commit 15816bc

Browse files
authored
Merge pull request udecode#4592 from DND-IT/hide-drop-line-on-cancel-drag
2 parents 7b71a32 + b19994e commit 15816bc

2 files changed

Lines changed: 43 additions & 4 deletions

File tree

.changeset/khaki-insects-remain.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@platejs/dnd': patch
3+
---
4+
5+
Hide drop line when user leaves document or drops (also besides editor)

packages/dnd/src/DndPlugin.tsx

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import React, { useCallback, useEffect } from 'react';
22

33
import type { Path, PluginConfig } from 'platejs';
44
import type { DropTargetMonitor } from 'react-dnd';
@@ -67,9 +67,6 @@ export const DndPlugin = createTPlatePlugin<DndConfig>({
6767
editor.setOption(plugin, '_isOver', true);
6868
},
6969
onDrop: ({ getOptions, setOption }) => {
70-
setOption('_isOver', false);
71-
setOption('dropTarget', undefined);
72-
7370
return getOptions().isDragging;
7471
},
7572
onFocus: ({ editor, plugin }) => {
@@ -88,6 +85,43 @@ export const DndPlugin = createTPlatePlugin<DndConfig>({
8885
isDragging: false,
8986
multiplePreviewRef: null,
9087
},
88+
useHooks: ({ setOption }) => {
89+
const handleDocumentDragLeave = useCallback(
90+
(e: DragEvent) => {
91+
// This event fires for every element that receives a drag leave event. If `clientX` and `clientY` are both 0,
92+
// it means the drag has left the viewport. Needed, if the drag did not start inside the editor, but for example
93+
// by dragging a file from the filesystem
94+
if (!e.clientX && !e.clientY) {
95+
setOption('dropTarget', undefined);
96+
}
97+
},
98+
[setOption]
99+
);
100+
101+
// We listen for the drop event on the document and not only inside the editor, because we want to
102+
// remove the dropTarget, and therefore hide the drop line, also when the drop happened outside of
103+
// the editor. Needed, if the drag did not start inside the editor, but for example by dragging a
104+
// file from the filesystem
105+
const handleDocumentDrop = useCallback(() => {
106+
setOption('_isOver', false);
107+
setOption('dropTarget', undefined);
108+
}, [setOption]);
109+
110+
useEffect(() => {
111+
document.addEventListener('dragleave', handleDocumentDragLeave, true);
112+
document.addEventListener('drop', handleDocumentDrop, true);
113+
114+
return () => {
115+
document.removeEventListener(
116+
'dragleave',
117+
handleDocumentDragLeave,
118+
true
119+
);
120+
121+
document.removeEventListener('drop', handleDocumentDrop, true);
122+
};
123+
}, [handleDocumentDragLeave, handleDocumentDrop]);
124+
},
91125
}).extend(({ getOptions }) => ({
92126
render: {
93127
afterEditable: getOptions().enableScroller

0 commit comments

Comments
 (0)