@portabletext/editor 1.45.3 → 1.46.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.
- package/lib/_chunks-cjs/behavior.core.cjs +20 -0
- package/lib/_chunks-cjs/behavior.core.cjs.map +1 -1
- package/lib/_chunks-cjs/behavior.markdown.cjs +25 -25
- package/lib/_chunks-cjs/behavior.markdown.cjs.map +1 -1
- package/lib/_chunks-cjs/editor-provider.cjs +93 -59
- package/lib/_chunks-cjs/editor-provider.cjs.map +1 -1
- package/lib/_chunks-es/behavior.core.js +20 -0
- package/lib/_chunks-es/behavior.core.js.map +1 -1
- package/lib/_chunks-es/behavior.markdown.js +26 -26
- package/lib/_chunks-es/behavior.markdown.js.map +1 -1
- package/lib/_chunks-es/editor-provider.js +93 -59
- package/lib/_chunks-es/editor-provider.js.map +1 -1
- package/lib/_chunks-es/selector.is-selecting-entire-blocks.js +1 -1
- package/lib/behaviors/index.cjs +37 -53
- package/lib/behaviors/index.cjs.map +1 -1
- package/lib/behaviors/index.d.cts +52 -37
- package/lib/behaviors/index.d.ts +52 -37
- package/lib/behaviors/index.js +38 -54
- package/lib/behaviors/index.js.map +1 -1
- package/lib/index.d.cts +33 -37
- package/lib/index.d.ts +33 -37
- package/lib/plugins/index.cjs +23 -29
- package/lib/plugins/index.cjs.map +1 -1
- package/lib/plugins/index.d.cts +33 -37
- package/lib/plugins/index.d.ts +33 -37
- package/lib/plugins/index.js +24 -30
- package/lib/plugins/index.js.map +1 -1
- package/lib/selectors/index.d.cts +33 -37
- package/lib/selectors/index.d.ts +33 -37
- package/lib/utils/index.d.cts +33 -37
- package/lib/utils/index.d.ts +33 -37
- package/package.json +1 -1
- package/src/behaviors/behavior.decorator-pair.ts +16 -19
- package/src/behaviors/behavior.emoji-picker.ts +26 -45
- package/src/behaviors/behavior.links.ts +5 -4
- package/src/behaviors/behavior.markdown.ts +37 -34
- package/src/behaviors/behavior.perform-event.ts +67 -18
- package/src/behaviors/behavior.types.action.ts +39 -13
- package/src/behaviors/behavior.types.guard.ts +1 -6
- package/src/behaviors/index.ts +3 -0
- package/src/editor/components/Synchronizer.tsx +6 -3
- package/src/editor/create-editor.ts +1 -1
- package/src/editor/editor-machine.ts +8 -6
- package/src/plugins/plugin.decorator-shortcut.ts +6 -8
- package/src/plugins/plugin.one-line.tsx +4 -4
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {assertEvent, assign, createActor, setup} from 'xstate'
|
|
2
2
|
import {isHotkey} from '../internal-utils/is-hotkey'
|
|
3
3
|
import * as selectors from '../selectors'
|
|
4
|
-
import {
|
|
4
|
+
import {effect, execute, noop} from './behavior.types.action'
|
|
5
5
|
import {defineBehavior} from './behavior.types.behavior'
|
|
6
6
|
|
|
7
7
|
const emojiCharRegEx = /^[a-zA-Z-_0-9]{1}$/
|
|
@@ -118,19 +118,16 @@ export function createEmojiPickerBehaviors<TEmojiMatch>(
|
|
|
118
118
|
},
|
|
119
119
|
actions: [
|
|
120
120
|
() => [
|
|
121
|
-
{
|
|
121
|
+
execute({
|
|
122
122
|
type: 'insert.text',
|
|
123
123
|
text: ':',
|
|
124
|
-
},
|
|
124
|
+
}),
|
|
125
125
|
],
|
|
126
126
|
(_, params) => [
|
|
127
|
-
{
|
|
128
|
-
type: '
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
},
|
|
132
|
-
},
|
|
133
|
-
raise({
|
|
127
|
+
effect(() => {
|
|
128
|
+
emojiPickerActor.send({type: 'select'})
|
|
129
|
+
}),
|
|
130
|
+
execute({
|
|
134
131
|
type: 'delete.text',
|
|
135
132
|
at: {
|
|
136
133
|
anchor: {
|
|
@@ -143,10 +140,10 @@ export function createEmojiPickerBehaviors<TEmojiMatch>(
|
|
|
143
140
|
},
|
|
144
141
|
},
|
|
145
142
|
}),
|
|
146
|
-
{
|
|
143
|
+
execute({
|
|
147
144
|
type: 'insert.text',
|
|
148
145
|
text: params.emoji,
|
|
149
|
-
},
|
|
146
|
+
}),
|
|
150
147
|
],
|
|
151
148
|
],
|
|
152
149
|
}),
|
|
@@ -220,13 +217,10 @@ export function createEmojiPickerBehaviors<TEmojiMatch>(
|
|
|
220
217
|
(_, params) => {
|
|
221
218
|
if (params.action === 'select') {
|
|
222
219
|
return [
|
|
223
|
-
{
|
|
224
|
-
type: '
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
},
|
|
228
|
-
},
|
|
229
|
-
raise({
|
|
220
|
+
effect(() => {
|
|
221
|
+
emojiPickerActor.send({type: 'select'})
|
|
222
|
+
}),
|
|
223
|
+
execute({
|
|
230
224
|
type: 'delete.text',
|
|
231
225
|
at: {
|
|
232
226
|
anchor: {
|
|
@@ -239,10 +233,10 @@ export function createEmojiPickerBehaviors<TEmojiMatch>(
|
|
|
239
233
|
},
|
|
240
234
|
},
|
|
241
235
|
}),
|
|
242
|
-
{
|
|
236
|
+
execute({
|
|
243
237
|
type: 'insert.text',
|
|
244
238
|
text: params.emoji,
|
|
245
|
-
},
|
|
239
|
+
}),
|
|
246
240
|
]
|
|
247
241
|
}
|
|
248
242
|
|
|
@@ -250,15 +244,10 @@ export function createEmojiPickerBehaviors<TEmojiMatch>(
|
|
|
250
244
|
return [
|
|
251
245
|
// If we are navigating then we want to hijack the key event and
|
|
252
246
|
// turn it into a noop.
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
type: 'effect',
|
|
258
|
-
effect: () => {
|
|
259
|
-
emojiPickerActor.send({type: 'navigate up'})
|
|
260
|
-
},
|
|
261
|
-
},
|
|
247
|
+
noop(),
|
|
248
|
+
effect(() => {
|
|
249
|
+
emojiPickerActor.send({type: 'navigate up'})
|
|
250
|
+
}),
|
|
262
251
|
]
|
|
263
252
|
}
|
|
264
253
|
|
|
@@ -266,25 +255,17 @@ export function createEmojiPickerBehaviors<TEmojiMatch>(
|
|
|
266
255
|
return [
|
|
267
256
|
// If we are navigating then we want to hijack the key event and
|
|
268
257
|
// turn it into a noop.
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
type: 'effect',
|
|
274
|
-
effect: () => {
|
|
275
|
-
emojiPickerActor.send({type: 'navigate down'})
|
|
276
|
-
},
|
|
277
|
-
},
|
|
258
|
+
noop(),
|
|
259
|
+
effect(() => {
|
|
260
|
+
emojiPickerActor.send({type: 'navigate down'})
|
|
261
|
+
}),
|
|
278
262
|
]
|
|
279
263
|
}
|
|
280
264
|
|
|
281
265
|
return [
|
|
282
|
-
{
|
|
283
|
-
type: '
|
|
284
|
-
|
|
285
|
-
emojiPickerActor.send({type: 'reset'})
|
|
286
|
-
},
|
|
287
|
-
},
|
|
266
|
+
effect(() => {
|
|
267
|
+
emojiPickerActor.send({type: 'reset'})
|
|
268
|
+
}),
|
|
288
269
|
]
|
|
289
270
|
},
|
|
290
271
|
],
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type {EditorSchema} from '../editor/define-schema'
|
|
2
2
|
import {looksLikeUrl} from '../internal-utils/looks-like-url'
|
|
3
3
|
import * as selectors from '../selectors'
|
|
4
|
+
import {execute} from './behavior.types.action'
|
|
4
5
|
import {defineBehavior} from './behavior.types.behavior'
|
|
5
6
|
|
|
6
7
|
/**
|
|
@@ -36,10 +37,10 @@ export function createLinkBehaviors(config: LinkBehaviorsConfig) {
|
|
|
36
37
|
},
|
|
37
38
|
actions: [
|
|
38
39
|
(_, {annotation}) => [
|
|
39
|
-
{
|
|
40
|
+
execute({
|
|
40
41
|
type: 'annotation.add',
|
|
41
42
|
annotation,
|
|
42
|
-
},
|
|
43
|
+
}),
|
|
43
44
|
],
|
|
44
45
|
],
|
|
45
46
|
})
|
|
@@ -68,11 +69,11 @@ export function createLinkBehaviors(config: LinkBehaviorsConfig) {
|
|
|
68
69
|
},
|
|
69
70
|
actions: [
|
|
70
71
|
(_, {annotation, url}) => [
|
|
71
|
-
{
|
|
72
|
+
execute({
|
|
72
73
|
type: 'insert.span',
|
|
73
74
|
text: url,
|
|
74
75
|
annotations: [annotation],
|
|
75
|
-
},
|
|
76
|
+
}),
|
|
76
77
|
],
|
|
77
78
|
],
|
|
78
79
|
})
|
|
@@ -3,7 +3,7 @@ import type {EditorSchema} from '../editor/define-schema'
|
|
|
3
3
|
import * as selectors from '../selectors'
|
|
4
4
|
import {spanSelectionPointToBlockOffset} from '../utils/util.block-offset'
|
|
5
5
|
import {getTextBlockText} from '../utils/util.get-text-block-text'
|
|
6
|
-
import {
|
|
6
|
+
import {execute} from './behavior.types.action'
|
|
7
7
|
import {defineBehavior} from './behavior.types.behavior'
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -120,23 +120,23 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
|
|
|
120
120
|
},
|
|
121
121
|
actions: [
|
|
122
122
|
() => [
|
|
123
|
-
{
|
|
123
|
+
execute({
|
|
124
124
|
type: 'insert.text',
|
|
125
125
|
text: ' ',
|
|
126
|
-
},
|
|
126
|
+
}),
|
|
127
127
|
],
|
|
128
128
|
(_, {focusTextBlock, style}) => [
|
|
129
|
-
{
|
|
129
|
+
execute({
|
|
130
130
|
type: 'block.unset',
|
|
131
131
|
props: ['listItem', 'level'],
|
|
132
132
|
at: focusTextBlock.path,
|
|
133
|
-
},
|
|
134
|
-
{
|
|
133
|
+
}),
|
|
134
|
+
execute({
|
|
135
135
|
type: 'block.set',
|
|
136
136
|
props: {style},
|
|
137
137
|
at: focusTextBlock.path,
|
|
138
|
-
},
|
|
139
|
-
|
|
138
|
+
}),
|
|
139
|
+
execute({
|
|
140
140
|
type: 'delete.text',
|
|
141
141
|
at: {
|
|
142
142
|
anchor: {
|
|
@@ -200,21 +200,21 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
|
|
|
200
200
|
},
|
|
201
201
|
actions: [
|
|
202
202
|
(_, {hrCharacter}) => [
|
|
203
|
-
{
|
|
203
|
+
execute({
|
|
204
204
|
type: 'insert.text',
|
|
205
205
|
text: hrCharacter,
|
|
206
|
-
},
|
|
206
|
+
}),
|
|
207
207
|
],
|
|
208
208
|
(_, {hrObject, hrBlockOffsets}) => [
|
|
209
|
-
{
|
|
209
|
+
execute({
|
|
210
210
|
type: 'insert.block',
|
|
211
211
|
placement: 'before',
|
|
212
212
|
block: {
|
|
213
213
|
_type: hrObject.name,
|
|
214
214
|
...(hrObject.value ?? {}),
|
|
215
215
|
},
|
|
216
|
-
},
|
|
217
|
-
|
|
216
|
+
}),
|
|
217
|
+
execute({
|
|
218
218
|
type: 'delete.text',
|
|
219
219
|
at: hrBlockOffsets,
|
|
220
220
|
}),
|
|
@@ -238,41 +238,44 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
|
|
|
238
238
|
},
|
|
239
239
|
actions: [
|
|
240
240
|
(_, {hrCharacters}) => [
|
|
241
|
-
{
|
|
241
|
+
execute({
|
|
242
242
|
type: 'insert.text',
|
|
243
243
|
text: hrCharacters,
|
|
244
|
-
},
|
|
244
|
+
}),
|
|
245
245
|
],
|
|
246
246
|
({snapshot}, {hrObject, focusBlock}) =>
|
|
247
247
|
isPortableTextTextBlock(focusBlock.node)
|
|
248
248
|
? [
|
|
249
|
-
{
|
|
249
|
+
execute({
|
|
250
250
|
type: 'insert.block',
|
|
251
251
|
block: {
|
|
252
252
|
_type: snapshot.context.schema.block.name,
|
|
253
253
|
children: focusBlock.node.children,
|
|
254
254
|
},
|
|
255
255
|
placement: 'after',
|
|
256
|
-
},
|
|
257
|
-
{
|
|
256
|
+
}),
|
|
257
|
+
execute({
|
|
258
258
|
type: 'insert.block',
|
|
259
259
|
block: {
|
|
260
260
|
_type: hrObject.name,
|
|
261
261
|
...(hrObject.value ?? {}),
|
|
262
262
|
},
|
|
263
263
|
placement: 'after',
|
|
264
|
-
},
|
|
265
|
-
{
|
|
264
|
+
}),
|
|
265
|
+
execute({
|
|
266
|
+
type: 'delete.block',
|
|
267
|
+
at: focusBlock.path,
|
|
268
|
+
}),
|
|
266
269
|
]
|
|
267
270
|
: [
|
|
268
|
-
{
|
|
271
|
+
execute({
|
|
269
272
|
type: 'insert.block',
|
|
270
273
|
block: {
|
|
271
274
|
_type: hrObject.name,
|
|
272
275
|
...(hrObject.value ?? {}),
|
|
273
276
|
},
|
|
274
277
|
placement: 'after',
|
|
275
|
-
},
|
|
278
|
+
}),
|
|
276
279
|
],
|
|
277
280
|
],
|
|
278
281
|
})
|
|
@@ -337,19 +340,19 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
|
|
|
337
340
|
return false
|
|
338
341
|
},
|
|
339
342
|
actions: [
|
|
340
|
-
({event}) => [event],
|
|
343
|
+
({event}) => [execute(event)],
|
|
341
344
|
(_, {focusTextBlock, style, level}) => [
|
|
342
|
-
{
|
|
345
|
+
execute({
|
|
343
346
|
type: 'block.unset',
|
|
344
347
|
props: ['listItem', 'level'],
|
|
345
348
|
at: focusTextBlock.path,
|
|
346
|
-
},
|
|
347
|
-
{
|
|
349
|
+
}),
|
|
350
|
+
execute({
|
|
348
351
|
type: 'block.set',
|
|
349
352
|
props: {style},
|
|
350
353
|
at: focusTextBlock.path,
|
|
351
|
-
},
|
|
352
|
-
|
|
354
|
+
}),
|
|
355
|
+
execute({
|
|
353
356
|
type: 'delete.text',
|
|
354
357
|
at: {
|
|
355
358
|
anchor: {
|
|
@@ -394,11 +397,11 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
|
|
|
394
397
|
},
|
|
395
398
|
actions: [
|
|
396
399
|
(_, {defaultStyle, focusTextBlock}) => [
|
|
397
|
-
{
|
|
400
|
+
execute({
|
|
398
401
|
type: 'block.set',
|
|
399
402
|
props: {style: defaultStyle},
|
|
400
403
|
at: focusTextBlock.path,
|
|
401
|
-
},
|
|
404
|
+
}),
|
|
402
405
|
],
|
|
403
406
|
],
|
|
404
407
|
})
|
|
@@ -477,9 +480,9 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
|
|
|
477
480
|
return false
|
|
478
481
|
},
|
|
479
482
|
actions: [
|
|
480
|
-
({event}) => [event],
|
|
483
|
+
({event}) => [execute(event)],
|
|
481
484
|
(_, {focusTextBlock, style, listItem, listItemLength}) => [
|
|
482
|
-
{
|
|
485
|
+
execute({
|
|
483
486
|
type: 'block.set',
|
|
484
487
|
props: {
|
|
485
488
|
listItem,
|
|
@@ -487,8 +490,8 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
|
|
|
487
490
|
style,
|
|
488
491
|
},
|
|
489
492
|
at: focusTextBlock.path,
|
|
490
|
-
},
|
|
491
|
-
|
|
493
|
+
}),
|
|
494
|
+
execute({
|
|
492
495
|
type: 'delete.text',
|
|
493
496
|
at: {
|
|
494
497
|
anchor: {
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
} from '../editor/with-applying-behavior-actions'
|
|
9
9
|
import {debugWithName} from '../internal-utils/debug'
|
|
10
10
|
import type {PortableTextSlateEditor} from '../types/editor'
|
|
11
|
+
import {defaultBehaviors} from './behavior.default'
|
|
11
12
|
import type {InternalBehaviorAction} from './behavior.types.action'
|
|
12
13
|
import {
|
|
13
14
|
isAbstractBehaviorEvent,
|
|
@@ -28,6 +29,7 @@ function eventCategory(event: BehaviorEvent) {
|
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
export function performEvent({
|
|
32
|
+
mode,
|
|
31
33
|
behaviors,
|
|
32
34
|
event,
|
|
33
35
|
editor,
|
|
@@ -37,6 +39,7 @@ export function performEvent({
|
|
|
37
39
|
nativeEvent,
|
|
38
40
|
defaultActionCallback,
|
|
39
41
|
}: {
|
|
42
|
+
mode: 'raise' | 'execute'
|
|
40
43
|
behaviors: Array<Behavior>
|
|
41
44
|
event: BehaviorEvent
|
|
42
45
|
editor: PortableTextSlateEditor
|
|
@@ -62,7 +65,9 @@ export function performEvent({
|
|
|
62
65
|
editor,
|
|
63
66
|
} satisfies InternalBehaviorAction)
|
|
64
67
|
|
|
65
|
-
const eventBehaviors =
|
|
68
|
+
const eventBehaviors = (
|
|
69
|
+
mode === 'raise' ? [...behaviors, ...defaultBehaviors] : behaviors
|
|
70
|
+
).filter((behavior) => {
|
|
66
71
|
// Catches all events
|
|
67
72
|
if (behavior.on === '*') {
|
|
68
73
|
return true
|
|
@@ -128,6 +133,7 @@ export function performEvent({
|
|
|
128
133
|
},
|
|
129
134
|
action: defaultAction,
|
|
130
135
|
})
|
|
136
|
+
editor.onChange()
|
|
131
137
|
} catch (error) {
|
|
132
138
|
console.error(
|
|
133
139
|
new Error(
|
|
@@ -136,11 +142,10 @@ export function performEvent({
|
|
|
136
142
|
)
|
|
137
143
|
}
|
|
138
144
|
})
|
|
139
|
-
editor.onChange()
|
|
140
145
|
return
|
|
141
146
|
}
|
|
142
147
|
|
|
143
|
-
const
|
|
148
|
+
const guardSnapshot = getSnapshot()
|
|
144
149
|
|
|
145
150
|
let behaviorOverwritten = false
|
|
146
151
|
|
|
@@ -148,8 +153,7 @@ export function performEvent({
|
|
|
148
153
|
const shouldRun =
|
|
149
154
|
eventBehavior.guard === undefined ||
|
|
150
155
|
eventBehavior.guard({
|
|
151
|
-
|
|
152
|
-
snapshot: editorSnapshot,
|
|
156
|
+
snapshot: guardSnapshot,
|
|
153
157
|
event,
|
|
154
158
|
})
|
|
155
159
|
|
|
@@ -157,31 +161,36 @@ export function performEvent({
|
|
|
157
161
|
continue
|
|
158
162
|
}
|
|
159
163
|
|
|
160
|
-
const
|
|
161
|
-
|
|
164
|
+
for (const actionSet of eventBehavior.actions) {
|
|
165
|
+
const actionsSnapshot = getSnapshot()
|
|
166
|
+
|
|
167
|
+
const actions = actionSet(
|
|
162
168
|
{
|
|
163
|
-
|
|
164
|
-
snapshot: editorSnapshot,
|
|
169
|
+
snapshot: actionsSnapshot,
|
|
165
170
|
event,
|
|
166
171
|
},
|
|
167
172
|
shouldRun,
|
|
168
|
-
)
|
|
169
|
-
)
|
|
173
|
+
)
|
|
170
174
|
|
|
171
|
-
|
|
172
|
-
if (actionSet.length === 0) {
|
|
175
|
+
if (actions.length === 0) {
|
|
173
176
|
continue
|
|
174
177
|
}
|
|
175
178
|
|
|
176
179
|
behaviorOverwritten =
|
|
177
180
|
behaviorOverwritten ||
|
|
178
|
-
|
|
181
|
+
actions.some((action) => action.type !== 'effect')
|
|
179
182
|
|
|
180
183
|
withApplyingBehaviorActionSet(editor, () => {
|
|
181
|
-
for (const action of
|
|
184
|
+
for (const action of actions) {
|
|
182
185
|
if (action.type === 'raise') {
|
|
183
186
|
performEvent({
|
|
184
|
-
|
|
187
|
+
mode,
|
|
188
|
+
behaviors:
|
|
189
|
+
mode === 'execute'
|
|
190
|
+
? isCustomBehaviorEvent(action.event)
|
|
191
|
+
? [...behaviors, ...defaultBehaviors]
|
|
192
|
+
: defaultBehaviors
|
|
193
|
+
: [...behaviors, ...defaultBehaviors],
|
|
185
194
|
event: action.event,
|
|
186
195
|
editor,
|
|
187
196
|
keyGenerator,
|
|
@@ -194,6 +203,46 @@ export function performEvent({
|
|
|
194
203
|
continue
|
|
195
204
|
}
|
|
196
205
|
|
|
206
|
+
if (action.type === 'execute') {
|
|
207
|
+
if (
|
|
208
|
+
isAbstractBehaviorEvent(action.event) ||
|
|
209
|
+
isCustomBehaviorEvent(action.event)
|
|
210
|
+
) {
|
|
211
|
+
performEvent({
|
|
212
|
+
mode: 'execute',
|
|
213
|
+
behaviors: isCustomBehaviorEvent(action.event)
|
|
214
|
+
? [...behaviors, ...defaultBehaviors]
|
|
215
|
+
: defaultBehaviors,
|
|
216
|
+
event: action.event,
|
|
217
|
+
editor,
|
|
218
|
+
keyGenerator,
|
|
219
|
+
schema,
|
|
220
|
+
getSnapshot,
|
|
221
|
+
defaultActionCallback: undefined,
|
|
222
|
+
nativeEvent: undefined,
|
|
223
|
+
})
|
|
224
|
+
} else {
|
|
225
|
+
try {
|
|
226
|
+
performAction({
|
|
227
|
+
context: {
|
|
228
|
+
keyGenerator,
|
|
229
|
+
schema,
|
|
230
|
+
},
|
|
231
|
+
action: {...action.event, editor},
|
|
232
|
+
})
|
|
233
|
+
} catch (error) {
|
|
234
|
+
console.error(
|
|
235
|
+
new Error(
|
|
236
|
+
`Performing action "${action.event.type}" as a result of "${event.type}" failed due to: ${error.message}`,
|
|
237
|
+
),
|
|
238
|
+
)
|
|
239
|
+
break
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
continue
|
|
244
|
+
}
|
|
245
|
+
|
|
197
246
|
const internalAction = {
|
|
198
247
|
...action,
|
|
199
248
|
editor,
|
|
@@ -216,8 +265,8 @@ export function performEvent({
|
|
|
216
265
|
break
|
|
217
266
|
}
|
|
218
267
|
}
|
|
268
|
+
editor.onChange()
|
|
219
269
|
})
|
|
220
|
-
editor.onChange()
|
|
221
270
|
}
|
|
222
271
|
|
|
223
272
|
if (behaviorOverwritten) {
|
|
@@ -255,6 +304,7 @@ export function performEvent({
|
|
|
255
304
|
},
|
|
256
305
|
action: defaultAction,
|
|
257
306
|
})
|
|
307
|
+
editor.onChange()
|
|
258
308
|
} catch (error) {
|
|
259
309
|
console.error(
|
|
260
310
|
new Error(
|
|
@@ -263,6 +313,5 @@ export function performEvent({
|
|
|
263
313
|
)
|
|
264
314
|
}
|
|
265
315
|
})
|
|
266
|
-
editor.onChange()
|
|
267
316
|
}
|
|
268
317
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type {EditorSnapshot} from '../editor/editor-snapshot'
|
|
2
|
+
import type {PickFromUnion} from '../type-utils'
|
|
3
3
|
import type {PortableTextSlateEditor} from '../types/editor'
|
|
4
4
|
import type {
|
|
5
5
|
AbstractBehaviorEvent,
|
|
@@ -11,7 +11,13 @@ import type {
|
|
|
11
11
|
* @beta
|
|
12
12
|
*/
|
|
13
13
|
export type BehaviorAction =
|
|
14
|
-
|
|
|
14
|
+
| {
|
|
15
|
+
type: 'execute'
|
|
16
|
+
event:
|
|
17
|
+
| AbstractBehaviorEvent
|
|
18
|
+
| SyntheticBehaviorEvent
|
|
19
|
+
| CustomBehaviorEvent
|
|
20
|
+
}
|
|
15
21
|
| {
|
|
16
22
|
type: 'raise'
|
|
17
23
|
event:
|
|
@@ -27,6 +33,15 @@ export type BehaviorAction =
|
|
|
27
33
|
effect: () => void
|
|
28
34
|
}
|
|
29
35
|
|
|
36
|
+
/**
|
|
37
|
+
* @beta
|
|
38
|
+
*/
|
|
39
|
+
export function execute(
|
|
40
|
+
event: AbstractBehaviorEvent | SyntheticBehaviorEvent | CustomBehaviorEvent,
|
|
41
|
+
): PickFromUnion<BehaviorAction, 'type', 'execute'> {
|
|
42
|
+
return {type: 'execute', event}
|
|
43
|
+
}
|
|
44
|
+
|
|
30
45
|
/**
|
|
31
46
|
* @beta
|
|
32
47
|
*/
|
|
@@ -36,26 +51,37 @@ export function raise(
|
|
|
36
51
|
return {type: 'raise', event}
|
|
37
52
|
}
|
|
38
53
|
|
|
54
|
+
/**
|
|
55
|
+
* @beta
|
|
56
|
+
*/
|
|
57
|
+
export function effect(
|
|
58
|
+
effect: () => void,
|
|
59
|
+
): PickFromUnion<BehaviorAction, 'type', 'effect'> {
|
|
60
|
+
return {type: 'effect', effect}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* @beta
|
|
65
|
+
*/
|
|
66
|
+
export function noop(): PickFromUnion<BehaviorAction, 'type', 'noop'> {
|
|
67
|
+
return {type: 'noop'}
|
|
68
|
+
}
|
|
69
|
+
|
|
39
70
|
/**
|
|
40
71
|
* @beta
|
|
41
72
|
*/
|
|
42
73
|
export type BehaviorActionSet<TBehaviorEvent, TGuardResponse> = (
|
|
43
74
|
payload: {
|
|
44
|
-
/**
|
|
45
|
-
* @deprecated
|
|
46
|
-
* Use `snapshot` instead
|
|
47
|
-
*/
|
|
48
|
-
context: EditorContext
|
|
49
75
|
snapshot: EditorSnapshot
|
|
50
76
|
event: TBehaviorEvent
|
|
51
77
|
},
|
|
52
78
|
guardResponse: TGuardResponse,
|
|
53
79
|
) => Array<BehaviorAction>
|
|
54
80
|
|
|
55
|
-
export type InternalBehaviorAction =
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
'
|
|
59
|
-
|
|
81
|
+
export type InternalBehaviorAction = (
|
|
82
|
+
| SyntheticBehaviorEvent
|
|
83
|
+
| {type: 'noop'}
|
|
84
|
+
| {type: 'effect'; effect: () => void}
|
|
85
|
+
) & {
|
|
60
86
|
editor: PortableTextSlateEditor
|
|
61
87
|
}
|
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {EditorSnapshot} from '../editor/editor-snapshot'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @beta
|
|
5
5
|
*/
|
|
6
6
|
export type BehaviorGuard<TBehaviorEvent, TGuardResponse> = (payload: {
|
|
7
|
-
/**
|
|
8
|
-
* @deprecated
|
|
9
|
-
* Use `snapshot` instead
|
|
10
|
-
*/
|
|
11
|
-
context: EditorContext
|
|
12
7
|
snapshot: EditorSnapshot
|
|
13
8
|
event: TBehaviorEvent
|
|
14
9
|
}) => TGuardResponse | false
|
package/src/behaviors/index.ts
CHANGED
|
@@ -25,7 +25,10 @@ export interface SynchronizerProps {
|
|
|
25
25
|
export function Synchronizer(props: SynchronizerProps) {
|
|
26
26
|
const {editorActor, slateEditor} = props
|
|
27
27
|
|
|
28
|
-
const
|
|
28
|
+
const incomingValue = useSelector(
|
|
29
|
+
props.editorActor,
|
|
30
|
+
(s) => s.context.incomingValue,
|
|
31
|
+
)
|
|
29
32
|
const readOnly = useSelector(props.editorActor, (s) =>
|
|
30
33
|
s.matches({'edit mode': 'read only'}),
|
|
31
34
|
)
|
|
@@ -110,8 +113,8 @@ export function Synchronizer(props: SynchronizerProps) {
|
|
|
110
113
|
|
|
111
114
|
useEffect(() => {
|
|
112
115
|
debug('Value from props changed, syncing new value')
|
|
113
|
-
syncActorRef.send({type: 'update value', value})
|
|
114
|
-
}, [syncActorRef,
|
|
116
|
+
syncActorRef.send({type: 'update value', value: incomingValue})
|
|
117
|
+
}, [syncActorRef, incomingValue])
|
|
115
118
|
|
|
116
119
|
// Subscribe to, and handle changes from the editor
|
|
117
120
|
useEffect(() => {
|