@portabletext/editor 2.9.1 → 2.9.2

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.
@@ -1,5 +1,5 @@
1
1
  import { Behavior, Editor, EditorEmittedEvent, EditorSchema } from "../_chunks-dts/behavior.types.action.cjs";
2
- import * as react22 from "react";
2
+ import * as react12 from "react";
3
3
  import React from "react";
4
4
  /**
5
5
  * @beta
@@ -181,7 +181,7 @@ type MarkdownPluginConfig = MarkdownBehaviorsConfig & {
181
181
  */
182
182
  declare function MarkdownPlugin(props: {
183
183
  config: MarkdownPluginConfig;
184
- }): react22.JSX.Element;
184
+ }): react12.JSX.Element;
185
185
  /**
186
186
  * @beta
187
187
  * Restrict the editor to one line. The plugin takes care of blocking
@@ -192,5 +192,5 @@ declare function MarkdownPlugin(props: {
192
192
  *
193
193
  * @deprecated Install the plugin from `@portabletext/plugin-one-line`
194
194
  */
195
- declare function OneLinePlugin(): react22.JSX.Element;
195
+ declare function OneLinePlugin(): react12.JSX.Element;
196
196
  export { BehaviorPlugin, DecoratorShortcutPlugin, EditorRefPlugin, EventListenerPlugin, MarkdownPlugin, type MarkdownPluginConfig, OneLinePlugin };
@@ -1,5 +1,5 @@
1
1
  import { Behavior, Editor, EditorEmittedEvent, EditorSchema } from "../_chunks-dts/behavior.types.action.js";
2
- import * as react21 from "react";
2
+ import * as react22 from "react";
3
3
  import React from "react";
4
4
  /**
5
5
  * @beta
@@ -181,7 +181,7 @@ type MarkdownPluginConfig = MarkdownBehaviorsConfig & {
181
181
  */
182
182
  declare function MarkdownPlugin(props: {
183
183
  config: MarkdownPluginConfig;
184
- }): react21.JSX.Element;
184
+ }): react22.JSX.Element;
185
185
  /**
186
186
  * @beta
187
187
  * Restrict the editor to one line. The plugin takes care of blocking
@@ -192,5 +192,5 @@ declare function MarkdownPlugin(props: {
192
192
  *
193
193
  * @deprecated Install the plugin from `@portabletext/plugin-one-line`
194
194
  */
195
- declare function OneLinePlugin(): react21.JSX.Element;
195
+ declare function OneLinePlugin(): react22.JSX.Element;
196
196
  export { BehaviorPlugin, DecoratorShortcutPlugin, EditorRefPlugin, EventListenerPlugin, MarkdownPlugin, type MarkdownPluginConfig, OneLinePlugin };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@portabletext/editor",
3
- "version": "2.9.1",
3
+ "version": "2.9.2",
4
4
  "description": "Portable Text Editor made in React",
5
5
  "keywords": [
6
6
  "sanity",
@@ -80,9 +80,9 @@
80
80
  "slate-react": "0.117.4",
81
81
  "xstate": "^5.21.0",
82
82
  "@portabletext/block-tools": "^3.5.5",
83
+ "@portabletext/schema": "^1.2.0",
83
84
  "@portabletext/keyboard-shortcuts": "^1.1.1",
84
- "@portabletext/patches": "^1.1.8",
85
- "@portabletext/schema": "^1.2.0"
85
+ "@portabletext/patches": "^1.1.8"
86
86
  },
