@portabletext/editor 1.0.18 → 1.1.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/index.d.mts +140 -66
- package/lib/index.d.ts +140 -66
- package/lib/index.esm.js +1164 -410
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +1164 -410
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +1164 -410
- package/lib/index.mjs.map +1 -1
- package/package.json +8 -4
- package/src/editor/Editable.tsx +107 -36
- package/src/editor/PortableTextEditor.tsx +47 -12
- package/src/editor/__tests__/PortableTextEditor.test.tsx +42 -15
- package/src/editor/__tests__/PortableTextEditorTester.tsx +50 -38
- package/src/editor/__tests__/RangeDecorations.test.tsx +0 -1
- package/src/editor/__tests__/handleClick.test.tsx +28 -9
- package/src/editor/__tests__/insert-block.test.tsx +22 -6
- package/src/editor/__tests__/pteWarningsSelfSolving.test.tsx +30 -62
- package/src/editor/__tests__/utils.ts +10 -3
- package/src/editor/components/DraggableBlock.tsx +36 -13
- package/src/editor/components/Element.tsx +59 -17
- package/src/editor/components/Leaf.tsx +106 -68
- package/src/editor/components/SlateContainer.tsx +12 -5
- package/src/editor/components/Synchronizer.tsx +5 -2
- package/src/editor/hooks/usePortableTextEditor.ts +2 -2
- package/src/editor/hooks/usePortableTextEditorSelection.tsx +9 -3
- package/src/editor/hooks/useSyncValue.test.tsx +9 -4
- package/src/editor/hooks/useSyncValue.ts +199 -130
- package/src/editor/nodes/DefaultAnnotation.tsx +6 -3
- package/src/editor/plugins/__tests__/createWithInsertData.test.tsx +25 -7
- package/src/editor/plugins/__tests__/withEditableAPIDelete.test.tsx +26 -9
- package/src/editor/plugins/__tests__/withEditableAPIGetFragment.test.tsx +15 -5
- package/src/editor/plugins/__tests__/withEditableAPIInsert.test.tsx +60 -19
- package/src/editor/plugins/__tests__/withEditableAPISelectionsOverlapping.test.tsx +4 -2
- package/src/editor/plugins/__tests__/withPortableTextLists.test.tsx +4 -2
- package/src/editor/plugins/__tests__/withPortableTextMarkModel.test.tsx +61 -550
- package/src/editor/plugins/__tests__/withPortableTextSelections.test.tsx +6 -3
- package/src/editor/plugins/__tests__/withUndoRedo.test.tsx +30 -13
- package/src/editor/plugins/createWithEditableAPI.ts +354 -115
- package/src/editor/plugins/createWithHotKeys.ts +41 -121
- package/src/editor/plugins/createWithInsertBreak.ts +166 -27
- package/src/editor/plugins/createWithInsertData.ts +60 -23
- package/src/editor/plugins/createWithMaxBlocks.ts +5 -2
- package/src/editor/plugins/createWithObjectKeys.ts +7 -3
- package/src/editor/plugins/createWithPatches.ts +60 -16
- package/src/editor/plugins/createWithPlaceholderBlock.ts +7 -3
- package/src/editor/plugins/createWithPortableTextBlockStyle.ts +17 -7
- package/src/editor/plugins/createWithPortableTextLists.ts +21 -8
- package/src/editor/plugins/createWithPortableTextMarkModel.ts +301 -155
- package/src/editor/plugins/createWithPortableTextSelections.ts +4 -2
- package/src/editor/plugins/createWithSchemaTypes.ts +25 -9
- package/src/editor/plugins/createWithUndoRedo.ts +107 -24
- package/src/editor/plugins/createWithUtils.ts +32 -10
- package/src/editor/plugins/index.ts +31 -10
- package/src/types/editor.ts +44 -15
- package/src/types/options.ts +4 -2
- package/src/types/slate.ts +2 -2
- package/src/utils/__tests__/dmpToOperations.test.ts +38 -13
- package/src/utils/__tests__/operationToPatches.test.ts +3 -2
- package/src/utils/__tests__/patchToOperations.test.ts +15 -4
- package/src/utils/__tests__/ranges.test.ts +8 -3
- package/src/utils/__tests__/valueNormalization.test.tsx +12 -4
- package/src/utils/__tests__/values.test.ts +0 -1
- package/src/utils/applyPatch.ts +71 -20
- package/src/utils/getPortableTextMemberSchemaTypes.ts +30 -15
- package/src/utils/operationToPatches.ts +126 -43
- package/src/utils/paths.ts +24 -7
- package/src/utils/ranges.ts +12 -5
- package/src/utils/selection.ts +19 -7
- package/src/utils/validateValue.ts +118 -45
- package/src/utils/values.ts +31 -10
- package/src/utils/weakMaps.ts +18 -8
- package/src/utils/withChanges.ts +4 -2
- package/src/editor/plugins/__tests__/withHotkeys.test.tsx +0 -212
- package/src/editor/plugins/__tests__/withInsertBreak.test.tsx +0 -220
- package/src/editor/plugins/__tests__/withPlaceholderBlock.test.tsx +0 -133
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/* eslint-disable max-nested-callbacks */
|
|
2
|
-
import {insert,
|
|
2
|
+
import {insert, setIfMissing, unset, type Patch} from '@portabletext/patches'
|
|
3
3
|
import {type Subject} from 'rxjs'
|
|
4
4
|
import {
|
|
5
|
-
type Descendant,
|
|
6
5
|
Editor,
|
|
6
|
+
type Descendant,
|
|
7
7
|
type InsertNodeOperation,
|
|
8
8
|
type InsertTextOperation,
|
|
9
9
|
type MergeNodeOperation,
|
|
@@ -14,7 +14,6 @@ import {
|
|
|
14
14
|
type SetNodeOperation,
|
|
15
15
|
type SplitNodeOperation,
|
|
16
16
|
} from 'slate'
|
|
17
|
-
|
|
18
17
|
import {
|
|
19
18
|
type EditorChange,
|
|
20
19
|
type PatchObservable,
|
|
@@ -24,9 +23,16 @@ import {
|
|
|
24
23
|
import {createApplyPatch} from '../../utils/applyPatch'
|
|
25
24
|
import {debugWithName} from '../../utils/debug'
|
|
26
25
|
import {fromSlateValue, isEqualToEmptyEditor} from '../../utils/values'
|
|
27
|
-
import {
|
|
26
|
+
import {
|
|
27
|
+
IS_PROCESSING_REMOTE_CHANGES,
|
|
28
|
+
KEY_TO_VALUE_ELEMENT,
|
|
29
|
+
} from '../../utils/weakMaps'
|
|
28
30
|
import {withRemoteChanges} from '../../utils/withChanges'
|
|
29
|
-
import {
|
|
31
|
+
import {
|
|
32
|
+
isPatching,
|
|
33
|
+
PATCHING,
|
|
34
|
+
withoutPatching,
|
|
35
|
+
} from '../../utils/withoutPatching'
|
|
30
36
|
import {withoutSaving} from './createWithUndoRedo'
|
|
31
37
|
|
|
32
38
|
const debug = debugWithName('plugin:withPatches')
|
|
@@ -117,7 +123,8 @@ export function createWithPatches({
|
|
|
117
123
|
withoutPatching(editor, () => {
|
|
118
124
|
withoutSaving(editor, () => {
|
|
119
125
|
patches.forEach((patch) => {
|
|
120
|
-
if (debug.enabled)
|
|
126
|
+
if (debug.enabled)
|
|
127
|
+
debug(`Handling remote patch ${JSON.stringify(patch)}`)
|
|
121
128
|
changed = applyPatch(editor, patch)
|
|
122
129
|
})
|
|
123
130
|
})
|
|
@@ -169,12 +176,19 @@ export function createWithPatches({
|
|
|
169
176
|
|
|
170
177
|
if (!isPatching(editor)) {
|
|
171
178
|
if (debugVerbose && debug.enabled)
|
|
172
|
-
debug(
|
|
179
|
+
debug(
|
|
180
|
+
`Editor is not producing patch for operation ${operation.type}`,
|
|
181
|
+
operation,
|
|
182
|
+
)
|
|
173
183
|
return editor
|
|
174
184
|
}
|
|
175
185
|
|
|
176
186
|
// If the editor was empty and now isn't, insert the placeholder into it.
|
|
177
|
-
if (
|
|
187
|
+
if (
|
|
188
|
+
editorWasEmpty &&
|
|
189
|
+
!editorIsEmpty &&
|
|
190
|
+
operation.type !== 'set_selection'
|
|
191
|
+
) {
|
|
178
192
|
patches.push(insert(previousChildren, 'before', [0]))
|
|
179
193
|
}
|
|
180
194
|
|
|
@@ -182,31 +196,51 @@ export function createWithPatches({
|
|
|
182
196
|
case 'insert_text':
|
|
183
197
|
patches = [
|
|
184
198
|
...patches,
|
|
185
|
-
...patchFunctions.insertTextPatch(
|
|
199
|
+
...patchFunctions.insertTextPatch(
|
|
200
|
+
editor,
|
|
201
|
+
operation,
|
|
202
|
+
previousChildren,
|
|
203
|
+
),
|
|
186
204
|
]
|
|
187
205
|
break
|
|
188
206
|
case 'remove_text':
|
|
189
207
|
patches = [
|
|
190
208
|
...patches,
|
|
191
|
-
...patchFunctions.removeTextPatch(
|
|
209
|
+
...patchFunctions.removeTextPatch(
|
|
210
|
+
editor,
|
|
211
|
+
operation,
|
|
212
|
+
previousChildren,
|
|
213
|
+
),
|
|
192
214
|
]
|
|
193
215
|
break
|
|
194
216
|
case 'remove_node':
|
|
195
217
|
patches = [
|
|
196
218
|
...patches,
|
|
197
|
-
...patchFunctions.removeNodePatch(
|
|
219
|
+
...patchFunctions.removeNodePatch(
|
|
220
|
+
editor,
|
|
221
|
+
operation,
|
|
222
|
+
previousChildren,
|
|
223
|
+
),
|
|
198
224
|
]
|
|
199
225
|
break
|
|
200
226
|
case 'split_node':
|
|
201
227
|
patches = [
|
|
202
228
|
...patches,
|
|
203
|
-
...patchFunctions.splitNodePatch(
|
|
229
|
+
...patchFunctions.splitNodePatch(
|
|
230
|
+
editor,
|
|
231
|
+
operation,
|
|
232
|
+
previousChildren,
|
|
233
|
+
),
|
|
204
234
|
]
|
|
205
235
|
break
|
|
206
236
|
case 'insert_node':
|
|
207
237
|
patches = [
|
|
208
238
|
...patches,
|
|
209
|
-
...patchFunctions.insertNodePatch(
|
|
239
|
+
...patchFunctions.insertNodePatch(
|
|
240
|
+
editor,
|
|
241
|
+
operation,
|
|
242
|
+
previousChildren,
|
|
243
|
+
),
|
|
210
244
|
]
|
|
211
245
|
break
|
|
212
246
|
case 'set_node':
|
|
@@ -218,13 +252,21 @@ export function createWithPatches({
|
|
|
218
252
|
case 'merge_node':
|
|
219
253
|
patches = [
|
|
220
254
|
...patches,
|
|
221
|
-
...patchFunctions.mergeNodePatch(
|
|
255
|
+
...patchFunctions.mergeNodePatch(
|
|
256
|
+
editor,
|
|
257
|
+
operation,
|
|
258
|
+
previousChildren,
|
|
259
|
+
),
|
|
222
260
|
]
|
|
223
261
|
break
|
|
224
262
|
case 'move_node':
|
|
225
263
|
patches = [
|
|
226
264
|
...patches,
|
|
227
|
-
...patchFunctions.moveNodePatch(
|
|
265
|
+
...patchFunctions.moveNodePatch(
|
|
266
|
+
editor,
|
|
267
|
+
operation,
|
|
268
|
+
previousChildren,
|
|
269
|
+
),
|
|
228
270
|
]
|
|
229
271
|
break
|
|
230
272
|
case 'set_selection':
|
|
@@ -236,7 +278,9 @@ export function createWithPatches({
|
|
|
236
278
|
if (
|
|
237
279
|
!editorWasEmpty &&
|
|
238
280
|
editorIsEmpty &&
|
|
239
|
-
['merge_node', 'set_node', 'remove_text', 'remove_node'].includes(
|
|
281
|
+
['merge_node', 'set_node', 'remove_text', 'remove_node'].includes(
|
|
282
|
+
operation.type,
|
|
283
|
+
)
|
|
240
284
|
) {
|
|
241
285
|
patches = [...patches, unset([])]
|
|
242
286
|
change$.next({
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {Editor, Path} from 'slate'
|
|
2
|
-
|
|
3
2
|
import {type PortableTextSlateEditor} from '../../types/editor'
|
|
4
3
|
import {type SlateTextBlock, type VoidElement} from '../../types/slate'
|
|
5
4
|
import {debugWithName} from '../../utils/debug'
|
|
@@ -15,7 +14,9 @@ const debug = debugWithName('plugin:withPlaceholderBlock')
|
|
|
15
14
|
export function createWithPlaceholderBlock(): (
|
|
16
15
|
editor: PortableTextSlateEditor,
|
|
17
16
|
) => PortableTextSlateEditor {
|
|
18
|
-
return function withPlaceholderBlock(
|
|
17
|
+
return function withPlaceholderBlock(
|
|
18
|
+
editor: PortableTextSlateEditor,
|
|
19
|
+
): PortableTextSlateEditor {
|
|
19
20
|
const {apply} = editor
|
|
20
21
|
|
|
21
22
|
editor.apply = (op) => {
|
|
@@ -45,7 +46,10 @@ export function createWithPlaceholderBlock(): (
|
|
|
45
46
|
// Is removing the first block which is a void (not a text block), add a new empty text block in it, if there is no other element in the next path
|
|
46
47
|
if (!editor.children[nextPath[0]]) {
|
|
47
48
|
debug('Adding placeholder block')
|
|
48
|
-
Editor.insertNode(
|
|
49
|
+
Editor.insertNode(
|
|
50
|
+
editor,
|
|
51
|
+
editor.pteCreateTextBlock({decorators: []}),
|
|
52
|
+
)
|
|
49
53
|
}
|
|
50
54
|
}
|
|
51
55
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import {Editor,
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {Editor, Path, Text as SlateText, Transforms, type Node} from 'slate'
|
|
2
|
+
import {
|
|
3
|
+
type PortableTextMemberSchemaTypes,
|
|
4
|
+
type PortableTextSlateEditor,
|
|
5
|
+
} from '../../types/editor'
|
|
4
6
|
import {debugWithName} from '../../utils/debug'
|
|
5
7
|
|
|
6
8
|
const debug = debugWithName('plugin:withPortableTextBlockStyle')
|
|
@@ -30,7 +32,11 @@ export function createWithPortableTextBlockStyle(
|
|
|
30
32
|
const [child] = Editor.node(editor, [op.path[0] + 1, 0])
|
|
31
33
|
if (SlateText.isText(child) && child.text === '') {
|
|
32
34
|
debug(`Normalizing split node to ${defaultStyle} style`, op)
|
|
33
|
-
Transforms.setNodes(
|
|
35
|
+
Transforms.setNodes(
|
|
36
|
+
editor,
|
|
37
|
+
{style: defaultStyle},
|
|
38
|
+
{at: [op.path[0] + 1], voids: false},
|
|
39
|
+
)
|
|
34
40
|
break
|
|
35
41
|
}
|
|
36
42
|
}
|
|
@@ -65,9 +71,13 @@ export function createWithPortableTextBlockStyle(
|
|
|
65
71
|
selectedBlocks.forEach(([node, path]) => {
|
|
66
72
|
if (editor.isTextBlock(node) && node.style === blockStyle) {
|
|
67
73
|
debug(`Unsetting block style '${blockStyle}'`)
|
|
68
|
-
Transforms.setNodes(
|
|
69
|
-
|
|
70
|
-
|
|
74
|
+
Transforms.setNodes(
|
|
75
|
+
editor,
|
|
76
|
+
{...node, style: defaultStyle} as Partial<Node>,
|
|
77
|
+
{
|
|
78
|
+
at: path,
|
|
79
|
+
},
|
|
80
|
+
)
|
|
71
81
|
} else {
|
|
72
82
|
if (blockStyle) {
|
|
73
83
|
debug(`Setting style '${blockStyle}'`)
|
|
@@ -1,13 +1,19 @@
|
|
|
1
|
-
import {Editor, Element,
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {Editor, Element, Text, Transforms, type Node} from 'slate'
|
|
2
|
+
import {
|
|
3
|
+
type PortableTextMemberSchemaTypes,
|
|
4
|
+
type PortableTextSlateEditor,
|
|
5
|
+
} from '../../types/editor'
|
|
4
6
|
import {debugWithName} from '../../utils/debug'
|
|
5
7
|
|
|
6
8
|
const debug = debugWithName('plugin:withPortableTextLists')
|
|
7
9
|
const MAX_LIST_LEVEL = 10
|
|
8
10
|
|
|
9
|
-
export function createWithPortableTextLists(
|
|
10
|
-
|
|
11
|
+
export function createWithPortableTextLists(
|
|
12
|
+
types: PortableTextMemberSchemaTypes,
|
|
13
|
+
) {
|
|
14
|
+
return function withPortableTextLists(
|
|
15
|
+
editor: PortableTextSlateEditor,
|
|
16
|
+
): PortableTextSlateEditor {
|
|
11
17
|
editor.pteToggleListItem = (listItemStyle: string) => {
|
|
12
18
|
const isActive = editor.pteHasListStyle(listItemStyle)
|
|
13
19
|
if (isActive) {
|
|
@@ -26,7 +32,8 @@ export function createWithPortableTextLists(types: PortableTextMemberSchemaTypes
|
|
|
26
32
|
const selectedBlocks = [
|
|
27
33
|
...Editor.nodes(editor, {
|
|
28
34
|
at: editor.selection,
|
|
29
|
-
match: (node) =>
|
|
35
|
+
match: (node) =>
|
|
36
|
+
Element.isElement(node) && node._type === types.block.name,
|
|
30
37
|
}),
|
|
31
38
|
]
|
|
32
39
|
selectedBlocks.forEach(([node, path]) => {
|
|
@@ -121,10 +128,16 @@ export function createWithPortableTextLists(types: PortableTextMemberSchemaTypes
|
|
|
121
128
|
let level = node.level || 1
|
|
122
129
|
if (reverse) {
|
|
123
130
|
level--
|
|
124
|
-
debug(
|
|
131
|
+
debug(
|
|
132
|
+
'Decrementing list level',
|
|
133
|
+
Math.min(MAX_LIST_LEVEL, Math.max(1, level)),
|
|
134
|
+
)
|
|
125
135
|
} else {
|
|
126
136
|
level++
|
|
127
|
-
debug(
|
|
137
|
+
debug(
|
|
138
|
+
'Incrementing list level',
|
|
139
|
+
Math.min(MAX_LIST_LEVEL, Math.max(1, level)),
|
|
140
|
+
)
|
|
128
141
|
}
|
|
129
142
|
Transforms.setNodes(
|
|
130
143
|
editor,
|