@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,16 +1,15 @@
1
1
  import {
2
- type DragEvent,
3
- type MutableRefObject,
4
- type ReactNode,
5
2
  useCallback,
6
3
  useEffect,
7
4
  useMemo,
8
5
  useRef,
9
6
  useState,
7
+ type DragEvent,
8
+ type MutableRefObject,
9
+ type ReactNode,
10
10
  } from 'react'
11
- import {Editor, type Element as SlateElement, Path, Transforms} from 'slate'
11
+ import {Editor, Path, Transforms, type Element as SlateElement} from 'slate'
12
12
  import {ReactEditor, useSlateStatic} from 'slate-react'
13
-
14
13
  import {debugWithName} from '../../utils/debug'
15
14
  import {
16
15
  IS_DRAGGING,
@@ -36,17 +35,31 @@ export interface DraggableBlockProps {
36
35
  * Implements drag and drop functionality on editor block nodes
37
36
  * @internal
38
37
  */
39
- export const DraggableBlock = ({children, element, readOnly, blockRef}: DraggableBlockProps) => {
38
+ export const DraggableBlock = ({
39
+ children,
40
+ element,
41
+ readOnly,
42
+ blockRef,
43
+ }: DraggableBlockProps) => {
40
44
  const editor = useSlateStatic()
41
45
  const dragGhostRef: MutableRefObject<undefined | HTMLElement> = useRef()
42
46
  const [isDragOver, setIsDragOver] = useState(false)
43
- const isVoid = useMemo(() => Editor.isVoid(editor, element), [editor, element])
44
- const isInline = useMemo(() => Editor.isInline(editor, element), [editor, element])
47
+ const isVoid = useMemo(
48
+ () => Editor.isVoid(editor, element),
49
+ [editor, element],
50
+ )
51
+ const isInline = useMemo(
52
+ () => Editor.isInline(editor, element),
53
+ [editor, element],
54
+ )
45
55
 
46
56
  const [blockElement, setBlockElement] = useState<HTMLElement | null>(null)
47
57
 
48
58
  useEffect(
49
- () => setBlockElement(blockRef ? blockRef.current : ReactEditor.toDOMNode(editor, element)),
59
+ () =>
60
+ setBlockElement(
61
+ blockRef ? blockRef.current : ReactEditor.toDOMNode(editor, element),
62
+ ),
50
63
  [editor, element, blockRef],
51
64
  )
52
65
 
@@ -122,7 +135,11 @@ export const DraggableBlock = ({children, element, readOnly, blockRef}: Draggabl
122
135
  )}`,
123
136
  )
124
137
  }
125
- if (dragPosition === 'top' && isBefore && targetPath[0] !== editor.children.length - 1) {
138
+ if (
139
+ dragPosition === 'top' &&
140
+ isBefore &&
141
+ targetPath[0] !== editor.children.length - 1
142
+ ) {
126
143
  const originalPath = targetPath
127
144
  targetPath = Path.previous(targetPath)
128
145
  debug(
@@ -201,7 +218,9 @@ export const DraggableBlock = ({children, element, readOnly, blockRef}: Draggabl
201
218
  // drag ghost by adding a truthy data attribute 'data-pt-drag-ghost-element' to a HTML element.
202
219
  if (blockElement && blockElement instanceof HTMLElement) {
203
220
  let dragGhost = blockElement.cloneNode(true) as HTMLElement
204
- const customGhost = dragGhost.querySelector('[data-pt-drag-ghost-element]')
221
+ const customGhost = dragGhost.querySelector(
222
+ '[data-pt-drag-ghost-element]',
223
+ )
205
224
  if (customGhost) {
206
225
  dragGhost = customGhost as HTMLElement
207
226
  }
@@ -232,12 +251,16 @@ export const DraggableBlock = ({children, element, readOnly, blockRef}: Draggabl
232
251
  isDragOver && editor.children[0] === IS_DRAGGING_ELEMENT_TARGET.get(editor)
233
252
  const isDraggingOverLastBlock =
234
253
  isDragOver &&
235
- editor.children[editor.children.length - 1] === IS_DRAGGING_ELEMENT_TARGET.get(editor)
254
+ editor.children[editor.children.length - 1] ===
255
+ IS_DRAGGING_ELEMENT_TARGET.get(editor)
236
256
  const dragPosition = IS_DRAGGING_BLOCK_TARGET_POSITION.get(editor)
237
257
 
238
258
  const isDraggingOverTop =
239
259
  isDraggingOverFirstBlock ||
240
- (isDragOver && !isDraggingOverFirstBlock && !isDraggingOverLastBlock && dragPosition === 'top')
260
+ (isDragOver &&
261
+ !isDraggingOverFirstBlock &&
262
+ !isDraggingOverLastBlock &&
263
+ dragPosition === 'top')
241
264
  const isDraggingOverBottom =
242
265
  isDraggingOverLastBlock ||
243
266
  (isDragOver &&
@@ -1,28 +1,34 @@
1
- /* eslint-disable complexity */
2
- /* eslint-disable max-statements */
3
- import {
4
- type Path,
5
- type PortableTextChild,
6
- type PortableTextObject,
7
- type PortableTextTextBlock,
1
+ import type {
2
+ Path,
3
+ PortableTextChild,
4
+ PortableTextObject,
5
+ PortableTextTextBlock,
8
6
  } from '@sanity/types'
9
- import {type FunctionComponent, type ReactElement, useMemo, useRef} from 'react'
10
- import {Editor, Element as SlateElement, Range} from 'slate'
11
- import {ReactEditor, type RenderElementProps, useSelected, useSlateStatic} from 'slate-react'
12
-
7
+ import {useMemo, useRef, type FunctionComponent, type ReactElement} from 'react'
8
+ import {Editor, Range, Element as SlateElement} from 'slate'
13
9
  import {
14
- type BlockRenderProps,
15
- type PortableTextMemberSchemaTypes,
16
- type RenderBlockFunction,
17
- type RenderChildFunction,
18
- type RenderListItemFunction,
19
- type RenderStyleFunction,
10
+ ReactEditor,
11
+ useSelected,
12
+ useSlateStatic,
13
+ type RenderElementProps,
14
+ } from 'slate-react'
15
+ import type {
16
+ BlockRenderProps,
17
+ PortableTextMemberSchemaTypes,
18
+ RenderBlockFunction,
19
+ RenderChildFunction,
20
+ RenderListItemFunction,
21
+ RenderStyleFunction,
20
22
  } from '../../types/editor'
21
23
  import {debugWithName} from '../../utils/debug'
22
24
  import {fromSlateValue} from '../../utils/values'
23
25
  import {KEY_TO_VALUE_ELEMENT} from '../../utils/weakMaps'
24
26
  import ObjectNode from '../nodes/DefaultObject'
25
- import {DefaultBlockObject, DefaultListItem, DefaultListItemInner} from '../nodes/index'
27
+ import {
28
+ DefaultBlockObject,
29
+ DefaultListItem,
30
+ DefaultListItemInner,
31
+ } from '../nodes/index'
26
32
  import {DraggableBlock} from './DraggableBlock'
27
33
 
28
34
  const debug = debugWithName('components:Element')
@@ -67,16 +73,23 @@ export const Element: FunctionComponent<ElementProps> = ({
67
73
  const selected = useSelected()
68
74
  const blockRef = useRef<HTMLDivElement | null>(null)
69
75
  const inlineBlockObjectRef = useRef(null)
70
- const focused = (selected && editor.selection && Range.isCollapsed(editor.selection)) || false
76
+ const focused =
77
+ (selected && editor.selection && Range.isCollapsed(editor.selection)) ||
78
+ false
71
79
 
72
80
  const value = useMemo(
73
- () => fromSlateValue([element], schemaTypes.block.name, KEY_TO_VALUE_ELEMENT.get(editor))[0],
81
+ () =>
82
+ fromSlateValue(
83
+ [element],
84
+ schemaTypes.block.name,
85
+ KEY_TO_VALUE_ELEMENT.get(editor),
86
+ )[0],
74
87
  [editor, element, schemaTypes.block.name],
75
88
  )
76
89
 
77
90
  let renderedBlock = children
78
91
 
79
- let className
92
+ let className: string | undefined
80
93
 
81
94
  const blockPath: Path = useMemo(() => [{_key: element._key}], [element])
82
95
 
@@ -92,12 +105,18 @@ export const Element: FunctionComponent<ElementProps> = ({
92
105
  if (editor.isInline(element)) {
93
106
  const path = ReactEditor.findPath(editor, element)
94
107
  const [block] = Editor.node(editor, path, {depth: 1})
95
- const schemaType = schemaTypes.inlineObjects.find((_type) => _type.name === element._type)
108
+ const schemaType = schemaTypes.inlineObjects.find(
109
+ (_type) => _type.name === element._type,
110
+ )
96
111
  if (!schemaType) {
97
112
  throw new Error('Could not find type for inline block element')
98
113
  }
99
114
  if (SlateElement.isElement(block)) {
100
- const elmPath: Path = [{_key: block._key}, 'children', {_key: element._key}]
115
+ const elmPath: Path = [
116
+ {_key: block._key},
117
+ 'children',
118
+ {_key: element._key},
119
+ ]
101
120
  if (debugRenders) {
102
121
  debug(`Render ${element._key} (inline object)`)
103
122
  }
@@ -144,7 +163,9 @@ export const Element: FunctionComponent<ElementProps> = ({
144
163
  }
145
164
  const style = ('style' in element && element.style) || 'normal'
146
165
  className = `pt-block pt-text-block pt-text-block-style-${style}`
147
- const blockStyleType = schemaTypes.styles.find((item) => item.value === style)
166
+ const blockStyleType = schemaTypes.styles.find(
167
+ (item) => item.value === style,
168
+ )
148
169
  if (renderStyle && blockStyleType) {
149
170
  renderedBlock = renderStyle({
150
171
  block: element as PortableTextTextBlock,
@@ -157,7 +178,7 @@ export const Element: FunctionComponent<ElementProps> = ({
157
178
  editorElementRef: blockRef,
158
179
  })
159
180
  }
160
- let level
181
+ let level: number | undefined
161
182
  if (isListItem) {
162
183
  if (typeof element.level === 'number') {
163
184
  level = element.level
@@ -165,7 +186,9 @@ export const Element: FunctionComponent<ElementProps> = ({
165
186
  className += ` pt-list-item pt-list-item-${element.listItem} pt-list-item-level-${level || 1}`
166
187
  }
167
188
  if (editor.isListBlock(value) && isListItem && element.listItem) {
168
- const listType = schemaTypes.lists.find((item) => item.value === element.listItem)
189
+ const listType = schemaTypes.lists.find(
190
+ (item) => item.value === element.listItem,
191
+ )
169
192
  if (renderListItem && listType) {
170
193
  renderedBlock = renderListItem({
171
194
  block: value,
@@ -206,7 +229,9 @@ export const Element: FunctionComponent<ElementProps> = ({
206
229
  {
207
230
  enumerable: false,
208
231
  get() {
209
- console.warn("Property 'type' is deprecated, use 'schemaType' instead.")
232
+ console.warn(
233
+ "Property 'type' is deprecated, use 'schemaType' instead.",
234
+ )
210
235
  return schemaTypes.block
211
236
  },
212
237
  },
@@ -216,16 +241,29 @@ export const Element: FunctionComponent<ElementProps> = ({
216
241
  ? renderBlock(renderProps as BlockRenderProps)
217
242
  : children
218
243
  return (
219
- <div key={element._key} {...attributes} className={className} spellCheck={spellCheck}>
220
- <DraggableBlock element={element} readOnly={readOnly} blockRef={blockRef}>
244
+ <div
245
+ key={element._key}
246
+ {...attributes}
247
+ className={className}
248
+ spellCheck={spellCheck}
249
+ >
250
+ <DraggableBlock
251
+ element={element}
252
+ readOnly={readOnly}
253
+ blockRef={blockRef}
254
+ >
221
255
  <div ref={blockRef}>{propsOrDefaultRendered}</div>
222
256
  </DraggableBlock>
223
257
  </div>
224
258
  )
225
259
  }
226
- const schemaType = schemaTypes.blockObjects.find((_type) => _type.name === element._type)
260
+ const schemaType = schemaTypes.blockObjects.find(
261
+ (_type) => _type.name === element._type,
262
+ )
227
263
  if (!schemaType) {
228
- throw new Error(`Could not find schema type for block element of _type ${element._type}`)
264
+ throw new Error(
265
+ `Could not find schema type for block element of _type ${element._type}`,
266
+ )
229
267
  }
230
268
  if (debugRenders) {
231
269
  debug(`Render ${element._key} (object block)`)
@@ -236,7 +274,7 @@ export const Element: FunctionComponent<ElementProps> = ({
236
274
  schemaTypes.block.name,
237
275
  KEY_TO_VALUE_ELEMENT.get(editor),
238
276
  )[0]
239
- let renderedBlockFromProps
277
+ let renderedBlockFromProps: JSX.Element | undefined
240
278
  if (renderBlock) {
241
279
  const _props: Omit<BlockRenderProps, 'type'> = Object.defineProperty(
242
280
  {
@@ -252,7 +290,9 @@ export const Element: FunctionComponent<ElementProps> = ({
252
290
  {
253
291
  enumerable: false,
254
292
  get() {
255
- console.warn("Property 'type' is deprecated, use 'schemaType' instead.")
293
+ console.warn(
294
+ "Property 'type' is deprecated, use 'schemaType' instead.",
295
+ )
256
296
  return schemaType
257
297
  },
258
298
  },
@@ -1,25 +1,28 @@
1
- import {type Path, type PortableTextObject, type PortableTextTextBlock} from '@sanity/types'
1
+ import type {
2
+ Path,
3
+ PortableTextObject,
4
+ PortableTextTextBlock,
5
+ } from '@sanity/types'
2
6
  import {isEqual, uniq} from 'lodash'
3
7
  import {
4
- type ReactElement,
5
8
  startTransition,
6
9
  useCallback,
7
10
  useEffect,
8
11
  useMemo,
9
12
  useRef,
10
13
  useState,
14
+ type ReactElement,
11
15
  } from 'react'
12
16
  import {Text} from 'slate'
13
- import {type RenderLeafProps, useSelected} from 'slate-react'
14
-
15
- import {
16
- type BlockAnnotationRenderProps,
17
- type BlockChildRenderProps,
18
- type BlockDecoratorRenderProps,
19
- type PortableTextMemberSchemaTypes,
20
- type RenderAnnotationFunction,
21
- type RenderChildFunction,
22
- type RenderDecoratorFunction,
17
+ import {useSelected, type RenderLeafProps} from 'slate-react'
18
+ import type {
19
+ BlockAnnotationRenderProps,
20
+ BlockChildRenderProps,
21
+ BlockDecoratorRenderProps,
22
+ PortableTextMemberSchemaTypes,
23
+ RenderAnnotationFunction,
24
+ RenderChildFunction,
25
+ RenderDecoratorFunction,
23
26
  } from '../../types/editor'
24
27
  import {debugWithName} from '../../utils/debug'
25
28
  import {usePortableTextEditor} from '../hooks/usePortableTextEditor'
@@ -47,8 +50,15 @@ export interface LeafProps extends RenderLeafProps {
47
50
  * @internal
48
51
  */
49
52
  export const Leaf = (props: LeafProps) => {
50
- const {attributes, children, leaf, schemaTypes, renderChild, renderDecorator, renderAnnotation} =
51
- props
53
+ const {
54
+ attributes,
55
+ children,
56
+ leaf,
57
+ schemaTypes,
58
+ renderChild,
59
+ renderDecorator,
60
+ renderAnnotation,
61
+ } = props
52
62
  const spanRef = useRef<HTMLElement>(null)
53
63
  const portableTextEditor = usePortableTextEditor()
54
64
  const blockSelected = useSelected()
@@ -64,7 +74,12 @@ export const Leaf = (props: LeafProps) => {
64
74
  [schemaTypes.decorators],
65
75
  )
66
76
  const marks: string[] = useMemo(
67
- () => uniq((leaf.marks || EMPTY_MARKS).filter((mark) => decoratorValues.includes(mark))),
77
+ () =>
78
+ uniq(
79
+ (leaf.marks || EMPTY_MARKS).filter((mark) =>
80
+ decoratorValues.includes(mark),
81
+ ),
82
+ ),
68
83
  [decoratorValues, leaf.marks],
69
84
  )
70
85
  const annotationMarks = Array.isArray(leaf.marks) ? leaf.marks : EMPTY_MARKS
@@ -73,7 +88,8 @@ export const Leaf = (props: LeafProps) => {
73
88
  annotationMarks
74
89
  .map(
75
90
  (mark) =>
76
- !decoratorValues.includes(mark) && block?.markDefs?.find((def) => def._key === mark),
91
+ !decoratorValues.includes(mark) &&
92
+ block?.markDefs?.find((def) => def._key === mark),
77
93
  )
78
94
  .filter(Boolean) as PortableTextObject[],
79
95
  [annotationMarks, block, decoratorValues],
@@ -159,7 +175,12 @@ export const Leaf = (props: LeafProps) => {
159
175
  return () => {
160
176
  sub.unsubscribe()
161
177
  }
162
- }, [path, portableTextEditor, setSelectedFromRange, shouldTrackSelectionAndFocus])
178
+ }, [
179
+ path,
180
+ portableTextEditor,
181
+ setSelectedFromRange,
182
+ shouldTrackSelectionAndFocus,
183
+ ])
163
184
 
164
185
  useEffect(() => setSelectedFromRange(), [setSelectedFromRange])
165
186
 
@@ -168,59 +189,73 @@ export const Leaf = (props: LeafProps) => {
168
189
  // Render text nodes
169
190
  if (Text.isText(leaf) && leaf._type === schemaTypes.span.name) {
170
191
  marks.forEach((mark) => {
171
- const schemaType = schemaTypes.decorators.find((dec) => dec.value === mark)
192
+ const schemaType = schemaTypes.decorators.find(
193
+ (dec) => dec.value === mark,
194
+ )
172
195
  if (schemaType && renderDecorator) {
173
- const _props: Omit<BlockDecoratorRenderProps, 'type'> = Object.defineProperty(
174
- {
175
- children: returnedChildren,
176
- editorElementRef: spanRef,
177
- focused,
178
- path,
179
- selected,
180
- schemaType,
181
- value: mark,
182
- },
183
- 'type',
184
- {
185
- enumerable: false,
186
- get() {
187
- console.warn("Property 'type' is deprecated, use 'schemaType' instead.")
188
- return schemaType
196
+ const _props: Omit<BlockDecoratorRenderProps, 'type'> =
197
+ Object.defineProperty(
198
+ {
199
+ children: returnedChildren,
200
+ editorElementRef: spanRef,
201
+ focused,
202
+ path,
203
+ selected,
204
+ schemaType,
205
+ value: mark,
206
+ },
207
+ 'type',
208
+ {
209
+ enumerable: false,
210
+ get() {
211
+ console.warn(
212
+ "Property 'type' is deprecated, use 'schemaType' instead.",
213
+ )
214
+ return schemaType
215
+ },
189
216
  },
190
- },
217
+ )
218
+ returnedChildren = renderDecorator(
219
+ _props as BlockDecoratorRenderProps,
191
220
  )
192
- returnedChildren = renderDecorator(_props as BlockDecoratorRenderProps)
193
221
  }
194
222
  })
195
223
 
196
224
  if (block && annotations.length > 0) {
197
225
  annotations.forEach((annotation) => {
198
- const schemaType = schemaTypes.annotations.find((t) => t.name === annotation._type)
226
+ const schemaType = schemaTypes.annotations.find(
227
+ (t) => t.name === annotation._type,
228
+ )
199
229
  if (schemaType) {
200
230
  if (renderAnnotation) {
201
- const _props: Omit<BlockAnnotationRenderProps, 'type'> = Object.defineProperty(
202
- {
203
- block,
204
- children: returnedChildren,
205
- editorElementRef: spanRef,
206
- focused,
207
- path,
208
- selected,
209
- schemaType,
210
- value: annotation,
211
- },
212
- 'type',
213
- {
214
- enumerable: false,
215
- get() {
216
- console.warn("Property 'type' is deprecated, use 'schemaType' instead.")
217
- return schemaType
231
+ const _props: Omit<BlockAnnotationRenderProps, 'type'> =
232
+ Object.defineProperty(
233
+ {
234
+ block,
235
+ children: returnedChildren,
236
+ editorElementRef: spanRef,
237
+ focused,
238
+ path,
239
+ selected,
240
+ schemaType,
241
+ value: annotation,
218
242
  },
219
- },
220
- )
243
+ 'type',
244
+ {
245
+ enumerable: false,
246
+ get() {
247
+ console.warn(
248
+ "Property 'type' is deprecated, use 'schemaType' instead.",
249
+ )
250
+ return schemaType
251
+ },
252
+ },
253
+ )
221
254
 
222
255
  returnedChildren = (
223
- <span ref={spanRef}>{renderAnnotation(_props as BlockAnnotationRenderProps)}</span>
256
+ <span ref={spanRef}>
257
+ {renderAnnotation(_props as BlockAnnotationRenderProps)}
258
+ </span>
224
259
  )
225
260
  } else {
226
261
  returnedChildren = (
@@ -236,26 +271,29 @@ export const Leaf = (props: LeafProps) => {
236
271
  const child = block.children.find((_child) => _child._key === leaf._key) // Ensure object equality
237
272
  if (child) {
238
273
  const defaultRendered = <>{returnedChildren}</>
239
- const _props: Omit<BlockChildRenderProps, 'type'> = Object.defineProperty(
240
- {
241
- annotations,
242
- children: defaultRendered,
243
- editorElementRef: spanRef,
244
- focused,
245
- path,
246
- schemaType: schemaTypes.span,
247
- selected,
248
- value: child,
249
- },
250
- 'type',
251
- {
252
- enumerable: false,
253
- get() {
254
- console.warn("Property 'type' is deprecated, use 'schemaType' instead.")
255
- return schemaTypes.span
274
+ const _props: Omit<BlockChildRenderProps, 'type'> =
275
+ Object.defineProperty(
276
+ {
277
+ annotations,
278
+ children: defaultRendered,
279
+ editorElementRef: spanRef,
280
+ focused,
281
+ path,
282
+ schemaType: schemaTypes.span,
283
+ selected,
284
+ value: child,
256
285
  },
257
- },
258
- )
286
+ 'type',
287
+ {
288
+ enumerable: false,
289
+ get() {
290
+ console.warn(
291
+ "Property 'type' is deprecated, use 'schemaType' instead.",
292
+ )
293
+ return schemaTypes.span
294
+ },
295
+ },
296
+ )
259
297
  returnedChildren = renderChild(_props as BlockChildRenderProps)
260
298
  }
261
299
  }
@@ -1,12 +1,11 @@
1
- import {type PropsWithChildren, useEffect, useMemo, useState} from 'react'
1
+ import {useEffect, useMemo, useState, type PropsWithChildren} from 'react'
2
2
  import {createEditor} from 'slate'
3
3
  import {Slate, withReact} from 'slate-react'
4
-
5
- import {type PatchObservable} from '../../types/editor'
4
+ import type {PatchObservable} from '../../types/editor'
6
5
  import {debugWithName} from '../../utils/debug'
7
6
  import {KEY_TO_SLATE_ELEMENT, KEY_TO_VALUE_ELEMENT} from '../../utils/weakMaps'
8
7
  import {withPlugins} from '../plugins'
9
- import {type PortableTextEditor} from '../PortableTextEditor'
8
+ import type {PortableTextEditor} from '../PortableTextEditor'
10
9
 
11
10
  const debug = debugWithName('component:PortableTextEditor:SlateContainer')
12
11
 
@@ -26,7 +25,8 @@ export interface SlateContainerProps extends PropsWithChildren {
26
25
  * @internal
27
26
  */
28
27
  export function SlateContainer(props: SlateContainerProps) {
29
- const {patches$, portableTextEditor, readOnly, maxBlocks, keyGenerator} = props
28
+ const {patches$, portableTextEditor, readOnly, maxBlocks, keyGenerator} =
29
+ props
30
30
 
31
31
  // Create the slate instance, using `useState` ensures setup is only run once, initially
32
32
  const [[slateEditor, subscribe]] = useState(() => {
@@ -60,10 +60,17 @@ export function SlateContainer(props: SlateContainerProps) {
60
60
  portableTextEditor,
61
61
  readOnly,
62
62
  })
63
- }, [keyGenerator, portableTextEditor, maxBlocks, readOnly, patches$, slateEditor])
63
+ }, [
64
+ keyGenerator,
65
+ portableTextEditor,
66
+ maxBlocks,
67
+ readOnly,
68
+ patches$,
69
+ slateEditor,
70
+ ])
64
71
 
65
72
  const initialValue = useMemo(() => {
66
- return [slateEditor.pteCreateEmptyBlock()]
73
+ return [slateEditor.pteCreateTextBlock({decorators: []})]
67
74
  }, [slateEditor])
68
75
 
69
76
  useEffect(() => {
@@ -1,11 +1,10 @@
1
- import {type Patch} from '@portabletext/patches'
2
- import {type PortableTextBlock} from '@sanity/types'
1
+ import type {Patch} from '@portabletext/patches'
2
+ import type {PortableTextBlock} from '@sanity/types'
3
3
  import {throttle} from 'lodash'
4
4
  import {useCallback, useEffect, useMemo, useRef} from 'react'
5
5
  import {Editor} from 'slate'
6
6
  import {useSlate} from 'slate-react'
7
-
8
- import {type EditorChange, type EditorChanges} from '../../types/editor'
7
+ import type {EditorChange, EditorChanges} from '../../types/editor'
9
8
  import {debugWithName} from '../../utils/debug'
10
9
  import {IS_PROCESSING_LOCAL_CHANGES} from '../../utils/weakMaps'
11
10
  import {usePortableTextEditor} from '../hooks/usePortableTextEditor'
@@ -61,7 +60,11 @@ export function Synchronizer(props: SynchronizerProps) {
61
60
  debug(`Patches:\n${JSON.stringify(pendingPatches.current, null, 2)}`)
62
61
  }
63
62
  const snapshot = getValue()
64
- change$.next({type: 'mutation', patches: pendingPatches.current, snapshot})
63
+ change$.next({
64
+ type: 'mutation',
65
+ patches: pendingPatches.current,
66
+ snapshot,
67
+ })
65
68
  pendingPatches.current = []
66
69
  }
67
70
  IS_PROCESSING_LOCAL_CHANGES.set(slateEditor, false)
@@ -1,11 +1,11 @@
1
1
  import {createContext, useContext} from 'react'
2
-
3
- import {type PortableTextEditor} from '../PortableTextEditor'
2
+ import type {PortableTextEditor} from '../PortableTextEditor'
4
3
 
5
4
  /**
6
5
  * A React context for sharing the editor object.
7
6
  */
8
- export const PortableTextEditorContext = createContext<PortableTextEditor | null>(null)
7
+ export const PortableTextEditorContext =
8
+ createContext<PortableTextEditor | null>(null)
9
9
 
10
10
  /**
11
11
  * @public
@@ -1,12 +1,18 @@
1
- import {createContext, startTransition, useContext, useEffect, useState} from 'react'
2
-
3
- import {type EditorChanges, type EditorSelection} from '../../types/editor'
1
+ import {
2
+ createContext,
3
+ startTransition,
4
+ useContext,
5
+ useEffect,
6
+ useState,
7
+ } from 'react'
8
+ import type {EditorChanges, EditorSelection} from '../../types/editor'
4
9
  import {debugWithName} from '../../utils/debug'
5
10
 
6
11
  /**
7
12
  * A React context for sharing the editor selection.
8
13
  */
9
- const PortableTextEditorSelectionContext = createContext<EditorSelection | null>(null)
14
+ const PortableTextEditorSelectionContext =
15
+ createContext<EditorSelection | null>(null)
10
16
 
11
17
  /**
12
18
  * @public