@portabletext/editor 1.33.5 → 1.34.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 (50) hide show
  1. package/lib/_chunks-cjs/behavior.core.cjs +14 -8
  2. package/lib/_chunks-cjs/behavior.core.cjs.map +1 -1
  3. package/lib/_chunks-cjs/behavior.markdown.cjs +20 -12
  4. package/lib/_chunks-cjs/behavior.markdown.cjs.map +1 -1
  5. package/lib/_chunks-cjs/plugin.event-listener.cjs +95 -70
  6. package/lib/_chunks-cjs/plugin.event-listener.cjs.map +1 -1
  7. package/lib/_chunks-cjs/util.block-offsets-to-selection.cjs +103 -46
  8. package/lib/_chunks-cjs/util.block-offsets-to-selection.cjs.map +1 -1
  9. package/lib/_chunks-es/behavior.core.js +14 -8
  10. package/lib/_chunks-es/behavior.core.js.map +1 -1
  11. package/lib/_chunks-es/behavior.markdown.js +20 -12
  12. package/lib/_chunks-es/behavior.markdown.js.map +1 -1
  13. package/lib/_chunks-es/plugin.event-listener.js +101 -75
  14. package/lib/_chunks-es/plugin.event-listener.js.map +1 -1
  15. package/lib/_chunks-es/util.block-offsets-to-selection.js +102 -46
  16. package/lib/_chunks-es/util.block-offsets-to-selection.js.map +1 -1
  17. package/lib/behaviors/index.d.cts +5 -34
  18. package/lib/behaviors/index.d.ts +5 -34
  19. package/lib/index.d.cts +300 -1460
  20. package/lib/index.d.ts +300 -1460
  21. package/lib/plugins/index.cjs +60 -43
  22. package/lib/plugins/index.cjs.map +1 -1
  23. package/lib/plugins/index.d.cts +300 -1460
  24. package/lib/plugins/index.d.ts +300 -1460
  25. package/lib/plugins/index.js +63 -45
  26. package/lib/plugins/index.js.map +1 -1
  27. package/lib/selectors/index.d.cts +12 -0
  28. package/lib/selectors/index.d.ts +12 -0
  29. package/lib/utils/index.cjs +23 -1
  30. package/lib/utils/index.cjs.map +1 -1
  31. package/lib/utils/index.d.cts +11 -0
  32. package/lib/utils/index.d.ts +11 -0
  33. package/lib/utils/index.js +25 -2
  34. package/lib/utils/index.js.map +1 -1
  35. package/package.json +6 -6
  36. package/src/behavior-actions/behavior.action.block.set.ts +48 -5
  37. package/src/behavior-actions/behavior.action.block.unset.ts +77 -3
  38. package/src/behavior-actions/behavior.action.decorator.add.ts +30 -8
  39. package/src/behavior-actions/behavior.actions.ts +1 -18
  40. package/src/behaviors/behavior.core.lists.ts +18 -14
  41. package/src/behaviors/behavior.markdown-emphasis.ts +82 -41
  42. package/src/behaviors/behavior.markdown.ts +14 -12
  43. package/src/behaviors/behavior.types.ts +2 -14
  44. package/src/converters/converter.portable-text.deserialize.test.ts +3 -2
  45. package/src/internal-utils/parse-blocks.test.ts +455 -0
  46. package/src/internal-utils/parse-blocks.ts +202 -87
  47. package/src/utils/index.ts +1 -0
  48. package/src/utils/util.child-selection-point-to-block-offset.ts +55 -0
  49. package/src/behavior-actions/behavior.action.text-block.set.ts +0 -25
  50. package/src/behavior-actions/behavior.action.text-block.unset.ts +0 -17
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@portabletext/editor",
3
- "version": "1.33.5",
3
+ "version": "1.34.0",
4
4
  "description": "Portable Text Editor made in React",
5
5
  "keywords": [
6
6
  "sanity",
@@ -79,15 +79,15 @@
79
79
  "slate-react": "0.112.1",
80
80
  "use-effect-event": "^1.0.2",
81
81
  "xstate": "^5.19.2",
82
- "@portabletext/block-tools": "1.1.7",
82
+ "@portabletext/block-tools": "1.1.8",
83
83
  "@portabletext/patches": "1.1.3"
84
84
  },
