@portabletext/editor 1.37.0 → 1.38.1
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/editor-provider.cjs +868 -534
- 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/editor-provider.js +858 -523
- 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 +10534 -4689
- package/lib/behaviors/index.d.ts +10534 -4689
- package/lib/index.cjs +578 -209
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +5296 -1178
- package/lib/index.d.ts +5296 -1178
- package/lib/index.js +587 -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 +5296 -1178
- package/lib/plugins/index.d.ts +5296 -1178
- package/lib/plugins/index.js +1 -1
- package/lib/selectors/index.cjs +15 -152
- package/lib/selectors/index.cjs.map +1 -1
- package/lib/selectors/index.d.cts +5296 -1178
- package/lib/selectors/index.d.ts +5296 -1178
- package/lib/selectors/index.js +7 -145
- 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 +5296 -1178
- package/lib/utils/index.d.ts +5296 -1178
- package/lib/utils/index.js +3 -4
- package/lib/utils/index.js.map +1 -1
- package/package.json +16 -15
- package/src/behavior-actions/behavior.action.blur.ts +8 -0
- package/src/behavior-actions/behavior.action.decorator.add.ts +1 -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 +1 -1
- 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 -139
- 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 +401 -48
- package/src/editor/components/Element.tsx +133 -18
- package/src/editor/components/use-draggable.ts +34 -102
- package/src/editor/editor-machine.ts +50 -7
- package/src/editor/editor-selector.ts +1 -0
- package/src/editor/editor-snapshot.ts +13 -0
- package/src/editor/plugins/create-with-event-listeners.ts +6 -40
- package/src/internal-utils/create-test-snapshot.ts +1 -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/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
|
@@ -1,277 +0,0 @@
|
|
|
1
|
-
import {fireEvent, render, waitFor} from '@testing-library/react'
|
|
2
|
-
import {act, createRef, type RefObject} from 'react'
|
|
3
|
-
import {describe, expect, it, vi} from 'vitest'
|
|
4
|
-
import {PortableTextEditor} from '../PortableTextEditor'
|
|
5
|
-
import {PortableTextEditorTester, schemaType} from './PortableTextEditorTester'
|
|
6
|
-
|
|
7
|
-
async function getEditableElement(
|
|
8
|
-
component: ReturnType<typeof render>,
|
|
9
|
-
): Promise<Element> {
|
|
10
|
-
await act(async () => component)
|
|
11
|
-
const element = component.container.querySelector(
|
|
12
|
-
'[data-slate-editor="true"]',
|
|
13
|
-
)
|
|
14
|
-
if (!element) {
|
|
15
|
-
throw new Error('Could not find element')
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Manually add this because JSDom doesn't implement this and Slate checks for it
|
|
19
|
-
* internally before doing stuff.
|
|
20
|
-
*
|
|
21
|
-
* https://github.com/jsdom/jsdom/issues/1670
|
|
22
|
-
*/
|
|
23
|
-
// @ts-ignore
|
|
24
|
-
element.isContentEditable = true
|
|
25
|
-
return element
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
describe('adds empty text block if its needed', () => {
|
|
29
|
-
const newBlock = {
|
|
30
|
-
_type: 'myTestBlockType',
|
|
31
|
-
_key: '1',
|
|
32
|
-
style: 'normal',
|
|
33
|
-
markDefs: [],
|
|
34
|
-
children: [
|
|
35
|
-
{
|
|
36
|
-
_type: 'span',
|
|
37
|
-
_key: '2',
|
|
38
|
-
text: '',
|
|
39
|
-
marks: [],
|
|
40
|
-
},
|
|
41
|
-
],
|
|
42
|
-
}
|
|
43
|
-
it('adds a new block at the bottom, when clicking on the portable text editor, because the only block is void and user is focused on that one', async () => {
|
|
44
|
-
const initialValue = [
|
|
45
|
-
{
|
|
46
|
-
_key: 'b',
|
|
47
|
-
_type: 'someObject',
|
|
48
|
-
},
|
|
49
|
-
]
|
|
50
|
-
|
|
51
|
-
const initialSelection = {
|
|
52
|
-
focus: {path: [{_key: 'b'}], offset: 0},
|
|
53
|
-
anchor: {path: [{_key: 'b'}], offset: 0},
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const editorRef: RefObject<PortableTextEditor | null> = createRef()
|
|
57
|
-
const onChange = vi.fn()
|
|
58
|
-
const component = render(
|
|
59
|
-
<PortableTextEditorTester
|
|
60
|
-
onChange={onChange}
|
|
61
|
-
ref={editorRef}
|
|
62
|
-
schemaType={schemaType}
|
|
63
|
-
value={initialValue}
|
|
64
|
-
/>,
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
await waitFor(() => {
|
|
68
|
-
if (editorRef.current) {
|
|
69
|
-
expect(onChange).toHaveBeenCalledWith({
|
|
70
|
-
type: 'value',
|
|
71
|
-
value: initialValue,
|
|
72
|
-
})
|
|
73
|
-
expect(onChange).toHaveBeenCalledWith({type: 'ready'})
|
|
74
|
-
}
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
const element = await getEditableElement(component)
|
|
78
|
-
|
|
79
|
-
await waitFor(() => {
|
|
80
|
-
if (editorRef.current && element) {
|
|
81
|
-
PortableTextEditor.focus(editorRef.current)
|
|
82
|
-
PortableTextEditor.select(editorRef.current, initialSelection)
|
|
83
|
-
fireEvent.click(element)
|
|
84
|
-
expect(PortableTextEditor.getValue(editorRef.current)).toEqual([
|
|
85
|
-
initialValue[0],
|
|
86
|
-
newBlock,
|
|
87
|
-
])
|
|
88
|
-
}
|
|
89
|
-
})
|
|
90
|
-
})
|
|
91
|
-
it('should not add blocks if the last element is a text block', async () => {
|
|
92
|
-
const initialValue = [
|
|
93
|
-
{
|
|
94
|
-
_key: 'b',
|
|
95
|
-
_type: 'someObject',
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
_type: 'myTestBlockType',
|
|
99
|
-
_key: '1',
|
|
100
|
-
style: 'normal',
|
|
101
|
-
markDefs: [],
|
|
102
|
-
children: [
|
|
103
|
-
{
|
|
104
|
-
_type: 'span',
|
|
105
|
-
_key: '2',
|
|
106
|
-
text: '',
|
|
107
|
-
marks: [],
|
|
108
|
-
},
|
|
109
|
-
],
|
|
110
|
-
},
|
|
111
|
-
]
|
|
112
|
-
|
|
113
|
-
const initialSelection = {
|
|
114
|
-
focus: {path: [{_key: 'b'}], offset: 0},
|
|
115
|
-
anchor: {path: [{_key: 'b'}], offset: 0},
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const editorRef: RefObject<PortableTextEditor | null> = createRef()
|
|
119
|
-
const onChange = vi.fn()
|
|
120
|
-
const component = render(
|
|
121
|
-
<PortableTextEditorTester
|
|
122
|
-
onChange={onChange}
|
|
123
|
-
ref={editorRef}
|
|
124
|
-
schemaType={schemaType}
|
|
125
|
-
value={initialValue}
|
|
126
|
-
/>,
|
|
127
|
-
)
|
|
128
|
-
const element = await getEditableElement(component)
|
|
129
|
-
|
|
130
|
-
await waitFor(() => {
|
|
131
|
-
if (editorRef.current && element) {
|
|
132
|
-
PortableTextEditor.focus(editorRef.current)
|
|
133
|
-
PortableTextEditor.select(editorRef.current, initialSelection)
|
|
134
|
-
fireEvent.click(element)
|
|
135
|
-
expect(PortableTextEditor.getValue(editorRef.current)).toEqual(
|
|
136
|
-
initialValue,
|
|
137
|
-
)
|
|
138
|
-
}
|
|
139
|
-
})
|
|
140
|
-
})
|
|
141
|
-
|
|
142
|
-
it('should not add blocks if the last element is void, but its not focused on that one', async () => {
|
|
143
|
-
const initialValue = [
|
|
144
|
-
{
|
|
145
|
-
_key: 'a',
|
|
146
|
-
_type: 'someObject',
|
|
147
|
-
},
|
|
148
|
-
{
|
|
149
|
-
_type: 'myTestBlockType',
|
|
150
|
-
_key: 'b',
|
|
151
|
-
style: 'normal',
|
|
152
|
-
markDefs: [],
|
|
153
|
-
children: [
|
|
154
|
-
{
|
|
155
|
-
_type: 'span',
|
|
156
|
-
_key: 'b1',
|
|
157
|
-
text: '',
|
|
158
|
-
marks: [],
|
|
159
|
-
},
|
|
160
|
-
],
|
|
161
|
-
},
|
|
162
|
-
{
|
|
163
|
-
_key: 'c',
|
|
164
|
-
_type: 'someObject',
|
|
165
|
-
},
|
|
166
|
-
]
|
|
167
|
-
|
|
168
|
-
const initialSelection = {
|
|
169
|
-
focus: {path: [{_key: 'b'}, 'children', {_key: 'b1'}], offset: 0},
|
|
170
|
-
anchor: {path: [{_key: 'b'}, 'children', {_key: 'b1'}], offset: 0},
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const editorRef: RefObject<PortableTextEditor | null> = createRef()
|
|
174
|
-
const onChange = vi.fn()
|
|
175
|
-
const component = render(
|
|
176
|
-
<PortableTextEditorTester
|
|
177
|
-
onChange={onChange}
|
|
178
|
-
ref={editorRef}
|
|
179
|
-
schemaType={schemaType}
|
|
180
|
-
value={initialValue}
|
|
181
|
-
/>,
|
|
182
|
-
)
|
|
183
|
-
|
|
184
|
-
await waitFor(() => {
|
|
185
|
-
if (editorRef.current) {
|
|
186
|
-
expect(onChange).toHaveBeenCalledWith({
|
|
187
|
-
type: 'value',
|
|
188
|
-
value: initialValue,
|
|
189
|
-
})
|
|
190
|
-
expect(onChange).toHaveBeenCalledWith({type: 'ready'})
|
|
191
|
-
}
|
|
192
|
-
})
|
|
193
|
-
|
|
194
|
-
const element = await getEditableElement(component)
|
|
195
|
-
|
|
196
|
-
await waitFor(() => {
|
|
197
|
-
if (editorRef.current && element) {
|
|
198
|
-
PortableTextEditor.focus(editorRef.current)
|
|
199
|
-
PortableTextEditor.select(editorRef.current, initialSelection)
|
|
200
|
-
fireEvent.click(element)
|
|
201
|
-
expect(PortableTextEditor.getValue(editorRef.current)).toEqual(
|
|
202
|
-
initialValue,
|
|
203
|
-
)
|
|
204
|
-
}
|
|
205
|
-
})
|
|
206
|
-
})
|
|
207
|
-
|
|
208
|
-
it('should not add blocks if the last element is void, and its focused on that one when clicking', async () => {
|
|
209
|
-
const initialValue = [
|
|
210
|
-
{
|
|
211
|
-
_key: 'a',
|
|
212
|
-
_type: 'someObject',
|
|
213
|
-
},
|
|
214
|
-
{
|
|
215
|
-
_type: 'myTestBlockType',
|
|
216
|
-
_key: 'b',
|
|
217
|
-
style: 'normal',
|
|
218
|
-
markDefs: [],
|
|
219
|
-
children: [
|
|
220
|
-
{
|
|
221
|
-
_type: 'span',
|
|
222
|
-
_key: 'b1',
|
|
223
|
-
text: '',
|
|
224
|
-
marks: [],
|
|
225
|
-
},
|
|
226
|
-
],
|
|
227
|
-
},
|
|
228
|
-
{
|
|
229
|
-
_key: 'c',
|
|
230
|
-
_type: 'someObject',
|
|
231
|
-
},
|
|
232
|
-
]
|
|
233
|
-
|
|
234
|
-
const initialSelection = {
|
|
235
|
-
focus: {path: [{_key: 'c'}], offset: 0},
|
|
236
|
-
anchor: {path: [{_key: 'c'}], offset: 0},
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
const editorRef: RefObject<PortableTextEditor | null> = createRef()
|
|
240
|
-
const onChange = vi.fn()
|
|
241
|
-
const component = render(
|
|
242
|
-
<PortableTextEditorTester
|
|
243
|
-
onChange={onChange}
|
|
244
|
-
ref={editorRef}
|
|
245
|
-
schemaType={schemaType}
|
|
246
|
-
value={initialValue}
|
|
247
|
-
/>,
|
|
248
|
-
)
|
|
249
|
-
|
|
250
|
-
await waitFor(() => {
|
|
251
|
-
if (editorRef.current) {
|
|
252
|
-
expect(onChange).toHaveBeenCalledWith({
|
|
253
|
-
type: 'value',
|
|
254
|
-
value: initialValue,
|
|
255
|
-
})
|
|
256
|
-
expect(onChange).toHaveBeenCalledWith({type: 'ready'})
|
|
257
|
-
}
|
|
258
|
-
})
|
|
259
|
-
|
|
260
|
-
const element = await getEditableElement(component)
|
|
261
|
-
|
|
262
|
-
const editor = editorRef.current
|
|
263
|
-
const inlineType = editor?.schemaTypes.inlineObjects.find(
|
|
264
|
-
(t) => t.name === 'someObject',
|
|
265
|
-
)
|
|
266
|
-
await waitFor(() => {
|
|
267
|
-
if (editor && inlineType && element) {
|
|
268
|
-
PortableTextEditor.focus(editor)
|
|
269
|
-
PortableTextEditor.select(editor, initialSelection)
|
|
270
|
-
fireEvent.click(element)
|
|
271
|
-
expect(PortableTextEditor.getValue(editor)).toEqual(
|
|
272
|
-
initialValue.concat(newBlock),
|
|
273
|
-
)
|
|
274
|
-
}
|
|
275
|
-
})
|
|
276
|
-
})
|
|
277
|
-
})
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import type React from 'react'
|
|
2
|
-
import {useCallback, useEffect, useState, type DragEvent} from 'react'
|
|
3
|
-
import type {Element as SlateElement} from 'slate'
|
|
4
|
-
import {ReactEditor, useSlateStatic} from 'slate-react'
|
|
5
|
-
import {debugWithName} from '../../internal-utils/debug'
|
|
6
|
-
import {
|
|
7
|
-
IS_DRAGGING_BLOCK_ELEMENT,
|
|
8
|
-
IS_DRAGGING_BLOCK_TARGET_POSITION,
|
|
9
|
-
IS_DRAGGING_ELEMENT_TARGET,
|
|
10
|
-
} from '../../internal-utils/weakMaps'
|
|
11
|
-
|
|
12
|
-
const debug = debugWithName('useDroppable')
|
|
13
|
-
|
|
14
|
-
type Droppable = {
|
|
15
|
-
droppableProps: {
|
|
16
|
-
onDragOver?: (event: DragEvent) => void
|
|
17
|
-
onDragLeave?: () => void
|
|
18
|
-
onDrop?: (event: DragEvent) => void
|
|
19
|
-
}
|
|
20
|
-
isDraggingOverTop: boolean
|
|
21
|
-
isDraggingOverBottom: boolean
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function useDroppable(props: {
|
|
25
|
-
element: SlateElement
|
|
26
|
-
blockRef: React.RefObject<HTMLDivElement | null>
|
|
27
|
-
readOnly: boolean
|
|
28
|
-
}): Droppable {
|
|
29
|
-
const editor = useSlateStatic()
|
|
30
|
-
const [isDragOver, setIsDragOver] = useState(false)
|
|
31
|
-
const [blockElement, setBlockElement] = useState<HTMLElement | null>(null)
|
|
32
|
-
|
|
33
|
-
useEffect(
|
|
34
|
-
() =>
|
|
35
|
-
setBlockElement(
|
|
36
|
-
props.blockRef
|
|
37
|
-
? props.blockRef.current
|
|
38
|
-
: ReactEditor.toDOMNode(editor, props.element),
|
|
39
|
-
),
|
|
40
|
-
[editor, props.element, props.blockRef],
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
const handleDragOver = useCallback(
|
|
44
|
-
(event: DragEvent) => {
|
|
45
|
-
const isMyDragOver = IS_DRAGGING_BLOCK_ELEMENT.get(editor)
|
|
46
|
-
// debug('Drag over', blockElement)
|
|
47
|
-
if (!isMyDragOver || !blockElement) {
|
|
48
|
-
return
|
|
49
|
-
}
|
|
50
|
-
event.preventDefault()
|
|
51
|
-
event.dataTransfer.dropEffect = 'move'
|
|
52
|
-
IS_DRAGGING_ELEMENT_TARGET.set(editor, props.element)
|
|
53
|
-
const elementRect = blockElement.getBoundingClientRect()
|
|
54
|
-
const offset = elementRect.top
|
|
55
|
-
const height = elementRect.height
|
|
56
|
-
const Y = event.pageY
|
|
57
|
-
const loc = Math.abs(offset - Y)
|
|
58
|
-
let position: 'top' | 'bottom' = 'bottom'
|
|
59
|
-
if (props.element === editor.children[0]) {
|
|
60
|
-
position = 'top'
|
|
61
|
-
} else if (loc < height / 2) {
|
|
62
|
-
position = 'top'
|
|
63
|
-
IS_DRAGGING_BLOCK_TARGET_POSITION.set(editor, position)
|
|
64
|
-
} else {
|
|
65
|
-
position = 'bottom'
|
|
66
|
-
IS_DRAGGING_BLOCK_TARGET_POSITION.set(editor, position)
|
|
67
|
-
}
|
|
68
|
-
if (isMyDragOver === props.element) {
|
|
69
|
-
event.dataTransfer.dropEffect = 'none'
|
|
70
|
-
return
|
|
71
|
-
}
|
|
72
|
-
setIsDragOver(true)
|
|
73
|
-
},
|
|
74
|
-
[blockElement, editor, props.element],
|
|
75
|
-
)
|
|
76
|
-
|
|
77
|
-
const handleDragLeave = useCallback(() => {
|
|
78
|
-
setIsDragOver(false)
|
|
79
|
-
}, [])
|
|
80
|
-
|
|
81
|
-
const handleDrop = useCallback(
|
|
82
|
-
(event: DragEvent) => {
|
|
83
|
-
if (IS_DRAGGING_BLOCK_ELEMENT.get(editor)) {
|
|
84
|
-
debug('On drop (prevented)', props.element)
|
|
85
|
-
event.preventDefault()
|
|
86
|
-
event.stopPropagation()
|
|
87
|
-
setIsDragOver(false)
|
|
88
|
-
}
|
|
89
|
-
},
|
|
90
|
-
[editor, props.element],
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
const isDraggingOverFirstBlock =
|
|
94
|
-
isDragOver && editor.children[0] === IS_DRAGGING_ELEMENT_TARGET.get(editor)
|
|
95
|
-
const isDraggingOverLastBlock =
|
|
96
|
-
isDragOver &&
|
|
97
|
-
editor.children[editor.children.length - 1] ===
|
|
98
|
-
IS_DRAGGING_ELEMENT_TARGET.get(editor)
|
|
99
|
-
const dragPosition = IS_DRAGGING_BLOCK_TARGET_POSITION.get(editor)
|
|
100
|
-
|
|
101
|
-
const isDraggingOverTop =
|
|
102
|
-
isDraggingOverFirstBlock ||
|
|
103
|
-
(isDragOver &&
|
|
104
|
-
!isDraggingOverFirstBlock &&
|
|
105
|
-
!isDraggingOverLastBlock &&
|
|
106
|
-
dragPosition === 'top')
|
|
107
|
-
const isDraggingOverBottom =
|
|
108
|
-
isDraggingOverLastBlock ||
|
|
109
|
-
(isDragOver &&
|
|
110
|
-
!isDraggingOverFirstBlock &&
|
|
111
|
-
!isDraggingOverLastBlock &&
|
|
112
|
-
dragPosition === 'bottom')
|
|
113
|
-
|
|
114
|
-
if (props.readOnly) {
|
|
115
|
-
return {
|
|
116
|
-
droppableProps: {
|
|
117
|
-
onDragOver: undefined,
|
|
118
|
-
onDragLeave: undefined,
|
|
119
|
-
onDrop: undefined,
|
|
120
|
-
},
|
|
121
|
-
isDraggingOverTop: false,
|
|
122
|
-
isDraggingOverBottom: false,
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
return {
|
|
127
|
-
droppableProps: {
|
|
128
|
-
onDragOver: handleDragOver,
|
|
129
|
-
onDragLeave: handleDragLeave,
|
|
130
|
-
onDrop: handleDrop,
|
|
131
|
-
},
|
|
132
|
-
isDraggingOverTop,
|
|
133
|
-
isDraggingOverBottom,
|
|
134
|
-
}
|
|
135
|
-
}
|