@portabletext/editor 1.24.0 → 1.26.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 (89) hide show
  1. package/lib/_chunks-cjs/behavior.core.cjs +283 -64
  2. package/lib/_chunks-cjs/behavior.core.cjs.map +1 -1
  3. package/lib/_chunks-cjs/selector.get-text-before.cjs +8 -8
  4. package/lib/_chunks-cjs/selector.get-text-before.cjs.map +1 -1
  5. package/lib/_chunks-cjs/selector.is-at-the-start-of-block.cjs +412 -0
  6. package/lib/_chunks-cjs/selector.is-at-the-start-of-block.cjs.map +1 -0
  7. package/lib/_chunks-cjs/util.is-empty-text-block.cjs +2 -2
  8. package/lib/_chunks-cjs/util.is-empty-text-block.cjs.map +1 -1
  9. package/lib/_chunks-cjs/util.is-equal-selection-points.cjs +46 -0
  10. package/lib/_chunks-cjs/util.is-equal-selection-points.cjs.map +1 -0
  11. package/lib/_chunks-cjs/util.reverse-selection.cjs +0 -16
  12. package/lib/_chunks-cjs/util.reverse-selection.cjs.map +1 -1
  13. package/lib/_chunks-es/behavior.core.js +259 -40
  14. package/lib/_chunks-es/behavior.core.js.map +1 -1
  15. package/lib/_chunks-es/selector.get-text-before.js +2 -2
  16. package/lib/_chunks-es/selector.is-at-the-start-of-block.js +414 -0
  17. package/lib/_chunks-es/selector.is-at-the-start-of-block.js.map +1 -0
  18. package/lib/_chunks-es/util.is-empty-text-block.js +1 -1
  19. package/lib/_chunks-es/util.is-equal-selection-points.js +47 -0
  20. package/lib/_chunks-es/util.is-equal-selection-points.js.map +1 -0
  21. package/lib/_chunks-es/util.reverse-selection.js +0 -16
  22. package/lib/_chunks-es/util.reverse-selection.js.map +1 -1
  23. package/lib/behaviors/index.cjs +27 -27
  24. package/lib/behaviors/index.cjs.map +1 -1
  25. package/lib/behaviors/index.d.cts +2208 -171
  26. package/lib/behaviors/index.d.ts +2208 -171
  27. package/lib/behaviors/index.js +1 -1
  28. package/lib/index.cjs +306 -298
  29. package/lib/index.cjs.map +1 -1
  30. package/lib/index.d.cts +10499 -521
  31. package/lib/index.d.ts +10499 -521
  32. package/lib/index.js +302 -294
  33. package/lib/index.js.map +1 -1
  34. package/lib/selectors/index.cjs +26 -171
  35. package/lib/selectors/index.cjs.map +1 -1
  36. package/lib/selectors/index.d.cts +16 -0
  37. package/lib/selectors/index.d.ts +16 -0
  38. package/lib/selectors/index.js +5 -151
  39. package/lib/selectors/index.js.map +1 -1
  40. package/lib/utils/index.cjs +5 -3
  41. package/lib/utils/index.cjs.map +1 -1
  42. package/lib/utils/index.d.cts +19 -0
  43. package/lib/utils/index.d.ts +19 -0
  44. package/lib/utils/index.js +4 -2
  45. package/package.json +6 -6
  46. package/src/behavior-actions/behavior.action-utils.insert-block.ts +3 -3
  47. package/src/behavior-actions/behavior.action.block.set.ts +23 -0
  48. package/src/behavior-actions/behavior.action.block.unset.ts +21 -0
  49. package/src/behavior-actions/behavior.action.insert-break.ts +2 -69
  50. package/src/behavior-actions/behavior.action.insert.block.ts +29 -0
  51. package/src/behavior-actions/behavior.actions.ts +116 -96
  52. package/src/behaviors/behavior.core.annotations.ts +29 -0
  53. package/src/behaviors/behavior.core.block-objects.ts +13 -13
  54. package/src/behaviors/behavior.core.decorators.ts +19 -0
  55. package/src/behaviors/behavior.core.insert-break.ts +122 -0
  56. package/src/behaviors/behavior.core.lists.ts +57 -23
  57. package/src/behaviors/behavior.core.style.ts +19 -0
  58. package/src/behaviors/behavior.core.ts +18 -2
  59. package/src/behaviors/behavior.types.ts +103 -88
  60. package/src/converters/converter.json.ts +4 -4
  61. package/src/converters/converter.portable-text.deserialize.test.ts +1 -1
  62. package/src/converters/converter.portable-text.ts +4 -4
  63. package/src/converters/converter.text-html.deserialize.test.ts +1 -1
  64. package/src/converters/converter.text-html.serialize.test.ts +1 -1
  65. package/src/converters/converter.text-html.ts +4 -4
  66. package/src/converters/converter.text-plain.test.ts +1 -1
  67. package/src/converters/converter.text-plain.ts +3 -3
  68. package/src/converters/{converter.ts → converter.types.ts} +6 -0
  69. package/src/editor/create-editor.ts +50 -7
  70. package/src/editor/editor-machine.ts +46 -3
  71. package/src/editor/editor-snapshot.ts +1 -1
  72. package/src/editor/plugins/__tests__/withPortableTextMarkModel.test.tsx +2 -2
  73. package/src/editor/plugins/create-with-event-listeners.ts +41 -106
  74. package/src/selectors/index.ts +2 -0
  75. package/src/selectors/selector.is-at-the-end-of-block.ts +22 -0
  76. package/src/selectors/selector.is-at-the-start-of-block.ts +25 -0
  77. package/src/selectors/selector.is-selection-collapsed.ts +6 -2
  78. package/src/utils/index.ts +2 -0
  79. package/src/utils/util.get-block-end-point.ts +34 -0
  80. package/src/utils/util.is-equal-selection-points.ts +13 -0
  81. package/lib/_chunks-cjs/selector.is-selection-collapsed.cjs +0 -231
  82. package/lib/_chunks-cjs/selector.is-selection-collapsed.cjs.map +0 -1
  83. package/lib/_chunks-cjs/util.is-keyed-segment.cjs +0 -6
  84. package/lib/_chunks-cjs/util.is-keyed-segment.cjs.map +0 -1
  85. package/lib/_chunks-es/selector.is-selection-collapsed.js +0 -232
  86. package/lib/_chunks-es/selector.is-selection-collapsed.js.map +0 -1
  87. package/lib/_chunks-es/util.is-keyed-segment.js +0 -7
  88. package/lib/_chunks-es/util.is-keyed-segment.js.map +0 -1
  89. /package/src/converters/{converters.ts → converters.core.ts} +0 -0