87
87
  "devDependencies": {
88
88
  "@sanity/diff-match-patch": "^3.2.0",
@@ -1,7 +1,7 @@
1
1
  import {createEditorDom} from '../editor/editor-dom'
2
2
  import type {EditorSchema} from '../editor/editor-schema'
3
3
  import type {EditorSnapshot} from '../editor/editor-snapshot'
4
- import {withApplyingBehaviorOperations} from '../editor/with-applying-behavior-operations'
4
+ import {withPerformingBehaviorOperation} from '../editor/with-performing-behavior-operation'
5
5
  import {clearUndoStep, createUndoStep} from '../editor/with-undo-step'
6
6
  import {debugWithName} from '../internal-utils/debug'
7
7
  import {performOperation} from '../operations/behavior.operations'
@@ -112,7 +112,7 @@ export function performEvent({
112
112
  clearUndoStep(editor)
113
113
  }
114
114
 
115
- withApplyingBehaviorOperations(editor, () => {
115
+ withPerformingBehaviorOperation(editor, () => {
116
116
  debug(`(execute:${eventCategory(event)})`, JSON.stringify(event, null, 2))
117
117
 
118
118
  performOperation({
@@ -198,6 +198,8 @@ export function performEvent({
198
198
  (action) => action.type === 'raise' || action.type === 'execute',
199
199
  ) || !actions.some((action) => action.type === 'forward')
200
200
 
201
+ let undoStepCreated = false
202
+
201
203
  if (actions.some((action) => action.type === 'execute')) {
202
204
  // Since at least one action is about to `execute` changes in the editor,
203
205
  // we set up a new undo step.
@@ -205,78 +207,7 @@ export function performEvent({
205
207
  // undo step
206
208
  createUndoStep(editor)
207
209
 
208
- for (const action of actions) {
209
- if (action.type === 'effect') {
210
- try {
211
- action.effect({
212
- send: sendBack,
213
- })
214
- } catch (error) {
215
- console.error(
216
- new Error(
217
- `Executing effect as a result of "${event.type}" failed due to: ${error.message}`,
218
- ),
219
- )
220
- }
221
-
222
- continue
223
- }
224
-
225
- if (action.type === 'forward') {
226
- const remainingEventBehaviors = eventBehaviors.slice(
227
- eventBehaviorIndex + 1,
228
- )
229
-
230
- performEvent({
231
- mode: 'forward',
232
- behaviors,
233
- remainingEventBehaviors: remainingEventBehaviors,
234
- event: action.event,
235
- editor,
236
- keyGenerator,
237
- schema,
238
- getSnapshot,
239
- nativeEvent,
240
- sendBack,
241
- })
242
-
243
- continue
244
- }
245
-
246
- if (action.type === 'raise') {
247
- performEvent({
248
- mode: 'raise',
249
- behaviors,
250
- remainingEventBehaviors: behaviors,
251
- event: action.event,
252
- editor,
253
- keyGenerator,
254
- schema,
255
- getSnapshot,
256
- nativeEvent,
257
- sendBack,
258
- })
259
-
260
- continue
261
- }
262
-
263
- performEvent({
264
- mode: 'execute',
265
- behaviors,
266
- remainingEventBehaviors: [],
267
- event: action.event,
268
- editor,
269
- keyGenerator,
270
- schema,
271
- getSnapshot,
272
- nativeEvent: undefined,
273
- sendBack,
274
- })
275
- }
276
-
277
- clearUndoStep(editor)
278
-
279
- continue
210
+ undoStepCreated = true
280
211
  }
281
212
 
282
213
  for (const action of actions) {
@@ -302,7 +233,7 @@ export function performEvent({
302
233
  )
303
234
 
304
235
  performEvent({
305
- mode: 'forward',
236
+ mode: mode === 'execute' ? 'execute' : 'forward',
306
237
  behaviors,
307
238
  remainingEventBehaviors: remainingEventBehaviors,
308
239
  event: action.event,
@@ -319,7 +250,7 @@ export function performEvent({
319
250
 
320
251
  if (action.type === 'raise') {
321
252
  performEvent({
322
- mode: 'raise',
253
+ mode: mode === 'execute' ? 'execute' : 'raise',
323
254
  behaviors,
324
255
  remainingEventBehaviors:
325
256
  mode === 'execute' ? remainingEventBehaviors : behaviors,
@@ -335,9 +266,22 @@ export function performEvent({
335
266
  continue
336
267
  }
337
268
 
338
- if (action.type === 'execute') {
339
- console.error('Unexpected action type: `execute`')
340
- }
269
+ performEvent({
270
+ mode: 'execute',
271
+ behaviors,
272
+ remainingEventBehaviors: [],
273
+ event: action.event,
274
+ editor,
275
+ keyGenerator,
276
+ schema,
277
+ getSnapshot,
278
+ nativeEvent: undefined,
279
+ sendBack,
280
+ })
281
+ }
282
+
283
+ if (undoStepCreated) {
284
+ clearUndoStep(editor)
341
285
  }
342
286
  }
343
287
 
@@ -351,7 +295,7 @@ export function performEvent({
351
295
  clearUndoStep(editor)
352
296
  }
353
297
 
354
- withApplyingBehaviorOperations(editor, () => {
298
+ withPerformingBehaviorOperation(editor, () => {
355
299
  debug(`(execute:${eventCategory(event)})`, JSON.stringify(event, null, 2))
356
300
 
357
301
  performOperation({
@@ -1,9 +1,8 @@
1
1
  import {Editor} from 'slate'
2
2
  import {slateRangeToSelection} from '../../internal-utils/slate-utils'
3
- import {insertTextOperationImplementation} from '../../operations/behavior.operation.insert.text'
4
3
  import {performOperation} from '../../operations/behavior.operations'
5
4
  import type {EditorActor} from '../editor-machine'
6
- import {isApplyingBehaviorOperations} from '../with-applying-behavior-operations'
5
+ import {isPerformingBehaviorOperation} from '../with-performing-behavior-operation'
7
6
 
8
7
  export function createWithEventListeners(editorActor: EditorActor) {
9
8
  return function withEventListeners(editor: Editor) {
@@ -14,7 +13,7 @@ export function createWithEventListeners(editorActor: EditorActor) {
14
13
  const {delete: editorDelete, select} = editor
15
14
 
16
15
  editor.delete = (options) => {
17
- if (isApplyingBehaviorOperations(editor)) {
16
+ if (isPerformingBehaviorOperation(editor)) {
18
17
  editorDelete(options)
19
18
  return
20
19
  }
@@ -54,7 +53,7 @@ export function createWithEventListeners(editorActor: EditorActor) {
54
53
  }
55
54
 
56
55
  editor.deleteBackward = (unit) => {
57
- if (isApplyingBehaviorOperations(editor)) {
56
+ if (isPerformingBehaviorOperation(editor)) {
58
57
  console.error('Unexpected call to .deleteBackward(...)')
59
58
  return
60
59
  }
@@ -71,7 +70,7 @@ export function createWithEventListeners(editorActor: EditorActor) {
71
70
  }
72
71
 
73
72
  editor.deleteForward = (unit) => {
74
- if (isApplyingBehaviorOperations(editor)) {
73
+ if (isPerformingBehaviorOperation(editor)) {
75
74
  console.error('Unexpected call to .deleteForward(...)')
76
75
  return
77
76
  }
@@ -88,7 +87,7 @@ export function createWithEventListeners(editorActor: EditorActor) {
88
87
  }
89
88
 
90
89
  editor.insertBreak = () => {
91
- if (isApplyingBehaviorOperations(editor)) {
90
+ if (isPerformingBehaviorOperation(editor)) {
92
91
  console.error('Unexpected call to .insertBreak(...)')
93
92
  return
94
93
  }
@@ -104,7 +103,7 @@ export function createWithEventListeners(editorActor: EditorActor) {
104
103
  }
105
104
 
106
105
  editor.insertData = (dataTransfer) => {
107
- if (isApplyingBehaviorOperations(editor)) {
106
+ if (isPerformingBehaviorOperation(editor)) {
108
107
  console.error('Unexpected call to .insertData(...)')
109
108
  return
110
109
  }
@@ -122,8 +121,8 @@ export function createWithEventListeners(editorActor: EditorActor) {
122
121
  }
123
122
 
124
123
  editor.insertSoftBreak = () => {
125
- if (isApplyingBehaviorOperations(editor)) {
126
- insertTextOperationImplementation({
124
+ if (isPerformingBehaviorOperation(editor)) {
125
+ performOperation({
127
126
  context: {
128
127
  keyGenerator: editorActor.getSnapshot().context.keyGenerator,
129
128
  schema: editorActor.getSnapshot().context.schema,
@@ -144,8 +143,8 @@ export function createWithEventListeners(editorActor: EditorActor) {
144
143
  }
145
144
 
146
145
  editor.insertText = (text) => {
147
- if (isApplyingBehaviorOperations(editor)) {
148
- insertTextOperationImplementation({
146
+ if (isPerformingBehaviorOperation(editor)) {
147
+ performOperation({
149
148
  context: {
150
149
  keyGenerator: editorActor.getSnapshot().context.keyGenerator,
151
150
  schema: editorActor.getSnapshot().context.schema,
@@ -167,7 +166,7 @@ export function createWithEventListeners(editorActor: EditorActor) {
167
166
  }
168
167
 
169
168
  editor.redo = () => {
170
- if (isApplyingBehaviorOperations(editor)) {
169
+ if (isPerformingBehaviorOperation(editor)) {
171
170
  performOperation({
172
171
  context: {
173
172
  keyGenerator: editorActor.getSnapshot().context.keyGenerator,
@@ -192,7 +191,7 @@ export function createWithEventListeners(editorActor: EditorActor) {
192
191
  }
193
192
 
194
193
  editor.select = (location) => {
195
- if (isApplyingBehaviorOperations(editor)) {
194
+ if (isPerformingBehaviorOperation(editor)) {
196
195
  select(location)
197
196
  return
198
197
  }
@@ -220,7 +219,7 @@ export function createWithEventListeners(editorActor: EditorActor) {
220
219
  }
221
220
 
222
221
  editor.undo = () => {
223
- if (isApplyingBehaviorOperations(editor)) {
222
+ if (isPerformingBehaviorOperation(editor)) {
224
223
  performOperation({
225
224
  context: {
226
225
  keyGenerator: editorActor.getSnapshot().context.keyGenerator,
@@ -507,6 +507,10 @@ async function updateValue({
507
507
 
508
508
  isChanged = blockChanged || isChanged
509
509
  isValid = isValid && blockValid
510
+
511
+ if (!isValid) {
512
+ break
513
+ }
510
514
  }
511
515
 
512
516
  resolve()
@@ -544,6 +548,11 @@ async function updateValue({
544
548
 
545
549
  isChanged = blockChanged || isChanged
546
550
  isValid = isValid && blockValid
551
+
552
+ if (!blockValid) {
553
+ break
554
+ }
555
+
547
556
  index++
548
557
  }
549
558
  })
@@ -0,0 +1,21 @@
1
+ import type {Editor} from 'slate'
2
+
3
+ const IS_PERFORMING_OPERATION: WeakMap<Editor, boolean | undefined> =
4
+ new WeakMap()
5
+
6
+ export function withPerformingBehaviorOperation(
7
+ editor: Editor,
8
+ fn: () => void,
9
+ ) {
10
+ const prev = IS_PERFORMING_OPERATION.get(editor)
11
+
12
+ IS_PERFORMING_OPERATION.set(editor, true)
13
+
14
+ fn()
15
+
16
+ IS_PERFORMING_OPERATION.set(editor, prev)
17
+ }
18
+
19
+ export function isPerformingBehaviorOperation(editor: Editor) {
20
+ return IS_PERFORMING_OPERATION.get(editor) ?? false
21
+ }
@@ -0,0 +1,119 @@
1
+ import {defineSchema} from '@portabletext/schema'
2
+ import {createTestKeyGenerator} from '@portabletext/test'
3
+ import React from 'react'
4
+ import {describe, expect, test} from 'vitest'
5
+ import {InternalSlateEditorRefPlugin} from '../plugins/plugin.internal.slate-editor-ref'
6
+ import type {PortableTextSlateEditor} from '../types/editor'
7
+ import {getFocusSpan} from './slate-utils'
8
+ import {createTestEditor} from './test-editor'
9
+
10
+ describe(getFocusSpan.name, () => {
11
+ const keyGenerator = createTestKeyGenerator()
12
+ const blockKey = keyGenerator()
13
+ const fooSpanKey = keyGenerator()
14
+ const stockTickerKey = keyGenerator()
15
+ const barSpanKey = keyGenerator()
16
+ const imageKey = keyGenerator()
17
+ const initialValue = [
18
+ {
19
+ _key: blockKey,
20
+ _type: 'block',
21
+ children: [
22
+ {
23
+ _type: 'span',
24
+ _key: fooSpanKey,
25
+ text: 'foo',
26
+ },
27
+ {
28
+ _type: 'stock-ticker',
29
+ _key: stockTickerKey,
30
+ },
31
+ {
32
+ _type: 'span',
33
+ _key: barSpanKey,
34
+ text: 'bar',
35
+ },
36
+ ],
37
+ },
38
+ {
39
+ _key: imageKey,
40
+ _type: 'image',
41
+ },
42
+ ]
43
+ const schemaDefinition = defineSchema({
44
+ blockObjects: [{name: 'image'}],
45
+ inlineObjects: [{name: 'stock-ticker'}],
46
+ })
47
+
48
+ test('Scenario: Text block span is selected', async () => {
49
+ const slateEditorRef = React.createRef<PortableTextSlateEditor>()
50
+ await createTestEditor({
51
+ children: <InternalSlateEditorRefPlugin ref={slateEditorRef} />,
52
+ schemaDefinition,
53
+ initialValue,
54
+ editableProps: {
55
+ selection: {
56
+ anchor: {
57
+ path: [{_key: blockKey}, 'children', {_key: fooSpanKey}],
58
+ offset: 0,
59
+ },
60
+ focus: {
61
+ path: [{_key: blockKey}, 'children', {_key: fooSpanKey}],
62
+ offset: 0,
63
+ },
64
+ },
65
+ },
66
+ })
67
+
68
+ expect(getFocusSpan({editor: slateEditorRef.current!})).toEqual([
69
+ {_type: 'span', _key: fooSpanKey, text: 'foo', marks: []},
70
+ [0, 0],
71
+ ])
72
+ })
73
+
74
+ test('Scenario: Inline object is selected', async () => {
75
+ const slateEditorRef = React.createRef<PortableTextSlateEditor>()
76
+ await createTestEditor({
77
+ children: <InternalSlateEditorRefPlugin ref={slateEditorRef} />,
78
+ schemaDefinition,
79
+ initialValue,
80
+ editableProps: {
81
+ selection: {
82
+ anchor: {
83
+ path: [{_key: blockKey}, 'children', {_key: stockTickerKey}],
84
+ offset: 0,
85
+ },
86
+ focus: {
87
+ path: [{_key: blockKey}, 'children', {_key: stockTickerKey}],
88
+ offset: 0,
89
+ },
90
+ },
91
+ },
92
+ })
93
+
94
+ expect(getFocusSpan({editor: slateEditorRef.current!})).toEqual([
95
+ undefined,
96
+ undefined,
97
+ ])
98
+ })
99
+
100
+ test('Scenario: Block object is selected', async () => {
101
+ const slateEditorRef = React.createRef<PortableTextSlateEditor>()
102
+ await createTestEditor({
103
+ children: <InternalSlateEditorRefPlugin ref={slateEditorRef} />,
104
+ schemaDefinition,
105
+ initialValue,
106
+ editableProps: {
107
+ selection: {
108
+ anchor: {path: [{_key: imageKey}], offset: 0},
109
+ focus: {path: [{_key: imageKey}], offset: 0},
110
+ },
111
+ },
112
+ })
113
+
114
+ expect(getFocusSpan({editor: slateEditorRef.current!})).toEqual([
115
+ undefined,
116
+ undefined,
117
+ ])
118
+ })
119
+ })
@@ -79,7 +79,20 @@ export function getFocusSpan({
79
79
  }
80
80
 
81
81
  try {
82
- const [node, path] = Editor.node(editor, editor.selection.focus.path)
82
+ const [focusBlock] = getFocusBlock({editor})
83
+
84
+ if (!focusBlock) {
85
+ return [undefined, undefined]
86
+ }
87
+
88
+ if (!editor.isTextBlock(focusBlock)) {
89
+ return [undefined, undefined]
90
+ }
91
+
92
+ const [node, path] = Editor.node(
93
+ editor,
94
+ editor.selection.focus.path.slice(0, 2),
95
+ )
83
96
 
84
97
  if (editor.isTextSpan(node)) {
85
98
  return [node, path]
@@ -5,7 +5,7 @@ export function getTextMarks(
5
5
  context: Pick<EditorContext, 'schema' | 'value'>,
6
6
  text: string,
7
7
  ) {
8
- let marks: Array<string> | undefined
8
+ let marks: Array<string> = []
9
9
 
10
10
  for (const block of context.value) {
11
11
  if (isTextBlock(context, block)) {
@@ -1,22 +1,17 @@
1
1
  import type {
2
- PathSegment,
3
2
  PortableTextBlock,
4
3
  PortableTextChild,
5
4
  PortableTextObject,
6
5
  PortableTextTextBlock,
7
6
  } from '@sanity/types'
8
7
  import {isEqual} from 'lodash'
9
- import {Element, Text, type Descendant, type Node} from 'slate'
8
+ import {Element, Text, type Descendant} from 'slate'
10
9
  import type {EditorSchema} from '../editor/editor-schema'
11
10
 
12
11
  export const EMPTY_MARKDEFS: PortableTextObject[] = []
13
12
 
14
13
  export const VOID_CHILD_KEY = 'void-child'
15
14
 
16
- type Partial<T> = {
17
- [P in keyof T]?: T[P]
18
- }
19
-
20
15
  function keepObjectEquality(
21
16
  object: PortableTextBlock | PortableTextChild,
22
17
  keyMap: Record<string, PortableTextBlock | PortableTextChild>,
@@ -188,52 +183,3 @@ export function isEqualToEmptyEditor(
188
183
  children[0].children[0].text === '')
189
184
  )
190
185
  }
191
-
192
- export function findBlockAndIndexFromPath(
193
- firstPathSegment: PathSegment,
194
- children: (Node | Partial<Node>)[],
195
- ): [Element | undefined, number | undefined] {
196
- let blockIndex = -1
197
- const isNumber = Number.isInteger(Number(firstPathSegment))
198
- if (isNumber) {
199
- blockIndex = Number(firstPathSegment)
200
- } else if (children) {
201
- blockIndex = children.findIndex(
202
- (blk) =>
203
- Element.isElement(blk) && isEqual({_key: blk._key}, firstPathSegment),
204
- )
205
- }
206
- if (blockIndex > -1) {
207
- return [children[blockIndex] as Element, blockIndex]
208
- }
209
- return [undefined, -1]
210
- }
211
-
212
- export function findChildAndIndexFromPath(
213
- secondPathSegment: PathSegment,
214
- block: Element,
215
- ): [Element | Text | undefined, number] {
216
- let childIndex = -1
217
- const isNumber = Number.isInteger(Number(secondPathSegment))
218
- if (isNumber) {
219
- childIndex = Number(secondPathSegment)
220
- } else {
221
- childIndex = block.children.findIndex((child) =>
222
- isEqual({_key: child._key}, secondPathSegment),
223
- )
224
- }
225
- if (childIndex > -1) {
226
- return [block.children[childIndex] as Element | Text, childIndex]
227
- }
228
- return [undefined, -1]
229
- }
230
-
231
- export function getValueOrInitialValue(
232
- value: unknown,
233
- initialValue: PortableTextBlock[],
234
- ): PortableTextBlock[] | undefined {
235
- if (value && Array.isArray(value) && value.length > 0) {
236
- return value
237
- }
238
- return initialValue
239
- }
@@ -1,64 +1,45 @@
1
- import {Editor, Transforms, type Element as SlateElement} from 'slate'
1
+ import {Transforms, type Element as SlateElement} from 'slate'
2
2
  import {parseBlock} from '../internal-utils/parse-blocks'
3
- import {toSlateRange} from '../internal-utils/to-slate-range'
4
- import {fromSlateValue, toSlateValue} from '../internal-utils/values'
5
- import {KEY_TO_VALUE_ELEMENT} from '../internal-utils/weakMaps'
3
+ import {toSlateValue} from '../internal-utils/values'
6
4
  import type {BehaviorOperationImplementation} from './behavior.operations'
7
5
 
8
6
  export const blockSetOperationImplementation: BehaviorOperationImplementation<
9
7
  'block.set'
10
8
  > = ({context, operation}) => {
11
- const location = toSlateRange({
12
- context: {
13
- schema: context.schema,
14
- value: operation.editor.value,
15
- selection: {
16
- anchor: {path: operation.at, offset: 0},
17
- focus: {path: operation.at, offset: 0},
18
- },
19
- },
20
- blockIndexMap: operation.editor.blockIndexMap,
21
- })
9
+ const blockIndex = operation.editor.blockIndexMap.get(operation.at[0]._key)
22
10
 
23
- if (!location) {
11
+ if (blockIndex === undefined) {
24
12
  throw new Error(
25
- `Unable to convert ${JSON.stringify(operation.at)} into a Slate Range`,
13
+ `Unable to find block index for block at ${JSON.stringify(operation.at)}`,
26
14
  )
27
15
  }
28
16
 
29
- const blockEntry = Editor.node(operation.editor, location, {depth: 1})
30
- const block = blockEntry?.[0]
17
+ const block = operation.editor.value.at(blockIndex)
31
18
 
32
19
  if (!block) {
33
20
  throw new Error(`Unable to find block at ${JSON.stringify(operation.at)}`)
34
21
  }
35
22
 
36
- const parsedBlock = fromSlateValue(
37
- [block],
38
- context.schema.block.name,
39
- KEY_TO_VALUE_ELEMENT.get(operation.editor),
40
- ).at(0)
23
+ const {_type, ...filteredProps} = operation.props
41
24
 
42
- if (!parsedBlock) {
43
- throw new Error(`Unable to parse block at ${JSON.stringify(operation.at)}`)
25
+ const updatedBlock = {
26
+ ...block,
27
+ ...filteredProps,
44
28
  }
45
29
 
46
- const {_type, ...filteredProps} = operation.props
47
-
48
- const updatedBlock = parseBlock({
30
+ const parsedBlock = parseBlock({
49
31
  context,
50
- block: {
51
- ...parsedBlock,
52
- ...filteredProps,
53
- },
32
+ block: updatedBlock,
54
33
  options: {validateFields: true},
55
34
  })
56
35
 
57
- if (!updatedBlock) {
36
+ if (!parsedBlock) {
58
37
  throw new Error(`Unable to update block at ${JSON.stringify(operation.at)}`)
59
38
  }
60
39
 
61
- const slateBlock = toSlateValue([updatedBlock], {
40
+ parsedBlock.markDefs = updatedBlock.markDefs
41
+
42
+ const slateBlock = toSlateValue([parsedBlock], {
62
43
  schemaTypes: context.schema,
63
44
  })?.at(0) as SlateElement | undefined
64
45
 
@@ -66,5 +47,5 @@ export const blockSetOperationImplementation: BehaviorOperationImplementation<
66
47
  throw new Error(`Unable to convert block to Slate value`)
67
48
  }
68
49
 
69
- Transforms.setNodes(operation.editor, slateBlock, {at: location})
50
+ Transforms.setNodes(operation.editor, slateBlock, {at: [blockIndex]})
70
51
  }