85
85
  "devDependencies": {
86
86
  "@portabletext/toolkit": "^2.0.17",
87
87
  "@sanity/diff-match-patch": "^3.2.0",
88
88
  "@sanity/pkg-utils": "^7.0.4",
89
- "@sanity/schema": "^3.75.0",
90
- "@sanity/types": "^3.75.0",
89
+ "@sanity/schema": "^3.75.1",
90
+ "@sanity/types": "^3.75.1",
91
91
  "@testing-library/jest-dom": "^6.6.3",
92
92
  "@testing-library/react": "^16.2.0",
93
93
  "@types/debug": "^4.1.12",
@@ -115,8 +115,8 @@
115
115
  "racejar": "1.2.0"
116
116
  },
117
117
  "peerDependencies": {
118
- "@sanity/schema": "^3.75.0",
119
- "@sanity/types": "^3.75.0",
118
+ "@sanity/schema": "^3.75.1",
119
+ "@sanity/types": "^3.75.1",
120
120
  "react": "^16.9 || ^17 || ^18 || ^19",
121
121
  "rxjs": "^7.8.1"
122
122
  },
@@ -1,10 +1,13 @@
1
- import {Transforms} from 'slate'
1
+ import {Editor, Transforms, type Element as SlateElement} from 'slate'
2
+ import {parseBlock} from '../internal-utils/parse-blocks'
2
3
  import {toSlateRange} from '../internal-utils/ranges'
4
+ import {fromSlateValue, toSlateValue} from '../internal-utils/values'
5
+ import {KEY_TO_VALUE_ELEMENT} from '../internal-utils/weakMaps'
3
6
  import type {BehaviorActionImplementation} from './behavior.actions'
4
7
 
5
8
  export const blockSetBehaviorActionImplementation: BehaviorActionImplementation<
6
9
  'block.set'