@@ -0,0 +1,122 @@
1
+ import * as selectors from '../selectors'
2
+ import {defineBehavior, raise} from './behavior.types'
3
+
4
+ const atTheEndOfTextBlock = defineBehavior({
5
+ on: 'insert.break',
6
+ guard: ({context}) => {
7
+ const focusTextBlock = selectors.getFocusTextBlock({context})
8
+ const selectionCollapsed = selectors.isSelectionCollapsed({context})
9
+
10
+ if (!context.selection || !focusTextBlock || !selectionCollapsed) {
11
+ return false
12
+ }
13
+
14
+ const atTheEndOfBlock = selectors.isAtTheEndOfBlock(focusTextBlock)({
15
+ context,
16
+ })
17
+
18
+ const focusListItem = focusTextBlock.node.listItem
19
+ const focusLevel = focusTextBlock.node.level
20
+
21
+ if (atTheEndOfBlock) {
22
+ return {focusListItem, focusLevel}
23
+ }
24
+
25
+ return false
26
+ },
27
+ actions: [
28
+ ({context}, {focusListItem, focusLevel}) => [
29
+ raise({
30
+ type: 'insert.block',
31
+ block: {
32
+ _type: context.schema.block.name,
33
+ _key: context.keyGenerator(),
34
+ children: [
35
+ {
36
+ _key: context.keyGenerator(),
37
+ _type: context.schema.span.name,
38
+ text: '',
39
+ marks: [],
40
+ },
41
+ ],
42
+ markDefs: [],
43
+ listItem: focusListItem,
44
+ level: focusLevel,
45
+ style: context.schema.styles[0]?.value,
46
+ },
47
+ placement: 'after',
48
+ }),
49
+ ],
50
+ ],
51
+ })
52
+
53
+ const atTheStartOfTextBlock = defineBehavior({
54
+ on: 'insert.break',
55
+ guard: ({context}) => {
56
+ const focusTextBlock = selectors.getFocusTextBlock({context})
57
+ const selectionCollapsed = selectors.isSelectionCollapsed({context})
58
+
59
+ if (!context.selection || !focusTextBlock || !selectionCollapsed) {
60
+ return false
61
+ }
62
+
63
+ const focusSpan = selectors.getFocusSpan({context})
64
+
65
+ const focusDecorators = focusSpan?.node.marks?.filter(
66
+ (mark) =>
67
+ context.schema.decorators.some(
68
+ (decorator) => decorator.value === mark,
69
+ ) ?? [],
70
+ )
71
+ const focusAnnotations =
72
+ focusSpan?.node.marks?.filter(
73
+ (mark) =>
74
+ !context.schema.decorators.some(
75
+ (decorator) => decorator.value === mark,
76
+ ),
77
+ ) ?? []
78
+ const focusListItem = focusTextBlock.node.listItem
79
+ const focusLevel = focusTextBlock.node.level
80
+
81
+ const atTheStartOfBlock = selectors.isAtTheStartOfBlock(focusTextBlock)({
82
+ context,
83
+ })
84
+
85
+ if (atTheStartOfBlock) {
86
+ return {focusAnnotations, focusDecorators, focusListItem, focusLevel}
87
+ }
88
+
89
+ return false
90
+ },
91
+ actions: [
92
+ (
93
+ {context},
94
+ {focusAnnotations, focusDecorators, focusListItem, focusLevel},
95
+ ) => [
96
+ raise({
97
+ type: 'insert.block',
98
+ block: {
99
+ _key: context.keyGenerator(),
100
+ _type: context.schema.block.name,
101
+ children: [
102
+ {
103
+ _key: context.keyGenerator(),
104
+ _type: context.schema.span.name,
105
+ marks: focusAnnotations.length === 0 ? focusDecorators : [],
106
+ text: '',
107
+ },
108
+ ],
109
+ listItem: focusListItem,
110
+ level: focusLevel,
111
+ style: context.schema.styles[0]?.value,
112
+ },
113
+ placement: 'before',
114
+ }),
115
+ ],
116
+ ],
117
+ })
118
+
119
+ export const coreInsertBreakBehaviors = {
120
+ atTheEndOfTextBlock,
121
+ atTheStartOfTextBlock,
122
+ }
@@ -2,10 +2,38 @@ import {createGuards} from '../behavior-actions/behavior.guards'
2
2
  import {isHotkey} from '../internal-utils/is-hotkey'
