@portabletext/editor 1.26.2 → 1.27.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 (45) hide show
  1. package/lib/_chunks-cjs/behavior.markdown.cjs +327 -0
  2. package/lib/_chunks-cjs/behavior.markdown.cjs.map +1 -0
  3. package/lib/_chunks-cjs/plugin.event-listener.cjs +6568 -0
  4. package/lib/_chunks-cjs/plugin.event-listener.cjs.map +1 -0
  5. package/lib/_chunks-es/behavior.markdown.js +332 -0
  6. package/lib/_chunks-es/behavior.markdown.js.map +1 -0
  7. package/lib/_chunks-es/plugin.event-listener.js +6592 -0
  8. package/lib/_chunks-es/plugin.event-listener.js.map +1 -0
  9. package/lib/behaviors/index.cjs +2 -325
  10. package/lib/behaviors/index.cjs.map +1 -1
  11. package/lib/behaviors/index.d.cts +1 -1
  12. package/lib/behaviors/index.d.ts +1 -1
  13. package/lib/behaviors/index.js +2 -326
  14. package/lib/behaviors/index.js.map +1 -1
  15. package/lib/index.cjs +182 -6702
  16. package/lib/index.cjs.map +1 -1
  17. package/lib/index.d.cts +3269 -2178
  18. package/lib/index.d.ts +3269 -2178
  19. package/lib/index.js +144 -6681
  20. package/lib/index.js.map +1 -1
  21. package/lib/plugins/index.cjs +29 -0
  22. package/lib/plugins/index.cjs.map +1 -0
  23. package/lib/plugins/index.d.cts +19411 -0
  24. package/lib/plugins/index.d.ts +19411 -0
  25. package/lib/plugins/index.js +29 -0
  26. package/lib/plugins/index.js.map +1 -0
  27. package/lib/selectors/index.d.cts +1 -1
  28. package/lib/selectors/index.d.ts +1 -1
  29. package/package.json +13 -7
  30. package/src/editor/Editable.tsx +6 -6
  31. package/src/editor/__tests__/PortableTextEditor.test.tsx +0 -1
  32. package/src/editor/components/Synchronizer.tsx +16 -1
  33. package/src/editor/create-editor.ts +8 -48
  34. package/src/editor/editor-machine.ts +130 -141
  35. package/src/editor/plugins/create-with-event-listeners.ts +19 -38
  36. package/src/editor/plugins/createWithPatches.ts +1 -1
  37. package/src/editor/plugins/createWithPortableTextSelections.ts +2 -2
  38. package/src/editor/sync-machine.ts +3 -5
  39. package/src/index.ts +5 -11
  40. package/src/plugins/_exports/index.ts +1 -0
  41. package/src/plugins/index.ts +3 -0
  42. package/src/plugins/plugin.editor-ref.tsx +17 -0
  43. package/src/{editor/editor-event-listener.tsx → plugins/plugin.event-listener.tsx} +7 -6
  44. package/src/plugins/plugin.markdown.tsx +70 -0
  45. package/src/type-utils.ts +12 -2
