@portabletext/editor 1.36.6 → 1.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/_chunks-cjs/behavior.core.cjs +84 -49
- package/lib/_chunks-cjs/behavior.core.cjs.map +1 -1
- package/lib/_chunks-cjs/behavior.markdown.cjs +1 -1
- package/lib/_chunks-cjs/editor-provider.cjs +919 -526
- package/lib/_chunks-cjs/editor-provider.cjs.map +1 -1
- package/lib/_chunks-cjs/{util.block-offsets-to-selection.cjs → parse-blocks.cjs} +36 -21
- package/lib/_chunks-cjs/parse-blocks.cjs.map +1 -0
- package/lib/_chunks-cjs/selector.get-text-before.cjs +2 -2
- package/lib/_chunks-cjs/selector.get-text-before.cjs.map +1 -1
- package/lib/_chunks-cjs/{selector.is-active-style.cjs → selector.is-overlapping-selection.cjs} +144 -3
- package/lib/_chunks-cjs/selector.is-overlapping-selection.cjs.map +1 -0
- package/lib/_chunks-cjs/util.slice-blocks.cjs +12 -0
- package/lib/_chunks-cjs/util.slice-blocks.cjs.map +1 -1
- package/lib/_chunks-es/behavior.core.js +84 -49
- package/lib/_chunks-es/behavior.core.js.map +1 -1
- package/lib/_chunks-es/behavior.markdown.js +1 -1
- package/lib/_chunks-es/editor-provider.js +911 -517
- package/lib/_chunks-es/editor-provider.js.map +1 -1
- package/lib/_chunks-es/{util.block-offsets-to-selection.js → parse-blocks.js} +37 -22
- package/lib/_chunks-es/parse-blocks.js.map +1 -0
- package/lib/_chunks-es/selector.get-text-before.js +1 -2
- package/lib/_chunks-es/selector.get-text-before.js.map +1 -1
- package/lib/_chunks-es/{selector.is-active-style.js → selector.is-overlapping-selection.js} +146 -5
- package/lib/_chunks-es/selector.is-overlapping-selection.js.map +1 -0
- package/lib/_chunks-es/util.slice-blocks.js +12 -0
- package/lib/_chunks-es/util.slice-blocks.js.map +1 -1
- package/lib/behaviors/index.d.cts +10535 -4689
- package/lib/behaviors/index.d.ts +10535 -4689
- package/lib/index.cjs +582 -209
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +5297 -1178
- package/lib/index.d.ts +5297 -1178
- package/lib/index.js +591 -213
- package/lib/index.js.map +1 -1
- package/lib/plugins/index.cjs +2 -2
- package/lib/plugins/index.cjs.map +1 -1
- package/lib/plugins/index.d.cts +5297 -1178
- package/lib/plugins/index.d.ts +5297 -1178
- package/lib/plugins/index.js +2 -2
- package/lib/selectors/index.cjs +21 -103
- package/lib/selectors/index.cjs.map +1 -1
- package/lib/selectors/index.d.cts +5313 -1178
- package/lib/selectors/index.d.ts +5313 -1178
- package/lib/selectors/index.js +13 -96
- package/lib/selectors/index.js.map +1 -1
- package/lib/utils/index.cjs +4 -4
- package/lib/utils/index.cjs.map +1 -1
- package/lib/utils/index.d.cts +5297 -1178
- package/lib/utils/index.d.ts +5297 -1178
- package/lib/utils/index.js +3 -4
- package/lib/utils/index.js.map +1 -1
- package/package.json +15 -14
- package/src/behavior-actions/behavior.action.blur.ts +8 -0
- package/src/behavior-actions/behavior.action.decorator.add.ts +2 -1
- package/src/behavior-actions/behavior.action.delete.backward.ts +7 -0
- package/src/behavior-actions/behavior.action.delete.block.ts +24 -0
- package/src/behavior-actions/behavior.action.delete.forward.ts +7 -0
- package/src/behavior-actions/behavior.action.delete.text.ts +2 -1
- package/src/behavior-actions/behavior.action.delete.ts +1 -3
- package/src/behavior-actions/behavior.action.deserialization.failure.ts +9 -0
- package/src/behavior-actions/behavior.action.deserialization.success.ts +16 -0
- package/src/behavior-actions/behavior.action.effect.ts +7 -0
- package/src/behavior-actions/behavior.action.focus.ts +8 -0
- package/src/behavior-actions/behavior.action.insert-blocks.ts +118 -74
- package/src/behavior-actions/behavior.action.insert-break.ts +1 -0
- package/src/behavior-actions/{behavior.action.insert-block-object.ts → behavior.action.insert.block-object.ts} +9 -14
- package/src/behavior-actions/behavior.action.insert.block.ts +247 -2
- package/src/behavior-actions/behavior.action.insert.text-block.ts +33 -0
- package/src/behavior-actions/behavior.action.insert.text.ts +7 -0
- package/src/behavior-actions/behavior.action.move.block-down.ts +48 -0
- package/src/behavior-actions/behavior.action.move.block-up.ts +53 -0
- package/src/behavior-actions/behavior.action.move.block.ts +16 -0
- package/src/behavior-actions/behavior.action.noop.ts +5 -0
- package/src/behavior-actions/behavior.action.select.next-block.ts +44 -0
- package/src/behavior-actions/behavior.action.select.previous-block.ts +48 -0
- package/src/behavior-actions/behavior.action.select.ts +15 -0
- package/src/behavior-actions/behavior.action.serialization.failure.ts +9 -0
- package/src/behavior-actions/behavior.action.serialization.success.ts +14 -0
- package/src/behavior-actions/behavior.actions.ts +54 -212
- package/src/behaviors/behavior.core.block-objects.ts +35 -6
- package/src/behaviors/behavior.core.insert-break.ts +1 -0
- package/src/behaviors/behavior.core.ts +2 -0
- package/src/behaviors/behavior.default.ts +241 -33
- package/src/behaviors/behavior.types.ts +138 -20
- package/src/converters/converter.portable-text.ts +5 -2
- package/src/converters/converter.text-html.serialize.test.ts +4 -4
- package/src/converters/converter.text-html.ts +5 -2
- package/src/converters/converter.text-plain.test.ts +6 -6
- package/src/converters/converter.text-plain.ts +5 -2
- package/src/converters/converter.types.ts +3 -3
- package/src/editor/Editable.tsx +403 -48
- package/src/editor/components/Element.tsx +133 -18
- package/src/editor/components/use-draggable.ts +34 -102
- package/src/editor/editor-machine.ts +66 -10
- package/src/editor/editor-selector.ts +2 -0
- package/src/editor/editor-snapshot.ts +17 -0
- package/src/editor/plugins/create-with-event-listeners.ts +6 -40
- package/src/internal-utils/create-test-snapshot.ts +2 -0
- package/src/internal-utils/event-position.ts +210 -0
- package/src/internal-utils/slate-utils.ts +56 -0
- package/src/internal-utils/weakMaps.ts +1 -15
- package/src/selectors/index.ts +2 -0
- package/src/selectors/selector.get-focus-inline-object.ts +21 -0
- package/src/selectors/selector.is-overlapping-selection.test.ts +171 -0
- package/src/selectors/selector.is-overlapping-selection.ts +108 -4
- package/src/selectors/selector.is-point-after-selection.ts +3 -1
- package/src/selectors/selector.is-point-before-selection.ts +3 -1
- package/src/selectors/selector.is-selecting-entire-blocks.ts +34 -0
- package/lib/_chunks-cjs/selector.is-active-style.cjs.map +0 -1
- package/lib/_chunks-cjs/util.block-offsets-to-selection.cjs.map +0 -1
- package/lib/_chunks-cjs/util.reverse-selection.cjs +0 -14
- package/lib/_chunks-cjs/util.reverse-selection.cjs.map +0 -1
- package/lib/_chunks-es/selector.is-active-style.js.map +0 -1
- package/lib/_chunks-es/util.block-offsets-to-selection.js.map +0 -1
- package/lib/_chunks-es/util.reverse-selection.js +0 -15
- package/lib/_chunks-es/util.reverse-selection.js.map +0 -1
- package/src/behavior-actions/behavior.action-utils.insert-block.ts +0 -61
- package/src/editor/__tests__/handleClick.test.tsx +0 -277
- package/src/editor/components/use-droppable.ts +0 -135
|
@@ -6,7 +6,10 @@ import {defineConverter} from './converter.types'
|
|
|
6
6
|
export const converterTextPlain = defineConverter({
|
|
7
7
|
mimeType: 'text/plain',
|
|
8
8
|
serialize: ({snapshot, event}) => {
|
|
9
|
-
|
|
9
|
+
const selection =
|
|
10
|
+
snapshot.beta.internalDrag?.origin.selection ?? snapshot.context.selection
|
|
11
|
+
|
|
12
|
+
if (!selection) {
|
|
10
13
|
return {
|
|
11
14
|
type: 'serialization.failure',
|
|
12
15
|
mimeType: 'text/plain',
|
|
@@ -17,7 +20,7 @@ export const converterTextPlain = defineConverter({
|
|
|
17
20
|
|
|
18
21
|
const blocks = sliceBlocks({
|
|
19
22
|
blocks: snapshot.context.value,
|
|
20
|
-
selection
|
|
23
|
+
selection,
|
|
21
24
|
})
|
|
22
25
|
|
|
23
26
|
const data = blocks
|
|
@@ -18,19 +18,19 @@ export function defineConverter<TMIMEType extends MIMEType>(
|
|
|
18
18
|
export type ConverterEvent<TMIMEType extends MIMEType = MIMEType> =
|
|
19
19
|
| {
|
|
20
20
|
type: 'serialize'
|
|
21
|
-
originEvent: 'copy' | 'cut' | 'drag'
|
|
21
|
+
originEvent: 'copy' | 'cut' | 'drag.dragstart'
|
|
22
22
|
}
|
|
23
23
|
| {
|
|
24
24
|
type: 'serialization.failure'
|
|
25
25
|
mimeType: TMIMEType
|
|
26
|
-
originEvent: 'copy' | 'cut' | 'drag'
|
|
26
|
+
originEvent: 'copy' | 'cut' | 'drag.dragstart'
|
|
27
27
|
reason: string
|
|
28
28
|
}
|
|
29
29
|
| {
|
|
30
30
|
type: 'serialization.success'
|
|
31
31
|
data: string
|
|
32
32
|
mimeType: TMIMEType
|
|
33
|
-
originEvent: 'copy' | 'cut' | 'drag'
|
|
33
|
+
originEvent: 'copy' | 'cut' | 'drag.dragstart'
|
|
34
34
|
}
|
|
35
35
|
| {
|
|
36
36
|
type: 'deserialize'
|
package/src/editor/Editable.tsx
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type {PortableTextBlock} from '@sanity/types'
|
|
2
1
|
import {useSelector} from '@xstate/react'
|
|
3
2
|
import {isEqual, noop} from 'lodash'
|
|
4
3
|
import {
|
|
@@ -19,8 +18,8 @@ import {
|
|
|
19
18
|
} from 'react'
|
|
20
19
|
import {
|
|
21
20
|
Editor,
|
|
22
|
-
Node,
|
|
23
21
|
Path,
|
|
22
|
+
Element as SlateElement,
|
|
24
23
|
Range as SlateRange,
|
|
25
24
|
Transforms,
|
|
26
25
|
type BaseRange,
|
|
@@ -36,17 +35,15 @@ import {
|
|
|
36
35
|
type RenderLeafProps,
|
|
37
36
|
} from 'slate-react'
|
|
38
37
|
import {debugWithName} from '../internal-utils/debug'
|
|
38
|
+
import {getEventPosition} from '../internal-utils/event-position'
|
|
39
|
+
import {parseBlocks} from '../internal-utils/parse-blocks'
|
|
39
40
|
import {
|
|
40
41
|
moveRangeByOperation,
|
|
41
42
|
toPortableTextRange,
|
|
42
43
|
toSlateRange,
|
|
43
44
|
} from '../internal-utils/ranges'
|
|
44
45
|
import {normalizeSelection} from '../internal-utils/selection'
|
|
45
|
-
import {
|
|
46
|
-
fromSlateValue,
|
|
47
|
-
isEqualToEmptyEditor,
|
|
48
|
-
toSlateValue,
|
|
49
|
-
} from '../internal-utils/values'
|
|
46
|
+
import {fromSlateValue, isEqualToEmptyEditor} from '../internal-utils/values'
|
|
50
47
|
import type {
|
|
51
48
|
EditorSelection,
|
|
52
49
|
OnCopyFn,
|
|
@@ -62,10 +59,10 @@ import type {
|
|
|
62
59
|
ScrollSelectionIntoViewFunction,
|
|
63
60
|
} from '../types/editor'
|
|
64
61
|
import type {HotkeyOptions} from '../types/options'
|
|
65
|
-
import type {SlateTextBlock, VoidElement} from '../types/slate'
|
|
66
62
|
import {Element} from './components/Element'
|
|
67
63
|
import {Leaf} from './components/Leaf'
|
|
68
64
|
import {EditorActorContext} from './editor-actor-context'
|
|
65
|
+
import {getEditorSnapshot} from './editor-selector'
|
|
69
66
|
import {usePortableTextEditor} from './hooks/usePortableTextEditor'
|
|
70
67
|
import {createWithHotkeys} from './plugins/createWithHotKeys'
|
|
71
68
|
import {PortableTextEditor} from './PortableTextEditor'
|
|
@@ -141,7 +138,15 @@ export const PortableTextEditable = forwardRef<
|
|
|
141
138
|
onBeforeInput,
|
|
142
139
|
onPaste,
|
|
143
140
|
onCopy,
|
|
141
|
+
onCut,
|
|
144
142
|
onClick,
|
|
143
|
+
onDragStart,
|
|
144
|
+
onDrag,
|
|
145
|
+
onDragEnd,
|
|
146
|
+
onDragEnter,
|
|
147
|
+
onDragOver,
|
|
148
|
+
onDrop,
|
|
149
|
+
onDragLeave,
|
|
145
150
|
rangeDecorations,
|
|
146
151
|
renderAnnotation,
|
|
147
152
|
renderBlock,
|
|
@@ -435,11 +440,30 @@ export const PortableTextEditable = forwardRef<
|
|
|
435
440
|
event.preventDefault()
|
|
436
441
|
}
|
|
437
442
|
} else if (event.nativeEvent.clipboardData) {
|
|
443
|
+
// Prevent Slate from handling the event
|
|
444
|
+
event.stopPropagation()
|
|
445
|
+
event.preventDefault()
|
|
446
|
+
|
|
447
|
+
const position = getEventPosition({
|
|
448
|
+
snapshot: getEditorSnapshot({
|
|
449
|
+
editorActorSnapshot: editorActor.getSnapshot(),
|
|
450
|
+
slateEditorInstance: slateEditor,
|
|
451
|
+
}),
|
|
452
|
+
slateEditor,
|
|
453
|
+
event: event.nativeEvent,
|
|
454
|
+
})
|
|
455
|
+
|
|
456
|
+
if (!position) {
|
|
457
|
+
console.warn('Could not find position for copy event')
|
|
458
|
+
return
|
|
459
|
+
}
|
|
460
|
+
|
|
438
461
|
editorActor.send({
|
|
439
462
|
type: 'behavior event',
|
|
440
463
|
behaviorEvent: {
|
|
441
464
|
type: 'copy',
|
|
442
465
|
data: event.nativeEvent.clipboardData,
|
|
466
|
+
position,
|
|
443
467
|
},
|
|
444
468
|
editor: slateEditor,
|
|
445
469
|
nativeEvent: event,
|
|
@@ -449,6 +473,48 @@ export const PortableTextEditable = forwardRef<
|
|
|
449
473
|
[onCopy, editorActor, slateEditor],
|
|
450
474
|
)
|
|
451
475
|
|
|
476
|
+
const handleCut = useCallback(
|
|
477
|
+
(event: ClipboardEvent<HTMLDivElement>) => {
|
|
478
|
+
if (onCut) {
|
|
479
|
+
const result = onCut(event)
|
|
480
|
+
// CutFn may return something to avoid doing default stuff
|
|
481
|
+
if (result !== undefined) {
|
|
482
|
+
event.preventDefault()
|
|
483
|
+
}
|
|
484
|
+
} else if (event.nativeEvent.clipboardData) {
|
|
485
|
+
// Prevent Slate from handling the event
|
|
486
|
+
event.stopPropagation()
|
|
487
|
+
event.preventDefault()
|
|
488
|
+
|
|
489
|
+
const position = getEventPosition({
|
|
490
|
+
snapshot: getEditorSnapshot({
|
|
491
|
+
editorActorSnapshot: editorActor.getSnapshot(),
|
|
492
|
+
slateEditorInstance: slateEditor,
|
|
493
|
+
}),
|
|
494
|
+
slateEditor,
|
|
495
|
+
event: event.nativeEvent,
|
|
496
|
+
})
|
|
497
|
+
|
|
498
|
+
if (!position) {
|
|
499
|
+
console.warn('Could not find position for cut event')
|
|
500
|
+
return
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
editorActor.send({
|
|
504
|
+
type: 'behavior event',
|
|
505
|
+
behaviorEvent: {
|
|
506
|
+
type: 'cut',
|
|
507
|
+
dataTransfer: event.nativeEvent.clipboardData,
|
|
508
|
+
position,
|
|
509
|
+
},
|
|
510
|
+
editor: slateEditor,
|
|
511
|
+
nativeEvent: event,
|
|
512
|
+
})
|
|
513
|
+
}
|
|
514
|
+
},
|
|
515
|
+
[onCut, editorActor, slateEditor],
|
|
516
|
+
)
|
|
517
|
+
|
|
452
518
|
// Handle incoming pasting events in the editor
|
|
453
519
|
const handlePaste = useCallback(
|
|
454
520
|
(event: ClipboardEvent<HTMLDivElement>): Promise<void> | void => {
|
|
@@ -474,13 +540,50 @@ export const PortableTextEditable = forwardRef<
|
|
|
474
540
|
if (!result || !result.insert) {
|
|
475
541
|
debug('No result from custom paste handler, pasting normally')
|
|
476
542
|
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
schemaTypes,
|
|
543
|
+
const position = getEventPosition({
|
|
544
|
+
snapshot: getEditorSnapshot({
|
|
545
|
+
editorActorSnapshot: editorActor.getSnapshot(),
|
|
546
|
+
slateEditorInstance: slateEditor,
|
|
482
547
|
}),
|
|
483
|
-
|
|
548
|
+
slateEditor,
|
|
549
|
+
event: event.nativeEvent,
|
|
550
|
+
})
|
|
551
|
+
|
|
552
|
+
if (!position) {
|
|
553
|
+
console.warn('Could not find position for paste event')
|
|
554
|
+
return
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
editorActor.send({
|
|
558
|
+
type: 'behavior event',
|
|
559
|
+
behaviorEvent: {
|
|
560
|
+
type: 'paste',
|
|
561
|
+
data: event.clipboardData,
|
|
562
|
+
position,
|
|
563
|
+
},
|
|
564
|
+
editor: slateEditor,
|
|
565
|
+
nativeEvent: event,
|
|
566
|
+
})
|
|
567
|
+
} else if (result.insert) {
|
|
568
|
+
editorActor.send({
|
|
569
|
+
type: 'behavior event',
|
|
570
|
+
behaviorEvent: {
|
|
571
|
+
type: 'insert.blocks',
|
|
572
|
+
blocks: parseBlocks({
|
|
573
|
+
context: {
|
|
574
|
+
keyGenerator:
|
|
575
|
+
editorActor.getSnapshot().context.keyGenerator,
|
|
576
|
+
schema: editorActor.getSnapshot().context.schema,
|
|
577
|
+
},
|
|
578
|
+
blocks: result.insert,
|
|
579
|
+
options: {
|
|
580
|
+
refreshKeys: true,
|
|
581
|
+
},
|
|
582
|
+
}),
|
|
583
|
+
placement: 'auto',
|
|
584
|
+
},
|
|
585
|
+
editor: slateEditor,
|
|
586
|
+
})
|
|
484
587
|
} else {
|
|
485
588
|
console.warn(
|
|
486
589
|
'Your onPaste function returned something unexpected:',
|
|
@@ -489,7 +592,7 @@ export const PortableTextEditable = forwardRef<
|
|
|
489
592
|
}
|
|
490
593
|
})
|
|
491
594
|
.catch((error) => {
|
|
492
|
-
console.
|
|
595
|
+
console.warn(error)
|
|
493
596
|
|
|
494
597
|
return error
|
|
495
598
|
})
|
|
@@ -497,11 +600,30 @@ export const PortableTextEditable = forwardRef<
|
|
|
497
600
|
editorActor.send({type: 'notify.done loading'})
|
|
498
601
|
})
|
|
499
602
|
} else if (event.nativeEvent.clipboardData) {
|
|
603
|
+
// Prevent Slate from handling the event
|
|
604
|
+
event.preventDefault()
|
|
605
|
+
event.stopPropagation()
|
|
606
|
+
|
|
607
|
+
const position = getEventPosition({
|
|
608
|
+
snapshot: getEditorSnapshot({
|
|
609
|
+
editorActorSnapshot: editorActor.getSnapshot(),
|
|
610
|
+
slateEditorInstance: slateEditor,
|
|
611
|
+
}),
|
|
612
|
+
slateEditor,
|
|
613
|
+
event: event.nativeEvent,
|
|
614
|
+
})
|
|
615
|
+
|
|
616
|
+
if (!position) {
|
|
617
|
+
console.warn('Could not find position for paste event')
|
|
618
|
+
return
|
|
619
|
+
}
|
|
620
|
+
|
|
500
621
|
editorActor.send({
|
|
501
622
|
type: 'behavior event',
|
|
502
623
|
behaviorEvent: {
|
|
503
624
|
type: 'paste',
|
|
504
625
|
data: event.nativeEvent.clipboardData,
|
|
626
|
+
position,
|
|
505
627
|
},
|
|
506
628
|
editor: slateEditor,
|
|
507
629
|
nativeEvent: event,
|
|
@@ -545,34 +667,35 @@ export const PortableTextEditable = forwardRef<
|
|
|
545
667
|
onClick(event)
|
|
546
668
|
}
|
|
547
669
|
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
const collapsedSelection =
|
|
565
|
-
slateEditor.selection && SlateRange.isCollapsed(slateEditor.selection)
|
|
566
|
-
|
|
567
|
-
if (collapsedSelection && lastNodeFocused && lastBlockIsVoid) {
|
|
568
|
-
Transforms.insertNodes(
|
|
569
|
-
slateEditor,
|
|
570
|
-
slateEditor.pteCreateTextBlock({decorators: []}),
|
|
571
|
-
)
|
|
572
|
-
slateEditor.onChange()
|
|
670
|
+
if (event.isDefaultPrevented() || event.isPropagationStopped()) {
|
|
671
|
+
return
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
const position = getEventPosition({
|
|
675
|
+
snapshot: getEditorSnapshot({
|
|
676
|
+
editorActorSnapshot: editorActor.getSnapshot(),
|
|
677
|
+
slateEditorInstance: slateEditor,
|
|
678
|
+
}),
|
|
679
|
+
slateEditor,
|
|
680
|
+
event: event.nativeEvent,
|
|
681
|
+
})
|
|
682
|
+
|
|
683
|
+
if (!position) {
|
|
684
|
+
console.warn('Could not find EventPosition for MouseEvent')
|
|
685
|
+
return
|
|
573
686
|
}
|
|
687
|
+
|
|
688
|
+
editorActor.send({
|
|
689
|
+
type: 'behavior event',
|
|
690
|
+
behaviorEvent: {
|
|
691
|
+
type: 'mouse.click',
|
|
692
|
+
position,
|
|
693
|
+
},
|
|
694
|
+
editor: slateEditor,
|
|
695
|
+
nativeEvent: event,
|
|
696
|
+
})
|
|
574
697
|
},
|
|
575
|
-
[onClick, slateEditor],
|
|
698
|
+
[onClick, editorActor, slateEditor],
|
|
576
699
|
)
|
|
577
700
|
|
|
578
701
|
const handleOnBlur: FocusEventHandler<HTMLDivElement> = useCallback(
|
|
@@ -825,9 +948,240 @@ export const PortableTextEditable = forwardRef<
|
|
|
825
948
|
}
|
|
826
949
|
}, [slateEditor, editorActor])
|
|
827
950
|
|
|
951
|
+
const handleDragStart = useCallback(
|
|
952
|
+
(event: React.DragEvent<HTMLDivElement>) => {
|
|
953
|
+
onDragStart?.(event)
|
|
954
|
+
|
|
955
|
+
if (!event.isDefaultPrevented() && !event.isPropagationStopped()) {
|
|
956
|
+
const position = getEventPosition({
|
|
957
|
+
snapshot: getEditorSnapshot({
|
|
958
|
+
editorActorSnapshot: editorActor.getSnapshot(),
|
|
959
|
+
slateEditorInstance: slateEditor,
|
|
960
|
+
}),
|
|
961
|
+
slateEditor,
|
|
962
|
+
event: event.nativeEvent,
|
|
963
|
+
})
|
|
964
|
+
|
|
965
|
+
if (!position) {
|
|
966
|
+
console.warn('Could not find position for dragstart event')
|
|
967
|
+
return
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
if (ReactEditor.hasTarget(slateEditor, event.target)) {
|
|
971
|
+
const node = ReactEditor.toSlateNode(slateEditor, event.target)
|
|
972
|
+
const path = ReactEditor.findPath(slateEditor, node)
|
|
973
|
+
const voidMatch =
|
|
974
|
+
(SlateElement.isElement(node) &&
|
|
975
|
+
Editor.isVoid(slateEditor, node)) ||
|
|
976
|
+
Editor.void(slateEditor, {at: path, voids: true})
|
|
977
|
+
|
|
978
|
+
// If starting a drag on a void node, make sure it is selected
|
|
979
|
+
// so that it shows up in the selection's fragment.
|
|
980
|
+
if (voidMatch) {
|
|
981
|
+
const range = Editor.range(slateEditor, path)
|
|
982
|
+
Transforms.select(slateEditor, range)
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
editorActor.send({
|
|
987
|
+
type: 'dragstart',
|
|
988
|
+
origin: position,
|
|
989
|
+
})
|
|
990
|
+
|
|
991
|
+
editorActor.send({
|
|
992
|
+
type: 'behavior event',
|
|
993
|
+
behaviorEvent: {
|
|
994
|
+
type: 'drag.dragstart',
|
|
995
|
+
dataTransfer: event.dataTransfer,
|
|
996
|
+
position,
|
|
997
|
+
},
|
|
998
|
+
editor: slateEditor,
|
|
999
|
+
})
|
|
1000
|
+
|
|
1001
|
+
// Prevent Slate from handling the event
|
|
1002
|
+
event.stopPropagation()
|
|
1003
|
+
}
|
|
1004
|
+
},
|
|
1005
|
+
[onDragStart, editorActor, slateEditor],
|
|
1006
|
+
)
|
|
1007
|
+
|
|
1008
|
+
const handleDrag = useCallback(
|
|
1009
|
+
(event: React.DragEvent<HTMLDivElement>) => {
|
|
1010
|
+
onDrag?.(event)
|
|
1011
|
+
|
|
1012
|
+
if (!event.isDefaultPrevented() && !event.isPropagationStopped()) {
|
|
1013
|
+
editorActor.send({
|
|
1014
|
+
type: 'behavior event',
|
|
1015
|
+
behaviorEvent: {
|
|
1016
|
+
type: 'drag.drag',
|
|
1017
|
+
dataTransfer: event.dataTransfer,
|
|
1018
|
+
},
|
|
1019
|
+
editor: slateEditor,
|
|
1020
|
+
})
|
|
1021
|
+
|
|
1022
|
+
// Prevent Slate from handling the event
|
|
1023
|
+
event.stopPropagation()
|
|
1024
|
+
}
|
|
1025
|
+
},
|
|
1026
|
+
[onDrag, editorActor, slateEditor],
|
|
1027
|
+
)
|
|
1028
|
+
|
|
1029
|
+
const handleDragEnd = useCallback(
|
|
1030
|
+
(event: React.DragEvent<HTMLDivElement>) => {
|
|
1031
|
+
onDragEnd?.(event)
|
|
1032
|
+
|
|
1033
|
+
if (!event.isDefaultPrevented() && !event.isPropagationStopped()) {
|
|
1034
|
+
editorActor.send({
|
|
1035
|
+
type: 'behavior event',
|
|
1036
|
+
behaviorEvent: {
|
|
1037
|
+
type: 'drag.dragend',
|
|
1038
|
+
dataTransfer: event.dataTransfer,
|
|
1039
|
+
},
|
|
1040
|
+
editor: slateEditor,
|
|
1041
|
+
})
|
|
1042
|
+
|
|
1043
|
+
// Prevent Slate from handling the event
|
|
1044
|
+
event.stopPropagation()
|
|
1045
|
+
}
|
|
1046
|
+
},
|
|
1047
|
+
[onDragEnd, editorActor, slateEditor],
|
|
1048
|
+
)
|
|
1049
|
+
|
|
1050
|
+
const handleDragEnter = useCallback(
|
|
1051
|
+
(event: React.DragEvent<HTMLDivElement>) => {
|
|
1052
|
+
onDragEnter?.(event)
|
|
1053
|
+
|
|
1054
|
+
if (!event.isDefaultPrevented() && !event.isPropagationStopped()) {
|
|
1055
|
+
const position = getEventPosition({
|
|
1056
|
+
snapshot: getEditorSnapshot({
|
|
1057
|
+
editorActorSnapshot: editorActor.getSnapshot(),
|
|
1058
|
+
slateEditorInstance: slateEditor,
|
|
1059
|
+
}),
|
|
1060
|
+
slateEditor,
|
|
1061
|
+
event: event.nativeEvent,
|
|
1062
|
+
})
|
|
1063
|
+
|
|
1064
|
+
if (!position) {
|
|
1065
|
+
console.warn('Could not find position for dragenter event')
|
|
1066
|
+
return
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
editorActor.send({
|
|
1070
|
+
type: 'behavior event',
|
|
1071
|
+
behaviorEvent: {
|
|
1072
|
+
type: 'drag.dragenter',
|
|
1073
|
+
dataTransfer: event.dataTransfer,
|
|
1074
|
+
position,
|
|
1075
|
+
},
|
|
1076
|
+
editor: slateEditor,
|
|
1077
|
+
})
|
|
1078
|
+
|
|
1079
|
+
// Prevent Slate from handling the event
|
|
1080
|
+
event.stopPropagation()
|
|
1081
|
+
}
|
|
1082
|
+
},
|
|
1083
|
+
[onDragEnter, editorActor, slateEditor],
|
|
1084
|
+
)
|
|
1085
|
+
|
|
1086
|
+
const handleDragOver = useCallback(
|
|
1087
|
+
(event: React.DragEvent<HTMLDivElement>) => {
|
|
1088
|
+
onDragOver?.(event)
|
|
1089
|
+
|
|
1090
|
+
if (!event.isDefaultPrevented() && !event.isPropagationStopped()) {
|
|
1091
|
+
const position = getEventPosition({
|
|
1092
|
+
snapshot: getEditorSnapshot({
|
|
1093
|
+
editorActorSnapshot: editorActor.getSnapshot(),
|
|
1094
|
+
slateEditorInstance: slateEditor,
|
|
1095
|
+
}),
|
|
1096
|
+
slateEditor,
|
|
1097
|
+
event: event.nativeEvent,
|
|
1098
|
+
})
|
|
1099
|
+
|
|
1100
|
+
if (!position) {
|
|
1101
|
+
console.warn('Could not find position for dragover event')
|
|
1102
|
+
return
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
editorActor.send({
|
|
1106
|
+
type: 'behavior event',
|
|
1107
|
+
behaviorEvent: {
|
|
1108
|
+
type: 'drag.dragover',
|
|
1109
|
+
dataTransfer: event.dataTransfer,
|
|
1110
|
+
position,
|
|
1111
|
+
},
|
|
1112
|
+
editor: slateEditor,
|
|
1113
|
+
nativeEvent: event,
|
|
1114
|
+
})
|
|
1115
|
+
|
|
1116
|
+
// Prevent Slate from handling the event
|
|
1117
|
+
event.stopPropagation()
|
|
1118
|
+
}
|
|
1119
|
+
},
|
|
1120
|
+
[onDragOver, editorActor, slateEditor],
|
|
1121
|
+
)
|
|
1122
|
+
|
|
1123
|
+
const handleDrop = useCallback(
|
|
1124
|
+
(event: React.DragEvent<HTMLDivElement>) => {
|
|
1125
|
+
onDrop?.(event)
|
|
1126
|
+
|
|
1127
|
+
if (!event.isDefaultPrevented() && !event.isPropagationStopped()) {
|
|
1128
|
+
const position = getEventPosition({
|
|
1129
|
+
snapshot: getEditorSnapshot({
|
|
1130
|
+
editorActorSnapshot: editorActor.getSnapshot(),
|
|
1131
|
+
slateEditorInstance: slateEditor,
|
|
1132
|
+
}),
|
|
1133
|
+
slateEditor,
|
|
1134
|
+
event: event.nativeEvent,
|
|
1135
|
+
})
|
|
1136
|
+
|
|
1137
|
+
if (!position) {
|
|
1138
|
+
console.warn('Could not find position for drop event')
|
|
1139
|
+
return
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
// Find and select the range where the drop happened
|
|
1143
|
+
const range = ReactEditor.findEventRange(slateEditor, event)
|
|
1144
|
+
slateEditor.select(range)
|
|
1145
|
+
|
|
1146
|
+
editorActor.send({
|
|
1147
|
+
type: 'behavior event',
|
|
1148
|
+
behaviorEvent: {
|
|
1149
|
+
type: 'drag.drop',
|
|
1150
|
+
dataTransfer: event.dataTransfer,
|
|
1151
|
+
position,
|
|
1152
|
+
},
|
|
1153
|
+
editor: slateEditor,
|
|
1154
|
+
})
|
|
1155
|
+
|
|
1156
|
+
// Prevent Slate from handling the event
|
|
1157
|
+
event.preventDefault()
|
|
1158
|
+
}
|
|
1159
|
+
},
|
|
1160
|
+
[onDrop, editorActor, slateEditor],
|
|
1161
|
+
)
|
|
1162
|
+
|
|
1163
|
+
const handleDragLeave = useCallback(
|
|
1164
|
+
(event: React.DragEvent<HTMLDivElement>) => {
|
|
1165
|
+
onDragLeave?.(event)
|
|
1166
|
+
|
|
1167
|
+
if (!event.isDefaultPrevented() && !event.isPropagationStopped()) {
|
|
1168
|
+
editorActor.send({
|
|
1169
|
+
type: 'behavior event',
|
|
1170
|
+
behaviorEvent: {
|
|
1171
|
+
type: 'drag.dragleave',
|
|
1172
|
+
dataTransfer: event.dataTransfer,
|
|
1173
|
+
},
|
|
1174
|
+
editor: slateEditor,
|
|
1175
|
+
})
|
|
1176
|
+
}
|
|
1177
|
+
},
|
|
1178
|
+
[onDragLeave, editorActor, slateEditor],
|
|
1179
|
+
)
|
|
1180
|
+
|
|
828
1181
|
if (!portableTextEditor) {
|
|
829
1182
|
return null
|
|
830
1183
|
}
|
|
1184
|
+
|
|
831
1185
|
return hasInvalidValue ? null : (
|
|
832
1186
|
<SlateEditable
|
|
833
1187
|
{...restProps}
|
|
@@ -836,15 +1190,16 @@ export const PortableTextEditable = forwardRef<
|
|
|
836
1190
|
decorate={decorate}
|
|
837
1191
|
onBlur={handleOnBlur}
|
|
838
1192
|
onCopy={handleCopy}
|
|
1193
|
+
onCut={handleCut}
|
|
839
1194
|
onClick={handleClick}
|
|
840
1195
|
onDOMBeforeInput={handleOnBeforeInput}
|
|
841
|
-
onDragStart={
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
}
|
|
1196
|
+
onDragStart={handleDragStart}
|
|
1197
|
+
onDrag={handleDrag}
|
|
1198
|
+
onDragEnd={handleDragEnd}
|
|
1199
|
+
onDragEnter={handleDragEnter}
|
|
1200
|
+
onDragOver={handleDragOver}
|
|
1201
|
+
onDrop={handleDrop}
|
|
1202
|
+
onDragLeave={handleDragLeave}
|
|
848
1203
|
onFocus={handleOnFocus}
|
|
849
1204
|
onKeyDown={handleKeyDown}
|
|
850
1205
|
onKeyUp={handleKeyUp}
|