3
3
  import * as selectors from '../selectors'
4
4
  import {isEmptyTextBlock} from '../utils/util.is-empty-text-block'
5
- import {defineBehavior} from './behavior.types'
5
+ import {defineBehavior, raise} from './behavior.types'
6
6
 
7
7
  const MAX_LIST_LEVEL = 10
8
8
 
9
+ const toggleListItemOff = defineBehavior({
10
+ on: 'list item.toggle',
11
+ guard: ({context, event}) =>
12
+ selectors.isActiveListItem(event.listItem)({context}),
13
+ actions: [
14
+ ({event}) => [
15
+ raise({
16
+ type: 'list item.remove',
17
+ listItem: event.listItem,
18
+ }),
19
+ ],
20
+ ],
21
+ })
22
+
23
+ const toggleListItemOn = defineBehavior({
24
+ on: 'list item.toggle',
25
+ guard: ({context, event}) =>
26
+ !selectors.isActiveListItem(event.listItem)({context}),
27
+ actions: [
28
+ ({event}) => [
29
+ raise({
30
+ type: 'list item.add',
31
+ listItem: event.listItem,
32
+ }),
33
+ ],
34
+ ],
35
+ })
36
+
9
37
  const clearListOnBackspace = defineBehavior({
10
38
  on: 'delete.backward',
11
39
  guard: ({context}) => {
@@ -29,11 +57,11 @@ const clearListOnBackspace = defineBehavior({
29
57
  },
30
58
  actions: [
31
59
  (_, {focusTextBlock}) => [
32
- {
60
+ raise({
33
61
  type: 'text block.unset',
34
62
  props: ['listItem', 'level'],
35
63
  at: focusTextBlock.path,
36
- },
64
+ }),
37
65
  ],
38
66
  ],
39
67
  })
@@ -65,11 +93,11 @@ const unindentListOnBackspace = defineBehavior({
65
93
  },
66
94
  actions: [
67
95
  (_, {focusTextBlock, level}) => [
68
- {
96
+ raise({
69
97
  type: 'text block.set',
70
98
  level,
71
99
  at: focusTextBlock.path,
72
- },
100
+ }),
73
101
  ],
74
102
  ],
75
103
  })
@@ -92,11 +120,11 @@ const clearListOnEnter = defineBehavior({
92
120
  },
93
121
  actions: [
94
122
  (_, {focusListBlock}) => [
95
- {
123
+ raise({
96
124
  type: 'text block.unset',
97
125
  props: ['listItem', 'level'],
98
126
  at: focusListBlock.path,
99
- },
127
+ }),
100
128
  ],
101
129
  ],
102
130
  })
