@portabletext/editor 1.0.19 → 1.1.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.
Files changed (76) hide show
  1. package/lib/index.d.mts +142 -67
  2. package/lib/index.d.ts +142 -67
  3. package/lib/index.esm.js +1130 -371
  4. package/lib/index.esm.js.map +1 -1
  5. package/lib/index.js +1130 -371
  6. package/lib/index.js.map +1 -1
  7. package/lib/index.mjs +1130 -371
  8. package/lib/index.mjs.map +1 -1
  9. package/package.json +4 -18
  10. package/src/editor/Editable.tsx +128 -55
  11. package/src/editor/PortableTextEditor.tsx +66 -32
  12. package/src/editor/__tests__/PortableTextEditor.test.tsx +44 -18
  13. package/src/editor/__tests__/PortableTextEditorTester.tsx +50 -38
  14. package/src/editor/__tests__/RangeDecorations.test.tsx +4 -6
  15. package/src/editor/__tests__/handleClick.test.tsx +28 -9
  16. package/src/editor/__tests__/insert-block.test.tsx +24 -8
  17. package/src/editor/__tests__/pteWarningsSelfSolving.test.tsx +31 -63
  18. package/src/editor/__tests__/utils.ts +10 -4
  19. package/src/editor/components/DraggableBlock.tsx +36 -13
  20. package/src/editor/components/Element.tsx +73 -33
  21. package/src/editor/components/Leaf.tsx +114 -76
  22. package/src/editor/components/SlateContainer.tsx +14 -7
  23. package/src/editor/components/Synchronizer.tsx +8 -5
  24. package/src/editor/hooks/usePortableTextEditor.ts +3 -3
  25. package/src/editor/hooks/usePortableTextEditorSelection.tsx +10 -4
  26. package/src/editor/hooks/useSyncValue.test.tsx +9 -4
  27. package/src/editor/hooks/useSyncValue.ts +198 -133
  28. package/src/editor/nodes/DefaultAnnotation.tsx +6 -4
  29. package/src/editor/nodes/DefaultObject.tsx +1 -1
  30. package/src/editor/plugins/__tests__/createWithInsertData.test.tsx +23 -8
  31. package/src/editor/plugins/__tests__/withEditableAPIDelete.test.tsx +26 -9
  32. package/src/editor/plugins/__tests__/withEditableAPIGetFragment.test.tsx +15 -5
  33. package/src/editor/plugins/__tests__/withEditableAPIInsert.test.tsx +60 -19
  34. package/src/editor/plugins/__tests__/withEditableAPISelectionsOverlapping.test.tsx +5 -3
  35. package/src/editor/plugins/__tests__/withPortableTextLists.test.tsx +4 -2
  36. package/src/editor/plugins/__tests__/withPortableTextMarkModel.test.tsx +61 -19
  37. package/src/editor/plugins/__tests__/withPortableTextSelections.test.tsx +6 -3
  38. package/src/editor/plugins/__tests__/withUndoRedo.test.tsx +30 -13
  39. package/src/editor/plugins/createWithEditableAPI.ts +361 -131
  40. package/src/editor/plugins/createWithHotKeys.ts +46 -130
  41. package/src/editor/plugins/createWithInsertBreak.ts +167 -28
  42. package/src/editor/plugins/createWithInsertData.ts +66 -30
  43. package/src/editor/plugins/createWithMaxBlocks.ts +6 -3
  44. package/src/editor/plugins/createWithObjectKeys.ts +7 -3
  45. package/src/editor/plugins/createWithPatches.ts +66 -24
  46. package/src/editor/plugins/createWithPlaceholderBlock.ts +9 -5
  47. package/src/editor/plugins/createWithPortableTextBlockStyle.ts +17 -7
  48. package/src/editor/plugins/createWithPortableTextLists.ts +21 -9
  49. package/src/editor/plugins/createWithPortableTextMarkModel.ts +217 -52
  50. package/src/editor/plugins/createWithPortableTextSelections.ts +11 -9
  51. package/src/editor/plugins/createWithSchemaTypes.ts +26 -10
  52. package/src/editor/plugins/createWithUndoRedo.ts +106 -27
  53. package/src/editor/plugins/createWithUtils.ts +33 -11
  54. package/src/editor/plugins/index.ts +34 -13
  55. package/src/types/editor.ts +73 -44
  56. package/src/types/options.ts +7 -5
  57. package/src/types/slate.ts +6 -6
  58. package/src/utils/__tests__/dmpToOperations.test.ts +41 -16
  59. package/src/utils/__tests__/operationToPatches.test.ts +4 -3
  60. package/src/utils/__tests__/patchToOperations.test.ts +16 -5
  61. package/src/utils/__tests__/ranges.test.ts +9 -4
  62. package/src/utils/__tests__/valueNormalization.test.tsx +12 -4
  63. package/src/utils/__tests__/values.test.ts +0 -1
  64. package/src/utils/applyPatch.ts +78 -29
  65. package/src/utils/getPortableTextMemberSchemaTypes.ts +38 -23
  66. package/src/utils/operationToPatches.ts +123 -44
  67. package/src/utils/paths.ts +26 -9
  68. package/src/utils/ranges.ts +16 -10
  69. package/src/utils/selection.ts +21 -9
  70. package/src/utils/ucs2Indices.ts +2 -2
  71. package/src/utils/validateValue.ts +118 -45
  72. package/src/utils/values.ts +38 -17
  73. package/src/utils/weakMaps.ts +20 -10
  74. package/src/utils/withChanges.ts +5 -3
  75. package/src/utils/withUndoRedo.ts +1 -1
  76. package/src/utils/withoutPatching.ts +1 -1
