@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
@@ -16,6 +16,7 @@ import type {
16
16
  PortableTextMemberSchemaTypes,
17
17
  PortableTextSlateEditor,
18
18
  } from '../types/editor'
19
+ import debug from '../utils/debug'
19
20
  import {toPortableTextRange} from '../utils/ranges'
20
21
  import {fromSlateValue} from '../utils/values'
21
22
  import {KEY_TO_VALUE_ELEMENT} from '../utils/weakMaps'
@@ -25,11 +26,11 @@ import type {
25
26
  Behavior,
26
27
  BehaviorAction,
27
28
  BehaviorActionIntend,
28
- BehaviorContext,
29
29
  BehaviorEvent,
30
30
  OmitFromUnion,
31
31
  PickFromUnion,
32
32
  } from './behavior/behavior.types'
33
+ import type {EditorContext} from './editor-snapshot'
33
34
 
34
35
  export * from 'xstate/guards'
35
36
 
@@ -105,10 +106,10 @@ export type InternalEditorEvent =
105
106
  export type EditorEmittedEvent = PickFromUnion<
106
107
  InternalEditorEmittedEvent,
107
108
  'type',
108
- | 'blur'
109
+ | 'blurred'
109
110
  | 'done loading'
110
111
  | 'error'
111
- | 'focus'
112
+ | 'focused'
112
113
  | 'invalid value'
113
114
  | 'loading'
114
115
  | 'mutation'
@@ -147,7 +148,7 @@ export type InternalEditorEmittedEvent =
147
148
  data: unknown
148
149
  }
149
150
  | {type: 'selection'; selection: EditorSelection}
150
- | {type: 'blur'; event: FocusEvent<HTMLDivElement, Element>}
151
+ | {type: 'blurred'; event: FocusEvent<HTMLDivElement, Element>}
151
152
  | {type: 'focused'; event: FocusEvent<HTMLDivElement, Element>}
152
153
  | {type: 'loading'}
153
154
  | {type: 'done loading'}
@@ -155,7 +156,18 @@ export type InternalEditorEmittedEvent =
155
156
  | PickFromUnion<
156
157
  BehaviorEvent,
157
158
  'type',
158
- 'annotation.add' | 'annotation.remove' | 'annotation.toggle' | 'focus'
159
+ | 'annotation.add'
160
+ | 'annotation.remove'
161
+ | 'annotation.toggle'
162
+ | 'blur'
163
+ | 'decorator.add'
164
+ | 'decorator.remove'
165
+ | 'decorator.toggle'
166
+ | 'insert.block object'
167
+ | 'insert.inline object'
168
+ | 'list item.toggle'
169
+ | 'focus'
170
+ | 'style.toggle'
159
171
  >
160
172
 
