@portabletext/editor 2.3.0 → 2.3.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 (32) hide show
  1. package/lib/_chunks-dts/behavior.types.action.d.ts +122 -122
  2. package/lib/index.cjs +162 -2
  3. package/lib/index.cjs.map +1 -1
  4. package/lib/index.js +164 -4
  5. package/lib/index.js.map +1 -1
  6. package/lib/plugins/index.d.ts +3 -3
  7. package/lib/utils/index.d.cts +2 -2
  8. package/lib/utils/index.d.ts +2 -2
  9. package/package.json +1 -1
  10. package/src/behaviors/behavior.core.lists.ts +149 -1
  11. package/src/behaviors/behavior.core.ts +1 -0
  12. package/src/converters/converter.text-plain.test.ts +7 -5
  13. package/src/editor/__tests__/PortableTextEditor.test.tsx +5 -14
  14. package/src/editor/__tests__/PortableTextEditorTester.tsx +23 -77
  15. package/src/editor/__tests__/RangeDecorations.test.tsx +2 -9
  16. package/src/editor/__tests__/insert-block.test.tsx +7 -28
  17. package/src/editor/__tests__/self-solving.test.tsx +5 -17
  18. package/src/editor/create-editor.ts +4 -1
  19. package/src/editor/editor-schema.ts +36 -3
  20. package/src/editor/plugins/__tests__/withEditableAPIDelete.test.tsx +8 -15
  21. package/src/editor/plugins/__tests__/withEditableAPIGetFragment.test.tsx +7 -11
  22. package/src/editor/plugins/__tests__/withEditableAPIInsert.test.tsx +81 -63
  23. package/src/editor/plugins/__tests__/withEditableAPISelectionsOverlapping.test.tsx +2 -9
  24. package/src/editor/plugins/__tests__/withPortableTextLists.test.tsx +3 -7
  25. package/src/editor/plugins/__tests__/withPortableTextMarkModel.test.tsx +17 -27
  26. package/src/editor/plugins/__tests__/withPortableTextSelections.test.tsx +3 -7
  27. package/src/editor/plugins/__tests__/withUndoRedo.test.tsx +4 -9
  28. package/src/internal-utils/__tests__/valueNormalization.test.tsx +3 -7
  29. package/src/internal-utils/__tests__/values.test.ts +5 -6
  30. package/src/internal-utils/operation-to-patches.test.ts +17 -12
  31. package/src/plugins/plugin.internal.portable-text-editor-ref.tsx +16 -0
  32. package/src/editor/__tests__/sync-value.test.tsx +0 -154
@@ -1,5 +1,5 @@
1
1
  import { Behavior, Editor, EditorEmittedEvent, EditorSchema } from "../_chunks-dts/behavior.types.action.js";
2
- import * as react22 from "react";
2
+ import * as react12 from "react";
3
3
  import React from "react";
4
4
  /**
5
5
  * @beta
@@ -181,7 +181,7 @@ type MarkdownPluginConfig = MarkdownBehaviorsConfig & {
181
181
  */
182
182
  declare function MarkdownPlugin(props: {
183
183
  config: MarkdownPluginConfig;
184
- }): react22.JSX.Element;
184
+ }): react12.JSX.Element;
185
185
  /**
186
186
  * @beta
187
187
  * Restrict the editor to one line. The plugin takes care of blocking
@@ -192,5 +192,5 @@ declare function MarkdownPlugin(props: {
192
192
  *
193
193
  * @deprecated Install the plugin from `@portabletext/plugin-one-line`
194
194
  */
195
- declare function OneLinePlugin(): react22.JSX.Element;
195
+ declare function OneLinePlugin(): react12.JSX.Element;
196
196
  export { BehaviorPlugin, DecoratorShortcutPlugin, EditorRefPlugin, EventListenerPlugin, MarkdownPlugin, type MarkdownPluginConfig, OneLinePlugin };
@@ -1,5 +1,5 @@
1
1
  import { BlockOffset, BlockPath, ChildPath, EditorContext, EditorSelection, EditorSelectionPoint } from "../_chunks-dts/behavior.types.action.cjs";
2
- import * as _sanity_types9 from "@sanity/types";
2
+ import * as _sanity_types8 from "@sanity/types";
3
3
  import { KeyedSegment, PortableTextBlock, PortableTextChild, PortableTextSpan, PortableTextTextBlock } from "@sanity/types";