@@ -131,14 +159,16 @@ const indentListOnTab = defineBehavior({
131
159
  },
132
160
  actions: [
133
161
  (_, {selectedListBlocks}) =>
134
- selectedListBlocks.map((selectedListBlock) => ({
135
- type: 'text block.set',
136
- level: Math.min(
137
- MAX_LIST_LEVEL,
138
- Math.max(1, selectedListBlock.node.level + 1),
139
- ),
140
- at: selectedListBlock.path,
141
- })),
162
+ selectedListBlocks.map((selectedListBlock) =>
163
+ raise({
164
+ type: 'text block.set',
165
+ level: Math.min(
166
+ MAX_LIST_LEVEL,
167
+ Math.max(1, selectedListBlock.node.level + 1),
168
+ ),
169
+ at: selectedListBlock.path,
170
+ }),
171
+ ),
142
172
  ],
143
173
  })
144
174
 
@@ -172,18 +202,22 @@ const unindentListOnShiftTab = defineBehavior({
172
202
  },
173
203
  actions: [
174
204
  (_, {selectedListBlocks}) =>
175
- selectedListBlocks.map((selectedListBlock) => ({
176
- type: 'text block.set',
177
- level: Math.min(
178
- MAX_LIST_LEVEL,
179
- Math.max(1, selectedListBlock.node.level - 1),
180
- ),
181
- at: selectedListBlock.path,
182
- })),
205
+ selectedListBlocks.map((selectedListBlock) =>
206
+ raise({
207
+ type: 'text block.set',
208
+ level: Math.min(
209
+ MAX_LIST_LEVEL,
210
+ Math.max(1, selectedListBlock.node.level - 1),
211
+ ),
212
+ at: selectedListBlock.path,
213
+ }),
214
+ ),
183
215
  ],
184
216
  })
185
217
 
