@portabletext/editor 1.43.0 → 1.44.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 (73) hide show
  1. package/lib/_chunks-cjs/behavior.markdown.cjs +1 -1
  2. package/lib/_chunks-cjs/editor-provider.cjs +445 -623
  3. package/lib/_chunks-cjs/editor-provider.cjs.map +1 -1
  4. package/lib/_chunks-cjs/parse-blocks.cjs +151 -0
  5. package/lib/_chunks-cjs/parse-blocks.cjs.map +1 -0
  6. package/lib/_chunks-cjs/selector.is-overlapping-selection.cjs +2 -1
  7. package/lib/_chunks-cjs/selector.is-overlapping-selection.cjs.map +1 -1
  8. package/lib/_chunks-cjs/{selector.is-active-style.cjs → selector.is-selecting-entire-blocks.cjs} +47 -11
  9. package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs.map +1 -0
  10. package/lib/_chunks-cjs/util.merge-text-blocks.cjs +3 -3
  11. package/lib/_chunks-cjs/util.merge-text-blocks.cjs.map +1 -1
  12. package/lib/_chunks-cjs/util.selection-point-to-block-offset.cjs +0 -149
  13. package/lib/_chunks-cjs/util.selection-point-to-block-offset.cjs.map +1 -1
  14. package/lib/_chunks-es/behavior.markdown.js +1 -1
  15. package/lib/_chunks-es/editor-provider.js +434 -611
  16. package/lib/_chunks-es/editor-provider.js.map +1 -1
  17. package/lib/_chunks-es/parse-blocks.js +152 -0
  18. package/lib/_chunks-es/parse-blocks.js.map +1 -0
  19. package/lib/_chunks-es/selector.is-overlapping-selection.js +2 -1
  20. package/lib/_chunks-es/selector.is-overlapping-selection.js.map +1 -1
  21. package/lib/_chunks-es/{selector.is-active-style.js → selector.is-selecting-entire-blocks.js} +49 -12
  22. package/lib/_chunks-es/selector.is-selecting-entire-blocks.js.map +1 -0
  23. package/lib/_chunks-es/util.merge-text-blocks.js +1 -1
  24. package/lib/_chunks-es/util.selection-point-to-block-offset.js +0 -149
  25. package/lib/_chunks-es/util.selection-point-to-block-offset.js.map +1 -1
  26. package/lib/behaviors/index.d.cts +1860 -5464
  27. package/lib/behaviors/index.d.ts +1860 -5464
  28. package/lib/index.cjs +4 -4
  29. package/lib/index.cjs.map +1 -1
  30. package/lib/index.d.cts +1529 -5062
  31. package/lib/index.d.ts +1529 -5062
  32. package/lib/index.js +3 -3
  33. package/lib/plugins/index.cjs +1 -1
  34. package/lib/plugins/index.d.cts +1529 -5062
  35. package/lib/plugins/index.d.ts +1529 -5062
  36. package/lib/plugins/index.js +1 -1
  37. package/lib/selectors/index.cjs +12 -11
  38. package/lib/selectors/index.cjs.map +1 -1
  39. package/lib/selectors/index.d.cts +1508 -5064
  40. package/lib/selectors/index.d.ts +1508 -5064
  41. package/lib/selectors/index.js +2 -1
  42. package/lib/utils/index.d.cts +1491 -5057
  43. package/lib/utils/index.d.ts +1491 -5057
  44. package/package.json +1 -1
  45. package/src/behavior-actions/behavior.actions.ts +1 -131
  46. package/src/behaviors/behavior.default.ts +47 -50
  47. package/src/behaviors/behavior.internal.insert.ts +118 -0
  48. package/src/behaviors/behavior.internal.list-item.ts +61 -0
  49. package/src/behaviors/behavior.internal.select.ts +62 -0
  50. package/src/behaviors/behavior.internal.style.ts +54 -0
  51. package/src/behaviors/behavior.perform-event.ts +15 -13
  52. package/src/behaviors/behavior.types.event.ts +143 -100
  53. package/src/editor/create-editor.ts +2 -2
  54. package/src/editor/editor-machine.ts +3 -4
  55. package/src/editor/plugins/createWithEditableAPI.ts +1 -2
  56. package/src/editor/sync-machine.ts +1 -1
  57. package/src/internal-utils/slate-utils.ts +52 -0
  58. package/src/plugins/plugin.internal.editor-actor-ref.tsx +15 -0
  59. package/src/plugins/plugin.internal.slate-editor-ref.tsx +15 -0
  60. package/src/selectors/index.ts +2 -1
  61. package/src/selectors/selector.get-selected-text-blocks.ts +67 -0
  62. package/lib/_chunks-cjs/selector.is-active-style.cjs.map +0 -1
  63. package/lib/_chunks-es/selector.is-active-style.js.map +0 -1
  64. package/src/behavior-actions/behavior.action.data-transfer-set.ts +0 -7
  65. package/src/behavior-actions/behavior.action.deserialization.failure.ts +0 -9
  66. package/src/behavior-actions/behavior.action.deserialization.success.ts +0 -16
  67. package/src/behavior-actions/behavior.action.insert-blocks.ts +0 -140
  68. package/src/behavior-actions/behavior.action.list-item.ts +0 -100
  69. package/src/behavior-actions/behavior.action.select.next-block.ts +0 -44
  70. package/src/behavior-actions/behavior.action.select.previous-block.ts +0 -48
  71. package/src/behavior-actions/behavior.action.serialization.failure.ts +0 -9
  72. package/src/behavior-actions/behavior.action.serialization.success.ts +0 -17
  73. package/src/behavior-actions/behavior.action.style.ts +0 -108