7
- > = ({action}) => {
10
+ > = ({context, action}) => {
8
11
  const location = toSlateRange(
9
12
  {
10
13
  anchor: {path: action.at, offset: 0},
@@ -14,10 +17,50 @@ export const blockSetBehaviorActionImplementation: BehaviorActionImplementation<
14
17
  )
15
18
 
16
19
  if (!location) {
17
- return
20
+ throw new Error(
21
+ `Unable to convert ${JSON.stringify(action.at)} into a Slate Range`,
22
+ )
18
23
  }
19
24
 
20
- const {at, editor, type, ...payload} = action
25
+ const blockEntry = Editor.node(action.editor, location, {depth: 1})
26
+ const block = blockEntry?.[0]
21
27
 
22
- Transforms.setNodes(action.editor, payload, {at: location})
28
+ if (!block) {
29
+ throw new Error(`Unable to find block at ${JSON.stringify(action.at)}`)
30
+ }
31
+
32
+ const parsedBlock = fromSlateValue(
33
+ [block],
34
+ context.schema.block.name,
35
+ KEY_TO_VALUE_ELEMENT.get(action.editor),
36
+ ).at(0)
37
+
38
+ if (!parsedBlock) {
39
+ throw new Error(`Unable to parse block at ${JSON.stringify(action.at)}`)
40
+ }
41
+
42
+ const {_type, ...filteredProps} = action.props
43
+
44
+ const updatedBlock = parseBlock({
45
+ context,
46
+ block: {
47
+ ...parsedBlock,
48
+ ...filteredProps,
49
+ },
50
+ options: {refreshKeys: false},
51
+ })
52
+
53
+ if (!updatedBlock) {
54
+ throw new Error(`Unable to update block at ${JSON.stringify(action.at)}`)
55
+ }
56
+
57
+ const slateBlock = toSlateValue([updatedBlock], {
58
+ schemaTypes: context.schema,
59
+ })?.at(0) as SlateElement | undefined
60
+
61
+ if (!slateBlock) {
62
+ throw new Error(`Unable to convert block to Slate value`)
63
+ }
64
+
65
+ Transforms.setNodes(action.editor, slateBlock, {at: location})
23
66
  }
@@ -1,10 +1,14 @@
1
- import {Transforms} from 'slate'
1
+ import {omit} from 'lodash'
2
+ import {Editor, Transforms} from 'slate'
3
+ import {isTextBlock, parseBlock} from '../internal-utils/parse-blocks'
2
4
  import {toSlateRange} from '../internal-utils/ranges'
5
+ import {fromSlateValue} from '../internal-utils/values'
6
+ import {KEY_TO_VALUE_ELEMENT} from '../internal-utils/weakMaps'
3
7
  import type {BehaviorActionImplementation} from './behavior.actions'
4
8
 
5
9
  export const blockUnsetBehaviorActionImplementation: BehaviorActionImplementation<
6
10
  'block.unset'
7
- > = ({action}) => {
11
+ > = ({context, action}) => {
8
12
  const location = toSlateRange(
9
13
  {
10
14
  anchor: {path: action.at, offset: 0},
@@ -14,8 +18,78 @@ export const blockUnsetBehaviorActionImplementation: BehaviorActionImplementatio
14
18
  )
15
19
 
16
20
  if (!location) {
21
+ throw new Error(
22
+ `Unable to convert ${JSON.stringify(action.at)} into a Slate Range`,
23
+ )
24
+ }
25
+
26
+ const blockEntry = Editor.node(action.editor, location, {depth: 1})
27
+ const block = blockEntry?.[0]
28
+
29
+ if (!block) {
30
+ throw new Error(`Unable to find block at ${JSON.stringify(action.at)}`)
31
+ }
32
+
33
+ const parsedBlock = fromSlateValue(
34
+ [block],
35
+ context.schema.block.name,
36
+ KEY_TO_VALUE_ELEMENT.get(action.editor),
37
+ ).at(0)
38
+
39
+ if (!parsedBlock) {
40
+ throw new Error(`Unable to parse block at ${JSON.stringify(action.at)}`)
41
+ }
42
+
43
+ if (isTextBlock(context.schema, parsedBlock)) {
44
+ const propsToRemove = action.props.filter((prop) => prop !== '_type')
45
+
46
+ const updatedTextBlock = parseBlock({
47
+ context,
48
+ block: omit(parsedBlock, propsToRemove),
49
+ options: {refreshKeys: false},
50
+ })
51
+
52
+ if (!updatedTextBlock) {
53
+ throw new Error(`Unable to update block at ${JSON.stringify(action.at)}`)
54
+ }
55
+
56
+ const propsToSet: Record<string, unknown> = {}
57
+
58
+ for (const prop of propsToRemove) {
59
+ if (!(prop in updatedTextBlock)) {
60
+ propsToSet[prop] = undefined
61
+ } else {
62
+ propsToSet[prop] = (updatedTextBlock as Record<string, unknown>)[prop]
63
+ }
64
+ }
65
+
66
+ Transforms.setNodes(action.editor, propsToSet, {at: location})
67
+
17
68
  return
18
69
  }
19
70
 
20
- Transforms.unsetNodes(action.editor, action.props, {at: location})
71
+ const updatedBlockObject = parseBlock({
72
+ context,
73
+ block: omit(
74
+ parsedBlock,
75
+ action.props.filter((prop) => prop !== '_type'),
76
+ ),
77
+ options: {refreshKeys: false},
78
+ })
79
+
80
+ if (!updatedBlockObject) {
81
+ throw new Error(`Unable to update block at ${JSON.stringify(action.at)}`)
82
+ }
83
+
84
+ const {_type, _key, ...props} = updatedBlockObject
85
+
86
+ Transforms.setNodes(
87
+ action.editor,
88
+ {
89
+ _type,
90
+ _key,
91
+ value: props,
92
+ },
93
+ {at: location},
94
+ )
21
95
  }
@@ -11,20 +11,42 @@ export const decoratorAddActionImplementation: BehaviorActionImplementation<
11
11
  > = ({context, action}) => {
12
12
  const editor = action.editor
13
13
  const mark = action.decorator
14
- const selection = action.selection
15
- ? (toSlateRange(action.selection, action.editor) ?? editor.selection)
16
- : editor.selection
17
-
18
- if (!selection) {
19
- return
20
- }
21
-
22
14
  const value = fromSlateValue(
23
15
  editor.children,
24
16
  context.schema.block.name,
25
17
  KEY_TO_VALUE_ELEMENT.get(editor),
26
18
  )
27
19
 
20
+ const manualAnchor = action.offsets?.anchor
21
+ ? utils.blockOffsetToSpanSelectionPoint({
22
+ value,
23
+ blockOffset: action.offsets.anchor,
24
+ direction: 'backward',
25
+ })
26
+ : undefined
27
+ const manualFocus = action.offsets?.focus
28
+ ? utils.blockOffsetToSpanSelectionPoint({
29
+ value,
30
+ blockOffset: action.offsets.focus,
31
+ direction: 'forward',
32
+ })
33
+ : undefined
34
+ const manualSelection =
35
+ manualAnchor && manualFocus
36
+ ? {
37
+ anchor: manualAnchor,
38
+ focus: manualFocus,
39
+ }
40
+ : undefined
41
+
42
+ const selection = manualSelection
43
+ ? (toSlateRange(manualSelection, action.editor) ?? editor.selection)
44
+ : editor.selection
45
+
46
+ if (!selection) {
47
+ return
48
+ }
49
+
28
50
  const editorSelection = toPortableTextRange(value, selection, context.schema)
29
51
  const anchorOffset = editorSelection
30
52
  ? utils.spanSelectionPointToBlockOffset({
@@ -48,8 +48,6 @@ import {
48
48
  removeStyleActionImplementation,
49
49
  toggleStyleActionImplementation,
50
50
  } from './behavior.action.style'
51
- import {textBlockSetActionImplementation} from './behavior.action.text-block.set'
52
- import {textBlockUnsetActionImplementation} from './behavior.action.text-block.unset'
53
51
 
54
52
  export type BehaviorActionImplementationContext = Pick<
55
53
  EditorContext,
@@ -266,8 +264,6 @@ const behaviorActionImplementations: BehaviorActionImplementations = {
266
264
  'style.toggle': toggleStyleActionImplementation,
267
265
  'style.add': addStyleActionImplementation,
268
266
  'style.remove': removeStyleActionImplementation,
269
- 'text block.set': textBlockSetActionImplementation,
270
- 'text block.unset': textBlockUnsetActionImplementation,
271
267
  }
272
268
 
273
269
  export function performAction({
@@ -600,25 +596,12 @@ function performDefaultAction({
600
596
  })
601
597
  break
602
598
  }
603
- case 'style.toggle': {
599
+ default: {
604
600
  behaviorActionImplementations['style.toggle']({
605
601
  context,
606
602
  action,
607
603
  })
608
604
  break
609
605
  }
610
- case 'text block.set': {
611
- behaviorActionImplementations['text block.set']({
612
- context,
613
- action,
614
- })
615
- break
616
- }
617
- default: {
618
- behaviorActionImplementations['text block.unset']({
619
- context,
620
- action,
621
- })
622
- }
623
606
  }
624
607
  }
@@ -30,7 +30,7 @@ const clearListOnBackspace = defineBehavior({
30
30
  actions: [
31
31
  (_, {focusTextBlock}) => [
32
32
  raise({
33
- type: 'text block.unset',
33
+ type: 'block.unset',
34
34
  props: ['listItem', 'level'],
35
35
  at: focusTextBlock.path,
36
36
  }),
@@ -66,8 +66,8 @@ const unindentListOnBackspace = defineBehavior({
66
66
  actions: [
67
67
  (_, {focusTextBlock, level}) => [
68
68
  raise({
69
- type: 'text block.set',
70
- level,
69
+ type: 'block.set',
70
+ props: {level},
71
71
  at: focusTextBlock.path,
72
72
  }),
73
73
  ],
@@ -93,7 +93,7 @@ const clearListOnEnter = defineBehavior({
93
93
  actions: [
94
94
  (_, {focusListBlock}) => [
95
95
  raise({
96
- type: 'text block.unset',
96
+ type: 'block.unset',
97
97
  props: ['listItem', 'level'],
98
98
  at: focusListBlock.path,
99
99
  }),
@@ -133,11 +133,13 @@ const indentListOnTab = defineBehavior({
133
133
  (_, {selectedListBlocks}) =>
134
134
  selectedListBlocks.map((selectedListBlock) =>
135
135
  raise({
136
- type: 'text block.set',
137
- level: Math.min(
138
- MAX_LIST_LEVEL,
139
- Math.max(1, selectedListBlock.node.level + 1),
140
- ),
136
+ type: 'block.set',
137
+ props: {
138
+ level: Math.min(
139
+ MAX_LIST_LEVEL,
140
+ Math.max(1, selectedListBlock.node.level + 1),
141
+ ),
142
+ },
141
143
  at: selectedListBlock.path,
142
144
  }),
143
145
  ),
@@ -176,11 +178,13 @@ const unindentListOnShiftTab = defineBehavior({
176
178
  (_, {selectedListBlocks}) =>
177
179
  selectedListBlocks.map((selectedListBlock) =>
178
180
  raise({
179
- type: 'text block.set',
180
- level: Math.min(
181
- MAX_LIST_LEVEL,
182
- Math.max(1, selectedListBlock.node.level - 1),
183
- ),
181
+ type: 'block.set',
182
+ props: {
183
+ level: Math.min(
184
+ MAX_LIST_LEVEL,
185
+ Math.max(1, selectedListBlock.node.level - 1),
186
+ ),
187
+ },
184
188
  at: selectedListBlock.path,
185
189
  }),
186
190
  ),
@@ -79,10 +79,6 @@ const emphasisListener: CallbackLogicFunction<
79
79
  return false
80
80
  }
81
81
 
82
- if (event.text !== '*' && event.text !== '_') {
83
- return false
84
- }
85
-
86
82
  const focusTextBlock = selectors.getFocusTextBlock({context})
87
83
  const selectionStartPoint = selectors.getSelectionStartPoint({context})
88
84
  const selectionStartOffset = selectionStartPoint
@@ -104,44 +100,33 @@ const emphasisListener: CallbackLogicFunction<
104
100
  const prefixOffsets = {
105
101
  anchor: {
106
102
  path: focusTextBlock.path,
107
- offset: textBefore.length - textToItalic.length + 1,
103
+ // Example: "foo *bar*".length - "*bar*".length = 4
104
+ offset: `${textBefore}${event.text}`.length - textToItalic.length,
108
105
  },
109
106
  focus: {
110
107
  path: focusTextBlock.path,
111
- offset: textBefore.length - textToItalic.length + 1 + 1,
108
+ // Example: "foo *bar*".length - "*bar*".length + 1 = 5
109
+ offset:
110
+ `${textBefore}${event.text}`.length - textToItalic.length + 1,
112
111
  },
113
112
  }
114
113
  const suffixOffsets = {
115
114
  anchor: {
116
115
  path: focusTextBlock.path,
117
- offset: selectionStartOffset.offset,
116
+ // Example: "foo *bar|" (8) + "*".length - 1 = 8
117
+ offset: selectionStartOffset.offset + event.text.length - 1,
118
118
  },
119
119
  focus: {
120
120
  path: focusTextBlock.path,
121
- offset: selectionStartOffset.offset + 1,
121
+ // Example: "foo *bar|" (8) + "*".length = 9
122
+ offset: selectionStartOffset.offset + event.text.length,
122
123
  },
123
124
  }
124
125
 
125
- const anchor = utils.blockOffsetToSpanSelectionPoint({
126
- value: context.value,
127
- blockOffset: prefixOffsets.focus,
128
- direction: 'backward',
129
- })
130
- const focus = utils.blockOffsetToSpanSelectionPoint({
131
- value: context.value,
132
- blockOffset: suffixOffsets.anchor,
133
- direction: 'forward',
134
- })
135
-
136
- if (!anchor || !focus) {
137
- return false
138
- }
139
-
140
126
  return {
141
127
  prefixOffsets,
142
128
  suffixOffsets,
143
129
  decorator: italicDecorator,
144
- selection: {anchor, focus},
145
130
  }
146
131
  }
147
132
 
@@ -151,35 +136,85 @@ const emphasisListener: CallbackLogicFunction<
151
136
  const prefixOffsets = {
152
137
  anchor: {
153
138
  path: focusTextBlock.path,
154
- offset: textBefore.length - textToBold.length + 1,
139
+ // Example: "foo **bar**".length - "**bar**".length = 4
140
+ offset: `${textBefore}${event.text}`.length - textToBold.length,
155
141
  },
156
142
  focus: {
157
143
  path: focusTextBlock.path,
158
- offset: textBefore.length - textToBold.length + 1 + 2,
144
+ // Example: "foo **bar**".length - "**bar**".length + 2 = 6
145
+ offset:
146
+ `${textBefore}${event.text}`.length - textToBold.length + 2,
159
147
  },
160
148
  }
149
+
150
+ const prefixSelection = utils.blockOffsetsToSelection({
151
+ value: context.value,
152
+ offsets: prefixOffsets,
153
+ })
154
+ const inlineObjectBeforePrefixFocus =
155
+ selectors.getPreviousInlineObject({
156
+ context: {
157
+ ...context,
158
+ selection: prefixSelection
159
+ ? {
160
+ anchor: prefixSelection.focus,
161
+ focus: prefixSelection.focus,
162
+ }
163
+ : null,
164
+ },
165
+ })
166
+ const inlineObjectBeforePrefixFocusOffset =
167
+ inlineObjectBeforePrefixFocus
168
+ ? utils.childSelectionPointToBlockOffset({
169
+ value: context.value,
170
+ selectionPoint: {
171
+ path: inlineObjectBeforePrefixFocus.path,
172
+ offset: 0,
173
+ },
174
+ })
175
+ : undefined
176
+
177
+ if (
178
+ inlineObjectBeforePrefixFocusOffset &&
179
+ inlineObjectBeforePrefixFocusOffset.offset >
180
+ prefixOffsets.anchor.offset &&
181
+ inlineObjectBeforePrefixFocusOffset.offset <
182
+ prefixOffsets.focus.offset
183
+ ) {
184
+ return false
185
+ }
186
+
161
187
  const suffixOffsets = {
162
188
  anchor: {
163
189
  path: focusTextBlock.path,
164
- offset: selectionStartOffset.offset - 1,
190
+ // Example: "foo **bar*|" (10) + "*".length - 2 = 9
191
+ offset: selectionStartOffset.offset + event.text.length - 2,
165
192
  },
166
193
  focus: {
167
194
  path: focusTextBlock.path,
168
- offset: selectionStartOffset.offset + 1,
195
+ // Example: "foo **bar*|" (10) + "*".length = 11
196
+ offset: selectionStartOffset.offset + event.text.length,
169
197
  },
170
198
  }
171
- const anchor = utils.blockOffsetToSpanSelectionPoint({
172
- value: context.value,
173
- blockOffset: prefixOffsets.focus,
174
- direction: 'backward',
175
- })
176
- const focus = utils.blockOffsetToSpanSelectionPoint({
177
- value: context.value,
178
- blockOffset: suffixOffsets.anchor,
179
- direction: 'forward',
199
+
200
+ const previousInlineObject = selectors.getPreviousInlineObject({
201
+ context,
180
202
  })
203
+ const previousInlineObjectOffset = previousInlineObject
204
+ ? utils.childSelectionPointToBlockOffset({
205
+ value: context.value,
206
+ selectionPoint: {
207
+ path: previousInlineObject.path,
208
+ offset: 0,
209
+ },
210
+ })
211
+ : undefined
181
212
 
182
- if (!anchor || !focus) {
213
+ if (
214
+ previousInlineObjectOffset &&
215
+ previousInlineObjectOffset.offset > suffixOffsets.anchor.offset &&
216
+ previousInlineObjectOffset.offset < suffixOffsets.focus.offset
217
+ ) {
183
218
  return false
184
219
  }
185
220
 
@@ -187,7 +222,6 @@ const emphasisListener: CallbackLogicFunction<
187
222
  prefixOffsets,
188
223
  suffixOffsets,
189
224
  decorator: boldDecorator,
190
- selection: {anchor, focus},
191
225
  }
192
226
  }
193
227
 
@@ -195,11 +229,14 @@ const emphasisListener: CallbackLogicFunction<
195
229
  },
196
230
  actions: [
197
231
  ({event}) => [event],
198
- (_, {prefixOffsets, suffixOffsets, decorator, selection}) => [
232
+ (_, {prefixOffsets, suffixOffsets, decorator}) => [
199
233
  {
200
234
  type: 'decorator.add',
201
235
  decorator,
202
- selection,
236
+ offsets: {
237
+ anchor: prefixOffsets.focus,
238
+ focus: suffixOffsets.anchor,
239
+ },
203
240
  },
204
241
  {
205
242
  type: 'delete.text',
@@ -209,6 +246,10 @@ const emphasisListener: CallbackLogicFunction<
209
246
  type: 'delete.text',
210
247
  ...prefixOffsets,
211
248
  },
249
+ {
250
+ type: 'decorator.remove',
251
+ decorator,
252
+ },
212
253
  {
213
254
  type: 'effect',
214
255
  effect: () => {
@@ -127,13 +127,13 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
127
127
  ],
128
128
  (_, {focusTextBlock, style}) => [
129
129
  {
130
- type: 'text block.unset',
130
+ type: 'block.unset',
131
131
  props: ['listItem', 'level'],
132
132
  at: focusTextBlock.path,
133
133
  },
134
134
  {
135
- type: 'text block.set',
136
- style,
135
+ type: 'block.set',
136
+ props: {style},
137
137
  at: focusTextBlock.path,
138
138
  },
139
139
  {
@@ -326,13 +326,13 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
326
326
  ({event}) => [event],
327
327
  (_, {focusTextBlock, style, level}) => [
328
328
  {
329
- type: 'text block.unset',
329
+ type: 'block.unset',
330
330
  props: ['listItem', 'level'],
331
331
  at: focusTextBlock.path,
332
332
  },
333
333
  {
334
- type: 'text block.set',
335
- style,
334
+ type: 'block.set',
335
+ props: {style},
336
336
  at: focusTextBlock.path,
337
337
  },
338
338
  {
@@ -379,8 +379,8 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
379
379
  actions: [
380
380
  (_, {defaultStyle, focusTextBlock}) => [
381
381
  {
382
- type: 'text block.set',
383
- style: defaultStyle,
382
+ type: 'block.set',
383
+ props: {style: defaultStyle},
384
384
  at: focusTextBlock.path,
385
385
  },
386
386
  ],
@@ -464,10 +464,12 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
464
464
  ({event}) => [event],
465
465
  (_, {focusTextBlock, style, listItem, listItemLength}) => [
466
466
  {
467
- type: 'text block.set',
468
- listItem,
469
- level: 1,
470
- style,
467
+ type: 'block.set',
468
+ props: {
469
+ listItem,
470
+ level: 1,
471
+ style,
472
+ },
471
473
  at: focusTextBlock.path,
472
474
  },
473
475
  {
@@ -38,7 +38,7 @@ export type SyntheticBehaviorEvent =
38
38
  | {
39
39
  type: 'block.set'
40
40
  at: [KeyedSegment]
41
- [props: string]: unknown
41
+ props: Record<string, unknown>
42
42
  }
43
43
  | {
44
44
  type: 'block.unset'
@@ -57,7 +57,7 @@ export type SyntheticBehaviorEvent =
57
57
  | {
58
58
  type: 'decorator.add'
59
59
  decorator: string
60
- selection?: NonNullable<EditorSelection>
60
+ offsets?: {anchor: BlockOffset; focus: BlockOffset}
61
61
  }
62
62
  | {
63
63
  type: 'decorator.remove'
@@ -195,18 +195,6 @@ export type SyntheticBehaviorEvent =
195
195
  type: 'style.toggle'
196
196
  style: string
197
197
  }
198
- | {
199
- type: 'text block.set'
200
- at: [KeyedSegment]
201
- level?: number
202
- listItem?: string
203
- style?: string
204
- }
205
- | {
206
- type: 'text block.unset'
207
- at: [KeyedSegment]
208
- props: Array<'level' | 'listItem' | 'style'>
209
- }
210
198
  | (PickFromUnion<
211
199
  ConverterEvent,
212
200
  'type',
@@ -412,6 +412,7 @@ describe(converterPortableText.deserialize, () => {
412
412
  },
413
413
  ],
414
414
  markDefs: [],
415
+ level: 1,
415
416
  style: 'normal',
416
417
  },
417
418
  ])
@@ -568,7 +569,7 @@ describe(converterPortableText.deserialize, () => {
568
569
  {
569
570
  _type: 'span',
570
571
  text: 'foo',
571
- marks: ['k0'],
572
+ marks: ['k1'],
572
573
  },
573
574
  {
574
575
  _type: 'span',
@@ -578,7 +579,7 @@ describe(converterPortableText.deserialize, () => {
578
579
  ],
579
580
  markDefs: [
580
581
  {
581
- _key: 'k0',
582
+ _key: 'k1',
582
583
  _type: 'link',
583
584
  href: 'https://example.com',
584
585
  },