@portabletext/editor 1.13.0 → 1.14.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 (74) hide show
  1. package/README.md +1 -1
  2. package/lib/_chunks-cjs/selector.get-text-before.cjs +320 -0
  3. package/lib/_chunks-cjs/selector.get-text-before.cjs.map +1 -0
  4. package/lib/_chunks-es/selector.get-text-before.js +321 -0
  5. package/lib/_chunks-es/selector.get-text-before.js.map +1 -0
  6. package/lib/{index.esm.js → index.cjs} +1703 -1431
  7. package/lib/index.cjs.map +1 -0
  8. package/lib/{index.d.mts → index.d.cts} +4038 -313
  9. package/lib/index.d.ts +4038 -313
  10. package/lib/index.js +1724 -1407
  11. package/lib/index.js.map +1 -1
  12. package/lib/selectors/index.cjs +35 -0
  13. package/lib/selectors/index.cjs.map +1 -0
  14. package/lib/selectors/index.d.cts +243 -0
  15. package/lib/selectors/index.d.ts +243 -0
  16. package/lib/selectors/index.js +36 -0
  17. package/lib/selectors/index.js.map +1 -0
  18. package/package.json +21 -13
  19. package/src/editor/Editable.tsx +1 -1
  20. package/src/editor/PortableTextEditor.tsx +19 -4
  21. package/src/editor/__tests__/handleClick.test.tsx +4 -4
  22. package/src/editor/behavior/behavior.action.insert-block-object.ts +1 -1
  23. package/src/editor/behavior/behavior.action.insert-break.ts +3 -3
  24. package/src/editor/behavior/behavior.action.insert-inline-object.ts +58 -0
  25. package/src/editor/behavior/behavior.action.insert-span.ts +1 -1
  26. package/src/editor/behavior/behavior.action.list-item.ts +100 -0
  27. package/src/editor/behavior/behavior.action.style.ts +108 -0
  28. package/src/editor/behavior/behavior.action.text-block.set.ts +25 -0
  29. package/src/editor/behavior/behavior.action.text-block.unset.ts +17 -0
  30. package/src/editor/behavior/behavior.actions.ts +178 -109
  31. package/src/editor/behavior/behavior.code-editor.ts +30 -40
  32. package/src/editor/behavior/behavior.core.block-objects.ts +26 -26
  33. package/src/editor/behavior/behavior.core.decorators.ts +9 -6
  34. package/src/editor/behavior/behavior.core.lists.ts +139 -17
  35. package/src/editor/behavior/behavior.core.ts +5 -2
  36. package/src/editor/behavior/behavior.guards.ts +28 -0
  37. package/src/editor/behavior/behavior.links.ts +7 -7
  38. package/src/editor/behavior/behavior.markdown.ts +68 -79
  39. package/src/editor/behavior/behavior.types.ts +86 -60
  40. package/src/editor/{use-editor.ts → create-editor.ts} +13 -8
  41. package/src/editor/editor-event-listener.tsx +2 -2
  42. package/src/editor/editor-machine.ts +54 -15
  43. package/src/editor/editor-provider.tsx +5 -5
  44. package/src/editor/editor-selector.ts +49 -0
  45. package/src/editor/editor-snapshot.ts +22 -0
  46. package/src/editor/get-value.ts +11 -0
  47. package/src/editor/plugins/create-with-event-listeners.ts +93 -5
  48. package/src/editor/plugins/createWithEditableAPI.ts +69 -20
  49. package/src/editor/plugins/createWithHotKeys.ts +0 -54
  50. package/src/editor/plugins/createWithPortableTextBlockStyle.ts +1 -55
  51. package/src/editor/plugins/with-plugins.ts +4 -8
  52. package/src/editor/{behavior/behavior.utils.block-offset.test.ts → utils/utils.block-offset.test.ts} +1 -1
  53. package/src/editor/{behavior/behavior.utils.block-offset.ts → utils/utils.block-offset.ts} +1 -8
  54. package/src/editor/{behavior/behavior.utils.reverse-selection.ts → utils/utils.reverse-selection.ts} +3 -5
  55. package/src/editor/utils/utils.ts +21 -0
  56. package/src/index.ts +13 -13
  57. package/src/selectors/index.ts +15 -0
  58. package/src/selectors/selector.get-active-list-item.ts +37 -0
  59. package/src/{editor/behavior/behavior.utils.get-selection-text.ts → selectors/selector.get-selection-text.ts} +10 -15
  60. package/src/selectors/selector.get-text-before.ts +41 -0
  61. package/src/selectors/selectors.ts +329 -0
  62. package/src/types/editor.ts +0 -60
  63. package/src/utils/is-hotkey.test.ts +2 -0
  64. package/src/utils/operationToPatches.ts +5 -0
  65. package/src/utils/paths.ts +4 -11
  66. package/src/utils/ranges.ts +3 -3
  67. package/lib/index.esm.js.map +0 -1
  68. package/lib/index.mjs +0 -7541
  69. package/lib/index.mjs.map +0 -1
  70. package/src/editor/behavior/behavior.utils.ts +0 -218
  71. package/src/editor/behavior/behavior.utilts.get-text-before.ts +0 -31
  72. package/src/editor/plugins/createWithPortableTextLists.ts +0 -172
  73. /package/src/editor/{behavior/behavior.utils.get-start-point.ts → utils/utils.get-start-point.ts} +0 -0
  74. /package/src/editor/{behavior/behavior.utils.is-keyed-segment.ts → utils/utils.is-keyed-segment.ts} +0 -0