@@ -10,16 +10,23 @@ import {debugWithName} from '../internal-utils/debug'
10
10
  import type {PortableTextSlateEditor} from '../types/editor'
11
11
  import type {InternalBehaviorAction} from './behavior.types.action'
12
12
  import {
13
- isClipboardBehaviorEvent,
14
13
  isCustomBehaviorEvent,
15
- isDragBehaviorEvent,
16
- isInputBehaviorEvent,
17
- isKeyboardBehaviorEvent,
18
- isMouseBehaviorEvent,
14
+ isInternalBehaviorEvent,
15
+ isNativeBehaviorEvent,
19
16
  } from './behavior.types.event'
20
17
 
21
18
  const debug = debugWithName('behaviors:event')
22
19
 
20
+ function eventCategory(event: BehaviorEvent) {
21
+ return isNativeBehaviorEvent(event)
22
+ ? 'native'
23
+ : isInternalBehaviorEvent(event)
24
+ ? 'internal'
25
+ : isCustomBehaviorEvent(event)
26
+ ? 'custom'
27
+ : 'synthetic'
28
+ }
29
+
23
30
  export function performEvent({
24
31
  behaviors,
25
32
  event,
@@ -43,17 +50,12 @@ export function performEvent({
43
50
  }
44
51
  | undefined
45
52
  }) {
46
- debug(JSON.stringify(event, null, 2))
53
+ debug(`(${eventCategory(event)})`, JSON.stringify(event, null, 2))
47
54
 
48
55
  const defaultAction =
49
56
  isCustomBehaviorEvent(event) ||
50
- isClipboardBehaviorEvent(event) ||
51
- isDragBehaviorEvent(event) ||
52
- isInputBehaviorEvent(event) ||
53
- isKeyboardBehaviorEvent(event) ||
54
- isMouseBehaviorEvent(event) ||
55
- event.type === 'deserialize' ||
56
- event.type === 'serialize'
57
+ isNativeBehaviorEvent(event) ||
58
+ isInternalBehaviorEvent(event)
57
59
  ? undefined
58
60
  : ({
59
61
  ...event,
@@ -28,17 +28,37 @@ type NamespacedBehaviorEventType<
28
28
  ? BehaviorEvent['type']
29
29
  : Extract<BehaviorEvent['type'], TNamespace | `${TNamespace}.${string}`>
30
30
 
31
- /**
32
- * @beta
33
- */
34
- export type ExternalSyntheticBehaviorEvent = {
35
- type: SyntheticBehaviorEventType<'insert', 'block object'>
36
- placement: InsertPlacement
37
- blockObject: {
38
- name: string
39
- value?: {[prop: string]: unknown}
40
- }
41
- }
31
+ /**************************************
32
+ * External events
33
+ **************************************/
34
+
35
+ type ExternalBehaviorEventNamespace = 'insert'
36
+
37
+ type ExternalBehaviorEventType<
38
+ TNamespace extends ExternalBehaviorEventNamespace,
39
+ TType extends string = '',
40
+ > = TType extends '' ? `${TNamespace}` : `${TNamespace}.${TType}`
41
+
42
+ export type ExternalBehaviorEvent =
43
+ | {
44
+ type: ExternalBehaviorEventType<'insert', 'block object'>
45
+ placement: InsertPlacement
46
+ blockObject: {
47
+ name: string
48
+ value?: {[prop: string]: unknown}
49
+ }
50
+ }
51
+ | PickFromUnion<
52
+ InternalBehaviorEvent,
53
+ 'type',
54
+ | 'insert.blocks'
55
+ | 'list item.add'
56
+ | 'list item.remove'
57
+ | 'list item.toggle'
58
+ | 'style.add'
59
+ | 'style.remove'
60
+ | 'style.toggle'
61
+ >
42
62
 
43
63
  /**************************************
44
64
  * Synthetic events
@@ -53,18 +73,13 @@ type SyntheticBehaviorEventNamespace =
53
73
  | 'annotation'
54
74
  | 'block'
55
75
  | 'blur'
56
- | 'data transfer'
57
76
  | 'decorator'
58
77
  | 'delete'
59
- | 'deserialization'
60
78
  | 'focus'
61
79
  | 'history'
62
80
  | 'insert'
63
- | 'list item'
64
81
  | 'move'
65
82
  | 'select'
66
- | 'serialization'
67
- | 'style'
68
83
 
69
84
  /**
70
85
  * @beta
@@ -103,12 +118,6 @@ export type SyntheticBehaviorEvent =
103
118
  | {
104
119
  type: SyntheticBehaviorEventType<'blur'>
105
120
  }
106
- | {
107
- type: SyntheticBehaviorEventType<'data transfer', 'set'>
108
- data: string
109
- dataTransfer: DataTransfer
110
- mimeType: MIMEType
111
- }
112
121
  | {
113
122
  type: SyntheticBehaviorEventType<'decorator', 'add'>
114
123
  decorator: string
@@ -153,11 +162,6 @@ export type SyntheticBehaviorEvent =
153
162
  | {
154
163
  type: SyntheticBehaviorEventType<'history', 'undo'>
155
164
  }
156
- | {
157
- type: SyntheticBehaviorEventType<'insert', 'blocks'>
158
- blocks: Array<PortableTextBlock>
159
- placement: InsertPlacement
160
- }
161
165
  | {
162
166
  type: SyntheticBehaviorEventType<'insert', 'inline object'>
163
167
  inlineObject: {
@@ -190,18 +194,6 @@ export type SyntheticBehaviorEvent =
190
194
  type: SyntheticBehaviorEventType<'insert', 'text'>
191
195
  text: string
192
196
  }
193
- | {
194
- type: SyntheticBehaviorEventType<'list item', 'add'>
195
- listItem: string
196
- }
197
- | {
198
- type: SyntheticBehaviorEventType<'list item', 'remove'>
199
- listItem: string
200
- }
201
- | {
202
- type: SyntheticBehaviorEventType<'list item', 'toggle'>
203
- listItem: string
204
- }
205
197
  | {
206
198
  type: SyntheticBehaviorEventType<'move', 'block'>
207
199
  at: [KeyedSegment]
@@ -219,28 +211,55 @@ export type SyntheticBehaviorEvent =
219
211
  type: SyntheticBehaviorEventType<'select'>
220
212
  selection: EditorSelection
221
213
  }
214
+
215
+ export type InsertPlacement = 'auto' | 'after' | 'before'
216
+
217
+ export function isKeyboardBehaviorEvent(
218
+ event: BehaviorEvent,
219
+ ): event is KeyboardBehaviorEvent {
220
+ return event.type.startsWith('keyboard.')
221
+ }
222
+
223
+ /**************************************
224
+ * Internal events
225
+ **************************************/
226
+
227
+ type InternalBehaviorEventNamespace =
228
+ | 'deserialize'
229
+ | 'deserialization'
230
+ | 'list item'
231
+ | 'insert'
232
+ | 'select'
233
+ | 'serialize'
234
+ | 'serialization'
235
+ | 'style'
236
+
237
+ type InternalBehaviorEventType<
238
+ TNamespace extends InternalBehaviorEventNamespace,
239
+ TType extends string = '',
240
+ > = TType extends '' ? `${TNamespace}` : `${TNamespace}.${TType}`
241
+
242
+ export type InternalBehaviorEvent =
222
243
  | {
223
- type: SyntheticBehaviorEventType<'select', 'previous block'>
224
- select?: 'start' | 'end'
225
- }
226
- | {
227
- type: SyntheticBehaviorEventType<'select', 'next block'>
228
- select?: 'start' | 'end'
229
- }
230
- | {
231
- type: SyntheticBehaviorEventType<'style', 'add'>
232
- style: string
233
- }
234
- | {
235
- type: SyntheticBehaviorEventType<'style', 'remove'>
236
- style: string
244
+ type: InternalBehaviorEventType<'deserialize'>
245
+ originEvent:
246
+ | PickFromUnion<
247
+ NativeBehaviorEvent,
248
+ 'type',
249
+ 'drag.drop' | 'clipboard.paste'
250
+ >
251
+ | InputBehaviorEvent
237
252
  }
238
253
  | {
239
- type: SyntheticBehaviorEventType<'style', 'toggle'>
240
- style: string
254
+ type: InternalBehaviorEventType<'serialize'>
255
+ originEvent: PickFromUnion<
256
+ NativeBehaviorEvent,
257
+ 'type',
258
+ 'clipboard.copy' | 'clipboard.cut' | 'drag.dragstart'
259
+ >
241
260
  }
242
261
  | {
243
- type: SyntheticBehaviorEventType<'deserialization', 'success'>
262
+ type: InternalBehaviorEventType<'deserialization', 'success'>
244
263
  mimeType: MIMEType
245
264
  data: Array<PortableTextBlock>
246
265
  originEvent:
@@ -252,7 +271,7 @@ export type SyntheticBehaviorEvent =
252
271
  | InputBehaviorEvent
253
272
  }
254
273
  | {
255
- type: SyntheticBehaviorEventType<'deserialization', 'failure'>
274
+ type: InternalBehaviorEventType<'deserialization', 'failure'>
256
275
  mimeType: MIMEType
257
276
  reason: string
258
277
  originEvent:
@@ -264,7 +283,7 @@ export type SyntheticBehaviorEvent =
264
283
  | InputBehaviorEvent
265
284
  }
266
285
  | {
267
- type: SyntheticBehaviorEventType<'serialization', 'success'>
286
+ type: InternalBehaviorEventType<'serialization', 'success'>
268
287
  mimeType: MIMEType
269
288
  data: string
270
289
  originEvent: PickFromUnion<
@@ -274,7 +293,7 @@ export type SyntheticBehaviorEvent =
274
293
  >
275
294
  }
276
295
  | {
277
- type: SyntheticBehaviorEventType<'serialization', 'failure'>
296
+ type: InternalBehaviorEventType<'serialization', 'failure'>
278
297
  mimeType: MIMEType
279
298
  reason: string
280
299
  originEvent: PickFromUnion<
@@ -283,45 +302,59 @@ export type SyntheticBehaviorEvent =
283
302
  'clipboard.copy' | 'clipboard.cut' | 'drag.dragstart'
284
303
  >
285
304
  }
286
-
287
- export type InsertPlacement = 'auto' | 'after' | 'before'
288
-
289
- export function isKeyboardBehaviorEvent(
290
- event: BehaviorEvent,
291
- ): event is KeyboardBehaviorEvent {
292
- return event.type.startsWith('keyboard.')
293
- }
294
-
295
- /**************************************
296
- * Internal events
297
- **************************************/
298
-
299
- type InternalBehaviorEventNamespace = 'deserialize' | 'serialize'
300
-
301
- type InternalBehaviorEventType<
302
- TNamespace extends InternalBehaviorEventNamespace,
303
- TType extends string = '',
304
- > = TType extends '' ? `${TNamespace}` : `${TNamespace}.${TType}`
305
-
306
- export type InternalBehaviorEvent =
307
305
  | {
308
- type: InternalBehaviorEventType<'deserialize'>
309
- originEvent:
310
- | PickFromUnion<
311
- NativeBehaviorEvent,
312
- 'type',
313
- 'drag.drop' | 'clipboard.paste'
314
- >
315
- | InputBehaviorEvent
306
+ type: InternalBehaviorEventType<'insert', 'blocks'>
307
+ blocks: Array<PortableTextBlock>
308
+ placement: InsertPlacement
316
309
  }
317
310
  | {
318
- type: InternalBehaviorEventType<'serialize'>
319
- originEvent: PickFromUnion<
320
- NativeBehaviorEvent,
321
- 'type',
322
- 'clipboard.copy' | 'clipboard.cut' | 'drag.dragstart'
323
- >
311
+ type: InternalBehaviorEventType<'list item', 'add'>
312
+ listItem: string
313
+ }
314
+ | {
315
+ type: InternalBehaviorEventType<'list item', 'remove'>
316
+ listItem: string
317
+ }
318
+ | {
319
+ type: InternalBehaviorEventType<'list item', 'toggle'>
320
+ listItem: string
321
+ }
322
+ | {
323
+ type: InternalBehaviorEventType<'select', 'previous block'>
324
+ select?: 'start' | 'end'
324
325
  }
326
+ | {
327
+ type: InternalBehaviorEventType<'select', 'next block'>
328
+ select?: 'start' | 'end'
329
+ }
330
+ | {
331
+ type: InternalBehaviorEventType<'style', 'add'>
332
+ style: string
333
+ }
334
+ | {
335
+ type: InternalBehaviorEventType<'style', 'remove'>
336
+ style: string
337
+ }
338
+ | {
339
+ type: InternalBehaviorEventType<'style', 'toggle'>
340
+ style: string
341
+ }
342
+
343
+ export function isInternalBehaviorEvent(
344
+ event: BehaviorEvent,
345
+ ): event is InternalBehaviorEvent {
346
+ return (
347
+ event.type === 'deserialize' ||
348
+ event.type.startsWith('deserialization.') ||
349
+ event.type === 'insert.blocks' ||
350
+ event.type.startsWith('list item.') ||
351
+ event.type === 'serialize' ||
352
+ event.type.startsWith('serialization.') ||
353
+ event.type === 'select.next block' ||
354
+ event.type === 'select.previous block' ||
355
+ event.type.startsWith('style.')
356
+ )
357
+ }
325
358
 
326
359
  /**************************************
327
360
  * Native events
@@ -339,6 +372,18 @@ type NativeBehaviorEventType<
339
372
  TType extends string = '',
340
373
  > = TType extends '' ? `${TNamespace}` : `${TNamespace}.${TType}`
341
374
 
375
+ export function isNativeBehaviorEvent(
376
+ event: BehaviorEvent,
377
+ ): event is NativeBehaviorEvent {
378
+ return (
379
+ isClipboardBehaviorEvent(event) ||
380
+ isDragBehaviorEvent(event) ||
381
+ isInputBehaviorEvent(event) ||
382
+ isKeyboardBehaviorEvent(event) ||
383
+ isMouseBehaviorEvent(event)
384
+ )
385
+ }
386
+
342
387
  /**
343
388
  * @beta
344
389
  */
@@ -372,7 +417,7 @@ type ClipboardBehaviorEvent =
372
417
  position: Pick<EventPosition, 'selection'>
373
418
  }
374
419
 
375
- export function isClipboardBehaviorEvent(
420
+ function isClipboardBehaviorEvent(
376
421
  event: BehaviorEvent,
377
422
  ): event is ClipboardBehaviorEvent {
378
423
  return event.type.startsWith('clipboard.')
@@ -426,9 +471,7 @@ type DragBehaviorEvent =
426
471
  }
427
472
  }
428
473
 
429
- export function isDragBehaviorEvent(
430
- event: BehaviorEvent,
431
- ): event is DragBehaviorEvent {
474
+ function isDragBehaviorEvent(event: BehaviorEvent): event is DragBehaviorEvent {
432
475
  return event.type.startsWith('drag.')
433
476
  }
434
477
 
@@ -450,7 +493,7 @@ export type InputBehaviorEvent = {
450
493
  }
451
494
  }
452
495
 
453
- export function isInputBehaviorEvent(
496
+ function isInputBehaviorEvent(
454
497
  event: BehaviorEvent,
455
498
  ): event is InputBehaviorEvent {
456
499
  return event.type.startsWith('input.')
@@ -477,7 +520,7 @@ export type MouseBehaviorEvent = {
477
520
  position: EventPosition
478
521
  }
479
522
 
480
- export function isMouseBehaviorEvent(
523
+ function isMouseBehaviorEvent(
481
524
  event: BehaviorEvent,
482
525
  ): event is MouseBehaviorEvent {
483
526
  return event.type.startsWith('mouse.')
@@ -14,7 +14,7 @@ import {
14
14
  import type {Behavior} from '../behaviors/behavior.types.behavior'
15
15
  import type {
16
16
  CustomBehaviorEvent,
17
- ExternalSyntheticBehaviorEvent,
17
+ ExternalBehaviorEvent,
18
18
  SyntheticBehaviorEvent,
19
19
  } from '../behaviors/behavior.types.event'
20
20
  import {coreConverters} from '../converters/converters.core'
@@ -65,7 +65,7 @@ export type EditorConfig = {
65
65
  */
66
66
  export type EditorEvent =
67
67
  | ExternalEditorEvent
68
- | ExternalSyntheticBehaviorEvent
68
+ | ExternalBehaviorEvent
69
69
  | SyntheticBehaviorEvent
70
70
  | CustomBehaviorEvent
71
71
 
@@ -15,7 +15,7 @@ import {performEvent} from '../behaviors/behavior.perform-event'
15
15
  import type {Behavior} from '../behaviors/behavior.types.behavior'
16
16
  import type {
17
17
  CustomBehaviorEvent,
18
- ExternalSyntheticBehaviorEvent,
18
+ ExternalBehaviorEvent,
19
19
  InternalBehaviorEvent,
20
20
  NativeBehaviorEvent,
21
21
  SyntheticBehaviorEvent,
@@ -193,7 +193,7 @@ export type InternalEditorEvent =
193
193
  nativeEvent?: {preventDefault: () => void}
194
194
  }
195
195
  | CustomBehaviorEvent
196
- | ExternalSyntheticBehaviorEvent
196
+ | ExternalBehaviorEvent
197
197
  | ExternalEditorEvent
198
198
  | MutationEvent
199
199
  | InternalPatchEvent
@@ -213,7 +213,7 @@ export type InternalEditorEvent =
213
213
  */
214
214
  export type InternalEditorEmittedEvent =
215
215
  | EditorEmittedEvent
216
- | ExternalSyntheticBehaviorEvent
216
+ | ExternalBehaviorEvent
217
217
  | InternalPatchEvent
218
218
  | PatchesEvent
219
219
  | UnsetEvent
@@ -406,7 +406,6 @@ export const editorMachine = setup({
406
406
  actions: 'handle behavior event',
407
407
  guard: ({event}) =>
408
408
  event.behaviorEvent.type === 'clipboard.copy' ||
409
- event.behaviorEvent.type === 'data transfer.set' ||
410
409
  event.behaviorEvent.type === 'serialize' ||
411
410
  event.behaviorEvent.type === 'serialization.failure' ||
412
411
  event.behaviorEvent.type === 'serialization.success' ||
@@ -18,11 +18,10 @@ import {
18
18
  } from 'slate'
19
19
  import type {DOMNode} from 'slate-dom'
20
20
  import {ReactEditor} from 'slate-react'
21
- import {isListItemActive} from '../../behavior-actions/behavior.action.list-item'
22
- import {isStyleActive} from '../../behavior-actions/behavior.action.style'
23
21
  import type {BehaviorActionImplementation} from '../../behavior-actions/behavior.actions'
24
22
  import {debugWithName} from '../../internal-utils/debug'
25
23
  import {toPortableTextRange, toSlateRange} from '../../internal-utils/ranges'
24
+ import {isListItemActive, isStyleActive} from '../../internal-utils/slate-utils'
26
25
  import {fromSlateValue, toSlateValue} from '../../internal-utils/values'
27
26
  import {
28
27
  KEY_TO_VALUE_ELEMENT,
@@ -526,7 +526,7 @@ async function* getBlocks({
526
526
  }) {
527
527
  let index = 0
528
528
  for await (const block of slateValue) {
529
- if (streamBlocks) {
529
+ if (streamBlocks && index % 10 === 0) {
530
530
  await new Promise<void>((resolve) => setTimeout(resolve, 0))
531
531
  }
532
532
  yield [block, index] as const
@@ -126,3 +126,55 @@ function isBlockElement(
126
126
  ))
127
127
  )
128
128
  }
129
+
130
+ export function isListItemActive({
131
+ editor,
132
+ listItem,
133
+ }: {
134
+ editor: Editor
135
+ listItem: string
136
+ }): boolean {
137
+ if (!editor.selection) {
138
+ return false
139
+ }
140
+
141
+ const selectedBlocks = [
142
+ ...Editor.nodes(editor, {
143
+ at: editor.selection,
144
+ match: (node) => editor.isTextBlock(node),
145
+ }),
146
+ ]
147
+
148
+ if (selectedBlocks.length > 0) {
149
+ return selectedBlocks.every(
150
+ ([node]) => editor.isListBlock(node) && node.listItem === listItem,
151
+ )
152
+ }
153
+
154
+ return false
155
+ }
156
+
157
+ export function isStyleActive({
158
+ editor,
159
+ style,
160
+ }: {
161
+ editor: Editor
162
+ style: string
163
+ }): boolean {
164
+ if (!editor.selection) {
165
+ return false
166
+ }
167
+
168
+ const selectedBlocks = [
169
+ ...Editor.nodes(editor, {
170
+ at: editor.selection,
171
+ match: (node) => editor.isTextBlock(node),
172
+ }),
173
+ ]
174
+
175
+ if (selectedBlocks.length > 0) {
176
+ return selectedBlocks.every(([node]) => node.style === style)
177
+ }
178
+
179
+ return false
180
+ }
@@ -0,0 +1,15 @@
1
+ import React, {useContext} from 'react'
2
+ import {EditorActorContext} from '../editor/editor-actor-context'
3
+ import type {EditorActor} from '../editor/editor-machine'
4
+
5
+ export const InternalEditorAfterRefPlugin =
6
+ React.forwardRef<EditorActor | null>((_, ref) => {
7
+ const editorActor = useContext(EditorActorContext)
8
+
9
+ const editorActorRef = React.useRef(editorActor)
10
+
11
+ React.useImperativeHandle(ref, () => editorActorRef.current, [])
12
+
13
+ return null
14
+ })
15
+ InternalEditorAfterRefPlugin.displayName = 'InternalEditorAfterRefPlugin'
@@ -0,0 +1,15 @@
1
+ import React from 'react'
2
+ import {useSlateStatic} from 'slate-react'
3
+ import type {PortableTextSlateEditor} from '../types/editor'
4
+
5
+ export const InternalSlateEditorRefPlugin =
6
+ React.forwardRef<PortableTextSlateEditor | null>((_, ref) => {
7
+ const slateEditor = useSlateStatic()
8
+
9
+ const slateEditorRef = React.useRef(slateEditor)
10
+
11
+ React.useImperativeHandle(ref, () => slateEditorRef.current, [])
12
+
13
+ return null
14
+ })
15
+ InternalSlateEditorRefPlugin.displayName = 'InternalSlateEditorRefPlugin'
@@ -1,4 +1,3 @@
1
- export {isSelectingEntireBlocks} from './selector.is-selecting-entire-blocks'
2
1
  export {getActiveAnnotations} from './selector.get-active-annotations'
3
2
  export {getActiveListItem} from './selector.get-active-list-item'
4
3
  export {getActiveStyle} from './selector.get-active-style'
@@ -13,6 +12,7 @@ export {getNextInlineObject} from './selector.get-next-inline-object'
13
12
  export {getPreviousInlineObject} from './selector.get-previous-inline-object'
14
13
  export {getSelectedSlice} from './selector.get-selected-slice'
15
14
  export {getSelectedSpans} from './selector.get-selected-spans'
15
+ export {getSelectedTextBlocks} from './selector.get-selected-text-blocks'
16
16
  export {getSelection} from './selector.get-selection'
17
17
  export {getSelectionEndPoint} from './selector.get-selection-end-point'
18
18
  export {getSelectionStartPoint} from './selector.get-selection-start-point'
@@ -29,6 +29,7 @@ export {isAtTheStartOfBlock} from './selector.is-at-the-start-of-block'
29
29
  export {isOverlappingSelection} from './selector.is-overlapping-selection'
30
30
  export {isPointAfterSelection} from './selector.is-point-after-selection'
31
31
  export {isPointBeforeSelection} from './selector.is-point-before-selection'
32
+ export {isSelectingEntireBlocks} from './selector.is-selecting-entire-blocks'
32
33
  export {isSelectionCollapsed} from './selector.is-selection-collapsed'
33
34
  export {isSelectionExpanded} from './selector.is-selection-expanded'
34
35
  export * from './selectors'
@@ -0,0 +1,67 @@
1
+ import type {KeyedSegment, PortableTextTextBlock} from '@sanity/types'
2
+ import type {EditorSelector} from '../editor/editor-selector'
3
+ import {isTextBlock} from '../internal-utils/parse-blocks'
4
+ import {isKeyedSegment} from '../utils'
5
+
6
+ /**
7
+ * @public
8
+ */
9
+ export const getSelectedTextBlocks: EditorSelector<
10
+ Array<{node: PortableTextTextBlock; path: [KeyedSegment]}>
11
+ > = (snapshot) => {
12
+ if (!snapshot.context.selection) {
13
+ return []
14
+ }
15
+
16
+ const selectedTextBlocks: Array<{
17
+ node: PortableTextTextBlock
18
+ path: [KeyedSegment]
19
+ }> = []
20
+ const startKey = snapshot.context.selection.backward
21
+ ? isKeyedSegment(snapshot.context.selection.focus.path[0])
22
+ ? snapshot.context.selection.focus.path[0]._key
23
+ : undefined
24
+ : isKeyedSegment(snapshot.context.selection.anchor.path[0])
25
+ ? snapshot.context.selection.anchor.path[0]._key
26
+ : undefined
27
+ const endKey = snapshot.context.selection.backward
28
+ ? isKeyedSegment(snapshot.context.selection.anchor.path[0])
29
+ ? snapshot.context.selection.anchor.path[0]._key
30
+ : undefined
31
+ : isKeyedSegment(snapshot.context.selection.focus.path[0])
32
+ ? snapshot.context.selection.focus.path[0]._key
33
+ : undefined
34
+
35
+ if (!startKey || !endKey) {
36
+ return selectedTextBlocks
37
+ }
38
+
39
+ for (const block of snapshot.context.value) {
40
+ if (block._key === startKey) {
41
+ if (isTextBlock(snapshot.context.schema, block)) {
42
+ selectedTextBlocks.push({node: block, path: [{_key: block._key}]})
43
+ }
44
+
45
+ if (startKey === endKey) {
46
+ break
47
+ }
48
+ continue
49
+ }
50
+
51
+ if (block._key === endKey) {
52
+ if (isTextBlock(snapshot.context.schema, block)) {
53
+ selectedTextBlocks.push({node: block, path: [{_key: block._key}]})
54
+ }
55
+
56
+ break
57
+ }
58
+
59
+ if (selectedTextBlocks.length > 0) {
60
+ if (isTextBlock(snapshot.context.schema, block)) {
61
+ selectedTextBlocks.push({node: block, path: [{_key: block._key}]})
62
+ }
63
+ }
64
+ }
65
+
66
+ return selectedTextBlocks
67
+ }