@portabletext/editor 2.7.2 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs +3 -1
  2. package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs.map +1 -1
  3. package/lib/_chunks-cjs/util.slice-blocks.cjs +60 -6
  4. package/lib/_chunks-cjs/util.slice-blocks.cjs.map +1 -1
  5. package/lib/_chunks-dts/behavior.types.action.d.cts +95 -95
  6. package/lib/_chunks-dts/behavior.types.action.d.ts +95 -95
  7. package/lib/_chunks-es/selector.is-selecting-entire-blocks.js +4 -2
  8. package/lib/_chunks-es/selector.is-selecting-entire-blocks.js.map +1 -1
  9. package/lib/_chunks-es/util.slice-blocks.js +56 -5
  10. package/lib/_chunks-es/util.slice-blocks.js.map +1 -1
  11. package/lib/index.cjs +94 -121
  12. package/lib/index.cjs.map +1 -1
  13. package/lib/index.js +90 -118
  14. package/lib/index.js.map +1 -1
  15. package/lib/plugins/index.d.cts +3 -3
  16. package/lib/plugins/index.d.ts +3 -3
  17. package/lib/selectors/index.d.cts +13 -3
  18. package/lib/selectors/index.d.ts +13 -3
  19. package/lib/utils/index.d.ts +2 -2
  20. package/package.json +13 -14
  21. package/src/behaviors/behavior.abstract.insert.ts +58 -1
  22. package/src/behaviors/behavior.core.annotations.ts +24 -2
  23. package/src/behaviors/behavior.core.ts +1 -1
  24. package/src/behaviors/behavior.types.event.ts +18 -18
  25. package/src/converters/converter.text-html.serialize.test.ts +27 -17
  26. package/src/converters/converter.text-plain.test.ts +1 -1
  27. package/src/editor/plugins/createWithEditableAPI.ts +16 -0
  28. package/src/internal-utils/parse-blocks.ts +2 -1
  29. package/src/operations/behavior.operation.annotation.add.ts +1 -12
  30. package/src/operations/behavior.operations.ts +0 -18
  31. package/src/selectors/selector.is-active-annotation.test.ts +320 -0
  32. package/src/selectors/selector.is-active-annotation.ts +24 -0
  33. package/src/utils/util.slice-blocks.test.ts +39 -5
  34. package/src/utils/util.slice-blocks.ts +36 -3
  35. package/src/editor/__tests__/PortableTextEditor.test.tsx +0 -430
  36. package/src/editor/__tests__/PortableTextEditorTester.tsx +0 -58
  37. package/src/editor/__tests__/RangeDecorations.test.tsx +0 -213
  38. package/src/editor/__tests__/insert-block.test.tsx +0 -224
  39. package/src/editor/__tests__/self-solving.test.tsx +0 -183
  40. package/src/editor/plugins/__tests__/withEditableAPIDelete.test.tsx +0 -298
  41. package/src/editor/plugins/__tests__/withEditableAPIGetFragment.test.tsx +0 -177
  42. package/src/editor/plugins/__tests__/withEditableAPIInsert.test.tsx +0 -538
  43. package/src/editor/plugins/__tests__/withEditableAPISelectionsOverlapping.test.tsx +0 -162
  44. package/src/editor/plugins/__tests__/withPortableTextLists.test.tsx +0 -65
  45. package/src/editor/plugins/__tests__/withPortableTextMarkModel.test.tsx +0 -612
  46. package/src/editor/plugins/__tests__/withPortableTextSelections.test.tsx +0 -103
  47. package/src/editor/plugins/__tests__/withUndoRedo.test.tsx +0 -147
  48. package/src/internal-utils/__tests__/valueNormalization.test.tsx +0 -79
  49. package/src/operations/behavior.operation.insert-inline-object.ts +0 -59
  50. package/src/operations/behavior.operation.insert-span.ts +0 -48