@@ -1,15 +1,15 @@
1
1
  import {isPortableTextTextBlock} from '@sanity/types'
2
- import type {PortableTextMemberSchemaTypes} from '../../types/editor'
3
- import {defineBehavior} from './behavior.types'
2
+ import {getBlockTextBefore} from '../../selectors/selector.get-text-before'
4
3
  import {
5
4
  getFocusBlock,
6
5
  getFocusSpan,
7
6
  getFocusTextBlock,
8
- getTextBlockText,
9
7
  selectionIsCollapsed,
10
- } from './behavior.utils'
11
- import {spanSelectionPointToBlockOffset} from './behavior.utils.block-offset'
12
- import {getBlockTextBefore} from './behavior.utilts.get-text-before'
8
+ } from '../../selectors/selectors'
9
+ import type {PortableTextMemberSchemaTypes} from '../../types/editor'
10
+ import {getTextBlockText} from '../utils/utils'
11
+ import {spanSelectionPointToBlockOffset} from '../utils/utils.block-offset'
12
+ import {defineBehavior} from './behavior.types'
13
13
 
14
14
  /**
15
15
  * @alpha
@@ -41,7 +41,7 @@ export type MarkdownBehaviorsConfig = {
41
41
  */
42
42
  export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
43
43
  const automaticBlockquoteOnSpace = defineBehavior({
44
- on: 'insert text',
44
+ on: 'insert.text',
45
45
  guard: ({context, event}) => {
46
46
  const isSpace = event.text === ' '
47
47
 
@@ -49,9 +49,9 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
49
49
  return false
50
50
  }
51
51
 
52
- const selectionCollapsed = selectionIsCollapsed(context)
53
- const focusTextBlock = getFocusTextBlock(context)
54
- const focusSpan = getFocusSpan(context)
52
+ const selectionCollapsed = selectionIsCollapsed({context})
53
+ const focusTextBlock = getFocusTextBlock({context})
54
+ const focusSpan = getFocusSpan({context})
55
55
 
56
56
  if (!selectionCollapsed || !focusTextBlock || !focusSpan) {
57
57
  return false
@@ -76,7 +76,7 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
76
76
  const blockText = getTextBlockText(focusTextBlock.node)
77
77
  const caretAtTheEndOfQuote = blockOffset.offset === 1
78
78
  const looksLikeMarkdownQuote = /^>/.test(blockText)
79
- const blockquoteStyle = config.blockquoteStyle?.({schema: context.schema})
79
+ const blockquoteStyle = config.blockquoteStyle?.(context)
80
80
 
81
81
  if (
82
82
  caretAtTheEndOfQuote &&
@@ -91,23 +91,23 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
91
91
  actions: [
92
92
  () => [
93
93
  {
94
- type: 'insert text',
94
+ type: 'insert.text',
95
95
  text: ' ',
96
96
  },
97
97
  ],
98
- (_, {focusTextBlock, style}) => [
98
+ ({focusTextBlock, style}) => [
99
99
  {
100
- type: 'unset block',
100
+ type: 'text block.unset',
101
101
  props: ['listItem', 'level'],
102
- paths: [focusTextBlock.path],
102
+ at: focusTextBlock.path,
103
103
  },
104
104
  {
105
- type: 'set block',
105
+ type: 'text block.set',
106
106
  style,
107
- paths: [focusTextBlock.path],
107
+ at: focusTextBlock.path,
108
108
  },
109
109
  {
110
- type: 'delete text',
110
+ type: 'delete.text',
111
111
  anchor: {
112
112
  path: focusTextBlock.path,
113
113
  offset: 0,
@@ -121,7 +121,7 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
121
121
  ],
122
122
  })
123
123
  const automaticHr = defineBehavior({
124
- on: 'insert text',
124
+ on: 'insert.text',
125
125
  guard: ({context, event}) => {
126
126
  const hrCharacter =
127
127
  event.text === '-'
@@ -136,20 +136,15 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
136
136
  return false
137
137
  }
138
138
 
139
- const hrObject = config.horizontalRuleObject?.({
140
- schema: context.schema,
141
- })
142
- const focusBlock = getFocusTextBlock(context)
143
- const selectionCollapsed = selectionIsCollapsed(context)
139
+ const hrObject = config.horizontalRuleObject?.(context)
140
+ const focusBlock = getFocusTextBlock({context})
141
+ const selectionCollapsed = selectionIsCollapsed({context})
144
142
 
145
143
  if (!hrObject || !focusBlock || !selectionCollapsed) {
146
144
  return false
147
145
  }
148
146
 
149
- const textBefore = getBlockTextBefore({
150
- value: context.value,
151
- point: context.selection.focus,
152
- })
147
+ const textBefore = getBlockTextBefore({context})
153
148
  const hrBlockOffsets = {
154
149
  anchor: {
155
150
  path: focusBlock.path,
@@ -168,20 +163,20 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
168
163
  return false
169
164
  },
170
165
  actions: [
171
- (_, {hrCharacter}) => [
166
+ ({hrCharacter}) => [
172
167
  {
173
- type: 'insert text',
168
+ type: 'insert.text',
174
169
  text: hrCharacter,
175
170
  },
176
171
  ],
177
- (_, {hrObject, hrBlockOffsets}) => [
172
+ ({hrObject, hrBlockOffsets}) => [
178
173
  {
179
- type: 'insert block object',
174
+ type: 'insert.block object',
180
175
  placement: 'before',
181
176
  blockObject: hrObject,
182
177
  },
183
178
  {
184
- type: 'delete text',
179
+ type: 'delete.text',
185
180
  ...hrBlockOffsets,
186
181
  },
187
182
  ],
@@ -193,10 +188,8 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
193
188
  const text = event.data.getData('text/plain')
194
189
  const hrRegExp = /^(---)$|(___)$|(\*\*\*)$/gm
195
190
  const hrCharacters = text.match(hrRegExp)?.[0]
196
- const hrObject = config.horizontalRuleObject?.({
197
- schema: context.schema,
198
- })
199
- const focusBlock = getFocusBlock(context)
191
+ const hrObject = config.horizontalRuleObject?.(context)
192
+ const focusBlock = getFocusBlock({context})
200
193
 
201
194
  if (!hrCharacters || !hrObject || !focusBlock) {
202
195
  return false
@@ -205,30 +198,30 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
205
198
  return {hrCharacters, hrObject, focusBlock}
206
199
  },
207
200
  actions: [
208
- (_, {hrCharacters}) => [
201
+ ({hrCharacters}) => [
209
202
  {
210
- type: 'insert text',
203
+ type: 'insert.text',
211
204
  text: hrCharacters,
212
205
  },
213
206
  ],
214
- (_, {hrObject, focusBlock}) =>
207
+ ({hrObject, focusBlock}) =>
215
208
  isPortableTextTextBlock(focusBlock.node)
216
209
  ? [
217
210
  {
218
- type: 'insert text block',
211
+ type: 'insert.text block',
219
212
  textBlock: {children: focusBlock.node.children},
220
213
  placement: 'after',
221
214
  },
222
215
  {
223
- type: 'insert block object',
216
+ type: 'insert.block object',
224
217
  blockObject: hrObject,
225
218
  placement: 'after',
226
219
  },
227
- {type: 'delete block', blockPath: focusBlock.path},
220
+ {type: 'delete.block', blockPath: focusBlock.path},
228
221
  ]
229
222
  : [
230
223
  {
231
- type: 'insert block object',
224
+ type: 'insert.block object',
232
225
  blockObject: hrObject,
233
226
  placement: 'after',
234
227
  },
@@ -236,7 +229,7 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
236
229
  ],
237
230
  })
238
231
  const automaticHeadingOnSpace = defineBehavior({
239
- on: 'insert text',
232
+ on: 'insert.text',
240
233
  guard: ({context, event}) => {
241
234
  const isSpace = event.text === ' '
242
235
 
@@ -244,9 +237,9 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
244
237
  return false
245
238
  }
246
239
 
247
- const selectionCollapsed = selectionIsCollapsed(context)
248
- const focusTextBlock = getFocusTextBlock(context)
249
- const focusSpan = getFocusSpan(context)
240
+ const selectionCollapsed = selectionIsCollapsed({context})
241
+ const focusTextBlock = getFocusTextBlock({context})
242
+ const focusSpan = getFocusSpan({context})
250
243
 
251
244
  if (!selectionCollapsed || !focusTextBlock || !focusSpan) {
252
245
  return false
@@ -297,23 +290,23 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
297
290
  actions: [
298
291
  () => [
299
292
  {
300
- type: 'insert text',
293
+ type: 'insert.text',
301
294
  text: ' ',
302
295
  },
303
296
  ],
304
- (_, {focusTextBlock, style, level}) => [
297
+ ({focusTextBlock, style, level}) => [
305
298
  {
306
- type: 'unset block',
299
+ type: 'text block.unset',
307
300
  props: ['listItem', 'level'],
308
- paths: [focusTextBlock.path],
301
+ at: focusTextBlock.path,
309
302
  },
310
303
  {
311
- type: 'set block',
304
+ type: 'text block.set',
312
305
  style,
313
- paths: [focusTextBlock.path],
306
+ at: focusTextBlock.path,
314
307
  },
315
308
  {
316
- type: 'delete text',
309
+ type: 'delete.text',
317
310
  anchor: {
318
311
  path: focusTextBlock.path,
319
312
  offset: 0,
@@ -327,11 +320,11 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
327
320
  ],
328
321
  })
329
322
  const clearStyleOnBackspace = defineBehavior({
330
- on: 'delete backward',
323
+ on: 'delete.backward',
331
324
  guard: ({context}) => {
332
- const selectionCollapsed = selectionIsCollapsed(context)
333
- const focusTextBlock = getFocusTextBlock(context)
334
- const focusSpan = getFocusSpan(context)
325
+ const selectionCollapsed = selectionIsCollapsed({context})
326
+ const focusTextBlock = getFocusTextBlock({context})
327
+ const focusSpan = getFocusSpan({context})
335
328
 
336
329
  if (!selectionCollapsed || !focusTextBlock || !focusSpan) {
337
330
  return false
@@ -341,7 +334,7 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
341
334
  focusTextBlock.node.children[0]._key === focusSpan.node._key &&
342
335
  context.selection.focus.offset === 0
343
336
 
344
- const defaultStyle = config.defaultStyle?.({schema: context.schema})
337
+ const defaultStyle = config.defaultStyle?.(context)
345
338
 
346
339
  if (
347
340
  atTheBeginningOfBLock &&
@@ -354,17 +347,17 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
354
347
  return false
355
348
  },
356
349
  actions: [
357
- (_, {defaultStyle, focusTextBlock}) => [
350
+ ({defaultStyle, focusTextBlock}) => [
358
351
  {
359
- type: 'set block',
352
+ type: 'text block.set',
360
353
  style: defaultStyle,
361
- paths: [focusTextBlock.path],
354
+ at: focusTextBlock.path,
362
355
  },
363
356
  ],
364
357
  ],
365
358
  })
366
359
  const automaticListOnSpace = defineBehavior({
367
- on: 'insert text',
360
+ on: 'insert.text',
368
361
  guard: ({context, event}) => {
369
362
  const isSpace = event.text === ' '
370
363
 
@@ -372,9 +365,9 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
372
365
  return false
373
366
  }
374
367
 
375
- const selectionCollapsed = selectionIsCollapsed(context)
376
- const focusTextBlock = getFocusTextBlock(context)
377
- const focusSpan = getFocusSpan(context)
368
+ const selectionCollapsed = selectionIsCollapsed({context})
369
+ const focusTextBlock = getFocusTextBlock({context})
370
+ const focusSpan = getFocusSpan({context})
378
371
 
379
372
  if (!selectionCollapsed || !focusTextBlock || !focusSpan) {
380
373
  return false
@@ -397,11 +390,9 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
397
390
  }
398
391
 
399
392
  const blockText = getTextBlockText(focusTextBlock.node)
400
- const defaultStyle = config.defaultStyle?.({schema: context.schema})
393
+ const defaultStyle = config.defaultStyle?.(context)
401
394
  const looksLikeUnorderedList = /^(-|\*)/.test(blockText)
402
- const unorderedListStyle = config.unorderedListStyle?.({
403
- schema: context.schema,
404
- })
395
+ const unorderedListStyle = config.unorderedListStyle?.(context)
405
396
  const caretAtTheEndOfUnorderedList = blockOffset.offset === 1
406
397
 
407
398
  if (
@@ -419,9 +410,7 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
419
410
  }
420
411
 
421
412
  const looksLikeOrderedList = /^1\./.test(blockText)
422
- const orderedListStyle = config.orderedListStyle?.({
423
- schema: context.schema,
424
- })
413
+ const orderedListStyle = config.orderedListStyle?.(context)
425
414
  const caretAtTheEndOfOrderedList = blockOffset.offset === 2
426
415
 
427
416
  if (
@@ -443,20 +432,20 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
443
432
  actions: [
444
433
  () => [
445
434
  {
446
- type: 'insert text',
435
+ type: 'insert.text',
447
436
  text: ' ',
448
437
  },
449
438
  ],
450
- (_, {focusTextBlock, style, listItem, listItemLength}) => [
439
+ ({focusTextBlock, style, listItem, listItemLength}) => [
451
440
  {
452
- type: 'set block',
441
+ type: 'text block.set',
453
442
  listItem,
454
443
  level: 1,
455
444
  style,
456
- paths: [focusTextBlock.path],
445
+ at: focusTextBlock.path,
457
446
  },
458
447
  {
459
- type: 'delete text',
448
+ type: 'delete.text',
460
449
  anchor: {
461
450
  path: focusTextBlock.path,
462
451
  offset: 0,
@@ -1,25 +1,8 @@
1
- import type {
2
- KeyedSegment,
3
- PortableTextBlock,
4
- PortableTextTextBlock,
5
- } from '@sanity/types'
1
+ import type {KeyedSegment, PortableTextTextBlock} from '@sanity/types'
6
2
  import type {TextUnit} from 'slate'
7
3
  import type {TextInsertTextOptions} from 'slate/dist/interfaces/transforms/text'
8
- import type {
9
- EditorSelection,
10
- PortableTextMemberSchemaTypes,
11
- PortableTextSlateEditor,
12
- } from '../../types/editor'
13
- import type {BlockOffset} from './behavior.utils.block-offset'
14
-
15
- /**
16
- * @alpha
17
- */
18
- export type BehaviorContext = {
19
- schema: PortableTextMemberSchemaTypes
20
- value: Array<PortableTextBlock>
21
- selection: NonNullable<EditorSelection>
22
- }
4
+ import type {EditorSelection, PortableTextSlateEditor} from '../../types/editor'
5
+ import type {EditorContext} from '../editor-snapshot'
23
6
 
24
7
  /**
25
8
  * @alpha
@@ -45,6 +28,9 @@ export type BehaviorEvent =
45
28
  value: {[prop: string]: unknown}
46
29
  }
47
30
  }
31
+ | {
32
+ type: 'blur'
33
+ }
48
34
  | {
49
35
  type: 'copy'
50
36
  data: DataTransfer
@@ -62,24 +48,39 @@ export type BehaviorEvent =
62
48
  decorator: string
63
49
  }
64
50
  | {
65
- type: 'delete backward'
51
+ type: 'delete.backward'
66
52
  unit: TextUnit
67
53
  }
68
54
  | {
69
- type: 'delete forward'
55
+ type: 'delete.forward'
70
56
  unit: TextUnit
71
57
  }
72
58
  | {
73
59
  type: 'focus'
74
60
  }
75
61
  | {
76
- type: 'insert soft break'
62
+ type: 'insert.block object'
63
+ placement: 'auto' | 'after' | 'before'
64
+ blockObject: {
65
+ name: string
66
+ value?: {[prop: string]: unknown}
67
+ }
77
68
  }
78
69
  | {
79
- type: 'insert break'
70
+ type: 'insert.inline object'
71
+ inlineObject: {
72
+ name: string
73
+ value?: {[prop: string]: unknown}
74
+ }
80
75
  }
81
76
  | {
82
- type: 'insert text'
77
+ type: 'insert.soft break'
78
+ }
79
+ | {
80
+ type: 'insert.break'
81
+ }
82
+ | {
83
+ type: 'insert.text'
83
84
  text: string
84
85
  options?: TextInsertTextOptions
85
86
  }
@@ -101,6 +102,14 @@ export type BehaviorEvent =
101
102
  'key' | 'code' | 'altKey' | 'ctrlKey' | 'metaKey' | 'shiftKey'
102
103
  >
103
104
  }
105
+ | {
106
+ type: 'list item.toggle'
107
+ listItem: string
108
+ }
109
+ | {
110
+ type: 'style.toggle'
111
+ style: string
112
+ }
104
113
 
105
114
  /**
106
115
  * @alpha
@@ -112,8 +121,8 @@ export type BehaviorGuard<
112
121
  context,
113
122
  event,
114
123
  }: {
124
+ context: EditorContext
115
125
  event: TBehaviorEvent
116
- context: BehaviorContext
117
126
  }) => TGuardResponse | false
118
127
 
119
128
  /**
@@ -122,15 +131,7 @@ export type BehaviorGuard<
122
131
  export type BehaviorActionIntend =
123
132
  | BehaviorEvent
124
133
  | {
125
- type: 'insert block object'
126
- placement: 'auto' | 'after' | 'before'
127
- blockObject: {
128
- name: string
129
- value?: {[prop: string]: unknown}
130
- }
131
- }
132
- | {
133
- type: 'insert span'
134
+ type: 'insert.span'
134
135
  text: string
135
136
  annotations?: Array<{
136
137
  name: string
@@ -139,35 +140,42 @@ export type BehaviorActionIntend =
139
140
  decorators?: Array<string>
140
141
  }
141
142
  | {
142
- type: 'insert text block'
143
+ type: 'insert.text block'
143
144
  placement: 'auto' | 'after' | 'before'
144
145
  textBlock?: {
145
146
  children?: PortableTextTextBlock['children']
146
147
  }
147
148
  }
148
149
  | {
149
- type: 'move block'
150
- blockPath: [KeyedSegment]
150
+ type: 'list item.add'
151
+ listItem: string
152
+ }
153
+ | {
154
+ type: 'list item.remove'
155
+ listItem: string
156
+ }
157
+ | {
158
+ type: 'move.block'
159
+ at: [KeyedSegment]
151
160
  to: [KeyedSegment]
152
161
  }
153
162
  | {
154
- type: 'set block'
155
- paths: Array<[KeyedSegment]>
156
- style?: string
157
- listItem?: string
158
- level?: number
163
+ type: 'move.block down'
164
+ at: [KeyedSegment]
165
+ }
166
+ | {
167
+ type: 'move.block up'
168
+ at: [KeyedSegment]
159
169
  }
160
170
  | {
161
- type: 'unset block'
162
- paths: Array<[KeyedSegment]>
163
- props: Array<'style' | 'listItem' | 'level'>
171
+ type: 'noop'
164
172
  }
165
173
  | {
166
- type: 'delete block'
174
+ type: 'delete.block'
167
175
  blockPath: [KeyedSegment]
168
176
  }
169
177
  | {
170
- type: 'delete text'
178
+ type: 'delete.text'
171
179
  anchor: BlockOffset
172
180
  focus: BlockOffset
173
181
  }
@@ -188,6 +196,26 @@ export type BehaviorActionIntend =
188
196
  | {
189
197
  type: 'reselect'
190
198
  }
199
+ | {
200
+ type: 'style.add'
201
+ style: string
202
+ }
203
+ | {
204
+ type: 'style.remove'
205
+ style: string
206
+ }
207
+ | {
208
+ type: 'text block.set'
209
+ at: [KeyedSegment]
210
+ level?: number
211
+ listItem?: string
212
+ style?: string
213
+ }
214
+ | {
215
+ type: 'text block.unset'
216
+ at: [KeyedSegment]
217
+ props: Array<'level' | 'listItem' | 'style'>
218
+ }
191
219
 
192
220
  /**
193
221
  * @alpha
@@ -219,23 +247,13 @@ export type Behavior<
219
247
  /**
220
248
  * Array of behavior action sets.
221
249
  */
222
- actions: Array<BehaviorActionIntendSet<TBehaviorEventType, TGuardResponse>>
250
+ actions: Array<BehaviorActionIntendSet<TGuardResponse>>
223
251
  }
224
252
 
225
253
  /**
226
254
  * @alpha
227
255
  */
228
- export type BehaviorActionIntendSet<
229
- TBehaviorEventType extends BehaviorEvent['type'] = BehaviorEvent['type'],
230
- TGuardResponse = true,
231
- > = (
232
- {
233
- context,
234
- event,
235
- }: {
236
- context: BehaviorContext
237
- event: PickFromUnion<BehaviorEvent, 'type', TBehaviorEventType>
238
- },
256
+ export type BehaviorActionIntendSet<TGuardResponse = true> = (
239
257
  guardResponse: TGuardResponse,
240
258
  ) => Array<
241
259
  OmitFromUnion<
@@ -255,6 +273,14 @@ export function defineBehavior<
255
273
  return behavior as unknown as Behavior
256
274
  }
257
275
 
276
+ /**
277
+ * @alpha
278
+ */
279
+ export type BlockOffset = {
280
+ path: [KeyedSegment]
281
+ offset: number
282
+ }
283
+
258
284
  /**
259
285
  * @alpha
260
286
  */
@@ -53,7 +53,15 @@ export type EditorEvent = PickFromUnion<
53
53
  InternalEditorEvent,
54
54
  'type',
55
55
  | 'annotation.toggle'
56
+ | 'blur'
57
+ | 'decorator.add'
58
+ | 'decorator.remove'
59
+ | 'decorator.toggle'
56
60
  | 'focus'
61
+ | 'insert.block object'
62
+ | 'insert.inline object'
63
+ | 'list item.toggle'
64
+ | 'style.toggle'
57
65
  | 'patches'
58
66
  | 'toggle readOnly'
59
67
  | 'update behaviors'
@@ -66,15 +74,15 @@ export type EditorEvent = PickFromUnion<
66
74
  export type Editor = {
67
75
  send: (event: EditorEvent) => void
68
76
  on: ActorRef<Snapshot<unknown>, EventObject, EditorEmittedEvent>['on']
69
- editable: EditableAPI
70
77
  _internal: {
78
+ editable: EditableAPI
71
79
  editorActor: EditorActor
72
80
  slateEditor: SlateEditor
73
81
  }
74
82
  }
75
83
 
76
84
  /**
77
- * @alpha
85
+ * @internal
78
86
  */
79
87
  export function createEditor(config: EditorConfig): Editor {
80
88
  const editorActor = createActor(editorMachine, {
@@ -96,18 +104,15 @@ export function createEditor(config: EditorConfig): Editor {
96
104
  // @ts-ignore
97
105
  listener,
98
106
  ),
99
- editable,
100
107
  _internal: {
108
+ editable,
101
109
  editorActor,
102
110
  slateEditor,
103
111
  },
104
112
  }
105
113
  }
106
114
 
107
- /**
108
- * @alpha
109
- */
110
- export function useEditor(config: EditorConfig): Editor {
115
+ export function useCreateEditor(config: EditorConfig): Editor {
111
116
  const editorActor = useActorRef(editorMachine, {
112
117
  input: editorConfigToMachineInput(config),
113
118
  })
@@ -135,8 +140,8 @@ export function useEditor(config: EditorConfig): Editor {
135
140
  () => ({
136
141
  send,
137
142
  on,
138
- editable,
139
143
  _internal: {
144
+ editable,
140
145
  editorActor,
141
146
  slateEditor,
142
147
  },
@@ -1,7 +1,7 @@
1
1
  import {useEffect} from 'react'
2
2
  import {useEffectEvent} from 'use-effect-event'
3
3
  import type {EditorEmittedEvent} from './editor-machine'
4
- import {useEditorContext} from './editor-provider'
4
+ import {useEditor} from './editor-provider'
5
5
 
6
6
  /**
7
7
  * @alpha
@@ -9,7 +9,7 @@ import {useEditorContext} from './editor-provider'
9
9
  export function EditorEventListener(props: {
10
10
  on: (event: EditorEmittedEvent) => void
11
11
  }) {
12
- const editor = useEditorContext()
12
+ const editor = useEditor()
13
13
  const on = useEffectEvent(props.on)
14
14
 
15
15
  useEffect(() => {