/
useDragNode.ts
55 lines (51 loc) · 1.41 KB
/
useDragNode.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import { DragSourceHookSpec, useDrag } from 'react-dnd';
import { TEditor, Value } from '@udecode/plate-core';
import { dndStore } from '../dndStore';
import { DragItemNode } from '../types';
export interface UseDragNodeOptions
extends DragSourceHookSpec<DragItemNode, unknown, { isDragging: boolean }> {
id: string;
}
/**
* `useDrag` hook to drag a node from the editor. `item` with `id` is required.
*
* On drag start:
* - set `editor.isDragging` to true
* - add `dragging` class to `body`
*
* On drag end:
* - set `editor.isDragging` to false
* - remove `dragging` class to `body`
*
* Collect:
* - isDragging: true if mouse is dragging the block
*/
export const useDragNode = <V extends Value>(
editor: TEditor<V>,
{ id, item, ...options }: UseDragNodeOptions
) => {
return useDrag<DragItemNode, unknown, { isDragging: boolean }>(
() => ({
item(monitor) {
dndStore.set.isDragging(true);
editor.isDragging = true;
document.body.classList.add('dragging');
const _item = typeof item === 'function' ? item(monitor) : item;
return {
id,
..._item,
};
},
collect: (monitor) => ({
isDragging: monitor.isDragging(),
}),
end: () => {
dndStore.set.isDragging(false);
editor.isDragging = false;
document.body.classList.remove('dragging');
},
...options,
}),
[]
);
};