@portabletext/editor 1.45.4 → 1.47.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 (46) hide show
  1. package/lib/_chunks-cjs/behavior.core.cjs +20 -0
  2. package/lib/_chunks-cjs/behavior.core.cjs.map +1 -1
  3. package/lib/_chunks-cjs/behavior.markdown.cjs +25 -25
  4. package/lib/_chunks-cjs/behavior.markdown.cjs.map +1 -1
  5. package/lib/_chunks-cjs/editor-provider.cjs +69 -4
  6. package/lib/_chunks-cjs/editor-provider.cjs.map +1 -1
  7. package/lib/_chunks-es/behavior.core.js +20 -0
  8. package/lib/_chunks-es/behavior.core.js.map +1 -1
  9. package/lib/_chunks-es/behavior.markdown.js +26 -26
  10. package/lib/_chunks-es/behavior.markdown.js.map +1 -1
  11. package/lib/_chunks-es/editor-provider.js +69 -4
  12. package/lib/_chunks-es/editor-provider.js.map +1 -1
  13. package/lib/_chunks-es/selector.is-selecting-entire-blocks.js +1 -1
  14. package/lib/behaviors/index.cjs +37 -53
  15. package/lib/behaviors/index.cjs.map +1 -1
  16. package/lib/behaviors/index.d.cts +546 -1
  17. package/lib/behaviors/index.d.ts +546 -1
  18. package/lib/behaviors/index.js +38 -54
  19. package/lib/behaviors/index.js.map +1 -1
  20. package/lib/index.d.cts +17 -1
  21. package/lib/index.d.ts +17 -1
  22. package/lib/plugins/index.cjs +23 -29
  23. package/lib/plugins/index.cjs.map +1 -1
  24. package/lib/plugins/index.d.cts +17 -1
  25. package/lib/plugins/index.d.ts +17 -1
  26. package/lib/plugins/index.js +24 -30
  27. package/lib/plugins/index.js.map +1 -1
  28. package/lib/selectors/index.d.cts +17 -1
  29. package/lib/selectors/index.d.ts +17 -1
  30. package/lib/utils/index.d.cts +17 -1
  31. package/lib/utils/index.d.ts +17 -1
  32. package/package.json +3 -3
  33. package/src/behavior-actions/behavior.action.move.backward.ts +12 -0
  34. package/src/behavior-actions/behavior.action.move.forward.ts +11 -0
  35. package/src/behavior-actions/behavior.actions.ts +18 -0
  36. package/src/behaviors/behavior.decorator-pair.ts +16 -19
  37. package/src/behaviors/behavior.emoji-picker.ts +26 -45
  38. package/src/behaviors/behavior.links.ts +5 -4
  39. package/src/behaviors/behavior.markdown.ts +37 -34
  40. package/src/behaviors/behavior.perform-event.ts +53 -2
  41. package/src/behaviors/behavior.types.action.ts +38 -7
  42. package/src/behaviors/behavior.types.event.ts +10 -0
  43. package/src/behaviors/index.ts +3 -0
  44. package/src/editor/editor-machine.ts +2 -2
  45. package/src/plugins/plugin.decorator-shortcut.ts +6 -8
  46. package/src/plugins/plugin.one-line.tsx +4 -4