161
173
  /**
@@ -170,6 +182,7 @@ export const editorMachine = setup({
170
182
  schema: PortableTextMemberSchemaTypes
171
183
  readOnly: boolean
172
184
  maxBlocks: number | undefined
185
+ selection: NonNullable<EditorSelection> | undefined
173
186
  value: Array<PortableTextBlock> | undefined
174
187
  },
175
188
  events: {} as InternalEditorEvent,
@@ -221,6 +234,8 @@ export const editorMachine = setup({
221
234
  'handle behavior event': enqueueActions(({context, event, enqueue}) => {
222
235
  assertEvent(event, ['behavior event'])
223
236
 
237
+ debug('Behavior event', event)
238
+
224
239
  const defaultAction = {
225
240
  ...event.behaviorEvent,
226
241
  editor: event.editor,
@@ -262,11 +277,12 @@ export const editorMachine = setup({
262
277
  return
263
278
  }
264
279
 
265
- const behaviorContext = {
280
+ const editorContext = {
281
+ keyGenerator: context.keyGenerator,
266
282
  schema: context.schema,
267
- value,
268
283
  selection,
269
- } satisfies BehaviorContext
284
+ value,
285
+ } satisfies EditorContext
270
286
 
271
287
  let behaviorOverwritten = false
272
288
 
@@ -274,7 +290,7 @@ export const editorMachine = setup({
274
290
  const shouldRun =
275
291
  eventBehavior.guard === undefined ||
276
292
  eventBehavior.guard({
277
- context: behaviorContext,
293
+ context: editorContext,
278
294
  event: event.behaviorEvent,
279
295
  })
280
296
 
@@ -283,10 +299,7 @@ export const editorMachine = setup({
283
299
  }
284
300
 
285
301
  const actionIntendSets = eventBehavior.actions.map((actionSet) =>
286
- actionSet(
287
- {context: behaviorContext, event: event.behaviorEvent},
288
- shouldRun,
289
- ),
302
+ actionSet(shouldRun),
290
303
  )
291
304
 
292
305
  for (const actionIntends of actionIntendSets) {
@@ -326,6 +339,7 @@ export const editorMachine = setup({
326
339
  keyGenerator: input.keyGenerator,
327
340
  pendingEvents: [],
328
341
  schema: input.schema,
342
+ selection: undefined,
329
343
  readOnly: input.readOnly ?? false,
330
344
  maxBlocks: input.maxBlocks,
331
345
  value: input.value,
@@ -343,17 +357,42 @@ export const editorMachine = setup({
343
357
  actions: emit(({event}) => event),
344
358
  guard: ({context}) => !context.readOnly,
345
359
  },
360
+ 'blur': {
361
+ actions: emit(({event}) => event),
362
+ guard: ({context}) => !context.readOnly,
363
+ },
364
+ 'decorator.*': {
365
+ actions: emit(({event}) => event),
366
+ guard: ({context}) => !context.readOnly,
367
+ },
346
368
  'focus': {
347
369
  actions: emit(({event}) => event),
348
370
  guard: ({context}) => !context.readOnly,
349
371
  },
372
+ 'insert.*': {
373
+ actions: emit(({event}) => event),
374
+ guard: ({context}) => !context.readOnly,
375
+ },
376
+ 'list item.*': {
377
+ actions: emit(({event}) => event),
378
+ guard: ({context}) => !context.readOnly,
379
+ },
380
+ 'style.*': {
381
+ actions: emit(({event}) => event),
382
+ guard: ({context}) => !context.readOnly,
383
+ },
350
384
  'ready': {actions: emit(({event}) => event)},
351
385
  'unset': {actions: emit(({event}) => event)},
352
386
  'value changed': {actions: emit(({event}) => event)},
353
387
  'invalid value': {actions: emit(({event}) => event)},
354
388
  'error': {actions: emit(({event}) => event)},
355
- 'selection': {actions: emit(({event}) => event)},
356
- 'blur': {actions: emit(({event}) => event)},
389
+ 'selection': {
390
+ actions: [
391
+ assign({selection: ({event}) => event.selection ?? undefined}),
392
+ emit(({event}) => event),
393
+ ],
394
+ },
395
+ 'blurred': {actions: emit(({event}) => event)},
357
396
  'focused': {actions: emit(({event}) => event)},
358
397
  'loading': {actions: emit({type: 'loading'})},
359
398
  'patches': {actions: emit(({event}) => event)},
@@ -1,6 +1,7 @@
1
1
  import React, {useMemo} from 'react'
2
2
  import {Slate} from 'slate-react'
3
3
  import {Synchronizer} from './components/Synchronizer'
4
+ import {useCreateEditor, type Editor, type EditorConfig} from './create-editor'
4
5
  import {EditorActorContext} from './editor-actor-context'
5
6
  import {PortableTextEditorContext} from './hooks/usePortableTextEditor'
6
7
  import {PortableTextEditorSelectionProvider} from './hooks/usePortableTextEditorSelection'
@@ -9,7 +10,6 @@ import {
9
10
  RouteEventsToChanges,
10
11
  type PortableTextEditorProps,
11
12
  } from './PortableTextEditor'
12
- import {useEditor, type Editor, type EditorConfig} from './use-editor'
13
13
 
14
14
  const EditorContext = React.createContext<Editor | undefined>(undefined)
15
15
 
@@ -17,7 +17,7 @@ const EditorContext = React.createContext<Editor | undefined>(undefined)
17
17
  * @alpha
18
18
  */
19
19
  export type EditorProviderProps = {
20
- config: EditorConfig
20
+ initialConfig: EditorConfig
21
21
  children?: React.ReactNode
22
22
  }
