@portabletext/editor 1.47.0 → 1.47.2

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 (93) hide show
  1. package/lib/_chunks-cjs/behavior.core.cjs +7 -7
  2. package/lib/_chunks-cjs/behavior.core.cjs.map +1 -1
  3. package/lib/_chunks-cjs/behavior.markdown.cjs.map +1 -1
  4. package/lib/_chunks-cjs/editor-provider.cjs +379 -326
  5. package/lib/_chunks-cjs/editor-provider.cjs.map +1 -1
  6. package/lib/_chunks-cjs/parse-blocks.cjs +4 -4
  7. package/lib/_chunks-cjs/parse-blocks.cjs.map +1 -1
  8. package/lib/_chunks-cjs/selector.is-overlapping-selection.cjs.map +1 -1
  9. package/lib/_chunks-es/behavior.core.js +7 -7
  10. package/lib/_chunks-es/behavior.core.js.map +1 -1
  11. package/lib/_chunks-es/behavior.markdown.js.map +1 -1
  12. package/lib/_chunks-es/editor-provider.js +380 -327
  13. package/lib/_chunks-es/editor-provider.js.map +1 -1
  14. package/lib/_chunks-es/parse-blocks.js +4 -4
  15. package/lib/_chunks-es/parse-blocks.js.map +1 -1
  16. package/lib/_chunks-es/selector.is-overlapping-selection.js.map +1 -1
  17. package/lib/behaviors/index.cjs.map +1 -1
  18. package/lib/behaviors/index.d.cts +70 -28
  19. package/lib/behaviors/index.d.ts +70 -28
  20. package/lib/behaviors/index.js.map +1 -1
  21. package/lib/index.cjs +12 -14
  22. package/lib/index.cjs.map +1 -1
  23. package/lib/index.d.cts +61 -3
  24. package/lib/index.d.ts +61 -3
  25. package/lib/index.js +12 -14
  26. package/lib/index.js.map +1 -1
  27. package/lib/plugins/index.cjs.map +1 -1
  28. package/lib/plugins/index.d.cts +68 -23
  29. package/lib/plugins/index.d.ts +68 -23
  30. package/lib/plugins/index.js.map +1 -1
  31. package/lib/selectors/index.d.cts +69 -27
  32. package/lib/selectors/index.d.ts +69 -27
  33. package/lib/utils/index.d.cts +74 -29
  34. package/lib/utils/index.d.ts +74 -29
  35. package/package.json +6 -6
  36. package/src/behavior-actions/behavior.action.insert.block.ts +1 -1
  37. package/src/behavior-actions/behavior.action.split.block.ts +1 -1
  38. package/src/behavior-actions/behavior.guards.ts +1 -1
  39. package/src/behaviors/behavior.core.decorators.ts +4 -4
  40. package/src/behaviors/behavior.core.insert-break.ts +4 -4
  41. package/src/behaviors/behavior.decorator-pair.ts +1 -1
  42. package/src/behaviors/behavior.links.ts +1 -1
  43. package/src/behaviors/behavior.markdown.ts +1 -1
  44. package/src/behaviors/behavior.perform-event.ts +1 -1
  45. package/src/converters/converter.portable-text.deserialize.test.ts +2 -3
  46. package/src/converters/converter.text-html.deserialize.test.ts +62 -5
  47. package/src/converters/converter.text-html.serialize.test.ts +9 -5
  48. package/src/converters/converter.text-html.ts +66 -64
  49. package/src/converters/converter.text-plain.test.ts +9 -4
  50. package/src/converters/converter.text-plain.ts +91 -87
  51. package/src/converters/converters.core.ts +13 -8
  52. package/src/editor/Editable.tsx +18 -13
  53. package/src/editor/PortableTextEditor.tsx +5 -5
  54. package/src/editor/__tests__/PortableTextEditorTester.tsx +4 -3
  55. package/src/editor/__tests__/insert-block.test.tsx +10 -10
  56. package/src/editor/__tests__/self-solving.test.tsx +2 -2
  57. package/src/editor/components/Synchronizer.tsx +1 -1
  58. package/src/editor/create-editor.ts +51 -18
  59. package/src/editor/editor-machine.ts +1 -1
  60. package/src/editor/{define-schema.ts → editor-schema.ts} +114 -5
  61. package/src/editor/editor-snapshot.ts +1 -1
  62. package/src/editor/get-active-decorators.ts +2 -2
  63. package/src/editor/{create-editor-schema.ts → legacy-schema.ts} +3 -3
  64. package/src/editor/mutation-machine.ts +1 -1
  65. package/src/editor/plugins/createWithObjectKeys.ts +6 -9
  66. package/src/editor/plugins/createWithPatches.ts +12 -11
  67. package/src/editor/plugins/createWithPortableTextBlockStyle.ts +2 -6
  68. package/src/editor/plugins/createWithPortableTextMarkModel.ts +15 -12
  69. package/src/editor/plugins/createWithSchemaTypes.ts +24 -16
  70. package/src/editor/plugins/createWithUndoRedo.ts +3 -4
  71. package/src/editor/plugins/createWithUtils.ts +12 -10
  72. package/src/editor/plugins/with-plugins.ts +5 -15
  73. package/src/editor/range-decorations-machine.ts +1 -1
  74. package/src/editor/sync-machine.ts +1 -1
  75. package/src/index.ts +2 -2
  76. package/src/internal-utils/__tests__/operationToPatches.test.ts +12 -10
  77. package/src/internal-utils/__tests__/patchToOperations.test.ts +3 -2
  78. package/src/internal-utils/__tests__/values.test.ts +3 -2
  79. package/src/internal-utils/applyPatch.ts +7 -9
  80. package/src/internal-utils/create-test-snapshot.ts +1 -1
  81. package/src/internal-utils/drag-selection.test.ts +1 -1
  82. package/src/internal-utils/operationToPatches.ts +4 -6
  83. package/src/internal-utils/parse-blocks.test.ts +1 -1
  84. package/src/internal-utils/parse-blocks.ts +8 -7
  85. package/src/internal-utils/slate-children-to-blocks.ts +1 -1
  86. package/src/internal-utils/slate-utils.ts +1 -1
  87. package/src/internal-utils/validateValue.ts +4 -6
  88. package/src/internal-utils/values.ts +5 -5
  89. package/src/plugins/plugin.decorator-shortcut.ts +1 -1
  90. package/src/plugins/plugin.markdown.test.tsx +1 -1
  91. package/src/plugins/plugin.markdown.tsx +1 -1
  92. package/src/selectors/selector.get-selection-text.test.ts +1 -1
  93. package/src/selectors/selector.get-trimmed-selection.test.ts +1 -1