@@ -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 = behaviors.filter((behavior) => {
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
@@ -179,7 +184,13 @@ export function performEvent({
179
184
  for (const action of actions) {
180
185
  if (action.type === 'raise') {
181
186
  performEvent({
182
- behaviors,
187
+ mode,
188
+ behaviors:
189
+ mode === 'execute'
190
+ ? isCustomBehaviorEvent(action.event)
191
+ ? [...behaviors, ...defaultBehaviors]
192
+ : defaultBehaviors
193
+ : [...behaviors, ...defaultBehaviors],
183
194
  event: action.event,
184
195
  editor,
185
196
  keyGenerator,
@@ -192,6 +203,46 @@ export function performEvent({
192
203
  continue
193
204
  }
194
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
+
195
246
  const internalAction = {
196
247
  ...action,
197
248
  editor,
@@ -1,5 +1,5 @@
1
1
  import type {EditorSnapshot} from '../editor/editor-snapshot'
2
- import type {OmitFromUnion, PickFromUnion} from '../type-utils'
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
- | SyntheticBehaviorEvent
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,6 +51,22 @@ 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
  */
@@ -47,10 +78,10 @@ export type BehaviorActionSet<TBehaviorEvent, TGuardResponse> = (
47
78
  guardResponse: TGuardResponse,
48
79
  ) => Array<BehaviorAction>
49
80
 
50
- export type InternalBehaviorAction = OmitFromUnion<
51
- BehaviorAction,
52
- 'type',
53
- 'raise'
54
- > & {
81
+ export type InternalBehaviorAction = (
82
+ | SyntheticBehaviorEvent
83
+ | {type: 'noop'}
84
+ | {type: 'effect'; effect: () => void}
85
+ ) & {
55
86
  editor: PortableTextSlateEditor
56
87
  }
@@ -75,7 +75,9 @@ const syntheticBehaviorEventTypes = [
75
75
  'insert.block',
76
76
  'insert.span',
77
77
  'insert.text',
78
+ 'move.backward',
78
79
  'move.block',
80
+ 'move.forward',
79
81
  'select',
80
82
  'split.block',
81
83
  ] as const
@@ -178,11 +180,19 @@ export type SyntheticBehaviorEvent =
178
180
  type: StrictExtract<SyntheticBehaviorEventType, 'insert.text'>
179
181
  text: string
180
182
  }
183
+ | {
184
+ type: StrictExtract<SyntheticBehaviorEventType, 'move.backward'>
185
+ distance: number
186
+ }
181
187
  | {
182
188
  type: StrictExtract<SyntheticBehaviorEventType, 'move.block'>
183
189
  at: [KeyedSegment]
184
190
  to: [KeyedSegment]
185
191
  }
192
+ | {
193
+ type: StrictExtract<SyntheticBehaviorEventType, 'move.forward'>
194
+ distance: number
195
+ }
186
196
  | {
187
197
  type: StrictExtract<SyntheticBehaviorEventType, 'select'>
188
198
  at: EditorSelection
@@ -14,7 +14,10 @@ export {
14
14
  } from './behavior.markdown'
15
15
 
16
16
  export {
17
+ execute,
18
+ noop,
17
19
  raise,
20
+ effect,
18
21
  type BehaviorAction,
19
22
  type BehaviorActionSet,
20
23
  } from './behavior.types.action'
@@ -10,7 +10,6 @@ import {
10
10
  type ActorRefFrom,
11
11
  } from 'xstate'
12
12
  import {coreBehaviors} from '../behaviors/behavior.core'
13
- import {defaultBehaviors} from '../behaviors/behavior.default'
14
13
  import {performEvent} from '../behaviors/behavior.perform-event'
15
14
  import type {Behavior} from '../behaviors/behavior.types.behavior'
16
15
  import type {BehaviorEvent} from '../behaviors/behavior.types.event'
@@ -297,7 +296,8 @@ export const editorMachine = setup({
297
296
  assertEvent(event, ['behavior event'])
298
297
 
299
298
  performEvent({
300
- behaviors: [...context.behaviors.values(), ...defaultBehaviors],
299
+ mode: 'raise',
300
+ behaviors: [...context.behaviors.values()],
301
301
  event: event.behaviorEvent,
302
302
  editor: event.editor,
303
303
  keyGenerator: context.keyGenerator,
@@ -8,6 +8,7 @@ import {
8
8
  type CallbackLogicFunction,
9
9
  } from 'xstate'
10
10
  import {createDecoratorPairBehavior} from '../behaviors/behavior.decorator-pair'
11
+ import {effect, execute} from '../behaviors/behavior.types.action'
11
12
  import {defineBehavior} from '../behaviors/behavior.types.behavior'
12
13
  import type {Editor} from '../editor/create-editor'
13
14
  import type {EditorSchema} from '../editor/define-schema'
@@ -132,15 +133,12 @@ const deleteBackwardListenerCallback: CallbackLogicFunction<
132
133
  on: 'delete.backward',
133
134
  actions: [
134
135
  () => [
135
- {
136
+ execute({
136
137
  type: 'history.undo',
137
- },
138
- {
139
- type: 'effect',
140
- effect: () => {
141
- sendBack({type: 'delete.backward'})
142
- },
143
- },
138
+ }),
139
+ effect(() => {
140
+ sendBack({type: 'delete.backward'})
141
+ }),
144
142
  ],
145
143
  ],
146
144
  }),
@@ -1,4 +1,4 @@
1
- import {defineBehavior, raise} from '../behaviors'
1
+ import {defineBehavior, execute, raise} from '../behaviors'
2
2
  import * as selectors from '../selectors'
3
3
  import * as utils from '../utils'
4
4
  import {BehaviorPlugin} from './plugin.behavior'
@@ -14,7 +14,7 @@ const oneLineBehaviors = [
14
14
  snapshot.context.selection && selectors.isSelectionExpanded(snapshot)
15
15
  ? {selection: snapshot.context.selection}
16
16
  : false,
17
- actions: [(_, {selection}) => [{type: 'delete', at: selection}]],
17
+ actions: [(_, {selection}) => [execute({type: 'delete', at: selection})]],
18
18
  }),
19
19
  /**
20
20
  * All other cases of `insert.break` should be aborted.
@@ -59,12 +59,12 @@ const oneLineBehaviors = [
59
59
  },
60
60
  actions: [
61
61
  ({event}) => [
62
- {
62
+ execute({
63
63
  type: 'insert.block',
64
64
  block: event.block,
65
65
  placement: 'auto',
66
66
  select: 'end',
67
- },
67
+ }),
68
68
  ],
69
69
  ],
70
70
  }),