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