186
218
  export const coreListBehaviors = {
219
+ toggleListItemOff,
220
+ toggleListItemOn,
187
221
  clearListOnBackspace,
188
222
  unindentListOnBackspace,
189
223
  clearListOnEnter,
@@ -0,0 +1,19 @@
1
+ import * as selectors from '../selectors'
2
+ import {defineBehavior, raise} from './behavior.types'
3
+
4
+ const toggleStyleOff = defineBehavior({
5
+ on: 'style.toggle',
6
+ guard: ({context, event}) => selectors.isActiveStyle(event.style)({context}),
7
+ actions: [({event}) => [raise({type: 'style.remove', style: event.style})]],
8
+ })
9
+
10
+ const toggleStyleOn = defineBehavior({
11
+ on: 'style.toggle',
12
+ guard: ({context, event}) => !selectors.isActiveStyle(event.style)({context}),
13
+ actions: [({event}) => [raise({type: 'style.add', style: event.style})]],
14
+ })
15
+
16
+ export const coreStyleBehaviors = {
17
+ toggleStyleOff,
18
+ toggleStyleOn,
19
+ }
@@ -1,13 +1,16 @@
1
+ import {coreAnnotationBehaviors} from './behavior.core.annotations'
1
2
  import {coreBlockObjectBehaviors} from './behavior.core.block-objects'
2
3
  import {coreDecoratorBehaviors} from './behavior.core.decorators'
3
4
  import {coreDeserializeBehavior} from './behavior.core.deserialize'
5
+ import {coreInsertBreakBehaviors} from './behavior.core.insert-break'
4
6
  import {coreListBehaviors} from './behavior.core.lists'
5
7
  import {coreSerializeBehaviors} from './behavior.core.serialize'
6
- import {defineBehavior} from './behavior.types'
8
+ import {coreStyleBehaviors} from './behavior.core.style'
9
+ import {defineBehavior, raise} from './behavior.types'
7
10
 
8
11
  const softReturn = defineBehavior({
9
12
  on: 'insert.soft break',
10
- actions: [() => [{type: 'insert.text', text: '\n'}]],
13
+ actions: [() => [raise({type: 'insert.text', text: '\n'})]],
11
14
  })
12
15
 
13
16
  /**
@@ -15,6 +18,10 @@ const softReturn = defineBehavior({
15
18
  */
16
19
  export const coreBehaviors = [
17
20
  softReturn,
21
+ coreAnnotationBehaviors.toggleAnnotationOff,
22
+ coreAnnotationBehaviors.toggleAnnotationOn,
23
+ coreDecoratorBehaviors.toggleDecoratorOff,
24
+ coreDecoratorBehaviors.toggleDecoratorOn,
18
25
  coreDecoratorBehaviors.strongShortcut,
19
26
  coreDecoratorBehaviors.emShortcut,
20
27
  coreDecoratorBehaviors.underlineShortcut,
@@ -25,13 +32,19 @@ export const coreBehaviors = [
25
32
  coreBlockObjectBehaviors.breakingBlockObject,
26
33
  coreBlockObjectBehaviors.deletingEmptyTextBlockAfterBlockObject,
27
34
  coreBlockObjectBehaviors.deletingEmptyTextBlockBeforeBlockObject,
35
+ coreListBehaviors.toggleListItemOff,
36
+ coreListBehaviors.toggleListItemOn,
28
37
  coreListBehaviors.clearListOnBackspace,
29
38
  coreListBehaviors.unindentListOnBackspace,
30
39
  coreListBehaviors.clearListOnEnter,
31
40
  coreListBehaviors.indentListOnTab,
32
41
  coreListBehaviors.unindentListOnShiftTab,
42
+ coreInsertBreakBehaviors.atTheEndOfTextBlock,
43
+ coreInsertBreakBehaviors.atTheStartOfTextBlock,
33
44
  coreSerializeBehaviors.serialize,
34
45
  coreSerializeBehaviors['serialization.success'],
46
+ coreStyleBehaviors.toggleStyleOff,
47
+ coreStyleBehaviors.toggleStyleOn,
35
48
  ]
36
49
 
37
50
  /**
@@ -39,9 +52,12 @@ export const coreBehaviors = [
39
52
  */
40
53
  export const coreBehavior = {
41
54
  softReturn,
55
+ annotation: coreAnnotationBehaviors,
42
56
  decorators: coreDecoratorBehaviors,
43
57
  deserialize: coreDeserializeBehavior,
44
58
  blockObjects: coreBlockObjectBehaviors,
59
+ insertBreak: coreInsertBreakBehaviors,
45
60
  lists: coreListBehaviors,
46
61
  ...coreSerializeBehaviors,
62
+ style: coreSerializeBehaviors,
47
63
  }
@@ -5,7 +5,7 @@ import type {
5
5
  } from '@sanity/types'
6
6
  import type {TextUnit} from 'slate'
7
7
  import type {TextInsertTextOptions} from 'slate/dist/interfaces/transforms/text'
8
- import type {ConverterEvent} from '../converters/converter'
8
+ import type {ConverterEvent} from '../converters/converter.types'
9
9
  import type {EditorContext} from '../editor/editor-snapshot'
10
10
  import type {MIMEType} from '../internal-utils/mime-type'
11
11
  import type {OmitFromUnion, PickFromUnion} from '../type-utils'
@@ -28,6 +28,23 @@ export type SyntheticBehaviorEvent =
28
28
  name: string
29
29
  }
30
30
  }
