@portabletext/editor 2.8.0 → 2.8.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 (42) hide show
  1. package/lib/_chunks-cjs/selector.is-selection-expanded.cjs +10 -4
  2. package/lib/_chunks-cjs/selector.is-selection-expanded.cjs.map +1 -1
  3. package/lib/_chunks-cjs/util.merge-text-blocks.cjs +0 -1
  4. package/lib/_chunks-cjs/util.merge-text-blocks.cjs.map +1 -1
  5. package/lib/_chunks-cjs/util.slice-blocks.cjs +3 -6
  6. package/lib/_chunks-cjs/util.slice-blocks.cjs.map +1 -1
  7. package/lib/_chunks-dts/behavior.types.action.d.cts +73 -73
  8. package/lib/_chunks-dts/behavior.types.action.d.ts +9 -9
  9. package/lib/_chunks-es/selector.is-selection-expanded.js +10 -4
  10. package/lib/_chunks-es/selector.is-selection-expanded.js.map +1 -1
  11. package/lib/_chunks-es/util.merge-text-blocks.js +0 -1
  12. package/lib/_chunks-es/util.merge-text-blocks.js.map +1 -1
  13. package/lib/_chunks-es/util.slice-blocks.js +3 -6
  14. package/lib/_chunks-es/util.slice-blocks.js.map +1 -1
  15. package/lib/index.cjs +0 -10
  16. package/lib/index.cjs.map +1 -1
  17. package/lib/index.js +0 -10
  18. package/lib/index.js.map +1 -1
  19. package/lib/plugins/index.d.cts +3 -3
  20. package/lib/plugins/index.d.ts +3 -3
  21. package/lib/utils/index.d.ts +2 -2
  22. package/package.json +5 -5
  23. package/src/behaviors/behavior.abstract.split.ts +0 -1
  24. package/src/converters/converter.portable-text.ts +0 -1
  25. package/src/converters/converter.text-html.ts +0 -1
  26. package/src/converters/converter.text-plain.ts +0 -1
  27. package/src/editor/Editable.tsx +0 -1
  28. package/src/internal-utils/parse-blocks.test.ts +23 -23
  29. package/src/internal-utils/parse-blocks.ts +11 -23
  30. package/src/internal-utils/test-editor.tsx +15 -21
  31. package/src/operations/behavior.operation.annotation.add.ts +1 -1
  32. package/src/operations/behavior.operation.block.set.ts +1 -1
  33. package/src/operations/behavior.operation.block.unset.ts +2 -2
  34. package/src/operations/behavior.operation.insert.block.ts +1 -1
  35. package/src/plugins/plugin.internal.auto-close-brackets.test.tsx +25 -71
  36. package/src/plugins/plugin.markdown.test.tsx +12 -30
  37. package/src/selectors/selector.get-selected-value.test.ts +748 -0
  38. package/src/selectors/selector.get-selected-value.ts +28 -7
  39. package/src/selectors/selector.get-trimmed-selection.test.ts +0 -1
  40. package/src/utils/util.merge-text-blocks.ts +1 -1
  41. package/src/utils/util.slice-blocks.ts +3 -3
  42. package/src/utils/util.slice-blocks.test.ts +0 -499
@@ -35,13 +35,34 @@ export const getSelectedValue: EditorSelector<Array<PortableTextBlock>> = (
35
35
  return []
36
36
  }
37
37
 
38
- const slicedValue = snapshot.context.value.slice(
39
- startBlockIndex,
40
- endBlockIndex + 1,
38
+ const startBlock = snapshot.context.value.at(startBlockIndex)
39
+ const slicedStartBlock = startBlock
40
+ ? sliceBlocks({
41
+ context: snapshot.context,
42
+ blocks: [startBlock],
43
+ }).at(0)
44
+ : undefined
45
+
46
+ if (startBlockIndex === endBlockIndex) {
47
+ return slicedStartBlock ? [slicedStartBlock] : []
48
+ }
49
+
50
+ const endBlock = snapshot.context.value.at(endBlockIndex)
51
+ const slicedEndBlock = endBlock
52
+ ? sliceBlocks({
53
+ context: snapshot.context,
54
+ blocks: [endBlock],
55
+ }).at(0)
56
+ : undefined
57
+
58
+ const middleBlocks = snapshot.context.value.slice(
59
+ startBlockIndex + 1,
60
+ endBlockIndex,
41
61
  )
42
62
 
43
- return sliceBlocks({
44
- context: snapshot.context,
45
- blocks: slicedValue,
46
- })
63
+ return [
64
+ ...(slicedStartBlock ? [slicedStartBlock] : []),
65
+ ...middleBlocks,
66
+ ...(slicedEndBlock ? [slicedEndBlock] : []),
67
+ ]
47
68
  }