@@ -1,5 +1,3 @@
1
- /* eslint-disable max-statements */
2
- /* eslint-disable complexity */
3
1
  /**
4
2
  *
5
3
  * This plugin will change Slate's default marks model (every prop is a mark) with the Portable Text model (marks is an array of strings on prop .marks).
@@ -7,14 +5,23 @@
7
5
  */
8
6
 
9
7
  import {isPortableTextBlock, isPortableTextSpan} from '@portabletext/toolkit'
8
+ import type {PortableTextObject} from '@sanity/types'
10
9
  import {isEqual, uniq} from 'lodash'
11
- import {type Subject} from 'rxjs'
12
- import {type Descendant, Editor, Element, Node, Path, Range, Text, Transforms} from 'slate'
13
-
10
+ import type {Subject} from 'rxjs'
14
11
  import {
15
- type EditorChange,
16
- type PortableTextMemberSchemaTypes,
17
- type PortableTextSlateEditor,
12
+ Editor,
13
+ Element,
14
+ Node,
15
+ Path,
16
+ Range,
17
+ Text,
18
+ Transforms,
19
+ type Descendant,
20
+ } from 'slate'
21
+ import type {
22
+ EditorChange,
23
+ PortableTextMemberSchemaTypes,
24
+ PortableTextSlateEditor,
18
25
  } from '../../types/editor'
19
26
  import {debugWithName} from '../../utils/debug'
20
27
  import {toPortableTextRange} from '../../utils/ranges'
@@ -47,7 +54,11 @@ export function createWithPortableTextMarkModel(
47
54
  Transforms.select(editor, {...editor.selection})
48
55
  editor.selection = {...editor.selection} // Ensure new object
49
56
  }
50
- const ptRange = toPortableTextRange(editor.children, editor.selection, types)
57
+ const ptRange = toPortableTextRange(
58
+ editor.children,
59
+ editor.selection,
60
+ types,
61
+ )
51
62
  change$.next({type: 'selection', selection: ptRange})
52
63
  }
53
64
 
@@ -71,12 +82,24 @@ export function createWithPortableTextMarkModel(
71
82
  JSON.stringify(child, null, 2),
72
83
  JSON.stringify(nextNode, null, 2),
73
84
  )