31
+ | {
32
+ type: 'annotation.toggle'
33
+ annotation: {
34
+ name: string
35
+ value: {[prop: string]: unknown}
36
+ }
37
+ }
38
+ | {
39
+ type: 'block.set'
40
+ at: [KeyedSegment]
41
+ [props: string]: unknown
42
+ }
43
+ | {
44
+ type: 'block.unset'
45
+ at: [KeyedSegment]
46
+ props: Array<string>
47
+ }
31
48
  | {
32
49
  type: 'blur'
33
50
  }
@@ -37,6 +54,14 @@ export type SyntheticBehaviorEvent =
37
54
  dataTransfer: DataTransfer
38
55
  mimeType: MIMEType
39
56
  }
57
+ | {
58
+ type: 'decorator.add'
59
+ decorator: string
60
+ }
61
+ | {
62
+ type: 'decorator.remove'
63
+ decorator: string
64
+ }
40
65
  | {
41
66
  type: 'decorator.toggle'
42
67
  decorator: string
@@ -45,10 +70,19 @@ export type SyntheticBehaviorEvent =
45
70
  type: 'delete.backward'
46
71
  unit: TextUnit
47
72
  }
73
+ | {
74
+ type: 'delete.block'
75
+ blockPath: [KeyedSegment]
76
+ }
48
77
  | {
49
78
  type: 'delete.forward'
50
79
  unit: TextUnit
51
80
  }
81
+ | {
82
+ type: 'delete.text'
83
+ anchor: BlockOffset
84
+ focus: BlockOffset
85
+ }
52
86
  | {
53
87
  type: 'focus'
54
88
  }
@@ -77,23 +111,91 @@ export type SyntheticBehaviorEvent =
77
111
  | {
78
112
  type: 'insert.soft break'
79
113
  }
114
+ | {
115
+ type: 'insert.block'
116
+ block: PortableTextBlock
117
+ placement: 'auto' | 'after' | 'before'
118
+ }
119
+ | {
120
+ type: 'insert.span'
121
+ text: string
122
+ annotations?: Array<{
123
+ name: string
124
+ value: {[prop: string]: unknown}
125
+ }>
126
+ decorators?: Array<string>
127
+ }
80
128
  | {
81
129
  type: 'insert.text'
82
130
  text: string
83
131
  options?: TextInsertTextOptions
84
132
  }
133
+ | {
134
+ type: 'insert.text block'
135
+ placement: 'auto' | 'after' | 'before'
136
+ textBlock?: {
137
+ children?: PortableTextTextBlock['children']
138
+ }
139
+ }
140
+ | {
141
+ type: 'list item.add'
142
+ listItem: string
143
+ }
144
+ | {
145
+ type: 'list item.remove'
146
+ listItem: string
147
+ }
85
148
  | {
86
149
  type: 'list item.toggle'
87
150
  listItem: string
88
151
  }