@@ -1,430 +0,0 @@
1
- import {createTestKeyGenerator} from '@portabletext/test'
2
- import type {PortableTextBlock} from '@sanity/types'
3
- import {render, waitFor} from '@testing-library/react'
4
- import {createRef, type RefObject} from 'react'
5
- import {describe, expect, it, vi} from 'vitest'
6
- import type {EditorSelection} from '../..'
7
- import {PortableTextEditor} from '../PortableTextEditor'
8
- import {PortableTextEditorTester} from './PortableTextEditorTester'
9
-
10
- const helloBlock: PortableTextBlock = {
11
- _key: '123',
12
- _type: 'block',
13
- markDefs: [],
14
- children: [{_key: '567', _type: 'span', text: 'Hello', marks: []}],
15
- }
16
-
17
- const renderPlaceholder = () => 'Jot something down here'
18
-
19
- describe('initialization', () => {
20
- it('receives initial onChange events and has custom placeholder', async () => {
21
- const editorRef: RefObject<PortableTextEditor | null> = createRef()
22
- const onChange = vi.fn()
23
- const {container} = render(
24
- <PortableTextEditorTester
25
- keyGenerator={createTestKeyGenerator()}
26
- onChange={onChange}
27
- renderPlaceholder={renderPlaceholder}
28
- ref={editorRef}
29
- value={undefined}
30
- />,
31
- )
32
-
33
- await waitFor(() => {
34
- expect(editorRef.current).not.toBe(null)
35
- expect(onChange).toHaveBeenCalledWith({type: 'ready'})
36
- expect(container).toMatchInlineSnapshot(`
37
- <div>
38
- <div
39
- aria-describedby="desc_foo"
40
- aria-multiline="true"
41
- autocapitalize="false"
42
- autocorrect="false"
43
- class="pt-editable"
44
- contenteditable="true"
45
- data-read-only="false"
46
- data-slate-editor="true"
47
- data-slate-node="value"
48
- role="textbox"
49
- spellcheck="false"
50
- style="position: relative; white-space: pre-wrap; word-wrap: break-word;"
51
- zindex="-1"
52
- >
53
- <div
54
- class="pt-block pt-text-block pt-text-block-style-normal"
55
- data-block-key="k0"
56
- data-block-name="block"
57
- data-block-type="text"
58
- data-slate-node="element"
59
- data-style="normal"
60
- >
61
- <div>
62
- <span
63
- data-child-key="k1"
64
- data-child-name="span"
65
- data-child-type="span"
66
- data-slate-node="text"
67
- >
68
- <span
69
- contenteditable="false"
70
- style="position: absolute; user-select: none; pointer-events: none; left: 0px; right: 0px;"
71
- >
72
- Jot something down here
73
- </span>
74
- <span
75
- data-slate-leaf="true"
76
- >
77
- <span
78
- data-slate-length="0"
79
- data-slate-zero-width="n"
80
- >
81
- 
82
- <br />
83
- </span>
84
- </span>
85
- </span>
86
- </div>
87
- </div>
88
- </div>
89
- </div>
90
- `)
91
- })
92
- })
93
- it('takes value from props and confirms it by emitting value change event', async () => {
94
- const initialValue = [helloBlock]
95
- const onChange = vi.fn()
96
- const editorRef = createRef<PortableTextEditor>()
97
- render(
98
- <PortableTextEditorTester
99
- keyGenerator={createTestKeyGenerator()}
100
- ref={editorRef}
101
- onChange={onChange}
102
- value={initialValue}
103
- />,
104
- )
105
- const normalizedEditorValue = [{...initialValue[0], style: 'normal'}]
106
- await waitFor(() => {
107
- expect(onChange).toHaveBeenCalledWith({
108
- type: 'value',
109
- value: initialValue,
110
- })
111
- })
112
- if (editorRef.current) {
113
- expect(PortableTextEditor.getValue(editorRef.current)).toStrictEqual(
114
- normalizedEditorValue,
115
- )
116
- }
117
- })
118
-
119
- it('takes initial selection from props', async () => {
120
- const editorRef: RefObject<PortableTextEditor | null> = createRef()
121
- const initialValue = [helloBlock]
122
- const initialSelection: EditorSelection = {
123
- anchor: {path: [{_key: '123'}, 'children', {_key: '567'}], offset: 2},
124
- focus: {path: [{_key: '123'}, 'children', {_key: '567'}], offset: 2},
125
- backward: false,
126
- }
127
- const onChange = vi.fn()
128
- render(
129
- <PortableTextEditorTester
130
- keyGenerator={createTestKeyGenerator()}
131
- onChange={onChange}
132
- ref={editorRef}
133
- selection={initialSelection}
134
- value={initialValue}
135
- />,
136
- )
137
-
138
- await waitFor(() => {
139
- if (editorRef.current) {
140
- expect(onChange).toHaveBeenCalledWith({
141
- type: 'value',
142
- value: initialValue,
143
- })
144
- expect(onChange).toHaveBeenCalledWith({type: 'ready'})
145
- }
146
- })
147
-
148
- await waitFor(() => {
149
- if (editorRef.current) {
150
- PortableTextEditor.focus(editorRef.current)
151
- expect(
152
- PortableTextEditor.getSelection(editorRef.current),
153
- ).toStrictEqual(initialSelection)
154
- }
155
- })
156
- })
157
-
158
- it('updates editor selection from new prop and keeps object equality in editor.getSelection()', async () => {
159
- const editorRef: RefObject<PortableTextEditor | null> = createRef()
160
- const initialValue = [helloBlock]
161
- const initialSelection: EditorSelection = {
162
- anchor: {path: [{_key: '123'}, 'children', {_key: '567'}], offset: 0},
163
- focus: {path: [{_key: '123'}, 'children', {_key: '567'}], offset: 0},
164
- backward: false,
165
- }
166
- const newSelection: EditorSelection = {
167
- anchor: {path: [{_key: '123'}, 'children', {_key: '567'}], offset: 0},
168
- focus: {path: [{_key: '123'}, 'children', {_key: '567'}], offset: 3},
169
- backward: false,
170
- }
171
- const onChange = vi.fn()
172
- const {rerender} = render(
173
- <PortableTextEditorTester
174
- keyGenerator={createTestKeyGenerator()}
175
- onChange={onChange}
176
- ref={editorRef}
177
- selection={initialSelection}
178
- value={initialValue}
179
- />,
180
- )
181
-
182
- await waitFor(() => {
183
- if (editorRef.current) {
184
- expect(onChange).toHaveBeenCalledWith({
185
- type: 'value',
186
- value: initialValue,
187
- })
188
- expect(onChange).toHaveBeenCalledWith({type: 'ready'})
189
- }
190
- })
191
-
192
- await waitFor(() => {
193
- if (editorRef.current) {
194
- const sel = PortableTextEditor.getSelection(editorRef.current)
195
- PortableTextEditor.focus(editorRef.current)
196
-
197
- // Test for object equality here!
198
- const anotherSel = PortableTextEditor.getSelection(editorRef.current)
199
- expect(
200
- PortableTextEditor.getSelection(editorRef.current),
201
- ).toStrictEqual(initialSelection)
202
- expect(sel).toBe(anotherSel)
203
- }
204
- })
205
- rerender(
206
- <PortableTextEditorTester
207
- keyGenerator={createTestKeyGenerator()}
208
- onChange={onChange}
209
- ref={editorRef}
210
- selection={newSelection}
211
- value={initialValue}
212
- />,
213
- )
214
- waitFor(() => {
215
- if (editorRef.current) {
216
- expect(PortableTextEditor.getSelection(editorRef.current)).toEqual(
217
- newSelection,
218
- )
219
- }
220
- })
221
- })
222
-
223
- it('handles empty array value', async () => {
224
- const editorRef: RefObject<PortableTextEditor | null> = createRef()
225
- const initialValue: PortableTextBlock[] = []
226
- const initialSelection: EditorSelection = {
227
- anchor: {path: [{_key: '123'}, 'children', {_key: '567'}], offset: 2},
228
- focus: {path: [{_key: '123'}, 'children', {_key: '567'}], offset: 2},
229
- }
230
- const onChange = vi.fn()
231
- render(
232
- <PortableTextEditorTester
233
- keyGenerator={createTestKeyGenerator()}
234
- onChange={onChange}
235
- ref={editorRef}
236
- selection={initialSelection}
237
- value={initialValue}
238
- />,
239
- )
240
- await waitFor(() => {
241
- if (editorRef.current) {
242
- expect(onChange).not.toHaveBeenCalledWith({
243
- type: 'invalidValue',
244
- value: initialValue,
245
- resolution: {
246
- action: 'Unset the value',
247
- description:
248
- 'Editor value must be an array of Portable Text blocks, or undefined.',
249
- item: initialValue,
250
- patches: [
251
- {
252
- path: [],
253
- type: 'unset',
254
- },
255
- ],
256
- },
257
- })
258
- expect(onChange).toHaveBeenCalledWith({
259
- type: 'value',
260
- value: initialValue,
261
- })
262
- expect(onChange).toHaveBeenCalledWith({type: 'ready'})
263
- }
264
- })
265
- })
266
- it('validates a non-initial value', async () => {
267
- const editorRef: RefObject<PortableTextEditor | null> = createRef()
268
- let value: PortableTextBlock[] = [helloBlock]
269
- const initialSelection: EditorSelection = {
270
- anchor: {path: [{_key: '123'}, 'children', {_key: '567'}], offset: 2},
271
- focus: {path: [{_key: '123'}, 'children', {_key: '567'}], offset: 2},
272
- }
273
- const onChange = vi.fn()
274
- let _rerender: any
275
- await waitFor(() => {
276
- render(
277
- <PortableTextEditorTester
278
- keyGenerator={createTestKeyGenerator()}
279
- onChange={onChange}
280
- ref={editorRef}
281
- selection={initialSelection}
282
- value={value}
283
- />,
284
- )
285
- _rerender = render
286
- })
287
- await waitFor(() => {
288
- expect(onChange).not.toHaveBeenCalledWith({
289
- type: 'invalidValue',
290
- value,
291
- resolution: {
292
- action: 'Unset the value',
293
- description:
294
- 'Editor value must be an array of Portable Text blocks, or undefined.',
295
- item: value,
296
- patches: [
297
- {
298
- path: [],
299
- type: 'unset',
300
- },
301
- ],
302
- },
303
- })
304
- expect(onChange).toHaveBeenCalledWith({type: 'value', value})
305
- })
306
- value = [{_type: 'banana', _key: '123'}]
307
- const newOnChange = vi.fn()
308
- _rerender(
309
- <PortableTextEditorTester
310
- keyGenerator={createTestKeyGenerator()}
311
- onChange={newOnChange}
312
- ref={editorRef}
313
- selection={initialSelection}
314
- value={value}
315
- />,
316
- )
317
- await waitFor(() => {
318
- expect(newOnChange).toHaveBeenCalledWith({
319
- type: 'invalidValue',
320
- value,
321
- resolution: {
322
- action: 'Remove the block',
323
- description: "Block with _key '123' has invalid _type 'banana'",
324
- item: value[0],
325
- patches: [
326
- {
327
- path: [{_key: '123'}],
328
- type: 'unset',
329
- },
330
- ],
331
- i18n: {
332
- action: 'inputs.portable-text.invalid-value.disallowed-type.action',
333
- description:
334
- 'inputs.portable-text.invalid-value.disallowed-type.description',
335
- values: {
336
- key: '123',
337
- typeName: 'banana',
338
- },
339
- },
340
- },
341
- })
342
- })
343
- })
344
- it("doesn't crash when containing a invalid block somewhere inside the content", async () => {
345
- const editorRef: RefObject<PortableTextEditor | null> = createRef()
346
- const initialValue: PortableTextBlock[] = [
347
- helloBlock,
348
- {
349
- _key: 'abc',
350
- _type: 'block',
351
- markDefs: [],
352
- children: [{_key: 'def', _type: 'span', marks: []}],
353
- },
354
- ]
355
- const initialSelection: EditorSelection = {
356
- anchor: {path: [{_key: '123'}, 'children', {_key: '567'}], offset: 2},
357
- focus: {path: [{_key: '123'}, 'children', {_key: '567'}], offset: 2},
358
- }
359
- const onChange = vi.fn()
360
- render(
361
- <PortableTextEditorTester
362
- keyGenerator={createTestKeyGenerator()}
363
- onChange={onChange}
364
- ref={editorRef}
365
- selection={initialSelection}
366
- value={initialValue}
367
- />,
368
- )
369
- await waitFor(() => {
370
- if (editorRef.current) {
371
- expect(onChange).toHaveBeenCalledWith({
372
- type: 'invalidValue',
373
- value: initialValue,
374
- resolution: {
375
- action: 'Write an empty text property to the object',
376
- description:
377
- "Child with _key 'def' in block with key 'abc' has missing or invalid text property!",
378
- i18n: {
379
- action:
380
- 'inputs.portable-text.invalid-value.invalid-span-text.action',
381
- description:
382
- 'inputs.portable-text.invalid-value.invalid-span-text.description',
383
- values: {
384
- key: 'abc',
385
- childKey: 'def',
386
- },
387
- },
388
- item: {
389
- _key: 'abc',
390
- _type: 'block',
391
- children: [
392
- {
393
- _key: 'def',
394
- _type: 'span',
395
- marks: [],
396
- },
397
- ],
398
- markDefs: [],
399
- },
400
- patches: [
401
- {
402
- path: [
403
- {
404
- _key: 'abc',
405
- },
406
- 'children',
407
- {
408
- _key: 'def',
409
- },
410
- ],
411
- type: 'set',
412
- value: {
413
- _key: 'def',
414
- _type: 'span',
415
- marks: [],
416
- text: '',
417
- },
418
- },
419
- ],
420
- },
421
- })
422
- }
423
- })
424
- expect(onChange).not.toHaveBeenCalledWith({
425
- type: 'value',
426
- value: initialValue,
427
- })
428
- expect(onChange).toHaveBeenCalledWith({type: 'ready'})
429
- })
430
- })
@@ -1,58 +0,0 @@
1
- import {forwardRef, useMemo, type ForwardedRef} from 'react'
2
- import {vi} from 'vitest'
3
- import {
4
- defineSchema,
5
- EditorProvider,
6
- PortableTextEditable,
7
- type PortableTextEditableProps,
8
- type PortableTextEditor,
9
- type PortableTextEditorProps,
10
- type SchemaDefinition,
11
- } from '../../index'
12
- import {InternalChange$Plugin} from '../../plugins/plugin.internal.change-ref'
13
- import {InternalPortableTextEditorRefPlugin} from '../../plugins/plugin.internal.portable-text-editor-ref'
14
-
15
- export const schemaDefinition = defineSchema({
16
- decorators: [{name: 'strong'}],
17
- blockObjects: [
18
- {name: 'custom image', fields: [{name: 'src', type: 'string'}]},
19
- ],
20
- inlineObjects: [
21
- {name: 'someObject', fields: [{name: 'color', type: 'string'}]},
22
- ],
23
- })
24
-
25
- export const PortableTextEditorTester = forwardRef(
26
- function PortableTextEditorTester(
27
- props: {
28
- onChange?: PortableTextEditorProps['onChange']
29
- rangeDecorations?: PortableTextEditableProps['rangeDecorations']
30
- renderPlaceholder?: PortableTextEditableProps['renderPlaceholder']
31
- schemaDefinition?: SchemaDefinition
32
- selection?: PortableTextEditableProps['selection']
33
- value?: PortableTextEditorProps['value']
34
- keyGenerator: PortableTextEditorProps['keyGenerator']
35
- },
36
- ref: ForwardedRef<PortableTextEditor>,
37
- ) {
38
- const onChange = useMemo(() => props.onChange || vi.fn(), [props.onChange])
39
- return (
40
- <EditorProvider
41
- initialConfig={{
42
- schemaDefinition: props.schemaDefinition ?? schemaDefinition,
43
- keyGenerator: props.keyGenerator,
44
- initialValue: props.value,
45
- }}
46
- >
47
- <InternalChange$Plugin onChange={onChange} />
48
- <InternalPortableTextEditorRefPlugin ref={ref} />
49
- <PortableTextEditable
50
- selection={props.selection || undefined}
51
- rangeDecorations={props.rangeDecorations}
52
- renderPlaceholder={props.renderPlaceholder}
53
- aria-describedby="desc_foo"
54
- />
55
- </EditorProvider>
56
- )
57
- },
58
- )
@@ -1,213 +0,0 @@
1
- import {createTestKeyGenerator} from '@portabletext/test'
2
- import type {PortableTextBlock} from '@sanity/types'
3
- import {render, waitFor} from '@testing-library/react'
4
- import {createRef, type ReactNode, type RefObject} from 'react'
5
- import {describe, expect, it, vi} from 'vitest'
6
- import type {RangeDecoration} from '../..'
7
- import type {PortableTextEditor} from '../PortableTextEditor'
8
- import {PortableTextEditorTester} from './PortableTextEditorTester'
9
-
10
- const helloBlock: PortableTextBlock = {
11
- _key: '123',
12
- _type: 'block',
13
- markDefs: [],
14
- children: [{_key: '567', _type: 'span', text: 'Hello', marks: []}],
15
- }
16
-
17
- let rangeDecorationIteration = 0
18
-
19
- const RangeDecorationTestComponent = ({children}: {children?: ReactNode}) => {
20
- rangeDecorationIteration++
21
- return <span data-testid="range-decoration">{children}</span>
22
- }
23
-
24
- describe('RangeDecorations', () => {
25
- it('only render range decorations as necessary', async () => {
26
- const editorRef: RefObject<PortableTextEditor | null> = createRef()
27
- const onChange = vi.fn()
28
- const value = [helloBlock]
29
- let rangeDecorations: RangeDecoration[] = [
30
- {
31
- component: RangeDecorationTestComponent,
32
- selection: {
33
- anchor: {path: [{_key: '123'}, 'children', {_key: '567'}], offset: 0},
34
- focus: {path: [{_key: '123'}, 'children', {_key: '567'}], offset: 2},
35
- },
36
- payload: {id: 'a'},
37
- },
38
- ]
39
-
40
- const {rerender} = await waitFor(() =>
41
- render(
42
- <PortableTextEditorTester
43
- keyGenerator={createTestKeyGenerator()}
44
- onChange={onChange}
45
- rangeDecorations={rangeDecorations}
46
- ref={editorRef}
47
- value={value}
48
- />,
49
- ),
50
- )
51
-
52
- await waitFor(() => {
53
- if (editorRef.current) {
54
- expect(onChange).toHaveBeenCalledWith({
55
- type: 'value',
56
- value,
57
- })
58
- expect(onChange).toHaveBeenCalledWith({type: 'ready'})
59
- }
60
- })
61
-
62
- await waitFor(() => {
63
- expect([rangeDecorationIteration, 'initial']).toEqual([1, 'initial'])
64
- })
65
-
66
- // Re-render with the same range decorations
67
- rerender(
68
- <PortableTextEditorTester
69
- keyGenerator={createTestKeyGenerator()}
70
- onChange={onChange}
71
- rangeDecorations={rangeDecorations}
72
- ref={editorRef}
73
- value={value}
74
- />,
75
- )
76
- await waitFor(() => {
77
- expect([rangeDecorationIteration, 'initial']).toEqual([1, 'initial'])
78
- })
79
- // Update the range decorations, a new object with identical values
80
- rangeDecorations = [
81
- {
82
- component: RangeDecorationTestComponent,
83
- selection: {
84
- anchor: {path: [{_key: '123'}, 'children', {_key: '567'}], offset: 0},
85
- focus: {path: [{_key: '123'}, 'children', {_key: '567'}], offset: 2},
86
- },
87
- payload: {id: 'a'},
88
- },
89
- ]
90
- rerender(
91
- <PortableTextEditorTester
92
- keyGenerator={createTestKeyGenerator()}
93
- onChange={onChange}
94
- rangeDecorations={rangeDecorations}
95
- ref={editorRef}
96
- value={value}
97
- />,
98
- )
99
- await waitFor(() => {
100
- expect([rangeDecorationIteration, 'updated-with-equal-values']).toEqual([
101
- 1,
102
- 'updated-with-equal-values',
103
- ])
104
- })
105
- // Update the range decorations with a new offset
106
- rangeDecorations = [
107
- {
108
- component: RangeDecorationTestComponent,
109
- selection: {
110
- anchor: {path: [{_key: '123'}, 'children', {_key: '567'}], offset: 2},
111
- focus: {path: [{_key: '123'}, 'children', {_key: '567'}], offset: 4},
112
- },
113
- payload: {id: 'a'},
114
- },
115
- ]
116
- rerender(
117
- <PortableTextEditorTester
118
- keyGenerator={createTestKeyGenerator()}
119
- onChange={onChange}
120
- rangeDecorations={rangeDecorations}
121
- ref={editorRef}
122
- value={value}
123
- />,
124
- )
125
- await waitFor(() => {
126
- expect([rangeDecorationIteration, 'updated-with-different']).toEqual([
127
- 2,
128
- 'updated-with-different',
129
- ])
130
- })
131
-
132
- // Update the range decorations with a new offset again
133
- rangeDecorations = [
134
- {
135
- component: RangeDecorationTestComponent,
136
- selection: {
137
- anchor: {path: [{_key: '123'}, 'children', {_key: '567'}], offset: 0},
138
- focus: {path: [{_key: '123'}, 'children', {_key: '567'}], offset: 2},
139
- },
140
- payload: {id: 'a'},
141
- },
142
- ]
143
- rerender(
144
- <PortableTextEditorTester
145
- keyGenerator={createTestKeyGenerator()}
146
- onChange={onChange}
147
- rangeDecorations={rangeDecorations}
148
- ref={editorRef}
149
- value={value}
150
- />,
151
- )
152
- await waitFor(() => {
153
- expect([rangeDecorationIteration, 'updated-with-different']).toEqual([
154
- 3,
155
- 'updated-with-different',
156
- ])
157
- })
158
-
159
- // Update the range decorations with a new payload
160
- rangeDecorations = [
161
- {
162
- component: RangeDecorationTestComponent,
163
- selection: {
164
- anchor: {path: [{_key: '123'}, 'children', {_key: '567'}], offset: 0},
165
- focus: {path: [{_key: '123'}, 'children', {_key: '567'}], offset: 2},
166
- },
167
- payload: {id: 'b'},
168
- },
169
- ]
170
- rerender(
171
- <PortableTextEditorTester
172
- keyGenerator={createTestKeyGenerator()}
173
- onChange={onChange}
174
- rangeDecorations={rangeDecorations}
175
- ref={editorRef}
176
- value={value}
177
- />,
178
- )
179
- await waitFor(() => {
180
- expect([
181
- rangeDecorationIteration,
182
- 'updated-with-different-payload',
183
- ]).toEqual([4, 'updated-with-different-payload'])
184
- })
185
-
186
- // Update the range decorations with a new payload again
187
- rangeDecorations = [
188
- {
189
- component: RangeDecorationTestComponent,
190
- selection: {
191
- anchor: {path: [{_key: '123'}, 'children', {_key: '567'}], offset: 0},
192
- focus: {path: [{_key: '123'}, 'children', {_key: '567'}], offset: 2},
193
- },
194
- payload: {id: 'c'},
195
- },
196
- ]
197
- rerender(
198
- <PortableTextEditorTester
199
- keyGenerator={createTestKeyGenerator()}
200
- onChange={onChange}
201
- rangeDecorations={rangeDecorations}
202
- ref={editorRef}
203
- value={value}
204
- />,
205
- )
206
- await waitFor(() => {
207
- expect([
208
- rangeDecorationIteration,
209
- 'updated-with-different-payload',
210
- ]).toEqual([5, 'updated-with-different-payload'])
211
- })
212
- })
213
- })