@@ -6,14 +6,18 @@ import { $dfsIterator, $insertNodeToNearestRoot, mergeRegister } from '@lexical/
6
6
import { useBulkUpload , useConfig , useEffectEvent , useModal } from '@payloadcms/ui'
7
7
import ObjectID from 'bson-objectid'
8
8
import {
9
+ $createRangeSelection ,
9
10
$getPreviousSelection ,
10
11
$getSelection ,
11
12
$isParagraphNode ,
12
13
$isRangeSelection ,
14
+ $setSelection ,
13
15
COMMAND_PRIORITY_EDITOR ,
14
16
COMMAND_PRIORITY_LOW ,
15
17
createCommand ,
16
18
DROP_COMMAND ,
19
+ getDOMSelectionFromTarget ,
20
+ isHTMLElement ,
17
21
PASTE_COMMAND ,
18
22
} from 'lexical'
19
23
import React , { useEffect } from 'react'
@@ -28,6 +32,39 @@ import { $createUploadNode, UploadNode } from '../nodes/UploadNode.js'
28
32
29
33
export type InsertUploadPayload = Readonly < Omit < UploadData , 'id' > & Partial < Pick < UploadData , 'id' > > >
30
34
35
+ declare global {
36
+ interface DragEvent {
37
+ rangeOffset ?: number
38
+ rangeParent ?: Node
39
+ }
40
+ }
41
+
42
+ function canDropImage ( event : DragEvent ) : boolean {
43
+ const target = event . target
44
+ return ! ! (
45
+ isHTMLElement ( target ) &&
46
+ ! target . closest ( 'code, span.editor-image' ) &&
47
+ isHTMLElement ( target . parentElement ) &&
48
+ target . parentElement . closest ( 'div.ContentEditable__root' )
49
+ )
50
+ }
51
+
52
+ function getDragSelection ( event : DragEvent ) : null | Range | undefined {
53
+ // Source: https://github.com/AlessioGr/lexical/blob/main/packages/lexical-playground/src/plugins/ImagesPlugin/index.tsx
54
+ let range
55
+ const domSelection = getDOMSelectionFromTarget ( event . target )
56
+ if ( document . caretRangeFromPoint ) {
57
+ range = document . caretRangeFromPoint ( event . clientX , event . clientY )
58
+ } else if ( event . rangeParent && domSelection !== null ) {
59
+ domSelection . collapse ( event . rangeParent , event . rangeOffset || 0 )
60
+ range = domSelection . getRangeAt ( 0 )
61
+ } else {
62
+ throw Error ( `Cannot get the selection when dragging` )
63
+ }
64
+
65
+ return range
66
+ }
67
+
31
68
export const INSERT_UPLOAD_COMMAND : LexicalCommand < InsertUploadPayload > =
32
69
createCommand ( 'INSERT_UPLOAD_COMMAND' )
33
70
@@ -300,9 +337,14 @@ export const UploadPlugin: PluginComponent<UploadFeaturePropsClient> = () => {
300
337
301
338
// Insert a PendingUploadNode for each image
302
339
editor . update ( ( ) => {
303
- const selection = $getSelection ( ) || $getPreviousSelection ( )
340
+ if ( canDropImage ( event ) ) {
341
+ const range = getDragSelection ( event )
342
+ const selection = $createRangeSelection ( )
343
+ if ( range !== null && range !== undefined ) {
344
+ selection . applyDOMRange ( range )
345
+ }
346
+ $setSelection ( selection )
304
347
305
- if ( $isRangeSelection ( selection ) ) {
306
348
for ( const file of files ) {
307
349
const pendingUploadNode = new PendingUploadNode ( {
308
350
data : {
0 commit comments