@@ -33,7 +33,6 @@ function snapshot(
33
33
  },
34
34
  block,
35
35
  options: {
36
- refreshKeys: false,
37
36
  validateFields: false,
38
37
  },
39
38
  })
@@ -18,7 +18,7 @@ export function mergeTextBlocks({
18
18
  const parsedIncomingBlock = parseBlock({
19
19
  context,
20
20
  block: incomingBlock,
21
- options: {refreshKeys: false, validateFields: false},
21
+ options: {validateFields: false},
22
22
  })
23
23
 
24
24
  if (!parsedIncomingBlock || !isTextBlock(context, parsedIncomingBlock)) {
@@ -171,7 +171,7 @@ export function sliceBlocks({
171
171
  keyGenerator: defaultKeyGenerator,
172
172
  },
173
173
  block,
174
- options: {refreshKeys: false, validateFields: false},
174
+ options: {validateFields: false},
175
175
  }) ?? block,
176
176
  )
177
177
  }
@@ -184,7 +184,7 @@ export function sliceBlocks({
184
184
  keyGenerator: defaultKeyGenerator,
185
185
  },
186
186
  block: startBlock,
187
- options: {refreshKeys: false, validateFields: false},
187
+ options: {validateFields: false},
188
188
  })
189
189
  : undefined
190
190
 
@@ -195,7 +195,7 @@ export function sliceBlocks({
195
195
  keyGenerator: defaultKeyGenerator,
196
196
  },
197
197
  block: endBlock,
198
- options: {refreshKeys: false, validateFields: false},
198
+ options: {validateFields: false},
199
199
  })
200
200
  : undefined
201
201
 
