@portabletext/editor 1.3.0 → 1.4.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/index.d.mts +2805 -44
- package/lib/index.d.ts +2805 -44
- package/lib/index.esm.js +866 -372
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +928 -434
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +866 -372
- package/lib/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/editor/PortableTextEditor.tsx +160 -99
- package/src/editor/behavior/behavior.markdown.ts +203 -0
- package/src/editor/components/SlateContainer.tsx +2 -13
- package/src/editor/components/Synchronizer.tsx +25 -28
- package/src/editor/editor-machine.ts +27 -2
- package/src/editor/plugins/createWithPatches.ts +8 -13
- package/src/editor/plugins/createWithUndoRedo.ts +34 -33
- package/src/editor/plugins/index.ts +2 -4
- package/src/editor/use-editor.ts +45 -0
- package/src/index.ts +15 -8
- package/src/types/options.ts +0 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type {Patch} from '@portabletext/patches'
|
|
2
2
|
import type {PortableTextBlock} from '@sanity/types'
|
|
3
3
|
import {throttle} from 'lodash'
|
|
4
|
-
import {useCallback, useEffect,
|
|
4
|
+
import {useCallback, useEffect, useRef} from 'react'
|
|
5
5
|
import {Editor} from 'slate'
|
|
6
6
|
import {useSlate} from 'slate-react'
|
|
7
7
|
import {useEffectEvent} from 'use-effect-event'
|
|
@@ -69,26 +69,6 @@ export function Synchronizer(props: SynchronizerProps) {
|
|
|
69
69
|
IS_PROCESSING_LOCAL_CHANGES.set(slateEditor, false)
|
|
70
70
|
}, [editorActor, slateEditor, getValue])
|
|
71
71
|
|
|
72
|
-
const onFlushPendingPatchesThrottled = useMemo(() => {
|
|
73
|
-
return throttle(
|
|
74
|
-
() => {
|
|
75
|
-
// If the editor is normalizing (each operation) it means that it's not in the middle of a bigger transform,
|
|
76
|
-
// and we can flush these changes immediately.
|
|
77
|
-
if (Editor.isNormalizing(slateEditor)) {
|
|
78
|
-
onFlushPendingPatches()
|
|
79
|
-
return
|
|
80
|
-
}
|
|
81
|
-
// If it's in the middle of something, try again.
|
|
82
|
-
onFlushPendingPatchesThrottled()
|
|
83
|
-
},
|
|
84
|
-
FLUSH_PATCHES_THROTTLED_MS,
|
|
85
|
-
{
|
|
86
|
-
leading: false,
|
|
87
|
-
trailing: true,
|
|
88
|
-
},
|
|
89
|
-
)
|
|
90
|
-
}, [onFlushPendingPatches, slateEditor])
|
|
91
|
-
|
|
92
72
|
// Flush pending patches immediately on unmount
|
|
93
73
|
useEffect(() => {
|
|
94
74
|
return () => {
|
|
@@ -106,6 +86,24 @@ export function Synchronizer(props: SynchronizerProps) {
|
|
|
106
86
|
|
|
107
87
|
// Subscribe to, and handle changes from the editor
|
|
108
88
|
useEffect(() => {
|
|
89
|
+
const onFlushPendingPatchesThrottled = throttle(
|
|
90
|
+
() => {
|
|
91
|
+
// If the editor is normalizing (each operation) it means that it's not in the middle of a bigger transform,
|
|
92
|
+
// and we can flush these changes immediately.
|
|
93
|
+
if (Editor.isNormalizing(slateEditor)) {
|
|
94
|
+
onFlushPendingPatches()
|
|
95
|
+
return
|
|
96
|
+
}
|
|
97
|
+
// If it's in the middle of something, try again.
|
|
98
|
+
onFlushPendingPatchesThrottled()
|
|
99
|
+
},
|
|
100
|
+
FLUSH_PATCHES_THROTTLED_MS,
|
|
101
|
+
{
|
|
102
|
+
leading: false,
|
|
103
|
+
trailing: true,
|
|
104
|
+
},
|
|
105
|
+
)
|
|
106
|
+
|
|
109
107
|
debug('Subscribing to editor changes')
|
|
110
108
|
const sub = editorActor.on('*', (event) => {
|
|
111
109
|
switch (event.type) {
|
|
@@ -150,6 +148,9 @@ export function Synchronizer(props: SynchronizerProps) {
|
|
|
150
148
|
})
|
|
151
149
|
break
|
|
152
150
|
}
|
|
151
|
+
case 'patches': {
|
|
152
|
+
break
|
|
153
|
+
}
|
|
153
154
|
default:
|
|
154
155
|
handleChange(event)
|
|
155
156
|
}
|
|
@@ -158,7 +159,7 @@ export function Synchronizer(props: SynchronizerProps) {
|
|
|
158
159
|
debug('Unsubscribing to changes')
|
|
159
160
|
sub.unsubscribe()
|
|
160
161
|
}
|
|
161
|
-
}, [
|
|
162
|
+
}, [editorActor, handleChange, onFlushPendingPatches, slateEditor])
|
|
162
163
|
|
|
163
164
|
// Sync the value when going online
|
|
164
165
|
const handleOnline = useCallback(() => {
|
|
@@ -168,16 +169,12 @@ export function Synchronizer(props: SynchronizerProps) {
|
|
|
168
169
|
|
|
169
170
|
// Notify about window online and offline status changes
|
|
170
171
|
useEffect(() => {
|
|
171
|
-
const subscription = editorActor.on('online',
|
|
172
|
-
if (portableTextEditor.props.patches$) {
|
|
173
|
-
handleOnline()
|
|
174
|
-
}
|
|
175
|
-
})
|
|
172
|
+
const subscription = editorActor.on('online', handleOnline)
|
|
176
173
|
|
|
177
174
|
return () => {
|
|
178
175
|
subscription.unsubscribe()
|
|
179
176
|
}
|
|
180
|
-
}, [handleOnline, editorActor
|
|
177
|
+
}, [handleOnline, editorActor])
|
|
181
178
|
|
|
182
179
|
// This hook must be set up after setting up the subscription above, or it will not pick up validation errors from the useSyncValue hook.
|
|
183
180
|
// This will cause the editor to not be able to signal a validation error and offer invalid value resolution of the initial value.
|
|
@@ -21,6 +21,7 @@ import {toPortableTextRange} from '../utils/ranges'
|
|
|
21
21
|
import {fromSlateValue} from '../utils/values'
|
|
22
22
|
import {KEY_TO_VALUE_ELEMENT} from '../utils/weakMaps'
|
|
23
23
|
import {performAction, performDefaultAction} from './behavior/behavior.actions'
|
|
24
|
+
import {coreBehaviors} from './behavior/behavior.core'
|
|
24
25
|
import type {
|
|
25
26
|
Behavior,
|
|
26
27
|
BehaviorAction,
|
|
@@ -56,6 +57,15 @@ const networkLogic = fromCallback(({sendBack}) => {
|
|
|
56
57
|
*/
|
|
57
58
|
export type PatchEvent = {type: 'patch'; patch: Patch}
|
|
58
59
|
|
|
60
|
+
/**
|
|
61
|
+
* @internal
|
|
62
|
+
*/
|
|
63
|
+
export type PatchesEvent = {
|
|
64
|
+
type: 'patches'
|
|
65
|
+
patches: Array<Patch>
|
|
66
|
+
snapshot: Array<PortableTextBlock> | undefined
|
|
67
|
+
}
|
|
68
|
+
|
|
59
69
|
/**
|
|
60
70
|
* @internal
|
|
61
71
|
*/
|
|
@@ -82,11 +92,16 @@ type EditorEvent =
|
|
|
82
92
|
type: 'update schema'
|
|
83
93
|
schema: PortableTextMemberSchemaTypes
|
|
84
94
|
}
|
|
95
|
+
| {
|
|
96
|
+
type: 'update behaviors'
|
|
97
|
+
behaviors: Array<Behavior>
|
|
98
|
+
}
|
|
85
99
|
| EditorEmittedEvent
|
|
86
100
|
|
|
87
101
|
type EditorEmittedEvent =
|
|
88
102
|
| {type: 'ready'}
|
|
89
103
|
| PatchEvent
|
|
104
|
+
| PatchesEvent
|
|
90
105
|
| MutationEvent
|
|
91
106
|
| {
|
|
92
107
|
type: 'unset'
|
|
@@ -129,12 +144,18 @@ export const editorMachine = setup({
|
|
|
129
144
|
events: {} as EditorEvent,
|
|
130
145
|
emitted: {} as EditorEmittedEvent,
|
|
131
146
|
input: {} as {
|
|
132
|
-
behaviors
|
|
147
|
+
behaviors?: Array<Behavior>
|
|
133
148
|
keyGenerator: () => string
|
|
134
149
|
schema: PortableTextMemberSchemaTypes
|
|
135
150
|
},
|
|
136
151
|
},
|
|
137
152
|
actions: {
|
|
153
|
+
'assign behaviors': assign({
|
|
154
|
+
behaviors: ({event}) => {
|
|
155
|
+
assertEvent(event, 'update behaviors')
|
|
156
|
+
return [...coreBehaviors, ...event.behaviors]
|
|
157
|
+
},
|
|
158
|
+
}),
|
|
138
159
|
'assign schema': assign({
|
|
139
160
|
schema: ({event}) => {
|
|
140
161
|
assertEvent(event, 'update schema')
|
|
@@ -253,7 +274,9 @@ export const editorMachine = setup({
|
|
|
253
274
|
}).createMachine({
|
|
254
275
|
id: 'editor',
|
|
255
276
|
context: ({input}) => ({
|
|
256
|
-
behaviors: input.behaviors
|
|
277
|
+
behaviors: input.behaviors
|
|
278
|
+
? [...coreBehaviors, ...input.behaviors]
|
|
279
|
+
: coreBehaviors,
|
|
257
280
|
keyGenerator: input.keyGenerator,
|
|
258
281
|
pendingEvents: [],
|
|
259
282
|
schema: input.schema,
|
|
@@ -274,7 +297,9 @@ export const editorMachine = setup({
|
|
|
274
297
|
'online': {actions: emit({type: 'online'})},
|
|
275
298
|
'offline': {actions: emit({type: 'offline'})},
|
|
276
299
|
'loading': {actions: emit({type: 'loading'})},
|
|
300
|
+
'patches': {actions: emit(({event}) => event)},
|
|
277
301
|
'done loading': {actions: emit({type: 'done loading'})},
|
|
302
|
+
'update behaviors': {actions: 'assign behaviors'},
|
|
278
303
|
'update schema': {actions: 'assign schema'},
|
|
279
304
|
'behavior event': {actions: 'handle behavior event'},
|
|
280
305
|
'behavior action intends': {
|
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
type SplitNodeOperation,
|
|
14
14
|
} from 'slate'
|
|
15
15
|
import type {
|
|
16
|
-
PatchObservable,
|
|
17
16
|
PortableTextMemberSchemaTypes,
|
|
18
17
|
PortableTextSlateEditor,
|
|
19
18
|
} from '../../types/editor'
|
|
@@ -81,7 +80,6 @@ export interface PatchFunctions {
|
|
|
81
80
|
|
|
82
81
|
interface Options {
|
|
83
82
|
editorActor: EditorActor
|
|
84
|
-
patches$?: PatchObservable
|
|
85
83
|
patchFunctions: PatchFunctions
|
|
86
84
|
readOnly: boolean
|
|
87
85
|
schemaTypes: PortableTextMemberSchemaTypes
|
|
@@ -89,7 +87,6 @@ interface Options {
|
|
|
89
87
|
|
|
90
88
|
export function createWithPatches({
|
|
91
89
|
editorActor,
|
|
92
|
-
patches$,
|
|
93
90
|
patchFunctions,
|
|
94
91
|
readOnly,
|
|
95
92
|
schemaTypes,
|
|
@@ -143,16 +140,14 @@ export function createWithPatches({
|
|
|
143
140
|
handleBufferedRemotePatches()
|
|
144
141
|
}
|
|
145
142
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
})
|
|
155
|
-
}
|
|
143
|
+
editor.subscriptions.push(() => {
|
|
144
|
+
debug('Subscribing to remote patches')
|
|
145
|
+
const sub = editorActor.on('patches', handlePatches)
|
|
146
|
+
return () => {
|
|
147
|
+
debug('Unsubscribing to remote patches')
|
|
148
|
+
sub.unsubscribe()
|
|
149
|
+
}
|
|
150
|
+
})
|
|
156
151
|
|
|
157
152
|
editor.apply = (operation: Operation): void | Editor => {
|
|
158
153
|
if (readOnly) {
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
type Descendant,
|
|
21
21
|
type SelectionOperation,
|
|
22
22
|
} from 'slate'
|
|
23
|
-
import type {
|
|
23
|
+
import type {PortableTextSlateEditor} from '../../types/editor'
|
|
24
24
|
import {debugWithName} from '../../utils/debug'
|
|
25
25
|
import {fromSlateValue} from '../../utils/values'
|
|
26
26
|
import {
|
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
withRedoing,
|
|
30
30
|
withUndoing,
|
|
31
31
|
} from '../../utils/withUndoRedo'
|
|
32
|
+
import type {EditorActor} from '../editor-machine'
|
|
32
33
|
|
|
33
34
|
const debug = debugWithName('plugin:withUndoRedo')
|
|
34
35
|
const debugVerbose = debug.enabled && false
|
|
@@ -51,7 +52,7 @@ const isSaving = (editor: Editor): boolean | undefined => {
|
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
export interface Options {
|
|
54
|
-
|
|
55
|
+
editorActor: EditorActor
|
|
55
56
|
readOnly: boolean
|
|
56
57
|
blockSchemaType: ObjectSchemaType
|
|
57
58
|
}
|
|
@@ -66,7 +67,7 @@ const getRemotePatches = (editor: Editor) => {
|
|
|
66
67
|
export function createWithUndoRedo(
|
|
67
68
|
options: Options,
|
|
68
69
|
): (editor: PortableTextSlateEditor) => PortableTextSlateEditor {
|
|
69
|
-
const {readOnly,
|
|
70
|
+
const {editorActor, readOnly, blockSchemaType} = options
|
|
70
71
|
|
|
71
72
|
return (editor: PortableTextSlateEditor) => {
|
|
72
73
|
let previousSnapshot: PortableTextBlock[] | undefined = fromSlateValue(
|
|
@@ -74,39 +75,39 @@ export function createWithUndoRedo(
|
|
|
74
75
|
blockSchemaType.name,
|
|
75
76
|
)
|
|
76
77
|
const remotePatches = getRemotePatches(editor)
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
remotePatches.push({
|
|
95
|
-
patch,
|
|
96
|
-
time: new Date(),
|
|
97
|
-
snapshot,
|
|
98
|
-
previousSnapshot,
|
|
99
|
-
})
|
|
78
|
+
|
|
79
|
+
editor.subscriptions.push(() => {
|
|
80
|
+
debug('Subscribing to patches')
|
|
81
|
+
const sub = editorActor.on('patches', ({patches, snapshot}) => {
|
|
82
|
+
let reset = false
|
|
83
|
+
patches.forEach((patch) => {
|
|
84
|
+
if (!reset && patch.origin !== 'local' && remotePatches) {
|
|
85
|
+
if (patch.type === 'unset' && patch.path.length === 0) {
|
|
86
|
+
debug(
|
|
87
|
+
'Someone else cleared the content, resetting undo/redo history',
|
|
88
|
+
)
|
|
89
|
+
editor.history = {undos: [], redos: []}
|
|
90
|
+
remotePatches.splice(0, remotePatches.length)
|
|
91
|
+
SAVING.set(editor, true)
|
|
92
|
+
reset = true
|
|
93
|
+
return
|
|
100
94
|
}
|
|
101
|
-
|
|
102
|
-
|
|
95
|
+
remotePatches.push({
|
|
96
|
+
patch,
|
|
97
|
+
time: new Date(),
|
|
98
|
+
snapshot,
|
|
99
|
+
previousSnapshot,
|
|
100
|
+
})
|
|
101
|
+
}
|
|
103
102
|
})
|
|
104
|
-
|
|
105
|
-
debug('Unsubscribing to patches')
|
|
106
|
-
sub.unsubscribe()
|
|
107
|
-
}
|
|
103
|
+
previousSnapshot = snapshot
|
|
108
104
|
})
|
|
109
|
-
|
|
105
|
+
return () => {
|
|
106
|
+
debug('Unsubscribing to patches')
|
|
107
|
+
sub.unsubscribe()
|
|
108
|
+
}
|
|
109
|
+
})
|
|
110
|
+
|
|
110
111
|
editor.history = {undos: [], redos: []}
|
|
111
112
|
const {apply} = editor
|
|
112
113
|
editor.apply = (op: Operation) => {
|
|
@@ -47,8 +47,7 @@ export const withPlugins = <T extends Editor>(
|
|
|
47
47
|
options: createEditorOptions,
|
|
48
48
|
): {editor: PortableTextSlateEditor; subscribe: () => () => void} => {
|
|
49
49
|
const e = editor as T & PortableTextSlateEditor
|
|
50
|
-
const {editorActor, portableTextEditor,
|
|
51
|
-
options
|
|
50
|
+
const {editorActor, portableTextEditor, readOnly, maxBlocks} = options
|
|
52
51
|
const {schemaTypes} = portableTextEditor
|
|
53
52
|
e.subscriptions = []
|
|
54
53
|
if (e.destroy) {
|
|
@@ -75,7 +74,6 @@ export const withPlugins = <T extends Editor>(
|
|
|
75
74
|
)
|
|
76
75
|
const withPatches = createWithPatches({
|
|
77
76
|
editorActor,
|
|
78
|
-
patches$,
|
|
79
77
|
patchFunctions: operationToPatches,
|
|
80
78
|
readOnly,
|
|
81
79
|
schemaTypes,
|
|
@@ -83,8 +81,8 @@ export const withPlugins = <T extends Editor>(
|
|
|
83
81
|
const withMaxBlocks = createWithMaxBlocks(maxBlocks || -1)
|
|
84
82
|
const withPortableTextLists = createWithPortableTextLists(schemaTypes)
|
|
85
83
|
const withUndoRedo = createWithUndoRedo({
|
|
84
|
+
editorActor,
|
|
86
85
|
readOnly,
|
|
87
|
-
patches$,
|
|
88
86
|
blockSchemaType: schemaTypes.block,
|
|
89
87
|
})
|
|
90
88
|
const withPortableTextMarkModel = createWithPortableTextMarkModel(
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ArrayDefinition,
|
|
3
|
+
ArraySchemaType,
|
|
4
|
+
PortableTextBlock,
|
|
5
|
+
} from '@sanity/types'
|
|
6
|
+
import {useActorRef} from '@xstate/react'
|
|
7
|
+
import {getPortableTextMemberSchemaTypes} from '../utils/getPortableTextMemberSchemaTypes'
|
|
8
|
+
import {compileType} from '../utils/schema'
|
|
9
|
+
import type {Behavior} from './behavior/behavior.types'
|
|
10
|
+
import {editorMachine} from './editor-machine'
|
|
11
|
+
import {defaultKeyGenerator} from './key-generator'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @alpha
|
|
15
|
+
*/
|
|
16
|
+
export type EditorConfig = {
|
|
17
|
+
behaviors?: Array<Behavior>
|
|
18
|
+
keyGenerator?: () => string
|
|
19
|
+
schema: ArraySchemaType<PortableTextBlock> | ArrayDefinition
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @alpha
|
|
24
|
+
*/
|
|
25
|
+
export type Editor = ReturnType<typeof useEditor>
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @alpha
|
|
29
|
+
*/
|
|
30
|
+
export function useEditor(config: EditorConfig) {
|
|
31
|
+
const schema = getPortableTextMemberSchemaTypes(
|
|
32
|
+
config.schema.hasOwnProperty('jsonType')
|
|
33
|
+
? config.schema
|
|
34
|
+
: compileType(config.schema),
|
|
35
|
+
)
|
|
36
|
+
const editorActor = useActorRef(editorMachine, {
|
|
37
|
+
input: {
|
|
38
|
+
behaviors: config.behaviors,
|
|
39
|
+
keyGenerator: config.keyGenerator ?? defaultKeyGenerator,
|
|
40
|
+
schema,
|
|
41
|
+
},
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
return editorActor
|
|
45
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
export type {Patch} from '@portabletext/patches'
|
|
2
|
-
export
|
|
3
|
-
Behavior,
|
|
4
|
-
BehaviorActionIntend,
|
|
5
|
-
BehaviorContext,
|
|
6
|
-
BehaviorEvent,
|
|
7
|
-
BehaviorGuard,
|
|
8
|
-
PickFromUnion,
|
|
9
|
-
BehaviorActionIntendSet,
|
|
2
|
+
export {
|
|
3
|
+
type Behavior,
|
|
4
|
+
type BehaviorActionIntend,
|
|
5
|
+
type BehaviorContext,
|
|
6
|
+
type BehaviorEvent,
|
|
7
|
+
type BehaviorGuard,
|
|
8
|
+
type PickFromUnion,
|
|
9
|
+
type BehaviorActionIntendSet,
|
|
10
|
+
defineBehavior,
|
|
10
11
|
} from './editor/behavior/behavior.types'
|
|
12
|
+
export {
|
|
13
|
+
createMarkdownBehaviors,
|
|
14
|
+
type MarkdownBehaviorsConfig,
|
|
15
|
+
} from './editor/behavior/behavior.markdown'
|
|
11
16
|
export {PortableTextEditable} from './editor/Editable'
|
|
12
17
|
export type {PortableTextEditableProps} from './editor/Editable'
|
|
13
18
|
export {
|
|
@@ -15,11 +20,13 @@ export {
|
|
|
15
20
|
type EditorActor,
|
|
16
21
|
type MutationEvent,
|
|
17
22
|
type PatchEvent,
|
|
23
|
+
type PatchesEvent,
|
|
18
24
|
} from './editor/editor-machine'
|
|
19
25
|
export {usePortableTextEditor} from './editor/hooks/usePortableTextEditor'
|
|
20
26
|
export {usePortableTextEditorSelection} from './editor/hooks/usePortableTextEditorSelection'
|
|
21
27
|
export {defaultKeyGenerator as keyGenerator} from './editor/key-generator'
|
|
22
28
|
export {PortableTextEditor} from './editor/PortableTextEditor'
|
|
23
29
|
export type {PortableTextEditorProps} from './editor/PortableTextEditor'
|
|
30
|
+
export {useEditor, type Editor, type EditorConfig} from './editor/use-editor'
|
|
24
31
|
export * from './types/editor'
|
|
25
32
|
export * from './types/options'
|
package/src/types/options.ts
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import type {BaseSyntheticEvent} from 'react'
|
|
2
2
|
import type {EditorActor} from '../editor/editor-machine'
|
|
3
3
|
import type {PortableTextEditor} from '../editor/PortableTextEditor'
|
|
4
|
-
import type {PatchObservable} from './editor'
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
6
|
* @internal
|
|
8
7
|
*/
|
|
9
8
|
export type createEditorOptions = {
|
|
10
9
|
editorActor: EditorActor
|
|
11
|
-
patches$?: PatchObservable
|
|
12
10
|
portableTextEditor: PortableTextEditor
|
|
13
11
|
readOnly: boolean
|
|
14
12
|
maxBlocks?: number
|