152
+ | {
153
+ type: 'move.block'
154
+ at: [KeyedSegment]
155
+ to: [KeyedSegment]
156
+ }
157
+ | {
158
+ type: 'move.block down'
159
+ at: [KeyedSegment]
160
+ }
161
+ | {
162
+ type: 'move.block up'
163
+ at: [KeyedSegment]
164
+ }
89
165
  | {
90
166
  type: 'select'
91
167
  selection: EditorSelection
92
168
  }
169
+ | {
170
+ type: 'select.previous block'
171
+ }
172
+ | {
173
+ type: 'select.next block'
174
+ }
175
+ | {
176
+ type: 'style.add'
177
+ style: string
178
+ }
179
+ | {
180
+ type: 'style.remove'
181
+ style: string
182
+ }
93
183
  | {
94
184
  type: 'style.toggle'
95
185
  style: string
96
186
  }
187
+ | {
188
+ type: 'text block.set'
189
+ at: [KeyedSegment]
190
+ level?: number
191
+ listItem?: string
192
+ style?: string
193
+ }
194
+ | {
195
+ type: 'text block.unset'
196
+ at: [KeyedSegment]
197
+ props: Array<'level' | 'listItem' | 'style'>
198
+ }
97
199
  | (PickFromUnion<
98
200
  ConverterEvent,
99
201
  'type',
@@ -165,100 +267,13 @@ export type BehaviorActionIntend =
165
267
  type: 'raise'
166
268
  event: SyntheticBehaviorEvent | CustomBehaviorEvent
167
269
  }
168
- | {
169
- type: 'annotation.toggle'
170
- annotation: {
171
- name: string
172
- value: {[prop: string]: unknown}
173
- }
174
- }
175
- | {
176
- type: 'decorator.add'
177
- decorator: string
178
- }
179
- | {
180
- type: 'decorator.remove'
181
- decorator: string
182
- }
183
- | {
184
- type: 'insert.span'
185
- text: string
186
- annotations?: Array<{
187
- name: string
188
- value: {[prop: string]: unknown}
189
- }>
190
- decorators?: Array<string>
191
- }
192
- | {
193
- type: 'insert.text block'
194
- placement: 'auto' | 'after' | 'before'
195
- textBlock?: {
196
- children?: PortableTextTextBlock['children']
197
- }
198
- }
199
- | {
200
- type: 'list item.add'
201
- listItem: string
202
- }
203
- | {
204
- type: 'list item.remove'
205
- listItem: string
206
- }
207
- | {
208
- type: 'move.block'
209
- at: [KeyedSegment]
210
- to: [KeyedSegment]
211
- }
212
- | {
213
- type: 'move.block down'
214
- at: [KeyedSegment]
215
- }
216
- | {
217
- type: 'move.block up'
218
- at: [KeyedSegment]
219
- }
220
270
  | {
221
271
  type: 'noop'
222
272
  }
223
- | {
224
- type: 'delete.block'
225
- blockPath: [KeyedSegment]
226
- }
227
- | {
228
- type: 'delete.text'
229
- anchor: BlockOffset
230
- focus: BlockOffset
231
- }
232
273
  | {
233
274
  type: 'effect'
234
275
  effect: () => void
235
276
  }
236
- | {
237
- type: 'select.previous block'
238
- }
239
- | {
240
- type: 'select.next block'
241
- }
242
- | {
243
- type: 'style.add'
244
- style: string
245
- }
246
- | {
247
- type: 'style.remove'
248
- style: string
249
- }
250
- | {
251
- type: 'text block.set'
252
- at: [KeyedSegment]
253
- level?: number
254
- listItem?: string
255
- style?: string
256
- }
257
- | {
258
- type: 'text block.unset'
259
- at: [KeyedSegment]
260
- props: Array<'level' | 'listItem' | 'style'>
261
- }
262
277
 