@@ -1,499 +0,0 @@
1
- import {compileSchema, defineSchema} from '@portabletext/schema'
2
- import type {PortableTextBlock, PortableTextTextBlock} from '@sanity/types'
3
- import {describe, expect, test} from 'vitest'
4
- import {sliceBlocks} from './util.slice-blocks'
5
-
6
- const b1: PortableTextTextBlock = {
7
- _type: 'block',
8
- _key: 'b1',
9
- children: [
10
- {
11
- _type: 'span',
12
- _key: 'b1c1',
13
- text: 'foo',
14
- marks: [],
15
- },
16
- {
17
- _type: 'span',
18
- _key: 'b1c2',
19
- text: 'bar',
20
- marks: [],
21
- },
22
- ],
23
- markDefs: [],
24
- style: 'normal',
25
- }
26
- const b2: PortableTextBlock = {
27
- _type: 'image',
28
- _key: 'b2',
29
- src: 'https://example.com/image.jpg',
30
- alt: 'Example',
31
- }
32
- const b3: PortableTextTextBlock = {
33
- _type: 'block',
34
- _key: 'b3',
35
- children: [
36
- {
37
- _type: 'span',
38
- _key: 'b3c1',
39
- text: 'baz',
40
- marks: [],
41
- },
42
- ],
43
- markDefs: [],
44
- style: 'normal',
45
- }
46
- const b4: PortableTextTextBlock = {
47
- _type: 'block',
48
- _key: 'b4',
49
- children: [
50
- {
51
- _type: 'span',
52
- _key: 'b4c1',
53
- text: 'fizz',
54
- marks: [],
55
- },
56
- {
57
- _type: 'stock-ticker',
58
- _key: 'b4c2',
59
- symbol: 'AAPL',
60
- },
61
- {
62
- _type: 'span',
63
- _key: 'b4c3',
64
- text: 'buzz',
65
- marks: [],
66
- },
67
- ],
68
- markDefs: [],
69
- style: 'normal',
70
- }
71
-
72
- const schema = compileSchema(
73
- defineSchema({
74
- blockObjects: [{name: 'image'}],
75
- inlineObjects: [{name: 'stock-ticker'}],
76
- }),
77
- )
78
- const blocks: Array<PortableTextBlock> = [b1, b2, b3, b4]
79
-
80
- describe(sliceBlocks.name, () => {
81
- test('sensible defaults', () => {
82
- expect(
83
- sliceBlocks({
84
- context: {
85
- schema,
86
- selection: null,
87
- },
88
- blocks: [],
89
- }),
90
- ).toEqual([])
91
- expect(
92
- sliceBlocks({
93
- context: {
94
- schema,
95
- selection: null,
96
- },
97
- blocks,
98
- }),
99
- ).toEqual([])
100
- })
101
-
102
- test('slicing a single block', () => {
103
- expect(
104
- sliceBlocks({
105
- context: {
106
- schema,
107
- selection: {
108
- anchor: {
109
- path: [{_key: b1._key}, 'children', {_key: b1.children[0]._key}],
110
- offset: 0,
111
- },
112
- focus: {
113
- path: [{_key: b1._key}, 'children', {_key: b1.children[0]._key}],
114
- offset: 3,
115
- },
116
- },
117
- },
118
- blocks,
119
- }),
120
- ).toEqual([
121
- {
122
- ...b1,
123
- children: [b1.children[0]],
124
- },
125
- ])
126
- })
127
-
128
- test('slicing a single span', () => {
129
- expect(
130
- sliceBlocks({
131
- context: {
132
- schema,
133
- selection: {
134
- anchor: {
135
- path: [{_key: b1._key}, 'children', {_key: b1.children[0]._key}],
136
- offset: 1,
137
- },
138
- focus: {
139
- path: [{_key: b1._key}, 'children', {_key: b1.children[0]._key}],
140
- offset: 2,
141
- },
142
- },
143
- },
144
- blocks,
145
- }),
146
- ).toEqual([
147
- {
148
- ...b1,
149
- children: [
150
- {
151
- ...b1.children[0],
152
- text: 'o',
153
- },
154
- ],
155
- },
156
- ])
157
- })
158
-
159
- test('starting and ending selection on a block object', () => {
160
- expect(
161
- sliceBlocks({
162
- context: {
163
- schema,
164
- selection: {
165
- anchor: {
166
- path: [{_key: b2._key}],
167
- offset: 0,
168
- },
169
- focus: {
170
- path: [{_key: b2._key}],
171
- offset: 0,
172
- },
173
- },
174
- },
175
- blocks,
176
- }),
177
- ).toEqual([b2])
178
- })
179
-
180
- test('starting selection on a block object', () => {
181
- expect(
182
- sliceBlocks({
183
- context: {
184
- schema,
185
- selection: {
186
- anchor: {
187
- path: [{_key: b2._key}],
188
- offset: 0,
189
- },
190
- focus: {
191
- path: [{_key: b3._key}, 'children', {_key: b3.children[0]._key}],
192
- offset: 3,
193
- },
194
- },
195
- },
196
- blocks,
197
- }),
198
- ).toEqual([b2, b3])
199
- })
200
-
201
- test('ending selection on a block object', () => {
202
- expect(
203
- sliceBlocks({
204
- context: {
205
- schema,
206
- selection: {
207
- anchor: {
208
- path: [{_key: b1._key}, 'children', {_key: b1.children[0]._key}],
209
- offset: 3,
210
- },
211
- focus: {
212
- path: [{_key: b2._key}],
213
- offset: 0,
214
- },
215
- },
216
- },
217
- blocks,
218
- }),
219
- ).toEqual([
220
- {
221
- ...b1,
222
- children: [
223
- {
224
- ...b1.children[0],
225
- text: '',
226
- },
227
- ...b1.children.slice(1),
228
- ],
229
- },
230
- blocks[1],
231
- ])
232
- })
233
-
234
- test('slicing across block object', () => {
235
- expect(
236
- sliceBlocks({
237
- context: {
238
- schema,
239
- selection: {
240
- anchor: {
241
- path: [{_key: b1._key}, 'children', {_key: b1.children[0]._key}],
242
- offset: 0,
243
- },
244
- focus: {
245
- path: [{_key: b3._key}, 'children', {_key: b3.children[0]._key}],
246
- offset: 3,
247
- },
248
- },
249
- },
250
- blocks,
251
- }),
252
- ).toEqual([b1, b2, b3])
253
- })
254
-
255
- test('starting and ending mid-span', () => {
256
- expect(
257
- sliceBlocks({
258
- context: {
259
- schema,
260
- selection: {
261
- anchor: {
262
- path: [{_key: b3._key}, 'children', {_key: b3.children[0]._key}],
263
- offset: 2,
264
- },
265
- focus: {
266
- path: [{_key: b4._key}, 'children', {_key: b4.children[0]._key}],
267
- offset: 1,
268
- },
269
- },
270
- },
271
- blocks,
272
- }),
273
- ).toEqual([
274
- {
275
- ...b3,
276
- children: [
277
- {
278
- ...b3.children[0],
279
- text: 'z',
280
- },
281
- ],
282
- },
283
- {
284
- ...b4,
285
- children: [
286
- {
287
- ...b4.children[0],
288
- text: 'f',
289
- },
290
- ],
291
- },
292
- ])
293
- })
294
-
295
- test('starting mid-span and ending end-span', () => {
296
- expect(
297
- sliceBlocks({
298
- context: {
299
- schema,
300
- selection: {
301
- anchor: {
302
- path: [{_key: b3._key}, 'children', {_key: b3.children[0]._key}],
303
- offset: 2,
304
- },
305
- focus: {
306
- path: [{_key: b4._key}, 'children', {_key: b4.children[0]._key}],
307
- offset: 4,
308
- },
309
- },
310
- },
311
- blocks,
312
- }),
313
- ).toEqual([
314
- {
315
- ...b3,
316
- children: [
317
- {
318
- ...b3.children[0],
319
- text: 'z',
320
- },
321
- ],
322
- },
323
- {
324
- ...b4,
325
- children: [
326
- {
327
- ...b4.children[0],
328
- },
329
- ],
330
- },
331
- ])
332
- })
333
-
334
- test('starting on inline object', () => {
335
- expect(
336
- sliceBlocks({
337
- context: {
338
- schema,
339
- selection: {
340
- anchor: {
341
- path: [{_key: b4._key}, 'children', {_key: b4.children[1]._key}],
342
- offset: 0,
343
- },
344
- focus: {
345
- path: [{_key: b4._key}, 'children', {_key: b4.children[2]._key}],
346
- offset: 4,
347
- },
348
- },
349
- },
350
- blocks,
351
- }),
352
- ).toEqual([
353
- {
354
- ...b4,
355
- children: [b4.children[1], b4.children[2]],
356
- },
357
- ])
358
- })
359
-
360
- test('ending on inline object', () => {
361
- expect(
362
- sliceBlocks({
363
- context: {
364
- schema,
365
- selection: {
366
- anchor: {
367
- path: [{_key: b4._key}, 'children', {_key: b4.children[0]._key}],
368
- offset: 0,
369
- },
370
- focus: {
371
- path: [{_key: b4._key}, 'children', {_key: b4.children[1]._key}],
372
- offset: 0,
373
- },
374
- },
375
- },
376
- blocks,
377
- }),
378
- ).toEqual([
379
- {
380
- ...b4,
381
- children: [b4.children[0], b4.children[1]],
382
- },
383
- ])
384
- })
385
-
386
- test('starting and ending on inline object', () => {
387
- expect(
388
- sliceBlocks({
389
- context: {
390
- schema,
391
- selection: {
392
- anchor: {
393
- path: [{_key: b4._key}, 'children', {_key: b4.children[1]._key}],
394
- offset: 0,
395
- },
396
- focus: {
397
- path: [{_key: b4._key}, 'children', {_key: b4.children[1]._key}],
398
- offset: 0,
399
- },
400
- },
401
- },
402
- blocks,
403
- }),
404
- ).toEqual([
405
- {
406
- ...b4,
407
- children: [b4.children[1]],
408
- },
409
- ])
410
- })
411
-
412
- test('slicing text block with custom props', () => {
413
- expect(
414
- sliceBlocks({
415
- context: {
416
- schema,
417
- selection: {
418
- anchor: {
419
- path: [{_key: 'b0'}, 'children', {_key: 's0'}],
420
- offset: 7,
421
- },
422
- focus: {
423
- path: [{_key: 'b0'}, 'children', {_key: 's0'}],
424
- offset: 12,
425
- },
426
- },
427
- },
428
- blocks: [
429
- {
430
- _key: 'b0',
431
- _type: 'block',
432
- children: [
433
- {_key: 's0', _type: 'span', text: 'Hello, world!', marks: []},
434
- ],
435
- markDefs: [],
436
- style: 'normal',
437
- _map: {},
438
- },
439
- ],
440
- }),
441
- ).toEqual([
442
- {
443
- _key: 'b0',
444
- _type: 'block',
445
- children: [{_key: 's0', _type: 'span', text: 'world', marks: []}],
446
- markDefs: [],
447
- style: 'normal',
448
- _map: {},
449
- },
450
- ])
451
- })
452
-
453
- test('slicing span with custom props', () => {
454
- expect(
455
- sliceBlocks({
456
- context: {
457
- schema,
458
- selection: {
459
- anchor: {
460
- path: [{_key: 'b0'}, 'children', {_key: 's0'}],
461
- offset: 7,
462
- },
463
- focus: {
464
- path: [{_key: 'b0'}, 'children', {_key: 's0'}],
465
- offset: 12,
466
- },
467
- },
468
- },
469
- blocks: [
470
- {
471
- _key: 'b0',
472
- _type: 'block',
473
- children: [
474
- {
475
- _key: 's0',
476
- _type: 'span',
477
- text: 'Hello, world!',
478
- _map: {},
479
- marks: [],
480
- },
481
- ],
482
- markDefs: [],
483
- style: 'normal',
484
- },
485
- ],
486
- }),
487
- ).toEqual([
488
- {
489
- _key: 'b0',
490
- _type: 'block',
491
- children: [
492
- {_key: 's0', _type: 'span', text: 'world', _map: {}, marks: []},
493
- ],
494
- markDefs: [],
495
- style: 'normal',
496
- },
497
- ])
498
- })
499
- })