74
- Transforms.mergeNodes(editor, {at: [childPath[0], childPath[1] + 1], voids: true})
85
+ Transforms.mergeNodes(editor, {
86
+ at: [childPath[0], childPath[1] + 1],
87
+ voids: true,
88
+ })
75
89
  return
76
90
  }
77
91
  }
78
92
  }
79
93
 
94
+ /**
95
+ * Add missing .markDefs to block nodes
96
+ */
97
+ if (editor.isTextBlock(node) && !Array.isArray(node.markDefs)) {
98
+ debug('Adding .markDefs to block node')
99
+ Transforms.setNodes(editor, {markDefs: []}, {at: path})
100
+ return
101
+ }
102
+
80
103
  /**
81
104
  * Add missing .marks to span nodes
82
105
  */
@@ -93,7 +116,9 @@ export function createWithPortableTextMarkModel(
93
116
  const blockPath = Path.parent(path)
94
117
  const [block] = Editor.node(editor, blockPath)
95
118
  const decorators = types.decorators.map((decorator) => decorator.value)
96
- const annotations = node.marks?.filter((mark) => !decorators.includes(mark))
119
+ const annotations = node.marks?.filter(
120
+ (mark) => !decorators.includes(mark),
121
+ )
97
122
 
98
123
  if (editor.isTextBlock(block)) {
99
124
  if (node.text === '' && annotations && annotations.length > 0) {
@@ -118,14 +143,21 @@ export function createWithPortableTextMarkModel(
118
143
  if (editor.isTextSpan(child)) {
119
144
  const marks = child.marks ?? []
120
145
  const orphanedAnnotations = marks.filter((mark) => {
121
- return !decorators.includes(mark) && !node.markDefs?.find((def) => def._key === mark)
146
+ return (
147
+ !decorators.includes(mark) &&
148
+ !node.markDefs?.find((def) => def._key === mark)
149
+ )
122
150
  })
123
151
 
124
152
  if (orphanedAnnotations.length > 0) {
125
153
  debug('Removing orphaned annotations from span node')
126
154
  Transforms.setNodes(
127
155
  editor,
128
- {marks: marks.filter((mark) => !orphanedAnnotations.includes(mark))},
156
+ {
157
+ marks: marks.filter(
158
+ (mark) => !orphanedAnnotations.includes(mark),
159
+ ),
160
+ },
129
161
  {at: childPath},
130
162
  )
131
163
  return
@@ -142,17 +174,26 @@ export function createWithPortableTextMarkModel(
142
174
  const [block] = Editor.node(editor, blockPath)
143
175
 
144
176
  if (editor.isTextBlock(block)) {
145
- const decorators = types.decorators.map((decorator) => decorator.value)
177
+ const decorators = types.decorators.map(
178
+ (decorator) => decorator.value,
179
+ )
146
180
  const marks = node.marks ?? []
147
181
  const orphanedAnnotations = marks.filter((mark) => {
148
- return !decorators.includes(mark) && !block.markDefs?.find((def) => def._key === mark)
182
+ return (
183
+ !decorators.includes(mark) &&
184
+ !block.markDefs?.find((def) => def._key === mark)
185
+ )
149
186
  })
150
187
 
151
188
  if (orphanedAnnotations.length > 0) {
152
189
  debug('Removing orphaned annotations from span node')
153
190
  Transforms.setNodes(
154
191
  editor,
155
- {marks: marks.filter((mark) => !orphanedAnnotations.includes(mark))},
192
+ {
193
+ marks: marks.filter(
194
+ (mark) => !orphanedAnnotations.includes(mark),
195
+ ),
196
+ },
156
197
  {at: path},
157
198
  )
158
199
  return
@@ -160,17 +201,41 @@ export function createWithPortableTextMarkModel(
160
201
  }
161
202
  }
162
203
 
204
+ // Remove duplicate markDefs
205
+ if (editor.isTextBlock(node)) {
206
+ const markDefs = node.markDefs ?? []
207
+ const markDefKeys = new Set<string>()
208
+ const newMarkDefs: Array<PortableTextObject> = []
209
+
210
+ for (const markDef of markDefs) {
211
+ if (!markDefKeys.has(markDef._key)) {
212
+ markDefKeys.add(markDef._key)
213
+ newMarkDefs.push(markDef)
214
+ }
215
+ }
216
+
217
+ if (markDefs.length !== newMarkDefs.length) {
218
+ debug('Removing duplicate markDefs')
219
+ Transforms.setNodes(editor, {markDefs: newMarkDefs}, {at: path})
220
+ }
221
+ }
222
+
163
223
  // Check consistency of markDefs (unless we are merging two nodes)
164
224
  if (
165
225
  editor.isTextBlock(node) &&
166
226
  !editor.operations.some(
167
- (op) => op.type === 'merge_node' && 'markDefs' in op.properties && op.path.length === 1,
227
+ (op) =>
228
+ op.type === 'merge_node' &&
229
+ 'markDefs' in op.properties &&
230
+ op.path.length === 1,
168
231
  )
169
232
  ) {
170
233
  const newMarkDefs = (node.markDefs || []).filter((def) => {
171
234
  return node.children.find((child) => {
172
235
  return (
173
- Text.isText(child) && Array.isArray(child.marks) && child.marks.includes(def._key)
236
+ Text.isText(child) &&
237
+ Array.isArray(child.marks) &&
238
+ child.marks.includes(def._key)
174
239
  )
175
240
  })
176
241
  })
@@ -215,13 +280,16 @@ export function createWithPortableTextMarkModel(
215
280
  if (
216
281
  selection &&
217
282
  Range.isCollapsed(selection) &&
218
- Editor.marks(editor)?.marks?.some((mark) => !decorators.includes(mark))
283
+ Editor.marks(editor)?.marks?.some(
284
+ (mark) => !decorators.includes(mark),
285
+ )
219
286
  ) {
220
287
  const [node] = Array.from(
221
288
  Editor.nodes(editor, {
222
289
  mode: 'lowest',
223
290
  at: selection.focus,
224
- match: (n) => (n as unknown as Descendant)._type === types.span.name,
291
+ match: (n) =>
292
+ (n as unknown as Descendant)._type === types.span.name,
225
293
  voids: false,
226
294
  }),
227
295
  )[0] || [undefined]
@@ -261,15 +329,25 @@ export function createWithPortableTextMarkModel(
261
329
  const blockEntry = Editor.node(editor, Path.parent(op.path))
262
330
  const block = blockEntry[0]
263
331
 
264
- if (node && isPortableTextSpan(node) && block && isPortableTextBlock(block)) {
332
+ if (
333
+ node &&
334
+ isPortableTextSpan(node) &&
335
+ block &&
336
+ isPortableTextBlock(block)
337
+ ) {
265
338
  const markDefs = block.markDefs ?? []
266
339
  const nodeHasAnnotations = (node.marks ?? []).some((mark) =>
267
340
  markDefs.find((markDef) => markDef._key === mark),
268
341
  )
269
342
  const deletingPartOfTheNode = op.offset !== 0
270
- const deletingFromTheEnd = op.offset + op.text.length === node.text.length
343
+ const deletingFromTheEnd =
344
+ op.offset + op.text.length === node.text.length
271
345
 
272
- if (nodeHasAnnotations && deletingPartOfTheNode && deletingFromTheEnd) {
346
+ if (
347
+ nodeHasAnnotations &&
348
+ deletingPartOfTheNode &&
349
+ deletingFromTheEnd
350
+ ) {
273
351
  Editor.withoutNormalizing(editor, () => {
274
352
  Transforms.splitNodes(editor, {
275
353
  match: Text.isText,
@@ -293,7 +371,11 @@ export function createWithPortableTextMarkModel(
293
371
 
294
372
  Editor.withoutNormalizing(editor, () => {
295
373
  apply(op)
296
- Transforms.setNodes(editor, {marks: marksWithoutAnnotationMarks}, {at: op.path})
374
+ Transforms.setNodes(
375
+ editor,
376
+ {marks: marksWithoutAnnotationMarks},
377
+ {at: op.path},
378
+ )
297
379
  })
298
380
 
299
381
  editor.onChange()
@@ -329,11 +411,16 @@ export function createWithPortableTextMarkModel(
329
411
  const [targetBlock, targetPath] = Editor.node(editor, [op.path[0] - 1])
330
412
 
331
413
  if (editor.isTextBlock(targetBlock)) {
332
- const oldDefs = (Array.isArray(targetBlock.markDefs) && targetBlock.markDefs) || []
414
+ const oldDefs =
415
+ (Array.isArray(targetBlock.markDefs) && targetBlock.markDefs) || []
333
416
  const newMarkDefs = uniq([...oldDefs, ...op.properties.markDefs])
334
417
 
335
418
  debug(`Copying markDefs over to merged block`, op)
336
- Transforms.setNodes(editor, {markDefs: newMarkDefs}, {at: targetPath, voids: false})
419
+ Transforms.setNodes(
420
+ editor,
421
+ {markDefs: newMarkDefs},
422
+ {at: targetPath, voids: false},
423
+ )
337
424
  apply(op)
338
425
  return
339
426
  }
@@ -348,10 +435,19 @@ export function createWithPortableTextMarkModel(
348
435
  if (Range.isExpanded(editor.selection)) {
349
436
  Editor.withoutNormalizing(editor, () => {
350
437
  // Split if needed
351
- Transforms.setNodes(editor, {}, {match: Text.isText, split: true})
438
+ Transforms.setNodes(
439
+ editor,
440
+ {},
441
+ {match: Text.isText, split: true, hanging: true},
442
+ )
352
443
  // Use new selection
353
444
  const splitTextNodes = Range.isRange(editor.selection)
354
- ? [...Editor.nodes(editor, {at: editor.selection, match: Text.isText})]
445
+ ? [
446
+ ...Editor.nodes(editor, {
447
+ at: editor.selection,
448
+ match: Text.isText,
449
+ }),
450
+ ]
355
451
  : []
356
452
  const shouldRemoveMark =
357
453
  splitTextNodes.length > 1 &&
@@ -376,17 +472,49 @@ export function createWithPortableTextMarkModel(
376
472
  }
377
473
  })
378
474
  } else {
379
- const existingMarks: string[] =
380
- {
475
+ const [block, blockPath] = Editor.node(editor, editor.selection, {
476
+ depth: 1,
477
+ })
478
+ const lonelyEmptySpan =
479
+ editor.isTextBlock(block) &&
480
+ block.children.length === 1 &&
481
+ editor.isTextSpan(block.children[0]) &&
482
+ block.children[0].text === ''
483
+ ? block.children[0]
484
+ : undefined
485
+
486
+ if (lonelyEmptySpan) {
487
+ const existingMarks = lonelyEmptySpan.marks ?? []
488
+ const existingMarksWithoutDecorator = existingMarks.filter(
489
+ (existingMark) => existingMark !== mark,
490
+ )
491
+
492
+ Transforms.setNodes(
493
+ editor,
494
+ {
495
+ marks:
496
+ existingMarks.length === existingMarksWithoutDecorator.length
497
+ ? [...existingMarks, mark]
498
+ : existingMarksWithoutDecorator,
499
+ },
500
+ {
501
+ at: blockPath,
502
+ match: (node) => editor.isTextSpan(node),
503
+ },
504
+ )
505
+ } else {
506
+ const existingMarks: string[] =
507
+ {
508
+ ...(Editor.marks(editor) || {}),
509
+ }.marks || []
510
+ const marks = {
381
511
  ...(Editor.marks(editor) || {}),
382
- }.marks || []
383
- const marks = {
384
- ...(Editor.marks(editor) || {}),
385
- marks: [...existingMarks, mark],
512
+ marks: [...existingMarks, mark],
513
+ }
514
+ editor.marks = marks as Text
515
+ forceNewSelection()
516
+ return editor
386
517
  }
387
- editor.marks = marks as Text
388
- forceNewSelection()
389
- return editor
390
518
  }
391
519
  editor.onChange()
392
520
  forceNewSelection()
@@ -401,10 +529,17 @@ export function createWithPortableTextMarkModel(
401
529
  if (Range.isExpanded(selection)) {
402
530
  Editor.withoutNormalizing(editor, () => {
403
531
  // Split if needed
404
- Transforms.setNodes(editor, {}, {match: Text.isText, split: true})
532
+ Transforms.setNodes(
533
+ editor,
534
+ {},
535
+ {match: Text.isText, split: true, hanging: true},
536
+ )
405
537
  if (editor.selection) {
406
538
  const splitTextNodes = [
407
- ...Editor.nodes(editor, {at: editor.selection, match: Text.isText}),
539
+ ...Editor.nodes(editor, {
540
+ at: editor.selection,
541
+ match: Text.isText,
542
+ }),
408
543
  ]
409
544
  splitTextNodes.forEach(([node, path]) => {
410
545
  const block = editor.children[path[0]]
@@ -412,9 +547,10 @@ export function createWithPortableTextMarkModel(
412
547
  Transforms.setNodes(
413
548
  editor,
414
549
  {
415
- marks: (Array.isArray(node.marks) ? node.marks : []).filter(
416
- (eMark: string) => eMark !== mark,
417
- ),
550
+ marks: (Array.isArray(node.marks)
551
+ ? node.marks
552
+ : []
553
+ ).filter((eMark: string) => eMark !== mark),
418
554
  _type: 'span',
419
555
  },
420
556
  {at: path},
@@ -425,17 +561,46 @@ export function createWithPortableTextMarkModel(
425
561
  })
426
562
  Editor.normalize(editor)
427
563
  } else {
428
- const existingMarks: string[] =
429
- {
564
+ const [block, blockPath] = Editor.node(editor, selection, {
565
+ depth: 1,
566
+ })
567
+ const lonelyEmptySpan =
568
+ editor.isTextBlock(block) &&
569
+ block.children.length === 1 &&
570
+ editor.isTextSpan(block.children[0]) &&
571
+ block.children[0].text === ''
572
+ ? block.children[0]
573
+ : undefined
574
+
575
+ if (lonelyEmptySpan) {
576
+ const existingMarks = lonelyEmptySpan.marks ?? []
577
+ const existingMarksWithoutDecorator = existingMarks.filter(
578
+ (existingMark) => existingMark !== mark,
579
+ )
580
+
581
+ Transforms.setNodes(
582
+ editor,
583
+ {
584
+ marks: existingMarksWithoutDecorator,
585
+ },
586
+ {
587
+ at: blockPath,
588
+ match: (node) => editor.isTextSpan(node),
589
+ },
590
+ )
591
+ } else {
592
+ const existingMarks: string[] =
593
+ {
594
+ ...(Editor.marks(editor) || {}),
595
+ }.marks || []
596
+ const marks = {
430
597
  ...(Editor.marks(editor) || {}),
431
- }.marks || []
432
- const marks = {
433
- ...(Editor.marks(editor) || {}),
434
- marks: existingMarks.filter((eMark) => eMark !== mark),
435
- } as Text
436
- editor.marks = {marks: marks.marks, _type: 'span'} as Text
437
- forceNewSelection()
438
- return editor
598
+ marks: existingMarks.filter((eMark) => eMark !== mark),
599
+ } as Text
600
+ editor.marks = {marks: marks.marks, _type: 'span'} as Text
601
+ forceNewSelection()
602
+ return editor
603
+ }
439
604
  }
440
605
  editor.onChange()
441
606
  forceNewSelection()
@@ -1,14 +1,16 @@
1
- import {type Subject} from 'rxjs'
2
- import {type BaseRange} from 'slate'
3
-
4
- import {
5
- type EditorChange,
6
- type EditorSelection,
7
- type PortableTextMemberSchemaTypes,
8
- type PortableTextSlateEditor,
1
+ import type {Subject} from 'rxjs'
2
+ import type {BaseRange} from 'slate'
3
+ import type {
4
+ EditorChange,
5
+ EditorSelection,
6
+ PortableTextMemberSchemaTypes,
7
+ PortableTextSlateEditor,
9
8
  } from '../../types/editor'
10
9
  import {debugWithName} from '../../utils/debug'
11
- import {type ObjectWithKeyAndType, toPortableTextRange} from '../../utils/ranges'
10
+ import {
11
+ toPortableTextRange,
12
+ type ObjectWithKeyAndType,
13
+ } from '../../utils/ranges'
12
14
  import {SLATE_TO_PORTABLE_TEXT_RANGE} from '../../utils/weakMaps'
13
15
 
14
16
  const debug = debugWithName('plugin:withPortableTextSelections')
@@ -6,9 +6,11 @@ import {
6
6
  type PortableTextSpan,
7
7
  type PortableTextTextBlock,
8
8
  } from '@sanity/types'
9
- import {type Element, Transforms} from 'slate'
10
-
11
- import {type PortableTextMemberSchemaTypes, type PortableTextSlateEditor} from '../../types/editor'
9
+ import {Transforms, type Element} from 'slate'
10
+ import type {
11
+ PortableTextMemberSchemaTypes,
12
+ PortableTextSlateEditor,
13
+ } from '../../types/editor'
12
14
  import {debugWithName} from '../../utils/debug'
13
15
 
14
16
  const debug = debugWithName('plugin:withSchemaTypes')
@@ -23,21 +25,31 @@ export function createWithSchemaTypes({
23
25
  schemaTypes: PortableTextMemberSchemaTypes
24
26
  keyGenerator: () => string
25
27
  }) {
26
- return function withSchemaTypes(editor: PortableTextSlateEditor): PortableTextSlateEditor {
28
+ return function withSchemaTypes(
29
+ editor: PortableTextSlateEditor,
30
+ ): PortableTextSlateEditor {
27
31
  editor.isTextBlock = (value: unknown): value is PortableTextTextBlock => {
28
- return isPortableTextTextBlock(value) && value._type === schemaTypes.block.name
32
+ return (
33
+ isPortableTextTextBlock(value) && value._type === schemaTypes.block.name
34
+ )
29
35
  }
30
36
  editor.isTextSpan = (value: unknown): value is PortableTextSpan => {
31
- return isPortableTextSpan(value) && value._type == schemaTypes.span.name
37
+ return isPortableTextSpan(value) && value._type === schemaTypes.span.name
32
38
  }
33
39
  editor.isListBlock = (value: unknown): value is PortableTextListBlock => {
34
- return isPortableTextListBlock(value) && value._type === schemaTypes.block.name
40
+ return (
41
+ isPortableTextListBlock(value) && value._type === schemaTypes.block.name
42
+ )
35
43
  }
36
44
  editor.isVoid = (element: Element): boolean => {
37
45
  return (
38
46
  schemaTypes.block.name !== element._type &&
39
- (schemaTypes.blockObjects.map((obj) => obj.name).includes(element._type) ||
40
- schemaTypes.inlineObjects.map((obj) => obj.name).includes(element._type))
47
+ (schemaTypes.blockObjects
48
+ .map((obj) => obj.name)
49
+ .includes(element._type) ||
50
+ schemaTypes.inlineObjects
51
+ .map((obj) => obj.name)
52
+ .includes(element._type))
41
53
  )
42
54
  }
43
55
  editor.isInline = (element: Element): boolean => {
@@ -59,7 +71,11 @@ export function createWithSchemaTypes({
59
71
  debug('Setting span type on text node without a type')
60
72
  const span = node as PortableTextSpan
61
73
  const key = span._key || keyGenerator()
62
- Transforms.setNodes(editor, {...span, _type: schemaTypes.span.name, _key: key}, {at: path})
74
+ Transforms.setNodes(
75
+ editor,
76
+ {...span, _type: schemaTypes.span.name, _key: key},
77
+ {at: path},
78
+ )
63
79
  }
64
80
 
65
81
  // catches cases when the children are missing keys but excludes it when the normalize is running the node as the editor object