263
278
  /**
264
279
  * @beta
@@ -1,6 +1,7 @@
1
- import type {Converter} from './converter'
1
+ import {defineConverter} from './converter.types'
2
2
 
3
- export const converterJson: Converter<'application/json'> = {
3
+ export const converterJson = defineConverter({
4
+ mimeType: 'application/json',
4
5
  serialize: ({context, event}) => {
5
6
  const portableTextConverter = context.converters.find(
6
7
  (converter) => converter.mimeType === 'application/x-portable-text',
@@ -49,5 +50,4 @@ export const converterJson: Converter<'application/json'> = {
49
50
  mimeType: 'application/json',
50
51
  }
51
52
  },
52
- mimeType: 'application/json',
53
- }
53
+ })
@@ -6,7 +6,7 @@ import {
6
6
  } from '../editor/define-schema'
7
7
  import {createTestKeyGenerator} from '../internal-utils/test-key-generator'
8
8
  import {converterPortableText} from './converter.portable-text'
9
- import {coreConverters} from './converters'
9
+ import {coreConverters} from './converters.core'
10
10
 
11
11
  function createContext(schema: SchemaDefinition) {
12
12
  return {
@@ -1,8 +1,9 @@
1
1
  import {parseBlock} from '../internal-utils/parse-blocks'
2
2
  import {sliceBlocks} from '../utils'
3
- import type {Converter} from './converter'
3
+ import {defineConverter} from './converter.types'
4
4
 
5
- export const converterPortableText: Converter<'application/x-portable-text'> = {
5
+ export const converterPortableText = defineConverter({
6
+ mimeType: 'application/x-portable-text',
6
7
  serialize: ({context, event}) => {
7
8
  if (!context.selection) {
8
9
  return {
@@ -55,5 +56,4 @@ export const converterPortableText: Converter<'application/x-portable-text'> = {
55
56
  mimeType: 'application/x-portable-text',
56
57
  }
57
58
  },
58
- mimeType: 'application/x-portable-text',
59
- }
59
+ })
@@ -6,7 +6,7 @@ import {
6
6
  } from '../editor/define-schema'
7
7
  import {createTestKeyGenerator} from '../internal-utils/test-key-generator'
8
8
  import {converterTextHtml} from './converter.text-html'
9
- import {coreConverters} from './converters'
9
+ import {coreConverters} from './converters.core'
10
10
 
11
11
  function createContext(schema: SchemaDefinition) {
12
12
  return {
@@ -8,7 +8,7 @@ import {
8
8
  import {createTestKeyGenerator} from '../internal-utils/test-key-generator'
9
9
  import type {EditorSelection} from '../utils'
10
10
  import {converterTextHtml} from './converter.text-html'
11
- import {coreConverters} from './converters'
11
+ import {coreConverters} from './converters.core'
12
12
 
13
13
  const decoratedParagraph: PortableTextTextBlock = {
14
14
  _key: 'k0',
@@ -2,9 +2,10 @@ import {htmlToBlocks} from '@portabletext/block-tools'
2
2
  import {toHTML} from '@portabletext/to-html'
3
3
  import type {PortableTextBlock} from '@sanity/types'
4
4
  import {sliceBlocks} from '../utils'
5
- import type {Converter} from './converter'
5
+ import {defineConverter} from './converter.types'
6
6
 
7
- export const converterTextHtml: Converter<'text/html'> = {
7
+ export const converterTextHtml = defineConverter({
8
+ mimeType: 'text/html',
8
9
  serialize: ({context, event}) => {
9
10
  if (!context.selection) {
10
11
  return {
@@ -57,5 +58,4 @@ export const converterTextHtml: Converter<'text/html'> = {
57
58
  mimeType: 'text/html',
58
59
  }
59
60
  },
60
- mimeType: 'text/html',
61
- }
61
+ })
@@ -8,7 +8,7 @@ import {
8
8
  import type {EditorContext} from '../editor/editor-snapshot'
9
9
  import type {EditorSelection} from '../utils'
10
10
  import {converterTextPlain} from './converter.text-plain'
11
- import {coreConverters} from './converters'
11
+ import {coreConverters} from './converters.core'
12
12
 
13
13
  const b1: PortableTextTextBlock = {
14
14
  _type: 'block',