@@ -17,6 +17,24 @@ export function createWithEventListeners(
17
17
  subscriptions.push(() => {
18
18
  const subscription = editorActor.on('*', (event) => {
19
19
  switch (event.type) {
20
+ // These events are not relevant for Behaviors
21
+ case 'blurred':
22
+ case 'done loading':
23
+ case 'editable':
24
+ case 'error':
25
+ case 'focused':
26
+ case 'invalid value':
27
+ case 'loading':
28
+ case 'mutation':
29
+ case 'patch':
30
+ case 'patches':
31
+ case 'read only':
32
+ case 'ready':
33
+ case 'selection':
34
+ case 'value changed':
35
+ case 'unset':
36
+ break
37
+
20
38
  case 'custom.*':
21
39
  editorActor.send({
22
40
  type: 'custom behavior event',
@@ -25,44 +43,7 @@ export function createWithEventListeners(
25
43
  })
26
44
  break
27
45
 
28
- case 'annotation.add':
29
- case 'annotation.remove':
30
- case 'annotation.toggle':
31
- case 'block.set':
32
- case 'block.unset':
33
- case 'blur':
34
- case 'data transfer.set':
35
- case 'decorator.add':
36
- case 'decorator.remove':
37
- case 'decorator.toggle':
38
- case 'delete.backward':
39
- case 'delete.block':
40
- case 'delete.forward':
41
- case 'delete.text':
42
- case 'deserialization.failure':
43
- case 'deserialization.success':
44
- case 'focus':
45
- case 'insert.block':
46
- case 'insert.block object':
47
- case 'insert.inline object':
48
- case 'insert.span':
49
- case 'insert.text block':
50
- case 'list item.add':
51
- case 'list item.remove':
52
- case 'list item.toggle':
53
- case 'move.block':
54
- case 'move.block down':
55
- case 'move.block up':
56
- case 'select':
57
- case 'select.next block':
58
- case 'select.previous block':
59
- case 'serialization.failure':
60
- case 'serialization.success':
61
- case 'style.add':
62
- case 'style.remove':
63
- case 'style.toggle':
64
- case 'text block.set':
65
- case 'text block.unset':
46
+ default:
66
47
  editorActor.send({
67
48
  type: 'behavior event',
68
49
  behaviorEvent: event,
@@ -271,7 +271,7 @@ export function createWithPatches({
271
271
  ) {
272
272
  patches = [...patches, unset([])]
273
273
  editorActor.send({
274
- type: 'unset',
274
+ type: 'notify.unset',
275
275
  previousValue: fromSlateValue(
276
276
  previousChildren,
277
277
  schemaTypes.block.name,
@@ -45,9 +45,9 @@ export function createWithPortableTextSelections(
45
45
  )
46
46
  }
47
47
  if (ptRange) {
48
- editorActor.send({type: 'selection', selection: ptRange})
48
+ editorActor.send({type: 'notify.selection', selection: ptRange})
49
49
  } else {
50
- editorActor.send({type: 'selection', selection: null})
50
+ editorActor.send({type: 'notify.selection', selection: null})
51
51
  }
52
52
  }
53
53
  prevSelection = editor.selection
@@ -168,11 +168,9 @@ export const syncMachine = setup({
168
168
  assertEvent(event, 'done syncing')
169
169
  return context.pendingValue !== event.value
170
170
  },
171
- 'pending value equals previous value': ({context}) =>
172
- !(
173
- context.previousValue === undefined &&
174
- context.pendingValue === undefined
175
- ) && isEqual(context.pendingValue, context.previousValue),
171
+ 'pending value equals previous value': ({context}) => {
172
+ return isEqual(context.pendingValue, context.previousValue)
173
+ },
176
174
  },
177
175
  actors: {
178
176
  'sync value': syncValueLogic,
package/src/index.ts CHANGED
@@ -25,16 +25,11 @@ export type {PortableTextMemberSchemaTypes} from './types/editor'
25
25
  export type {EditorSchema} from './editor/define-schema'
26
26
  export {PortableTextEditable} from './editor/Editable'
27
27
  export type {PortableTextEditableProps} from './editor/Editable'
28
- export {EditorEventListener} from './editor/editor-event-listener'
29
- export {
30
- editorMachine,
31
- type EditorActor,
32
- type EditorEmittedEvent,
33
- type InternalEditorEmittedEvent,
34
- type InternalEditorEvent,
35
- type MutationEvent,
36
- type PatchEvent,
37
- type PatchesEvent,
28
+ export {EventListenerPlugin as EditorEventListener} from './plugins/plugin.event-listener'
29
+ export type {
30
+ EditorEmittedEvent,
31
+ MutationEvent,
32
+ PatchesEvent,
38
33
  } from './editor/editor-machine'
39
34
  export {
40
35
  EditorProvider,
@@ -49,6 +44,5 @@ export {defaultKeyGenerator as keyGenerator} from './editor/key-generator'
49
44
  export type {AddedAnnotationPaths} from './editor/plugins/createWithEditableAPI'
50
45
  export {PortableTextEditor} from './editor/PortableTextEditor'
51
46
  export type {PortableTextEditorProps} from './editor/PortableTextEditor'
52
- export type {OmitFromUnion, PickFromUnion} from './type-utils'
53
47
  export * from './types/editor'
54
48
  export type {HotkeyOptions} from './types/options'
@@ -0,0 +1 @@
1
+ export * from '../index'
@@ -0,0 +1,3 @@
1
+ export {EventListenerPlugin} from './plugin.event-listener'
2
+ export {EditorRefPlugin} from './plugin.editor-ref'
3
+ export {MarkdownPlugin, type MarkdownPluginConfig} from './plugin.markdown'
@@ -0,0 +1,17 @@
1
+ import React from 'react'
2
+ import type {Editor} from '../editor/create-editor'
3
+ import {useEditor} from '../editor/editor-provider'
4
+
5
+ /**
6
+ * @beta
7
+ */
8
+ export const EditorRefPlugin = React.forwardRef<Editor | null>((_, ref) => {
9
+ const editor = useEditor()
10
+
11
+ const portableTextEditorRef = React.useRef(editor)
12
+
13
+ React.useImperativeHandle(ref, () => portableTextEditorRef.current, [])
14
+
15
+ return null
16
+ })
17
+ EditorRefPlugin.displayName = 'EditorRefPlugin'
@@ -1,7 +1,7 @@
1
1
  import {useEffect} from 'react'
2
2
  import {useEffectEvent} from 'use-effect-event'
3
- import type {EditorEmittedEvent} from './editor-machine'
4
- import {useEditor} from './editor-provider'
3
+ import type {EditorEmittedEvent} from '../editor/editor-machine'
4
+ import {useEditor} from '../editor/editor-provider'
5
5
 
6
6
  /**
7
7
  * @public
@@ -23,12 +23,13 @@ import {useEditor} from './editor-provider'
23
23
  * @example
24
24
  * Listen and log events.
25
25
  * ```tsx
26
- * import {EditorEventListener, EditorProvider} from '@portabletext/editor'
26
+ * import {EditorProvider} from '@portabletext/editor'
27
+ * import {EventListenerPlugin} from '@portabletext/editor/plugins'
27
28
  *
28
29
  * function MyComponent() {
29
30
  * return (
30
31
  * <EditorProvider>
31
- * <EditorEventListener
32
+ * <EventListenerPlugin
32
33
  * on={(event) => {
33
34
  * console.log(event)
34
35
  * }
@@ -41,7 +42,7 @@ import {useEditor} from './editor-provider'
41
42
  * @example
42
43
  * Handle events when there is a mutation.
43
44
  * ```tsx
44
- * <EditorEventListener
45
+ * <EventListenerPlugin
45
46
  * on={(event) => {
46
47
  * if (event.type === 'mutation') {
47
48
  * console.log('Value changed:', event.snapshot)
@@ -51,7 +52,7 @@ import {useEditor} from './editor-provider'
51
52
  * ```
52
53
  * @group Components
53
54
  */
54
- export function EditorEventListener(props: {
55
+ export function EventListenerPlugin(props: {
55
56
  on: (event: EditorEmittedEvent) => void
56
57
  }) {
57
58
  const editor = useEditor()
@@ -0,0 +1,70 @@
1
+ import {useEffect} from 'react'
2
+ import {
3
+ createMarkdownBehaviors,
4
+ type MarkdownBehaviorsConfig,
5
+ } from '../behaviors/behavior.markdown'
6
+ import {useEditor} from '../editor/editor-provider'
7
+
8
+ /**
9
+ * @beta
10
+ */
11
+ export type MarkdownPluginConfig = MarkdownBehaviorsConfig
12
+
13
+ /**
14
+ * @beta
15
+ * Add markdown behaviors for common markdown actions such as converting ### to headings, --- to HRs, and more.
16
+ *
17
+ * @example
18
+ * Configure the bundled markdown behaviors
19
+ * ```ts
20
+ * import {EditorProvider} from '@portabletext/editor'
21
+ * import {MarkdownPlugin} from '@portabletext/editor/plugins'
22
+ *
23
+ * function App() {
24
+ * return (
25
+ * <EditorProvider>
26
+ * <MarkdownPlugin
27
+ * config={{
28
+ * horizontalRuleObject: ({schema}) => {
29
+ * const name = schema.blockObjects.find(
30
+ * (object) => object.name === 'break',
31
+ * )?.name
32
+ * return name ? {name} : undefined
33
+ * },
34
+ * defaultStyle: ({schema}) => schema.styles[0].value,
35
+ * headingStyle: ({schema, level}) =>
36
+ * schema.styles.find((style) => style.value === `h${level}`)
37
+ * ?.value,
38
+ * blockquoteStyle: ({schema}) =>
39
+ * schema.styles.find((style) => style.value === 'blockquote')
40
+ * ?.value,
41
+ * unorderedListStyle: ({schema}) =>
42
+ * schema.lists.find((list) => list.value === 'bullet')?.value,
43
+ * orderedListStyle: ({schema}) =>
44
+ * schema.lists.find((list) => list.value === 'number')?.value,
45
+ * }}
46
+ * />
47
+ * {...}
48
+ * </EditorProvider>
49
+ * )
50
+ * }
51
+ */
52
+ export function MarkdownPlugin(props: {config: MarkdownPluginConfig}) {
53
+ const editor = useEditor()
54
+
55
+ useEffect(() => {
56
+ const behaviors = createMarkdownBehaviors(props.config)
57
+
58
+ const unregisterBehaviors = behaviors.map((behavior) =>
59
+ editor.registerBehavior({behavior}),
60
+ )
61
+
62
+ return () => {
63
+ for (const unregisterBehavior of unregisterBehaviors) {
64
+ unregisterBehavior()
65
+ }
66
+ }
67
+ }, [editor, props.config])
68
+
69
+ return null
70
+ }
package/src/type-utils.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @alpha
2
+ * @internal
3
3
  */
4
4
  export type PickFromUnion<
5
5
  TUnion,
@@ -8,10 +8,20 @@ export type PickFromUnion<
8
8
  > = TUnion extends Record<TTagKey, TPickedTags> ? TUnion : never
9
9
 
10
10
  /**
11
- * @alpha
11
+ * @internal
12
12
  */
13
13
  export type OmitFromUnion<
14
14
  TUnion,
15
15
  TTagKey extends keyof TUnion,
16
16
  TOmittedTags extends TUnion[TTagKey],
17
17
  > = TUnion extends Record<TTagKey, TOmittedTags> ? never : TUnion
18
+
19
+ export type NamespaceEvent<TEvent, TNamespace extends string> = TEvent extends {
20
+ type: infer TEventType
21
+ }
22
+ ? {
23
+ [K in keyof TEvent]: K extends 'type'
24
+ ? `${TNamespace}.${TEventType & string}`
25
+ : TEvent[K]
26
+ }
27
+ : never