23
23
 
@@ -25,10 +25,10 @@ export type EditorProviderProps = {
25
25
  * @alpha
26
26
  */
27
27
  export function EditorProvider(props: EditorProviderProps) {
28
- const editor = useEditor(props.config)
28
+ const editor = useCreateEditor(props.initialConfig)
29
29
  const editorActor = editor._internal.editorActor
30
30
  const slateEditor = editor._internal.slateEditor
31
- const editable = editor.editable
31
+ const editable = editor._internal.editable
32
32
  const portableTextEditor = useMemo(
33
33
  () =>
34
34
  new PortableTextEditor({
@@ -70,7 +70,7 @@ export function EditorProvider(props: EditorProviderProps) {
70
70
  /**
71
71
  * @alpha
72
72
  */
73
- export function useEditorContext() {
73
+ export function useEditor() {
74
74
  const editor = React.useContext(EditorContext)
75
75
 
76
76
  if (!editor) {
@@ -0,0 +1,49 @@
1
+ import {useSelector} from '@xstate/react'
2
+ import type {EditorSelection} from '../types/editor'
3
+ import type {Editor} from './create-editor'
4
+ import type {EditorSnapshot} from './editor-snapshot'
5
+ import {getValue} from './get-value'
6
+
7
+ function defaultCompare<T>(a: T, b: T) {
8
+ return a === b
9
+ }
10
+
11
+ /**
12
+ * @alpha
13
+ */
14
+ export type EditorSelectorSnapshot = {
15
+ context: Omit<EditorSnapshot['context'], 'selection'> & {
16
+ selection?: NonNullable<EditorSelection>
17
+ }
18
+ }
19
+
20
+ /**
21
+ * @alpha
22
+ */
23
+ export type EditorSelector<TSelected> = (
24
+ snapshot: EditorSelectorSnapshot,
25
+ ) => TSelected
26
+
27
+ /**
28
+ * @alpha
29
+ */
30
+ export function useEditorSelector<TSelected>(
31
+ editor: Editor,
32
+ selector: EditorSelector<TSelected>,
33
+ compare: (a: TSelected, b: TSelected) => boolean = defaultCompare,
34
+ ) {
35
+ return useSelector(
36
+ editor._internal.editorActor,
37
+ (snapshot) => {
38
+ const context = {
39
+ keyGenerator: snapshot.context.keyGenerator,
40
+ schema: snapshot.context.schema,
41
+ selection: snapshot.context.selection,
42
+ value: getValue(editor),
43
+ }
44
+
45
+ return selector({context})
46
+ },
47
+ compare,
48
+ )
49
+ }
@@ -0,0 +1,22 @@
1
+ import type {PortableTextBlock} from '@sanity/types'
2
+ import type {
3
+ EditorSelection,
4
+ PortableTextMemberSchemaTypes,
5
+ } from '../types/editor'
6
+
7
+ /**
8
+ * @alpha
9
+ */
10
+ export type EditorContext = {
11
+ keyGenerator: () => string
12
+ schema: PortableTextMemberSchemaTypes
13
+ selection: NonNullable<EditorSelection>
14
+ value: Array<PortableTextBlock>
15
+ }
16
+
17
+ /**
18
+ * @alpha
19
+ */
20
+ export type EditorSnapshot = {
21
+ context: EditorContext
22
+ }
@@ -0,0 +1,11 @@
1
+ import {fromSlateValue} from '../utils/values'
2
+ import {KEY_TO_VALUE_ELEMENT} from '../utils/weakMaps'
3
+ import type {Editor} from './create-editor'
4
+
5
+ export function getValue(editor: Editor) {
6
+ return fromSlateValue(
7
+ editor._internal.slateEditor.instance.children,
8
+ editor._internal.editorActor.getSnapshot().context.schema.block.name,
9
+ KEY_TO_VALUE_ELEMENT.get(editor._internal.slateEditor.instance),
10
+ )
11
+ }
@@ -46,6 +46,49 @@ export function createWithEventListeners(
46
46
  })
47
47
  break
48
48
  }
49
+ case 'blur': {
50
+ editorActor.send({
51
+ type: 'behavior event',
52
+ behaviorEvent: {
53
+ type: 'blur',
54
+ },
55
+ editor,
56
+ })
57
+ break
58
+ }
59
+ case 'decorator.add': {
60
+ editorActor.send({
61
+ type: 'behavior event',
62
+ behaviorEvent: {
63
+ type: 'decorator.add',
64
+ decorator: event.decorator,
65
+ },
66
+ editor,
67
+ })
68
+ break
69
+ }
70
+ case 'decorator.remove': {
71
+ editorActor.send({
72
+ type: 'behavior event',
73
+ behaviorEvent: {
74
+ type: 'decorator.remove',
75
+ decorator: event.decorator,
76
+ },
77
+ editor,
78
+ })
79
+ break
80
+ }
81
+ case 'decorator.toggle': {
82
+ editorActor.send({
83
+ type: 'behavior event',
84
+ behaviorEvent: {
85
+ type: 'decorator.toggle',
86
+ decorator: event.decorator,
87
+ },
88
+ editor,
89
+ })
90
+ break
91
+ }
49
92
  case 'focus': {
50
93
  editorActor.send({
51
94
  type: 'behavior event',
@@ -56,6 +99,51 @@ export function createWithEventListeners(
56
99
  })
57
100
  break
58
101
  }
102
+ case 'insert.block object': {
103
+ editorActor.send({
104
+ type: 'behavior event',
105
+ behaviorEvent: {
106
+ type: 'insert.block object',
107
+ placement: event.placement,
108
+ blockObject: event.blockObject,
109
+ },
110
+ editor,
111
+ })
112
+ break
113
+ }
114
+ case 'insert.inline object': {
115
+ editorActor.send({
116
+ type: 'behavior event',
117
+ behaviorEvent: {
118
+ type: 'insert.inline object',
119
+ inlineObject: event.inlineObject,
120
+ },
121
+ editor,
122
+ })
123
+ break
124
+ }
125
+ case 'list item.toggle': {
126
+ editorActor.send({
127
+ type: 'behavior event',
128
+ behaviorEvent: {
129
+ type: 'list item.toggle',
130
+ listItem: event.listItem,
131
+ },
132
+ editor,
133
+ })
134
+ break
135
+ }
136
+ case 'style.toggle': {
137
+ editorActor.send({
138
+ type: 'behavior event',
139
+ behaviorEvent: {
140
+ type: 'style.toggle',
141
+ style: event.style,
142
+ },
143
+ editor,
144
+ })
145
+ break
146
+ }
59
147
  }
60
148
  })
61
149
 
@@ -92,7 +180,7 @@ export function createWithEventListeners(
92
180
  editorActor.send({
93
181
  type: 'behavior event',
94
182
  behaviorEvent: {
95
- type: 'delete backward',
183
+ type: 'delete.backward',
96
184
  unit,
97
185
  },
98
186
  editor,
@@ -104,7 +192,7 @@ export function createWithEventListeners(
104
192
  editorActor.send({
105
193
  type: 'behavior event',
106
194
  behaviorEvent: {
107
- type: 'delete forward',
195
+ type: 'delete.forward',
108
196
  unit,
109
197
  },
110
198
  editor,
@@ -116,7 +204,7 @@ export function createWithEventListeners(
116
204
  editorActor.send({
117
205
  type: 'behavior event',
118
206
  behaviorEvent: {
119
- type: 'insert break',
207
+ type: 'insert.break',
120
208
  },
121
209
  editor,
122
210
  })
@@ -127,7 +215,7 @@ export function createWithEventListeners(
127
215
  editorActor.send({
128
216
  type: 'behavior event',
129
217
  behaviorEvent: {
130
- type: 'insert soft break',
218
+ type: 'insert.soft break',
131
219
  },
132
220
  editor,
133
221
  })
@@ -138,7 +226,7 @@ export function createWithEventListeners(
138
226
  editorActor.send({
139
227
  type: 'behavior event',
140
228
  behaviorEvent: {
141
- type: 'insert text',
229
+ type: 'insert.text',
142
230
  text,
143
231
  options,
144
232
  },
@@ -31,7 +31,8 @@ import {
31
31
  KEY_TO_VALUE_ELEMENT,
32
32
  SLATE_TO_PORTABLE_TEXT_RANGE,
33
33
  } from '../../utils/weakMaps'
34
- import {insertBlockObjectActionImplementation} from '../behavior/behavior.action.insert-block-object'
34
+ import {isListItemActive} from '../behavior/behavior.action.list-item'
35
+ import {isStyleActive} from '../behavior/behavior.action.style'
35
36
  import type {BehaviorActionImplementation} from '../behavior/behavior.actions'
36
37
  import type {EditorActor} from '../editor-machine'
37
38
  import {isDecoratorActive} from './createWithPortableTextMarkModel'
@@ -46,10 +47,22 @@ export function createEditableAPI(
46
47
 
47
48
  const editableApi: EditableAPI = {
48
49
  focus: (): void => {
49
- ReactEditor.focus(editor)
50
+ editorActor.send({
51
+ type: 'behavior event',
52
+ behaviorEvent: {
53
+ type: 'focus',
54
+ },
55
+ editor,
56
+ })
50
57
  },
51
58
  blur: (): void => {
52
- ReactEditor.blur(editor)
59
+ editorActor.send({
60
+ type: 'behavior event',
61
+ behaviorEvent: {
62
+ type: 'blur',
63
+ },
64
+ editor,
65
+ })
53
66
  },
54
67
  toggleMark: (mark: string): void => {
55
68
  editorActor.send({
@@ -61,11 +74,25 @@ export function createEditableAPI(
61
74
  editor,
62
75
  })
63
76
  },
64
- toggleList: (listStyle: string): void => {
65
- editor.pteToggleListItem(listStyle)
77
+ toggleList: (listItem: string): void => {
78
+ editorActor.send({
79
+ type: 'behavior event',
80
+ behaviorEvent: {
81
+ type: 'list item.toggle',
82
+ listItem,
83
+ },
84
+ editor,
85
+ })
66
86
  },
67
- toggleBlockStyle: (blockStyle: string): void => {
68
- editor.pteToggleBlockStyle(blockStyle)
87
+ toggleBlockStyle: (style: string): void => {
88
+ editorActor.send({
89
+ type: 'behavior event',
90
+ behaviorEvent: {
91
+ type: 'style.toggle',
92
+ style,
93
+ },
94
+ editor,
95
+ })
69
96
  },
70
97
  isMarkActive: (mark: string): boolean => {
71
98
  // Try/catch this, as Slate may error because the selection is currently wrong
@@ -132,6 +159,32 @@ export function createEditableAPI(
132
159
  type: TSchemaType,
133
160
  value?: {[prop: string]: any},
134
161
  ): Path => {
162
+ if (type.name !== types.span.name) {
163
+ editorActor.send({
164
+ type: 'behavior event',
165
+ behaviorEvent: {
166
+ type: 'insert.inline object',
167
+ inlineObject: {
168
+ name: type.name,
169
+ value,
170
+ },
171
+ },
172
+ editor,
173
+ })
174
+
175
+ return (
176
+ toPortableTextRange(
177
+ fromSlateValue(
178
+ editor.children,
179
+ types.block.name,
180
+ KEY_TO_VALUE_ELEMENT.get(editor),
181
+ ),
182
+ editor.selection,
183
+ types,
184
+ )?.focus.path ?? []
185
+ )
186
+ }
187
+
135
188
  if (!editor.selection) {
136
189
  throw new Error('The editor has no selection')
137
190
  }
@@ -187,6 +240,7 @@ export function createEditableAPI(
187
240
  at: editor.selection,
188
241
  })
189
242
  editor.onChange()
243
+
190
244
  return (
191
245
  toPortableTextRange(
192
246
  fromSlateValue(
@@ -203,24 +257,19 @@ export function createEditableAPI(
203
257
  type: TSchemaType,
204
258
  value?: {[prop: string]: any},
205
259
  ): Path => {
206
- insertBlockObjectActionImplementation({
207
- context: {
208
- keyGenerator: editorActor.getSnapshot().context.keyGenerator,
209
- schema: types,
210
- },
211
- action: {
212
- type: 'insert block object',
260
+ editorActor.send({
261
+ type: 'behavior event',
262
+ behaviorEvent: {
263
+ type: 'insert.block object',
213
264
  blockObject: {
214
265
  name: type.name,
215
266
  value,
216
267
  },
217
268
  placement: 'auto',
218
- editor,
219
269
  },
270
+ editor,
220
271
  })
221
272
 
222
- editor.onChange()
223
-
224
273
  return (
225
274
  toPortableTextRange(
226
275
  fromSlateValue(
@@ -235,15 +284,15 @@ export function createEditableAPI(
235
284
  },
236
285
  hasBlockStyle: (style: string): boolean => {
237
286
  try {
238
- return editor.pteHasBlockStyle(style)
287
+ return isStyleActive({editor, style})
239
288
  } catch {
240
289
  // This is fine.
241
290
  return false
242
291
  }
243
292
  },
244
- hasListStyle: (listStyle: string): boolean => {
293
+ hasListStyle: (listItem: string): boolean => {
245
294
  try {
246
- return editor.pteHasListStyle(listStyle)
295
+ return isListItemActive({editor, listItem})
247
296
  } catch {
248
297
  // This is fine.
249
298
  return false
@@ -1,10 +1,7 @@
1
- import {isPortableTextSpan, isPortableTextTextBlock} from '@sanity/types'
2
1
  import type {KeyboardEvent} from 'react'
3
- import {Editor, Node, Range} from 'slate'
4
2
  import type {ReactEditor} from 'slate-react'
5
3
  import type {PortableTextSlateEditor} from '../../types/editor'
6
4
  import type {HotkeyOptions} from '../../types/options'
7
- import type {SlateTextBlock, VoidElement} from '../../types/slate'
8
5
  import {debugWithName} from '../../utils/debug'
9
6
  import {isHotkey} from '../../utils/is-hotkey'
10
7
  import type {EditorActor} from '../editor-machine'
@@ -75,57 +72,6 @@ export function createWithHotkeys(
75
72
  }
76
73
  }
77
74
  })
78
-
79
- const isEnter = isHotkey('enter', event.nativeEvent)
80
- const isTab = isHotkey('tab', event.nativeEvent)
81
- const isShiftEnter = isHotkey('shift+enter', event.nativeEvent)
82
- const isShiftTab = isHotkey('shift+tab', event.nativeEvent)
83
-
84
- // Tab for lists
85
- // Only steal tab when we are on a plain text span or we are at the start of the line (fallback if the whole block is annotated or contains a single inline object)
86
- // Otherwise tab is reserved for accessability for buttons etc.
87
- if ((isTab || isShiftTab) && editor.selection) {
88
- const [focusChild] = Editor.node(editor, editor.selection.focus, {
89
- depth: 2,
90
- })
91
- const [focusBlock] = isPortableTextSpan(focusChild)
92
- ? Editor.node(editor, editor.selection.focus, {depth: 1})
93
- : []
94
- const hasAnnotationFocus =
95
- focusChild &&
96
- isPortableTextTextBlock(focusBlock) &&
97
- isPortableTextSpan(focusChild) &&
98
- (focusChild.marks || ([] as string[])).filter((m) =>
99
- (focusBlock.markDefs || []).map((def) => def._key).includes(m),
100
- ).length > 0
101
- const [start] = Range.edges(editor.selection)
102
- const atStartOfNode = Editor.isStart(editor, start, start.path)
103
-
104
- if (
105
- focusChild &&
106
- isPortableTextSpan(focusChild) &&
107
- (!hasAnnotationFocus || atStartOfNode) &&
108
- editor.pteIncrementBlockLevels(isShiftTab)
109
- ) {
110
- event.preventDefault()
111
- }
112
- }
113
-
114
- // Deal with enter key combos
115
- if (isEnter && !isShiftEnter && editor.selection) {
116
- const focusBlockPath = editor.selection.focus.path.slice(0, 1)
117
- const focusBlock = Node.descendant(editor, focusBlockPath) as
118
- | SlateTextBlock
119
- | VoidElement
120
-
121
- // List item enter key
122
- if (editor.isListBlock(focusBlock)) {
123
- if (editor.pteEndList()) {
124
- event.preventDefault()
125
- }
126
- return
127
- }
128
- }
129
75
  }
130
76
  return editor
131
77
  }