@@ -1,14 +1,15 @@
1
1
  import type {PortableTextBlock, PortableTextTextBlock} from '@sanity/types'
2
2
  import {expect, test} from 'vitest'
3
3
  import type {EditorSelection} from '..'
4
+ import {schemaType} from '../editor/__tests__/PortableTextEditorTester'
4
5
  import {
5
6
  compileSchemaDefinition,
6
7
  defineSchema,
7
8
  type SchemaDefinition,
8
- } from '../editor/define-schema'
9
+ } from '../editor/editor-schema'
10
+ import {createLegacySchema} from '../editor/legacy-schema'
9
11
  import {createTestSnapshot} from '../internal-utils/create-test-snapshot'
10
- import {converterTextPlain} from './converter.text-plain'
11
- import {coreConverters} from './converters.core'
12
+ import {createConverterTextPlain} from './converter.text-plain'
12
13
 
13
14
  const b1: PortableTextTextBlock = {
14
15
  _type: 'block',
@@ -74,7 +75,7 @@ function createSnapshot({
74
75
  }) {
75
76
  return createTestSnapshot({
76
77
  context: {
77
- converters: coreConverters,
78
+ converters: [],
78
79
  schema: compileSchemaDefinition(schema),
79
80
  selection,
80
81
  value: [b1, b2, b3, b4],
@@ -82,6 +83,10 @@ function createSnapshot({
82
83
  })
83
84
  }
84
85
 
86
+ const converterTextPlain = createConverterTextPlain(
87
+ createLegacySchema(schemaType),
88
+ )
89
+
85
90
  test(converterTextPlain.serialize.name, () => {
86
91
  expect(
87
92
  converterTextPlain.serialize({
@@ -1,112 +1,116 @@
1
1
  import {htmlToBlocks} from '@portabletext/block-tools'
2
2
  import {isPortableTextTextBlock, type PortableTextBlock} from '@sanity/types'
3
3
  import {parseBlock} from '../internal-utils/parse-blocks'
4
+ import type {PortableTextMemberSchemaTypes} from '../types/editor'
4
5
  import {sliceBlocks} from '../utils'
5
6
  import {defineConverter} from './converter.types'
6
7
 
7
- export const converterTextPlain = defineConverter({
8
- mimeType: 'text/plain',
9
- serialize: ({snapshot, event}) => {
10
- const selection =
11
- snapshot.beta.internalDrag?.origin.selection ?? snapshot.context.selection
8
+ export function createConverterTextPlain(
9
+ legacySchema: PortableTextMemberSchemaTypes,
10
+ ) {
11
+ return defineConverter({
12
+ mimeType: 'text/plain',
13
+ serialize: ({snapshot, event}) => {
14
+ const selection =
15
+ snapshot.beta.internalDrag?.origin.selection ??
16
+ snapshot.context.selection
12
17
 
13
- if (!selection) {
14
- return {
15
- type: 'serialization.failure',
16
- mimeType: 'text/plain',
17
- originEvent: event.originEvent,
18
- reason: 'No selection',
18
+ if (!selection) {
19
+ return {
20
+ type: 'serialization.failure',
21
+ mimeType: 'text/plain',
22
+ originEvent: event.originEvent,
23
+ reason: 'No selection',
24
+ }
19
25
  }
20
- }
21
26
 
22
- const blocks = sliceBlocks({
23
- blocks: snapshot.context.value,
24
- selection,
25
- })
27
+ const blocks = sliceBlocks({
28
+ blocks: snapshot.context.value,
29
+ selection,
30
+ })
26
31
 
27
- const data = blocks
28
- .map((block) => {
29
- if (isPortableTextTextBlock(block)) {
30
- return block.children
31
- .map((child) => {
32
- if (child._type === snapshot.context.schema.span.name) {
33
- return child.text
34
- }
32
+ const data = blocks
33
+ .map((block) => {
34
+ if (isPortableTextTextBlock(block)) {
35
+ return block.children
36
+ .map((child) => {
37
+ if (child._type === snapshot.context.schema.span.name) {
38
+ return child.text
39
+ }
35
40
 
36
- return snapshot.beta.hasTag('dragging internally')
37
- ? `[${
38
- snapshot.context.schema.inlineObjects.find(
39
- (inlineObjectType) =>
40
- inlineObjectType.name === child._type,
41
- )?.title ?? 'Object'
42
- }]`
43
- : ''
44
- })
45
- .join('')
46
- }
41
+ return snapshot.beta.hasTag('dragging internally')
42
+ ? `[${
43
+ snapshot.context.schema.inlineObjects.find(
44
+ (inlineObjectType) =>
45
+ inlineObjectType.name === child._type,
46
+ )?.title ?? 'Object'
47
+ }]`
48
+ : ''
49
+ })
50
+ .join('')
51
+ }
47
52
 
48
- return snapshot.beta.hasTag('dragging internally')
49
- ? `[${
50
- snapshot.context.schema.blockObjects.find(
51
- (blockObjectType) => blockObjectType.name === block._type,
52
- )?.title ?? 'Object'
53
- }]`
54
- : ''
55
- })
56
- .filter((block) => block !== '')
57
- .join('\n\n')
53
+ return snapshot.beta.hasTag('dragging internally')
54
+ ? `[${
55
+ snapshot.context.schema.blockObjects.find(
56
+ (blockObjectType) => blockObjectType.name === block._type,
57
+ )?.title ?? 'Object'
58
+ }]`
59
+ : ''
60
+ })
61
+ .filter((block) => block !== '')
62
+ .join('\n\n')
58
63
 
59
- return {
60
- type: 'serialization.success',
61
- data,
62
- mimeType: 'text/plain',
63
- originEvent: event.originEvent,
64
- }
65
- },
66
- deserialize: ({snapshot, event}) => {
67
- const html = escapeHtml(event.data)
68
- .split(/\n{2,}/)
69
- .map((line) =>
70
- line ? `<p>${line.replace(/(?:\r\n|\r|\n)/g, '<br/>')}</p>` : '<p></p>',
71
- )
72
- .join('')
64
+ return {
65
+ type: 'serialization.success',
66
+ data,
67
+ mimeType: 'text/plain',
68
+ originEvent: event.originEvent,
69
+ }
70
+ },
71
+ deserialize: ({snapshot, event}) => {
72
+ const html = escapeHtml(event.data)
73
+ .split(/\n{2,}/)
74
+ .map((line) =>
75
+ line
76
+ ? `<p>${line.replace(/(?:\r\n|\r|\n)/g, '<br/>')}</p>`
77
+ : '<p></p>',
78
+ )
79
+ .join('')
73
80
 
74
- const textToHtml = `<html><body>${html}</body></html>`
81
+ const textToHtml = `<html><body>${html}</body></html>`
75
82
 
76
- const blocks = htmlToBlocks(
77
- textToHtml,
78
- snapshot.context.schema.portableText,
79
- {
83
+ const blocks = htmlToBlocks(textToHtml, legacySchema.portableText, {
80
84
  keyGenerator: snapshot.context.keyGenerator,
81
- },
82
- ) as Array<PortableTextBlock>
85
+ }) as Array<PortableTextBlock>
83
86
 
84
- const parsedBlocks = blocks.flatMap((block) => {
85
- const parsedBlock = parseBlock({
86
- context: snapshot.context,
87
- block,
88
- options: {
89
- refreshKeys: false,
90
- },
87
+ const parsedBlocks = blocks.flatMap((block) => {
88
+ const parsedBlock = parseBlock({
89
+ context: snapshot.context,
90
+ block,
91
+ options: {
92
+ refreshKeys: false,
93
+ },
94
+ })
95
+ return parsedBlock ? [parsedBlock] : []
91
96
  })
92
- return parsedBlock ? [parsedBlock] : []
93
- })
94
97
 
95
- if (parsedBlocks.length === 0) {
98
+ if (parsedBlocks.length === 0) {
99
+ return {
100
+ type: 'deserialization.failure',
101
+ mimeType: 'text/plain',
102
+ reason: 'No blocks deserialized',
103
+ }
104
+ }
105
+
96
106
  return {
97
- type: 'deserialization.failure',
107
+ type: 'deserialization.success',
108
+ data: parsedBlocks,
98
109
  mimeType: 'text/plain',
99
- reason: 'No blocks deserialized',
100
110
  }
101
- }
102
-
103
- return {
104
- type: 'deserialization.success',
105
- data: parsedBlocks,
106
- mimeType: 'text/plain',
107
- }
108
- },
109
- })
111
+ },
112
+ })
113
+ }
110
114
 
111
115
  const entityMap: Record<string, string> = {
112
116
  '&': '&amp;',
@@ -1,11 +1,16 @@
1
+ import type {PortableTextMemberSchemaTypes} from '../types/editor'
1
2
  import {converterJson} from './converter.json'
2
3
  import {converterPortableText} from './converter.portable-text'
3
- import {converterTextHtml} from './converter.text-html'
4
- import {converterTextPlain} from './converter.text-plain'
4
+ import {createConverterTextHtml} from './converter.text-html'
5
+ import {createConverterTextPlain} from './converter.text-plain'
5
6
 
6
- export const coreConverters = [
7
- converterJson,
8
- converterPortableText,
9
- converterTextHtml,
10
- converterTextPlain,
11
- ]
7
+ export function createCoreConverters(
8
+ legacySchema: PortableTextMemberSchemaTypes,
9
+ ) {
10
+ return [
11
+ converterJson,
12
+ converterPortableText,
13
+ createConverterTextHtml(legacySchema),
14
+ createConverterTextPlain(legacySchema),
15
+ ]
16
+ }
@@ -170,14 +170,13 @@ export const PortableTextEditable = forwardRef<
170
170
  const readOnly = useSelector(editorActor, (s) =>
171
171
  s.matches({'edit mode': 'read only'}),
172
172
  )
173
- const schemaTypes = useSelector(editorActor, (s) => s.context.schema)
174
173
  const slateEditor = useSlate()
175
174
 
176
175
  const rangeDecorationsActor = useActorRef(rangeDecorationsMachine, {
177
176
  input: {
178
177
  rangeDecorations: rangeDecorations ?? [],
179
178
  readOnly,
180
- schema: schemaTypes,
179
+ schema: editorActor.getSnapshot().context.schema,
181
180
  slateEditor,
182
181
  skipSetup: !editorActor.getSnapshot().matches({setup: 'setting up'}),
183
182
  },
@@ -202,8 +201,6 @@ export const PortableTextEditable = forwardRef<
202
201
  })
203
202
  }, [rangeDecorationsActor, rangeDecorations])
204
203
 
205
- const blockTypeName = schemaTypes.block.name
206
-
207
204
  // Output a minimal React editor inside Editable when in readOnly mode.
208
205
  // NOTE: make sure all the plugins used here can be safely run over again at any point.
209
206
  // There will be a problem if they redefine editor methods and then calling the original method within themselves.
@@ -232,12 +229,12 @@ export const PortableTextEditable = forwardRef<
232
229
  renderChild={renderChild}
233
230
  renderListItem={renderListItem}
234
231
  renderStyle={renderStyle}
235
- schemaTypes={schemaTypes}
232
+ schemaTypes={portableTextEditor.schemaTypes}
236
233
  spellCheck={spellCheck}
237
234
  />
238
235
  ),
239
236
  [
240
- schemaTypes,
237
+ portableTextEditor,
241
238
  spellCheck,
242
239
  readOnly,
243
240
  renderBlock,
@@ -258,7 +255,7 @@ export const PortableTextEditable = forwardRef<
258
255
  <Leaf
259
256
  {...lProps}
260
257
  editorActor={editorActor}
261
- schemaTypes={schemaTypes}
258
+ schemaTypes={portableTextEditor.schemaTypes}
262
259
  renderAnnotation={renderAnnotation}
263
260
  renderChild={renderChild}
264
261
  renderDecorator={renderDecorator}
@@ -289,12 +286,12 @@ export const PortableTextEditable = forwardRef<
289
286
  },
290
287
  [
291
288
  editorActor,
289
+ portableTextEditor,
292
290
  readOnly,
293
291
  renderAnnotation,
294
292
  renderChild,
295
293
  renderDecorator,
296
294
  renderPlaceholder,
297
- schemaTypes,
298
295
  ],
299
296
  )
300
297
 
@@ -303,7 +300,10 @@ export const PortableTextEditable = forwardRef<
303
300
  debug(`Selection from props ${JSON.stringify(propsSelection)}`)
304
301
  const normalizedSelection = normalizeSelection(
305
302
  propsSelection,
306
- fromSlateValue(slateEditor.children, blockTypeName),
303
+ fromSlateValue(
304
+ slateEditor.children,
305
+ editorActor.getSnapshot().context.schema.block.name,
306
+ ),
307
307
  )
308
308
  if (normalizedSelection !== null) {
309
309
  debug(
@@ -324,7 +324,7 @@ export const PortableTextEditable = forwardRef<
324
324
  }
325
325
  }
326
326
  }
327
- }, [blockTypeName, editorActor, propsSelection, slateEditor])
327
+ }, [editorActor, propsSelection, slateEditor])
328
328
 
329
329
  // Restore selection from props when the editor has been initialized properly with it's value
330
330
  useEffect(() => {
@@ -447,13 +447,18 @@ export const PortableTextEditable = forwardRef<
447
447
  const value = PortableTextEditor.getValue(portableTextEditor)
448
448
  const ptRange = slateEditor.selection
449
449
  ? slateRangeToSelection({
450
- schema: schemaTypes,
450
+ schema: editorActor.getSnapshot().context.schema,
451
451
  editor: slateEditor,
452
452
  range: slateEditor.selection,
453
453
  })
454
454
  : null
455
455
  const path = ptRange?.focus.path || []
456
- const onPasteResult = onPaste?.({event, value, path, schemaTypes})
456
+ const onPasteResult = onPaste?.({
457
+ event,
458
+ value,
459
+ path,
460
+ schemaTypes: portableTextEditor.schemaTypes,
461
+ })
457
462
 
458
463
  if (onPasteResult || !slateEditor.selection) {
459
464
  event.preventDefault()
@@ -552,7 +557,7 @@ export const PortableTextEditable = forwardRef<
552
557
 
553
558
  debug('No result from custom paste handler, pasting normally')
554
559
  },
555
- [editorActor, onPaste, portableTextEditor, schemaTypes, slateEditor],
560
+ [editorActor, onPaste, portableTextEditor, slateEditor],
556
561
  )
557
562
 
558
563
  const handleOnFocus: FocusEventHandler<HTMLDivElement> = useCallback(
@@ -29,12 +29,13 @@ import type {
29
29
  } from '../types/editor'
30
30
  import {Synchronizer} from './components/Synchronizer'
31
31
  import {createInternalEditor, type InternalEditor} from './create-editor'
32
- import {createEditorSchema} from './create-editor-schema'
33
32
  import {EditorActorContext} from './editor-actor-context'
34
33
  import type {EditorActor} from './editor-machine'
34
+ import {legacySchemaToEditorSchema} from './editor-schema'
35
35
  import {PortableTextEditorContext} from './hooks/usePortableTextEditor'
36
36
  import {PortableTextEditorSelectionProvider} from './hooks/usePortableTextEditorSelection'
37
37
  import {defaultKeyGenerator} from './key-generator'
38
+ import {createLegacySchema} from './legacy-schema'
38
39
 
39
40
  const debug = debugWithName('component:PortableTextEditor')
40
41
 
@@ -148,8 +149,7 @@ export class PortableTextEditor extends Component<
148
149
  })
149
150
  }
150
151
 
151
- this.schemaTypes =
152
- this.editor._internal.editorActor.getSnapshot().context.schema
152
+ this.schemaTypes = this.editor._internal.legacySchema
153
153
  this.editable = this.editor._internal.editable
154
154
  }
155
155
 
@@ -160,7 +160,7 @@ export class PortableTextEditor extends Component<
160
160
  !prevProps.editor &&
161
161
  this.props.schemaType !== prevProps.schemaType
162
162
  ) {
163
- this.schemaTypes = createEditorSchema(
163
+ this.schemaTypes = createLegacySchema(
164
164
  this.props.schemaType.hasOwnProperty('jsonType')
165
165
  ? this.props.schemaType
166
166
  : compileType(this.props.schemaType),
@@ -168,7 +168,7 @@ export class PortableTextEditor extends Component<
168
168
 
169
169
  this.editor._internal.editorActor.send({
170
170
  type: 'update schema',
171
- schema: this.schemaTypes,
171
+ schema: legacySchemaToEditorSchema(this.schemaTypes),
172
172
  })
173
173
  }
174
174
 
@@ -10,8 +10,9 @@ import {
10
10
  } from '../../index'
11
11
 
12
12
  const imageType = defineField({
13
- type: 'image',
14
- name: 'blockImage',
13
+ name: 'custom image',
14
+ type: 'object',
15
+ fields: [],
15
16
  })
16
17
 
17
18
  const someObject = defineField({
@@ -68,7 +69,7 @@ const colorAndLink = defineArrayMember({
68
69
 
69
70
  const schema = Schema.compile({
70
71
  name: 'test',
71
- types: [portableTextType, colorAndLink],
72
+ types: [portableTextType, colorAndLink, imageType],
72
73
  })
73
74
 
74
75
  export const PortableTextEditorTester = forwardRef(
@@ -12,9 +12,9 @@ const schema = Schema.compile({
12
12
  {
13
13
  name: 'portable-text',
14
14
  type: 'array',
15
- of: [{type: 'block'}, {type: 'image'}],
15
+ of: [{type: 'block'}, {type: 'custom image'}],
16
16
  },
17
- {name: 'image', type: 'object'},
17
+ {name: 'custom image', type: 'object'},
18
18
  ],
19
19
  }).get('portable-text')
20
20
 
@@ -71,7 +71,7 @@ describe(PortableTextEditor.insertBlock.name, () => {
71
71
  await waitFor(() => {
72
72
  if (editorRef.current) {
73
73
  const imageBlockType = editorRef.current.schemaTypes.blockObjects.find(
74
- (object) => object.name === 'image',
74
+ (object) => object.name === 'custom image',
75
75
  )!
76
76
  PortableTextEditor.insertBlock(editorRef.current, imageBlockType)
77
77
  }
@@ -81,7 +81,7 @@ describe(PortableTextEditor.insertBlock.name, () => {
81
81
  await waitFor(() => {
82
82
  if (editorRef.current) {
83
83
  expect(PortableTextEditor.getValue(editorRef.current)).toEqual([
84
- {_key: 'bb', _type: 'image'},
84
+ {_key: 'bb', _type: 'custom image'},
85
85
  ])
86
86
  }
87
87
  })
@@ -140,7 +140,7 @@ describe(PortableTextEditor.insertBlock.name, () => {
140
140
  await waitFor(() => {
141
141
  if (editorRef.current) {
142
142
  const imageBlockType = editorRef.current.schemaTypes.blockObjects.find(
143
- (object) => object.name === 'image',
143
+ (object) => object.name === 'custom image',
144
144
  )!
145
145
  PortableTextEditor.insertBlock(editorRef.current, imageBlockType)
146
146
  }
@@ -151,7 +151,7 @@ describe(PortableTextEditor.insertBlock.name, () => {
151
151
  if (editorRef.current) {
152
152
  expect(PortableTextEditor.getValue(editorRef.current)).toEqual([
153
153
  nonEmptyTextBlock,
154
- {_key: 'bb', _type: 'image'},
154
+ {_key: 'bb', _type: 'custom image'},
155
155
  ])
156
156
  }
157
157
  })
@@ -174,7 +174,7 @@ describe(PortableTextEditor.insertBlock.name, () => {
174
174
  }
175
175
  const imageBlock: PortableTextBlock = {
176
176
  _key: 'bb',
177
- _type: 'image',
177
+ _type: 'custom image',
178
178
  }
179
179
  const initialValue: Array<PortableTextBlock> = [emptyTextBlock, imageBlock]
180
180
  const onChange: (change: EditorChange) => void = vi.fn()
@@ -226,7 +226,7 @@ describe(PortableTextEditor.insertBlock.name, () => {
226
226
  await waitFor(() => {
227
227
  if (editorRef.current) {
228
228
  const imageBlockType = editorRef.current.schemaTypes.blockObjects.find(
229
- (object) => object.name === 'image',
229
+ (object) => object.name === 'custom image',
230
230
  )!
231
231
  PortableTextEditor.insertBlock(editorRef.current, imageBlockType)
232
232
  }
@@ -236,8 +236,8 @@ describe(PortableTextEditor.insertBlock.name, () => {
236
236
  await waitFor(() => {
237
237
  if (editorRef.current) {
238
238
  expect(PortableTextEditor.getValue(editorRef.current)).toEqual([
239
- {_key: 'bc', _type: 'image'},
240
- {_key: 'bb', _type: 'image'},
239
+ {_key: 'bc', _type: 'custom image'},
240
+ {_key: 'bb', _type: 'custom image'},
241
241
  ])
242
242
  }
243
243
  })
@@ -13,9 +13,9 @@ const schema = Schema.compile({
13
13
  {
14
14
  name: 'portable-text',
15
15
  type: 'array',
16
- of: [{type: 'block'}, {type: 'image'}],
16
+ of: [{type: 'block'}, {type: 'custom image'}],
17
17
  },
18
- {name: 'image', type: 'object'},
18
+ {name: 'custom image', type: 'object'},
19
19
  ],
20
20
  }).get('portable-text')
21
21
  type OnChange = ComponentProps<typeof PortableTextEditor>['onChange']
@@ -44,7 +44,7 @@ export function Synchronizer(props: SynchronizerProps) {
44
44
  })
45
45
  const mutationActorRef = useActorRef(mutationMachine, {
46
46
  input: {
47
- schema: editorActor.getSnapshot().context.schema,
47
+ schema: props.editorActor.getSnapshot().context.schema,
48
48
  slateEditor,
49
49
  },
50
50
  })
@@ -13,21 +13,26 @@ import {
13
13
  } from 'xstate'
14
14
  import type {Behavior} from '../behaviors/behavior.types.behavior'
15
15
  import type {ExternalBehaviorEvent} from '../behaviors/behavior.types.event'
16
- import {coreConverters} from '../converters/converters.core'
16
+ import {createCoreConverters} from '../converters/converters.core'
17
17
  import {compileType} from '../internal-utils/schema'
18
- import type {EditableAPI} from '../types/editor'
19
- import {createEditorSchema} from './create-editor-schema'
18
+ import type {EditableAPI, PortableTextMemberSchemaTypes} from '../types/editor'
20
19
  import {createSlateEditor, type SlateEditor} from './create-slate-editor'
21
- import {compileSchemaDefinition, type SchemaDefinition} from './define-schema'
22
20
  import {
23
21
  editorMachine,
24
22
  type EditorActor,
25
23
  type EditorEmittedEvent,
26
24
  type ExternalEditorEvent,
27
25
  } from './editor-machine'
26
+ import {
27
+ compileSchemaDefinitionToLegacySchema,
28
+ legacySchemaToEditorSchema,
29
+ type SchemaDefinition,
30
+ } from './editor-schema'
31
+ import type {EditorSchema} from './editor-schema'
28
32
  import {getEditorSnapshot} from './editor-selector'
29
33
  import type {EditorSnapshot} from './editor-snapshot'
30
34
  import {defaultKeyGenerator} from './key-generator'
35
+ import {createLegacySchema} from './legacy-schema'
31
36
  import {createEditableAPI} from './plugins/createWithEditableAPI'
32
37
 
33
38
  /**
@@ -79,49 +84,76 @@ export type InternalEditor = Editor & {
79
84
  editable: EditableAPI
80
85
  editorActor: EditorActor
81
86
  slateEditor: SlateEditor
87
+ legacySchema: PortableTextMemberSchemaTypes
82
88
  }
83
89
  }
84
90
 
85
91
  export function createInternalEditor(config: EditorConfig): InternalEditor {
92
+ const legacySchema = config.schemaDefinition
93
+ ? compileSchemaDefinitionToLegacySchema(config.schemaDefinition)
94
+ : createLegacySchema(
95
+ config.schema.hasOwnProperty('jsonType')
96
+ ? config.schema
97
+ : compileType(config.schema),
98
+ )
99
+ const editorSchema = legacySchemaToEditorSchema(legacySchema)
100
+
86
101
  const editorActor = createActor(editorMachine, {
87
- input: editorConfigToMachineInput(config),
102
+ input: editorConfigToMachineInput({
103
+ ...config,
104
+ schema: editorSchema,
105
+ legacySchema,
106
+ }),
88
107
  })
89
108
  editorActor.start()
90
109
 
91
- return createInternalEditorFromActor(editorActor)
110
+ return createInternalEditorFromActor(editorActor, legacySchema)
92
111
  }
93
112
 
94
113
  export function useCreateInternalEditor(config: EditorConfig): InternalEditor {
114
+ const legacySchema = config.schemaDefinition
115
+ ? compileSchemaDefinitionToLegacySchema(config.schemaDefinition)
116
+ : createLegacySchema(
117
+ config.schema.hasOwnProperty('jsonType')
118
+ ? config.schema
119
+ : compileType(config.schema),
120
+ )
121
+ const editorSchema = legacySchemaToEditorSchema(legacySchema)
122
+
95
123
  const editorActor = useActorRef(editorMachine, {
96
- input: editorConfigToMachineInput(config),
124
+ input: editorConfigToMachineInput({
125
+ ...config,
126
+ schema: editorSchema,
127
+ legacySchema,
128
+ }),
97
129
  })
98
130
 
99
131
  return useMemo(
100
- () => createInternalEditorFromActor(editorActor),
101
- [editorActor],
132
+ () => createInternalEditorFromActor(editorActor, legacySchema),
133
+ [editorActor, legacySchema],
102
134
  )
103
135
  }
104
136
 
105
- function editorConfigToMachineInput(config: EditorConfig) {
137
+ function editorConfigToMachineInput(
138
+ config: Omit<EditorConfig, 'schema'> & {
139
+ schema: EditorSchema
140
+ legacySchema: PortableTextMemberSchemaTypes
141
+ },
142
+ ) {
106
143
  return {
107
144
  behaviors: config.behaviors,
108
- converters: coreConverters,
145
+ converters: createCoreConverters(config.legacySchema),
109
146
  keyGenerator: config.keyGenerator ?? defaultKeyGenerator,
110
147
  maxBlocks: config.maxBlocks,
111
148
  readOnly: config.readOnly,
112
- schema: config.schemaDefinition
113
- ? compileSchemaDefinition(config.schemaDefinition)
114
- : createEditorSchema(
115
- config.schema.hasOwnProperty('jsonType')
116
- ? config.schema
117
- : compileType(config.schema),
118
- ),
149
+ schema: config.schema,
119
150
  initialValue: config.initialValue,
120
151
  } as const
121
152
  }
122
153
 
123
154
  function createInternalEditorFromActor(
124
155
  editorActor: EditorActor,
156
+ legacySchema: PortableTextMemberSchemaTypes,
125
157
  ): InternalEditor {
126
158
  const slateEditor = createSlateEditor({editorActor})
127
159
  const editable = createEditableAPI(slateEditor.instance, editorActor)
@@ -208,6 +240,7 @@ function createInternalEditorFromActor(
208
240
  _internal: {
209
241
  editable,
210
242
  editorActor,
243
+ legacySchema,
211
244
  slateEditor,
212
245
  },
213
246
  }