4
4
  /**
5
5
  * @public
@@ -150,7 +150,7 @@ declare function mergeTextBlocks({
150
150
  context: Pick<EditorContext, 'keyGenerator' | 'schema'>;
151
151
  targetBlock: PortableTextTextBlock;
152
152
  incomingBlock: PortableTextTextBlock;
153
- }): PortableTextTextBlock<_sanity_types9.PortableTextObject | _sanity_types9.PortableTextSpan>;
153
+ }): PortableTextTextBlock<_sanity_types8.PortableTextObject | _sanity_types8.PortableTextSpan>;
154
154
  /**
155
155
  * @public
156
156
  */
@@ -1,5 +1,5 @@
1
1
  import { BlockOffset, BlockPath, ChildPath, EditorContext, EditorSelection, EditorSelectionPoint } from "../_chunks-dts/behavior.types.action.js";
2
- import * as _sanity_types9 from "@sanity/types";
2
+ import * as _sanity_types6 from "@sanity/types";
3
3
  import { KeyedSegment, PortableTextBlock, PortableTextChild, PortableTextSpan, PortableTextTextBlock } from "@sanity/types";
4
4
  /**
5
5
  * @public
@@ -150,7 +150,7 @@ declare function mergeTextBlocks({
150
150
  context: Pick<EditorContext, 'keyGenerator' | 'schema'>;
151
151
  targetBlock: PortableTextTextBlock;
152
152
  incomingBlock: PortableTextTextBlock;
153
- }): PortableTextTextBlock<_sanity_types9.PortableTextObject | _sanity_types9.PortableTextSpan>;
153
+ }): PortableTextTextBlock<_sanity_types6.PortableTextSpan | _sanity_types6.PortableTextObject>;
154
154
  /**
155
155
  * @public
156
156
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@portabletext/editor",
3
- "version": "2.3.0",
3
+ "version": "2.3.2",
4
4
  "description": "Portable Text Editor made in React",
5
5
  "keywords": [
6
6
  "sanity",
@@ -1,9 +1,14 @@
1
1
  import {isListBlock, isTextBlock} from '../internal-utils/parse-blocks'
2
2
  import {defaultKeyboardShortcuts} from '../keyboard-shortcuts/default-keyboard-shortcuts'
3
3
  import * as selectors from '../selectors'
4
- import {getBlockEndPoint} from '../utils'
4
+ import {
5
+ getBlockEndPoint,
6
+ getBlockStartPoint,
7
+ isEqualSelectionPoints,
8
+ } from '../utils'
5
9
  import {isAtTheBeginningOfBlock} from '../utils/util.at-the-beginning-of-block'
6
10
  import {isEmptyTextBlock} from '../utils/util.is-empty-text-block'
11
+ import {sliceTextBlock} from '../utils/util.slice-text-block'
7
12
  import {raise} from './behavior.types.action'
8
13
  import {defineBehavior} from './behavior.types.behavior'
9
14
 
@@ -183,6 +188,148 @@ const mergeTextIntoListOnBackspace = defineBehavior({
183
188
  ],
184
189
  })
185
190
 
191
+ /**
192
+ * When performing a delete operation where the start point of the operation is
193
+ * at the start of a list item and the end point of the operation is in another
194
+ * list item, we make sure the preserve the first list item. Otherwise, the
195
+ * default behavior would be to preserve the last item.
196
+ */
197
+ const deletingListFromStart = defineBehavior({
198
+ on: 'delete',
199
+ guard: ({snapshot, event}) => {
200
+ const blocksToDelete = selectors.getSelectedBlocks({
201
+ ...snapshot,
202
+ context: {
203
+ ...snapshot.context,
204
+ selection: event.at,
205
+ },
206
+ })
207
+
208
+ if (blocksToDelete.length < 2) {
209
+ return false
210
+ }
211
+
212
+ const startBlock = blocksToDelete.at(0)?.node
213
+ const middleBlocks = blocksToDelete.slice(1, -1)
214
+ const endBlock = blocksToDelete.at(-1)?.node
215
+
216
+ if (
217
+ !isListBlock(snapshot.context, startBlock) ||
218
+ !isListBlock(snapshot.context, endBlock)
219
+ ) {
220
+ // It's that any block in between isn't a list item, but the first and
221
+ // last blocks have to be list items for this Behavior to take effect.
222
+ return false
223
+ }
224
+
225
+ const deleteStartPoint = selectors.getSelectionStartPoint({
226
+ ...snapshot,
227
+ context: {
228
+ ...snapshot.context,
229
+ selection: event.at,
230
+ },
231
+ })
232
+ const deleteEndPoint = selectors.getSelectionEndPoint({
233
+ ...snapshot,
234
+ context: {
235
+ ...snapshot.context,
236
+ selection: event.at,
237
+ },
238
+ })
239
+
240
+ if (!deleteStartPoint || !deleteEndPoint) {
241
+ return false
242
+ }
243
+
244
+ const startBlockStartPoint = getBlockStartPoint({
245
+ context: snapshot.context,
246
+ block: {
247
+ node: startBlock,
248
+ path: [{_key: startBlock._key}],
249
+ },
250
+ })
251
+
252
+ if (!isEqualSelectionPoints(deleteStartPoint, startBlockStartPoint)) {
253
+ // If we aren't deleting from the beginning of the first list item, then
254
+ // there is no need to proceed. The default delete Behavior will suffice.
255
+ return false
256
+ }
257
+
258
+ const startBlockEndPoint = getBlockEndPoint({
259
+ context: snapshot.context,
260
+ block: {
261
+ node: startBlock,
262
+ path: [{_key: startBlock._key}],
263
+ },
264
+ })
265
+ const endBlockEndPoint = getBlockEndPoint({
266
+ context: snapshot.context,
267
+ block: {
268
+ node: endBlock,
269
+ path: [{_key: endBlock._key}],
270
+ },
271
+ })
272
+ const slicedEndBlock = sliceTextBlock({
273
+ context: {
274
+ schema: snapshot.context.schema,
275
+ selection: {
276
+ anchor: deleteEndPoint,
277
+ focus: endBlockEndPoint,
278
+ },
279
+ },
280
+ block: endBlock,
281
+ })
282
+
283
+ return {
284
+ startBlockStartPoint,
285
+ startBlockEndPoint,
286
+ middleBlocks,
287
+ endBlock,
288
+ slicedEndBlock,
289
+ }
290
+ },
291
+ actions: [
292
+ (
293
+ _,
294
+ {
295
+ startBlockStartPoint,
296
+ startBlockEndPoint,
297
+ middleBlocks,
298
+ endBlock,
299
+ slicedEndBlock,
300
+ },
301
+ ) => [
302
+ // All block in between can safely be deleted.
303
+ ...middleBlocks.map((block) =>
304
+ raise({type: 'delete.block', at: block.path}),
305
+ ),
306
+ // The last block is deleted as well.
307
+ raise({type: 'delete.block', at: [{_key: endBlock._key}]}),
308
+ // But in case the delete operation didn't reach all the way to the end
309
+ // of it, we first place the caret at the end of the start block...
310
+ raise({
311
+ type: 'select',
312
+ at: {
313
+ anchor: startBlockEndPoint,
314
+ focus: startBlockEndPoint,
315
+ },
316
+ }),
317
+ // ...and insert the rest of the end block at the end of it.
318
+ raise({
319
+ type: 'insert.block',
320
+ block: slicedEndBlock,
321
+ placement: 'auto',
322
+ select: 'none',
323
+ }),
324
+ // And finally, we delete the original text of the start block.
325
+ raise({
326
+ type: 'delete',
327
+ at: {anchor: startBlockStartPoint, focus: startBlockEndPoint},
328
+ }),
329
+ ],
330
+ ],
331
+ })
332
+
186
333
  /**
187
334
  * Hitting Enter in an empty list item would create a new list item below by
188
335
  * default. Instead, the list properties should be cleared.
@@ -521,6 +668,7 @@ export const coreListBehaviors = {
521
668
  unindentListOnBackspace,
522
669
  mergeTextIntoListOnDelete,
523
670
  mergeTextIntoListOnBackspace,
671
+ deletingListFromStart,
524
672
  clearListOnEnter,
525
673
  indentListOnTab,
526
674
  unindentListOnShiftTab,
@@ -24,6 +24,7 @@ export const coreBehaviorsConfig = [
24
24
  coreListBehaviors.unindentListOnBackspace,
25
25
  coreListBehaviors.mergeTextIntoListOnDelete,
26
26
  coreListBehaviors.mergeTextIntoListOnBackspace,
27
+ coreListBehaviors.deletingListFromStart,
27
28
  coreListBehaviors.clearListOnEnter,
28
29
  coreListBehaviors.indentListOnTab,
29
30
  coreListBehaviors.unindentListOnShiftTab,
@@ -1,11 +1,13 @@
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'
5
- import {compileSchemaDefinition} from '../editor/editor-schema'
6
- import {defineSchema} from '../editor/editor-schema-definition'
4
+ import {schemaDefinition} from '../editor/__tests__/PortableTextEditorTester'
5
+ import {
6
+ compileSchemaDefinition,
7
+ compileSchemaDefinitionToLegacySchema,
8
+ } from '../editor/editor-schema'
7
9
  import type {SchemaDefinition} from '../editor/editor-schema-definition'
8
- import {createLegacySchema} from '../editor/legacy-schema'
10
+ import {defineSchema} from '../editor/editor-schema-definition'
9
11
  import {createTestSnapshot} from '../internal-utils/create-test-snapshot'
10
12
  import {createConverterTextPlain} from './converter.text-plain'
11
13
 
@@ -82,7 +84,7 @@ function createSnapshot({
82
84
  }
83
85
 
84
86
  const converterTextPlain = createConverterTextPlain(
85
- createLegacySchema(schemaType),
87
+ compileSchemaDefinitionToLegacySchema(schemaDefinition),
86
88
  )
87
89
 
88
90
  test(converterTextPlain.serialize.name, () => {
@@ -5,11 +5,11 @@ import {describe, expect, it, vi} from 'vitest'
5
5
  import type {EditorSelection} from '../..'
6
6
  import {createTestKeyGenerator} from '../../internal-utils/test-key-generator'
7
7
  import {PortableTextEditor} from '../PortableTextEditor'
8
- import {PortableTextEditorTester, schemaType} from './PortableTextEditorTester'
8
+ import {PortableTextEditorTester} from './PortableTextEditorTester'
9
9
 
10
10
  const helloBlock: PortableTextBlock = {
11
11
  _key: '123',
12
- _type: 'myTestBlockType',
12
+ _type: 'block',
13
13
  markDefs: [],
14
14
  children: [{_key: '567', _type: 'span', text: 'Hello', marks: []}],
15
15
  }
@@ -26,7 +26,6 @@ describe('initialization', () => {
26
26
  onChange={onChange}
27
27
  renderPlaceholder={renderPlaceholder}
28
28
  ref={editorRef}
29
- schemaType={schemaType}
30
29
  value={undefined}
31
30
  />,
32
31
  )
@@ -54,7 +53,7 @@ describe('initialization', () => {
54
53
  <div
55
54
  class="pt-block pt-text-block pt-text-block-style-normal"
56
55
  data-block-key="k0"
57
- data-block-name="myTestBlockType"
56
+ data-block-name="block"
58
57
  data-block-type="text"
59
58
  data-slate-node="element"
60
59
  data-style="normal"
@@ -100,7 +99,6 @@ describe('initialization', () => {
100
99
  keyGenerator={createTestKeyGenerator()}
101
100
  ref={editorRef}
102
101
  onChange={onChange}
103
- schemaType={schemaType}
104
102
  value={initialValue}
105
103
  />,
106
104
  )
@@ -133,7 +131,6 @@ describe('initialization', () => {
133
131
  onChange={onChange}
134
132
  ref={editorRef}
135
133
  selection={initialSelection}
136
- schemaType={schemaType}
137
134
  value={initialValue}
138
135
  />,
139
136
  )
@@ -178,7 +175,6 @@ describe('initialization', () => {
178
175
  onChange={onChange}
179
176
  ref={editorRef}
180
177
  selection={initialSelection}
181
- schemaType={schemaType}
182
178
  value={initialValue}
183
179
  />,
184
180
  )
@@ -212,7 +208,6 @@ describe('initialization', () => {
212
208
  onChange={onChange}
213
209
  ref={editorRef}
214
210
  selection={newSelection}
215
- schemaType={schemaType}
216
211
  value={initialValue}
217
212
  />,
218
213
  )
@@ -239,7 +234,6 @@ describe('initialization', () => {
239
234
  onChange={onChange}
240
235
  ref={editorRef}
241
236
  selection={initialSelection}
242
- schemaType={schemaType}
243
237
  value={initialValue}
244
238
  />,
245
239
  )
@@ -285,7 +279,6 @@ describe('initialization', () => {
285
279
  onChange={onChange}
286
280
  ref={editorRef}
287
281
  selection={initialSelection}
288
- schemaType={schemaType}
289
282
  value={value}
290
283
  />,
291
284
  )
@@ -318,7 +311,6 @@ describe('initialization', () => {
318
311
  onChange={newOnChange}
319
312
  ref={editorRef}
320
313
  selection={initialSelection}
321
- schemaType={schemaType}
322
314
  value={value}
323
315
  />,
324
316
  )
@@ -355,7 +347,7 @@ describe('initialization', () => {
355
347
  helloBlock,
356
348
  {
357
349
  _key: 'abc',
358
- _type: 'myTestBlockType',
350
+ _type: 'block',
359
351
  markDefs: [],
360
352
  children: [{_key: 'def', _type: 'span', marks: []}],
361
353
  },
@@ -371,7 +363,6 @@ describe('initialization', () => {
371
363
  onChange={onChange}
372
364
  ref={editorRef}
373
365
  selection={initialSelection}
374
- schemaType={schemaType}
375
366
  value={initialValue}
376
367
  />,
377
368
  )
@@ -396,7 +387,7 @@ describe('initialization', () => {
396
387
  },
397
388
  item: {
398
389
  _key: 'abc',
399
- _type: 'myTestBlockType',
390
+ _type: 'block',
400
391
  children: [
401
392
  {
402
393
  _key: 'def',
@@ -1,86 +1,34 @@
1
- import {Schema} from '@sanity/schema'
2
- import {defineArrayMember, defineField} from '@sanity/types'
3
1
  import {forwardRef, useMemo, type ForwardedRef} from 'react'
4
2
  import {vi} from 'vitest'
5
3
  import {
4
+ defineSchema,
5
+ EditorProvider,
6
6
  PortableTextEditable,
7
- PortableTextEditor,
8
7
  type PortableTextEditableProps,
8
+ type PortableTextEditor,
9
9
  type PortableTextEditorProps,
10
+ type SchemaDefinition,
10
11
  } from '../../index'
12
+ import {InternalChange$Plugin} from '../../plugins/plugin.internal.change-ref'
13
+ import {InternalPortableTextEditorRefPlugin} from '../../plugins/plugin.internal.portable-text-editor-ref'
11
14
 
12
- const imageType = defineField({
13
- name: 'custom image',
14
- type: 'object',
15
- fields: [],
16
- })
17
-
18
- const someObject = defineField({
19
- type: 'object',
20
- name: 'someObject',
21
- fields: [{type: 'string', name: 'color'}],
22
- })
23
-
24
- const blockType = defineField({
25
- type: 'block',
26
- name: 'myTestBlockType',
27
- styles: [
28
- {title: 'Normal', value: 'normal'},
29
- {title: 'H1', value: 'h1'},
30
- {title: 'H2', value: 'h2'},
31
- {title: 'H3', value: 'h3'},
32
- {title: 'H4', value: 'h4'},
33
- {title: 'H5', value: 'h5'},
34
- {title: 'H6', value: 'h6'},
35
- {title: 'Quote', value: 'blockquote'},
15
+ export const schemaDefinition = defineSchema({
16
+ decorators: [{name: 'strong'}],
17
+ blockObjects: [
18
+ {name: 'custom image', fields: [{name: 'src', type: 'string'}]},
36
19
  ],
37
- of: [someObject, imageType],
38
- })
39
-
40
- const portableTextType = defineArrayMember({
41
- type: 'array',
42
- name: 'body',
43
- of: [blockType, someObject],
44
- })
45
-
46
- const colorAndLink = defineArrayMember({
47
- type: 'array',
48
- name: 'colorAndLink',
49
- of: [
50
- {
51
- ...blockType,
52
- marks: {
53
- annotations: [
54
- {
55
- name: 'link',
56
- type: 'object',
57
- fields: [{type: 'string', name: 'color'}],
58
- },
59
- {
60
- name: 'color',
61
- type: 'object',
62
- fields: [{type: 'string', name: 'color'}],
63
- },
64
- ],
65
- },
66
- },
20
+ inlineObjects: [
21
+ {name: 'someObject', fields: [{name: 'color', type: 'string'}]},
67
22
  ],
68
23
  })
69
24
 
70
- const schema = Schema.compile({
71
- name: 'test',
72
- types: [portableTextType, colorAndLink, imageType],
73
- })
74
-
75
25
  export const PortableTextEditorTester = forwardRef(
76
26
  function PortableTextEditorTester(
77
- props: Partial<
78
- Omit<PortableTextEditorProps, 'type' | 'onChange' | 'value'>
79
- > & {
27
+ props: {
80
28
  onChange?: PortableTextEditorProps['onChange']
81
29
  rangeDecorations?: PortableTextEditableProps['rangeDecorations']
82
30
  renderPlaceholder?: PortableTextEditableProps['renderPlaceholder']
83
- schemaType: PortableTextEditorProps['schemaType']
31
+ schemaDefinition?: SchemaDefinition
84
32
  selection?: PortableTextEditableProps['selection']
85
33
  value?: PortableTextEditorProps['value']
86
34
  keyGenerator: PortableTextEditorProps['keyGenerator']
@@ -89,24 +37,22 @@ export const PortableTextEditorTester = forwardRef(
89
37
  ) {
90
38
  const onChange = useMemo(() => props.onChange || vi.fn(), [props.onChange])
91
39
  return (
92
- <PortableTextEditor
93
- schemaType={props.schemaType}
94
- onChange={onChange}
95
- value={props.value || undefined}
96
- keyGenerator={props.keyGenerator}
97
- ref={ref}
40
+ <EditorProvider
41
+ initialConfig={{
42
+ schemaDefinition: props.schemaDefinition ?? schemaDefinition,
43
+ keyGenerator: props.keyGenerator,
44
+ initialValue: props.value,
45
+ }}
98
46
  >
47
+ <InternalChange$Plugin onChange={onChange} />
48
+ <InternalPortableTextEditorRefPlugin ref={ref} />
99
49
  <PortableTextEditable
100
50
  selection={props.selection || undefined}
101
51
  rangeDecorations={props.rangeDecorations}
102
52
  renderPlaceholder={props.renderPlaceholder}
103
53
  aria-describedby="desc_foo"
104
54
  />
105
- </PortableTextEditor>
55
+ </EditorProvider>
106
56
  )
107
57
  },
108
58
  )
109
-
110
- export const schemaType = schema.get('body')
111
-
112
- export const schemaTypeWithColorAndLink = schema.get('colorAndLink')
@@ -5,11 +5,11 @@ import {describe, expect, it, vi} from 'vitest'
5
5
  import type {RangeDecoration} from '../..'
6
6
  import {createTestKeyGenerator} from '../../internal-utils/test-key-generator'
7
7
  import type {PortableTextEditor} from '../PortableTextEditor'
8
- import {PortableTextEditorTester, schemaType} from './PortableTextEditorTester'
8
+ import {PortableTextEditorTester} from './PortableTextEditorTester'
9
9
 
10
10
  const helloBlock: PortableTextBlock = {
11
11
  _key: '123',
12
- _type: 'myTestBlockType',
12
+ _type: 'block',
13
13
  markDefs: [],
14
14
  children: [{_key: '567', _type: 'span', text: 'Hello', marks: []}],
15
15
  }
@@ -44,7 +44,6 @@ describe('RangeDecorations', () => {
44
44
  onChange={onChange}
45
45
  rangeDecorations={rangeDecorations}
46
46
  ref={editorRef}
47
- schemaType={schemaType}
48
47
  value={value}
49
48
  />,
50
49
  ),
@@ -71,7 +70,6 @@ describe('RangeDecorations', () => {
71
70
  onChange={onChange}
72
71
  rangeDecorations={rangeDecorations}
73
72
  ref={editorRef}
74
- schemaType={schemaType}
75
73
  value={value}
76
74
  />,
77
75
  )
@@ -95,7 +93,6 @@ describe('RangeDecorations', () => {
95
93
  onChange={onChange}
96
94
  rangeDecorations={rangeDecorations}
97
95
  ref={editorRef}
98
- schemaType={schemaType}
99
96
  value={value}
100
97
  />,
101
98
  )
@@ -122,7 +119,6 @@ describe('RangeDecorations', () => {
122
119
  onChange={onChange}
123
120
  rangeDecorations={rangeDecorations}
124
121
  ref={editorRef}
125
- schemaType={schemaType}
126
122
  value={value}
127
123
  />,
128
124
  )
@@ -150,7 +146,6 @@ describe('RangeDecorations', () => {
150
146
  onChange={onChange}
151
147
  rangeDecorations={rangeDecorations}
152
148
  ref={editorRef}
153
- schemaType={schemaType}
154
149
  value={value}
155
150
  />,
156
151
  )
@@ -178,7 +173,6 @@ describe('RangeDecorations', () => {
178
173
  onChange={onChange}
179
174
  rangeDecorations={rangeDecorations}
180
175
  ref={editorRef}
181
- schemaType={schemaType}
182
176
  value={value}
183
177
  />,
184
178
  )
@@ -206,7 +200,6 @@ describe('RangeDecorations', () => {
206
200
  onChange={onChange}
207
201
  rangeDecorations={rangeDecorations}
208
202
  ref={editorRef}
209
- schemaType={schemaType}
210
203
  value={value}
211
204
  />,
212
205
  )
@@ -1,22 +1,10 @@
1
- import {Schema} from '@sanity/schema'
2
1
  import type {PortableTextBlock} from '@sanity/types'
3
2
  import {render, waitFor} from '@testing-library/react'
4
3
  import {createRef, type RefObject} from 'react'
5
4
  import {describe, expect, test, vi} from 'vitest'
6
5
  import type {EditorChange, EditorSelection} from '../../types/editor'
7
- import {PortableTextEditable} from '../Editable'
8
6
  import {PortableTextEditor} from '../PortableTextEditor'
9
-
10
- const schema = Schema.compile({
11
- types: [
12
- {
13
- name: 'portable-text',
14
- type: 'array',
15
- of: [{type: 'block'}, {type: 'custom image'}],
16
- },
17
- {name: 'custom image', type: 'object'},
18
- ],
19
- }).get('portable-text')
7
+ import {PortableTextEditorTester} from './PortableTextEditorTester'
20
8
 
21
9
  describe(PortableTextEditor.insertBlock.name, () => {
22
10
  test('Scenario: Inserting a custom block without a selection #1', async () => {
@@ -38,15 +26,12 @@ describe(PortableTextEditor.insertBlock.name, () => {
38
26
  const onChange: (change: EditorChange) => void = vi.fn()
39
27
 
40
28
  render(
41
- <PortableTextEditor
29
+ <PortableTextEditorTester
42
30
  ref={editorRef}
43
- schemaType={schema}
44
31
  value={initialValue}
45
32
  keyGenerator={() => 'bb'}
46
33
  onChange={onChange}
47
- >
48
- <PortableTextEditable />
49
- </PortableTextEditor>,
34
+ />,
50
35
  )
51
36
 
52
37
  // Given an empty text block
@@ -107,15 +92,12 @@ describe(PortableTextEditor.insertBlock.name, () => {
107
92
  const onChange: (change: EditorChange) => void = vi.fn()
108
93
 
109
94
  render(
110
- <PortableTextEditor
95
+ <PortableTextEditorTester
111
96
  ref={editorRef}
112
- schemaType={schema}
113
97
  value={initialValue}
114
98
  keyGenerator={() => 'bb'}
115
99
  onChange={onChange}
116
- >
117
- <PortableTextEditable />
118
- </PortableTextEditor>,
100
+ />,
119
101
  )
120
102
 
121
103
  // Given an non-empty text block
@@ -180,15 +162,12 @@ describe(PortableTextEditor.insertBlock.name, () => {
180
162
  const onChange: (change: EditorChange) => void = vi.fn()
181
163
 
182
164
  render(
183
- <PortableTextEditor
165
+ <PortableTextEditorTester
184
166
  ref={editorRef}
185
- schemaType={schema}
186
167
  value={initialValue}
187
168
  keyGenerator={() => 'bc'}
188
169
  onChange={onChange}
189
- >
190
- <PortableTextEditable />
191
- </PortableTextEditor>,
170
+ />,
192
171
  )
193
172
 
194
173
  // Given an empty text block followed by an image