@portabletext/editor 1.6.0 → 1.7.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/README.md +5 -0
- package/lib/index.d.mts +3317 -3488
- package/lib/index.d.ts +3317 -3488
- package/lib/index.esm.js +4337 -4089
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +4325 -4077
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +4337 -4089
- package/lib/index.mjs.map +1 -1
- package/package.json +10 -11
- package/src/editor/Editable.tsx +26 -28
- package/src/editor/PortableTextEditor.tsx +90 -66
- package/src/editor/behavior/behavior.action.insert-break.ts +12 -2
- package/src/editor/behavior/behavior.actions.ts +51 -11
- package/src/editor/behavior/behavior.types.ts +23 -0
- package/src/editor/components/Synchronizer.tsx +11 -4
- package/src/editor/create-slate-editor.tsx +67 -0
- package/src/editor/editor-machine.ts +58 -8
- package/src/editor/key-generator.ts +30 -1
- package/src/editor/plugins/create-with-event-listeners.ts +62 -1
- package/src/editor/plugins/createWithEditableAPI.ts +800 -728
- package/src/editor/plugins/createWithMaxBlocks.ts +7 -2
- package/src/editor/plugins/createWithPatches.ts +4 -4
- package/src/editor/plugins/createWithPlaceholderBlock.ts +8 -3
- package/src/editor/plugins/createWithPortableTextMarkModel.ts +3 -4
- package/src/editor/plugins/createWithUndoRedo.ts +6 -7
- package/src/editor/plugins/createWithUtils.ts +2 -8
- package/src/editor/plugins/{index.ts → with-plugins.ts} +22 -79
- package/src/editor/use-editor.ts +46 -14
- package/src/editor/withSyncRangeDecorations.ts +20 -0
- package/src/index.ts +9 -1
- package/src/types/editor.ts +0 -1
- package/src/types/options.ts +1 -3
- package/src/utils/__tests__/operationToPatches.test.ts +7 -14
- package/src/utils/__tests__/patchToOperations.test.ts +4 -7
- package/src/editor/components/SlateContainer.tsx +0 -79
- package/src/editor/hooks/usePortableTextReadOnly.ts +0 -20
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
import type {PortableTextSlateEditor} from '../../types/editor'
|
|
2
2
|
import {isChangingRemotely} from '../../utils/withChanges'
|
|
3
3
|
import {isRedoing, isUndoing} from '../../utils/withUndoRedo'
|
|
4
|
+
import type {EditorActor} from '../editor-machine'
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* This plugin makes sure that the PTE maxBlocks prop is respected
|
|
7
8
|
*
|
|
8
9
|
*/
|
|
9
|
-
export function createWithMaxBlocks(
|
|
10
|
+
export function createWithMaxBlocks(editorActor: EditorActor) {
|
|
10
11
|
return function withMaxBlocks(
|
|
11
12
|
editor: PortableTextSlateEditor,
|
|
12
13
|
): PortableTextSlateEditor {
|
|
13
14
|
const {apply} = editor
|
|
14
15
|
editor.apply = (operation) => {
|
|
16
|
+
if (editorActor.getSnapshot().context.readOnly) {
|
|
17
|
+
return
|
|
18
|
+
}
|
|
19
|
+
|
|
15
20
|
/**
|
|
16
21
|
* We don't want to run any side effects when the editor is processing
|
|
17
22
|
* remote changes.
|
|
@@ -30,7 +35,7 @@ export function createWithMaxBlocks(maxBlocks: number) {
|
|
|
30
35
|
return
|
|
31
36
|
}
|
|
32
37
|
|
|
33
|
-
const rows = maxBlocks
|
|
38
|
+
const rows = editorActor.getSnapshot().context.maxBlocks ?? -1
|
|
34
39
|
if (rows > 0 && editor.children.length >= rows) {
|
|
35
40
|
if (
|
|
36
41
|
(operation.type === 'insert_node' ||
|
|
@@ -81,15 +81,15 @@ export interface PatchFunctions {
|
|
|
81
81
|
interface Options {
|
|
82
82
|
editorActor: EditorActor
|
|
83
83
|
patchFunctions: PatchFunctions
|
|
84
|
-
readOnly: boolean
|
|
85
84
|
schemaTypes: PortableTextMemberSchemaTypes
|
|
85
|
+
subscriptions: Array<() => () => void>
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
export function createWithPatches({
|
|
89
89
|
editorActor,
|
|
90
90
|
patchFunctions,
|
|
91
|
-
readOnly,
|
|
92
91
|
schemaTypes,
|
|
92
|
+
subscriptions,
|
|
93
93
|
}: Options): (editor: PortableTextSlateEditor) => PortableTextSlateEditor {
|
|
94
94
|
// The previous editor children are needed to figure out the _key of deleted nodes
|
|
95
95
|
// The editor.children would no longer contain that information if the node is already deleted.
|
|
@@ -140,7 +140,7 @@ export function createWithPatches({
|
|
|
140
140
|
handleBufferedRemotePatches()
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
-
|
|
143
|
+
subscriptions.push(() => {
|
|
144
144
|
debug('Subscribing to remote patches')
|
|
145
145
|
const sub = editorActor.on('patches', handlePatches)
|
|
146
146
|
return () => {
|
|
@@ -150,7 +150,7 @@ export function createWithPatches({
|
|
|
150
150
|
})
|
|
151
151
|
|
|
152
152
|
editor.apply = (operation: Operation): void | Editor => {
|
|
153
|
-
if (readOnly) {
|
|
153
|
+
if (editorActor.getSnapshot().context.readOnly) {
|
|
154
154
|
apply(operation)
|
|
155
155
|
return editor
|
|
156
156
|
}
|
|
@@ -4,6 +4,7 @@ import type {SlateTextBlock, VoidElement} from '../../types/slate'
|
|
|
4
4
|
import {debugWithName} from '../../utils/debug'
|
|
5
5
|
import {isChangingRemotely} from '../../utils/withChanges'
|
|
6
6
|
import {isRedoing, isUndoing} from '../../utils/withUndoRedo'
|
|
7
|
+
import type {EditorActor} from '../editor-machine'
|
|
7
8
|
|
|
8
9
|
const debug = debugWithName('plugin:withPlaceholderBlock')
|
|
9
10
|
|
|
@@ -11,15 +12,19 @@ const debug = debugWithName('plugin:withPlaceholderBlock')
|
|
|
11
12
|
* Keep a "placeholder" block present when the editor is empty
|
|
12
13
|
*
|
|
13
14
|
*/
|
|
14
|
-
export function createWithPlaceholderBlock(
|
|
15
|
-
|
|
16
|
-
) => PortableTextSlateEditor {
|
|
15
|
+
export function createWithPlaceholderBlock(
|
|
16
|
+
editorActor: EditorActor,
|
|
17
|
+
): (editor: PortableTextSlateEditor) => PortableTextSlateEditor {
|
|
17
18
|
return function withPlaceholderBlock(
|
|
18
19
|
editor: PortableTextSlateEditor,
|
|
19
20
|
): PortableTextSlateEditor {
|
|
20
21
|
const {apply} = editor
|
|
21
22
|
|
|
22
23
|
editor.apply = (op) => {
|
|
24
|
+
if (editorActor.getSnapshot().context.readOnly) {
|
|
25
|
+
return
|
|
26
|
+
}
|
|
27
|
+
|
|
23
28
|
/**
|
|
24
29
|
* We don't want to run any side effects when the editor is processing
|
|
25
30
|
* remote changes.
|
|
@@ -17,7 +17,6 @@ import {getNextSpan, getPreviousSpan} from '../../utils/sibling-utils'
|
|
|
17
17
|
import {isChangingRemotely} from '../../utils/withChanges'
|
|
18
18
|
import {isRedoing, isUndoing} from '../../utils/withUndoRedo'
|
|
19
19
|
import type {BehaviourActionImplementation} from '../behavior/behavior.actions'
|
|
20
|
-
import type {BehaviorAction, PickFromUnion} from '../behavior/behavior.types'
|
|
21
20
|
import type {EditorActor} from '../editor-machine'
|
|
22
21
|
|
|
23
22
|
const debug = debugWithName('plugin:withPortableTextMarkModel')
|
|
@@ -656,7 +655,7 @@ export function createWithPortableTextMarkModel(
|
|
|
656
655
|
}
|
|
657
656
|
|
|
658
657
|
export const addDecoratorActionImplementation: BehaviourActionImplementation<
|
|
659
|
-
|
|
658
|
+
'decorator.add'
|
|
660
659
|
> = ({action}) => {
|
|
661
660
|
const editor = action.editor
|
|
662
661
|
const mark = action.decorator
|
|
@@ -747,7 +746,7 @@ export const addDecoratorActionImplementation: BehaviourActionImplementation<
|
|
|
747
746
|
}
|
|
748
747
|
|
|
749
748
|
export const removeDecoratorActionImplementation: BehaviourActionImplementation<
|
|
750
|
-
|
|
749
|
+
'decorator.remove'
|
|
751
750
|
> = ({action}) => {
|
|
752
751
|
const editor = action.editor
|
|
753
752
|
const mark = action.decorator
|
|
@@ -858,7 +857,7 @@ export function isDecoratorActive({
|
|
|
858
857
|
}
|
|
859
858
|
|
|
860
859
|
export const toggleDecoratorActionImplementation: BehaviourActionImplementation<
|
|
861
|
-
|
|
860
|
+
'decorator.toggle'
|
|
862
861
|
> = ({context, action}) => {
|
|
863
862
|
const isActive = isDecoratorActive({
|
|
864
863
|
editor: action.editor,
|
|
@@ -56,8 +56,8 @@ const isSaving = (editor: Editor): boolean | undefined => {
|
|
|
56
56
|
|
|
57
57
|
export interface Options {
|
|
58
58
|
editorActor: EditorActor
|
|
59
|
-
readOnly: boolean
|
|
60
59
|
blockSchemaType: ObjectSchemaType
|
|
60
|
+
subscriptions: Array<() => () => void>
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
const getRemotePatches = (editor: Editor) => {
|
|
@@ -70,7 +70,7 @@ const getRemotePatches = (editor: Editor) => {
|
|
|
70
70
|
export function createWithUndoRedo(
|
|
71
71
|
options: Options,
|
|
72
72
|
): (editor: PortableTextSlateEditor) => PortableTextSlateEditor {
|
|
73
|
-
const {editorActor,
|
|
73
|
+
const {editorActor, blockSchemaType} = options
|
|
74
74
|
|
|
75
75
|
return (editor: PortableTextSlateEditor) => {
|
|
76
76
|
let previousSnapshot: PortableTextBlock[] | undefined = fromSlateValue(
|
|
@@ -79,7 +79,7 @@ export function createWithUndoRedo(
|
|
|
79
79
|
)
|
|
80
80
|
const remotePatches = getRemotePatches(editor)
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
options.subscriptions.push(() => {
|
|
83
83
|
debug('Subscribing to patches')
|
|
84
84
|
const sub = editorActor.on('patches', ({patches, snapshot}) => {
|
|
85
85
|
let reset = false
|
|
@@ -114,8 +114,7 @@ export function createWithUndoRedo(
|
|
|
114
114
|
editor.history = {undos: [], redos: []}
|
|
115
115
|
const {apply} = editor
|
|
116
116
|
editor.apply = (op: Operation) => {
|
|
117
|
-
if (readOnly) {
|
|
118
|
-
apply(op)
|
|
117
|
+
if (editorActor.getSnapshot().context.readOnly) {
|
|
119
118
|
return
|
|
120
119
|
}
|
|
121
120
|
|
|
@@ -181,7 +180,7 @@ export function createWithUndoRedo(
|
|
|
181
180
|
}
|
|
182
181
|
|
|
183
182
|
editor.undo = () => {
|
|
184
|
-
if (readOnly) {
|
|
183
|
+
if (editorActor.getSnapshot().context.readOnly) {
|
|
185
184
|
return
|
|
186
185
|
}
|
|
187
186
|
const {undos} = editor.history
|
|
@@ -239,7 +238,7 @@ export function createWithUndoRedo(
|
|
|
239
238
|
}
|
|
240
239
|
|
|
241
240
|
editor.redo = () => {
|
|
242
|
-
if (readOnly) {
|
|
241
|
+
if (editorActor.getSnapshot().context.readOnly) {
|
|
243
242
|
return
|
|
244
243
|
}
|
|
245
244
|
const {redos} = editor.history
|
|
@@ -6,24 +6,18 @@ import type {
|
|
|
6
6
|
import {debugWithName} from '../../utils/debug'
|
|
7
7
|
import {toSlateValue} from '../../utils/values'
|
|
8
8
|
import type {EditorActor} from '../editor-machine'
|
|
9
|
-
import type {PortableTextEditor} from '../PortableTextEditor'
|
|
10
9
|
|
|
11
10
|
const debug = debugWithName('plugin:withUtils')
|
|
12
11
|
|
|
13
12
|
interface Options {
|
|
14
13
|
editorActor: EditorActor
|
|
15
14
|
schemaTypes: PortableTextMemberSchemaTypes
|
|
16
|
-
portableTextEditor: PortableTextEditor
|
|
17
15
|
}
|
|
18
16
|
/**
|
|
19
17
|
* This plugin makes various util commands available in the editor
|
|
20
18
|
*
|
|
21
19
|
*/
|
|
22
|
-
export function createWithUtils({
|
|
23
|
-
editorActor,
|
|
24
|
-
schemaTypes,
|
|
25
|
-
portableTextEditor,
|
|
26
|
-
}: Options) {
|
|
20
|
+
export function createWithUtils({editorActor, schemaTypes}: Options) {
|
|
27
21
|
return function withUtils(
|
|
28
22
|
editor: PortableTextSlateEditor,
|
|
29
23
|
): PortableTextSlateEditor {
|
|
@@ -101,7 +95,7 @@ export function createWithUtils({
|
|
|
101
95
|
],
|
|
102
96
|
},
|
|
103
97
|
],
|
|
104
|
-
|
|
98
|
+
{schemaTypes},
|
|
105
99
|
)[0]
|
|
106
100
|
return block
|
|
107
101
|
}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import {noop} from 'lodash'
|
|
2
1
|
import type {BaseOperation, Editor, Node, NodeEntry} from 'slate'
|
|
3
2
|
import type {PortableTextSlateEditor} from '../../types/editor'
|
|
4
3
|
import type {createEditorOptions} from '../../types/options'
|
|
5
4
|
import {createOperationToPatches} from '../../utils/operationToPatches'
|
|
6
5
|
import {createWithEventListeners} from './create-with-event-listeners'
|
|
7
|
-
import {createWithEditableAPI} from './createWithEditableAPI'
|
|
8
6
|
import {createWithMaxBlocks} from './createWithMaxBlocks'
|
|
9
7
|
import {createWithObjectKeys} from './createWithObjectKeys'
|
|
10
8
|
import {createWithPatches} from './createWithPatches'
|
|
@@ -17,20 +15,6 @@ import {createWithSchemaTypes} from './createWithSchemaTypes'
|
|
|
17
15
|
import {createWithUndoRedo} from './createWithUndoRedo'
|
|
18
16
|
import {createWithUtils} from './createWithUtils'
|
|
19
17
|
|
|
20
|
-
export {createWithEditableAPI} from './createWithEditableAPI'
|
|
21
|
-
export {createWithHotkeys} from './createWithHotKeys'
|
|
22
|
-
export {createWithInsertData} from './createWithInsertData'
|
|
23
|
-
export {createWithMaxBlocks} from './createWithMaxBlocks'
|
|
24
|
-
export {createWithObjectKeys} from './createWithObjectKeys'
|
|
25
|
-
export {createWithPatches} from './createWithPatches'
|
|
26
|
-
export {createWithPortableTextBlockStyle} from './createWithPortableTextBlockStyle'
|
|
27
|
-
export {createWithPortableTextLists} from './createWithPortableTextLists'
|
|
28
|
-
export {createWithPortableTextMarkModel} from './createWithPortableTextMarkModel'
|
|
29
|
-
export {createWithPortableTextSelections} from './createWithPortableTextSelections'
|
|
30
|
-
export {createWithSchemaTypes} from './createWithSchemaTypes'
|
|
31
|
-
export {createWithUndoRedo} from './createWithUndoRedo'
|
|
32
|
-
export {createWithUtils} from './createWithUtils'
|
|
33
|
-
|
|
34
18
|
export interface OriginalEditorFunctions {
|
|
35
19
|
apply: (operation: BaseOperation) => void
|
|
36
20
|
onChange: () => void
|
|
@@ -45,11 +29,10 @@ const originalFnMap = new WeakMap<
|
|
|
45
29
|
export const withPlugins = <T extends Editor>(
|
|
46
30
|
editor: T,
|
|
47
31
|
options: createEditorOptions,
|
|
48
|
-
):
|
|
32
|
+
): PortableTextSlateEditor => {
|
|
49
33
|
const e = editor as T & PortableTextSlateEditor
|
|
50
|
-
const {editorActor
|
|
51
|
-
const
|
|
52
|
-
e.subscriptions = []
|
|
34
|
+
const {editorActor} = options
|
|
35
|
+
const schemaTypes = editorActor.getSnapshot().context.schema
|
|
53
36
|
if (e.destroy) {
|
|
54
37
|
e.destroy()
|
|
55
38
|
} else {
|
|
@@ -67,23 +50,18 @@ export const withPlugins = <T extends Editor>(
|
|
|
67
50
|
editorActor,
|
|
68
51
|
schemaTypes,
|
|
69
52
|
})
|
|
70
|
-
const withEditableAPI = createWithEditableAPI(
|
|
71
|
-
editorActor,
|
|
72
|
-
portableTextEditor,
|
|
73
|
-
schemaTypes,
|
|
74
|
-
)
|
|
75
53
|
const withPatches = createWithPatches({
|
|
76
54
|
editorActor,
|
|
77
55
|
patchFunctions: operationToPatches,
|
|
78
|
-
readOnly,
|
|
79
56
|
schemaTypes,
|
|
57
|
+
subscriptions: options.subscriptions,
|
|
80
58
|
})
|
|
81
|
-
const withMaxBlocks = createWithMaxBlocks(
|
|
59
|
+
const withMaxBlocks = createWithMaxBlocks(editorActor)
|
|
82
60
|
const withPortableTextLists = createWithPortableTextLists(schemaTypes)
|
|
83
61
|
const withUndoRedo = createWithUndoRedo({
|
|
84
62
|
editorActor,
|
|
85
|
-
readOnly,
|
|
86
63
|
blockSchemaType: schemaTypes.block,
|
|
64
|
+
subscriptions: options.subscriptions,
|
|
87
65
|
})
|
|
88
66
|
const withPortableTextMarkModel = createWithPortableTextMarkModel(
|
|
89
67
|
editorActor,
|
|
@@ -94,18 +72,20 @@ export const withPlugins = <T extends Editor>(
|
|
|
94
72
|
schemaTypes,
|
|
95
73
|
)
|
|
96
74
|
|
|
97
|
-
const withPlaceholderBlock = createWithPlaceholderBlock()
|
|
75
|
+
const withPlaceholderBlock = createWithPlaceholderBlock(editorActor)
|
|
98
76
|
|
|
99
77
|
const withUtils = createWithUtils({
|
|
100
78
|
editorActor,
|
|
101
79
|
schemaTypes,
|
|
102
|
-
portableTextEditor,
|
|
103
80
|
})
|
|
104
81
|
const withPortableTextSelections = createWithPortableTextSelections(
|
|
105
82
|
editorActor,
|
|
106
83
|
schemaTypes,
|
|
107
84
|
)
|
|
108
|
-
const withEventListeners = createWithEventListeners(
|
|
85
|
+
const withEventListeners = createWithEventListeners(
|
|
86
|
+
editorActor,
|
|
87
|
+
options.subscriptions,
|
|
88
|
+
)
|
|
109
89
|
|
|
110
90
|
e.destroy = () => {
|
|
111
91
|
const originalFunctions = originalFnMap.get(e)
|
|
@@ -117,44 +97,18 @@ export const withPlugins = <T extends Editor>(
|
|
|
117
97
|
e.normalizeNode = originalFunctions.normalizeNode
|
|
118
98
|
e.onChange = originalFunctions.onChange
|
|
119
99
|
}
|
|
120
|
-
if (readOnly) {
|
|
121
|
-
return {
|
|
122
|
-
editor: withSchemaTypes(
|
|
123
|
-
withObjectKeys(
|
|
124
|
-
withPortableTextMarkModel(
|
|
125
|
-
withPortableTextBlockStyle(
|
|
126
|
-
withUtils(
|
|
127
|
-
withPlaceholderBlock(
|
|
128
|
-
withPortableTextLists(
|
|
129
|
-
withPortableTextSelections(withEditableAPI(e)),
|
|
130
|
-
),
|
|
131
|
-
),
|
|
132
|
-
),
|
|
133
|
-
),
|
|
134
|
-
),
|
|
135
|
-
),
|
|
136
|
-
),
|
|
137
|
-
subscribe: () => noop,
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
100
|
|
|
141
101
|
// Ordering is important here, selection dealing last, data manipulation in the middle and core model stuff first.
|
|
142
|
-
return
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
withUndoRedo(
|
|
153
|
-
withPatches(
|
|
154
|
-
withPortableTextSelections(withEditableAPI(e)),
|
|
155
|
-
),
|
|
156
|
-
),
|
|
157
|
-
),
|
|
102
|
+
return withEventListeners(
|
|
103
|
+
withSchemaTypes(
|
|
104
|
+
withObjectKeys(
|
|
105
|
+
withPortableTextMarkModel(
|
|
106
|
+
withPortableTextBlockStyle(
|
|
107
|
+
withPortableTextLists(
|
|
108
|
+
withPlaceholderBlock(
|
|
109
|
+
withUtils(
|
|
110
|
+
withMaxBlocks(
|
|
111
|
+
withUndoRedo(withPatches(withPortableTextSelections(e))),
|
|
158
112
|
),
|
|
159
113
|
),
|
|
160
114
|
),
|
|
@@ -163,16 +117,5 @@ export const withPlugins = <T extends Editor>(
|
|
|
163
117
|
),
|
|
164
118
|
),
|
|
165
119
|
),
|
|
166
|
-
|
|
167
|
-
const unsubscribes: (() => void)[] = []
|
|
168
|
-
editor.subscriptions.forEach((subscribeFn) => {
|
|
169
|
-
unsubscribes.push(subscribeFn())
|
|
170
|
-
})
|
|
171
|
-
return () => {
|
|
172
|
-
unsubscribes.forEach((unsubscribeFn) => {
|
|
173
|
-
unsubscribeFn()
|
|
174
|
-
})
|
|
175
|
-
}
|
|
176
|
-
},
|
|
177
|
-
}
|
|
120
|
+
)
|
|
178
121
|
}
|
package/src/editor/use-editor.ts
CHANGED
|
@@ -3,12 +3,16 @@ import type {
|
|
|
3
3
|
ArraySchemaType,
|
|
4
4
|
PortableTextBlock,
|
|
5
5
|
} from '@sanity/types'
|
|
6
|
-
import {useActorRef} from '@xstate/react'
|
|
6
|
+
import {useActorRef, useSelector} from '@xstate/react'
|
|
7
7
|
import {getPortableTextMemberSchemaTypes} from '../utils/getPortableTextMemberSchemaTypes'
|
|
8
8
|
import {compileType} from '../utils/schema'
|
|
9
|
-
import type {Behavior} from './behavior/behavior.types'
|
|
9
|
+
import type {Behavior, PickFromUnion} from './behavior/behavior.types'
|
|
10
10
|
import {compileSchemaDefinition, type SchemaDefinition} from './define-schema'
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
editorMachine,
|
|
13
|
+
type EditorActor,
|
|
14
|
+
type InternalEditorEvent,
|
|
15
|
+
} from './editor-machine'
|
|
12
16
|
import {defaultKeyGenerator} from './key-generator'
|
|
13
17
|
|
|
14
18
|
/**
|
|
@@ -31,27 +35,55 @@ export type EditorConfig = {
|
|
|
31
35
|
/**
|
|
32
36
|
* @alpha
|
|
33
37
|
*/
|
|
34
|
-
export type
|
|
38
|
+
export type EditorEvent = PickFromUnion<
|
|
39
|
+
InternalEditorEvent,
|
|
40
|
+
'type',
|
|
41
|
+
| 'annotation.toggle'
|
|
42
|
+
| 'focus'
|
|
43
|
+
| 'patches'
|
|
44
|
+
| 'toggle readOnly'
|
|
45
|
+
| 'update behaviors'
|
|
46
|
+
>
|
|
35
47
|
|
|
36
48
|
/**
|
|
37
49
|
* @alpha
|
|
38
50
|
*/
|
|
39
|
-
export
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
51
|
+
export type Editor = {
|
|
52
|
+
send: (event: EditorEvent) => void
|
|
53
|
+
on: EditorActor['on']
|
|
54
|
+
readOnly: boolean
|
|
55
|
+
_internal: {
|
|
56
|
+
editorActor: EditorActor
|
|
57
|
+
}
|
|
58
|
+
}
|
|
47
59
|
|
|
60
|
+
/**
|
|
61
|
+
* @alpha
|
|
62
|
+
*/
|
|
63
|
+
export function useEditor(config: EditorConfig): Editor {
|
|
48
64
|
const editorActor = useActorRef(editorMachine, {
|
|
49
65
|
input: {
|
|
50
66
|
behaviors: config.behaviors,
|
|
51
67
|
keyGenerator: config.keyGenerator ?? defaultKeyGenerator,
|
|
52
|
-
schema
|
|
68
|
+
schema: config.schemaDefinition
|
|
69
|
+
? compileSchemaDefinition(config.schemaDefinition)
|
|
70
|
+
: getPortableTextMemberSchemaTypes(
|
|
71
|
+
config.schema.hasOwnProperty('jsonType')
|
|
72
|
+
? config.schema
|
|
73
|
+
: compileType(config.schema),
|
|
74
|
+
),
|
|
53
75
|
},
|
|
54
76
|
})
|
|
77
|
+
const readOnly = useSelector(editorActor, (s) => s.context.readOnly)
|
|
55
78
|
|
|
56
|
-
return
|
|
79
|
+
return {
|
|
80
|
+
send: (event) => {
|
|
81
|
+
editorActor.send(event)
|
|
82
|
+
},
|
|
83
|
+
on: (event, listener) => editorActor.on(event, listener),
|
|
84
|
+
readOnly,
|
|
85
|
+
_internal: {
|
|
86
|
+
editorActor,
|
|
87
|
+
},
|
|
88
|
+
}
|
|
57
89
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type {BaseEditor, Operation} from 'slate'
|
|
2
|
+
import type {ReactEditor} from 'slate-react'
|
|
3
|
+
import type {PortableTextSlateEditor} from '../types/editor'
|
|
4
|
+
|
|
5
|
+
// React Compiler considers `slateEditor` as immutable, and opts-out if we do this inline in a useEffect, doing it in a function moves it out of the scope, and opts-in again for the rest of the component.
|
|
6
|
+
export function withSyncRangeDecorations(
|
|
7
|
+
slateEditor: BaseEditor & ReactEditor & PortableTextSlateEditor,
|
|
8
|
+
syncRangeDecorations: (operation?: Operation) => void,
|
|
9
|
+
) {
|
|
10
|
+
const originalApply = slateEditor.apply
|
|
11
|
+
slateEditor.apply = (op: Operation) => {
|
|
12
|
+
originalApply(op)
|
|
13
|
+
if (op.type !== 'set_selection') {
|
|
14
|
+
syncRangeDecorations(op)
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return () => {
|
|
18
|
+
slateEditor.apply = originalApply
|
|
19
|
+
}
|
|
20
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -25,6 +25,8 @@ export type {PortableTextEditableProps} from './editor/Editable'
|
|
|
25
25
|
export {
|
|
26
26
|
editorMachine,
|
|
27
27
|
type EditorActor,
|
|
28
|
+
type InternalEditorEmittedEvent,
|
|
29
|
+
type InternalEditorEvent,
|
|
28
30
|
type MutationEvent,
|
|
29
31
|
type PatchEvent,
|
|
30
32
|
type PatchesEvent,
|
|
@@ -32,8 +34,14 @@ export {
|
|
|
32
34
|
export {usePortableTextEditor} from './editor/hooks/usePortableTextEditor'
|
|
33
35
|
export {usePortableTextEditorSelection} from './editor/hooks/usePortableTextEditorSelection'
|
|
34
36
|
export {defaultKeyGenerator as keyGenerator} from './editor/key-generator'
|
|
37
|
+
export type {AddedAnnotationPaths} from './editor/plugins/createWithEditableAPI'
|
|
35
38
|
export {PortableTextEditor} from './editor/PortableTextEditor'
|
|
36
39
|
export type {PortableTextEditorProps} from './editor/PortableTextEditor'
|
|
37
|
-
export {
|
|
40
|
+
export {
|
|
41
|
+
useEditor,
|
|
42
|
+
type Editor,
|
|
43
|
+
type EditorConfig,
|
|
44
|
+
type EditorEvent,
|
|
45
|
+
} from './editor/use-editor'
|
|
38
46
|
export * from './types/editor'
|
|
39
47
|
export * from './types/options'
|
package/src/types/editor.ts
CHANGED
|
@@ -133,7 +133,6 @@ export interface PortableTextSlateEditor extends ReactEditor {
|
|
|
133
133
|
isTextBlock: (value: unknown) => value is PortableTextTextBlock
|
|
134
134
|
isTextSpan: (value: unknown) => value is PortableTextSpan
|
|
135
135
|
isListBlock: (value: unknown) => value is PortableTextListBlock
|
|
136
|
-
subscriptions: (() => () => void)[]
|
|
137
136
|
|
|
138
137
|
/**
|
|
139
138
|
* Increments selected list items levels, or decrements them if `reverse` is true.
|
package/src/types/options.ts
CHANGED
|
@@ -7,9 +7,7 @@ import type {PortableTextEditor} from '../editor/PortableTextEditor'
|
|
|
7
7
|
*/
|
|
8
8
|
export type createEditorOptions = {
|
|
9
9
|
editorActor: EditorActor
|
|
10
|
-
|
|
11
|
-
readOnly: boolean
|
|
12
|
-
maxBlocks?: number
|
|
10
|
+
subscriptions: Array<() => () => void>
|
|
13
11
|
}
|
|
14
12
|
|
|
15
13
|
/**
|
|
@@ -2,34 +2,27 @@ import type {PortableTextTextBlock} from '@sanity/types'
|
|
|
2
2
|
import {createEditor, type Descendant} from 'slate'
|
|
3
3
|
import {beforeEach, describe, expect, it} from 'vitest'
|
|
4
4
|
import {createActor} from 'xstate'
|
|
5
|
-
import {
|
|
6
|
-
editorMachine,
|
|
7
|
-
PortableTextEditor,
|
|
8
|
-
type PortableTextEditorProps,
|
|
9
|
-
} from '../..'
|
|
5
|
+
import {editorMachine} from '../..'
|
|
10
6
|
import {schemaType} from '../../editor/__tests__/PortableTextEditorTester'
|
|
11
7
|
import {coreBehaviors} from '../../editor/behavior/behavior.core'
|
|
12
8
|
import {defaultKeyGenerator} from '../../editor/key-generator'
|
|
13
|
-
import {withPlugins} from '../../editor/plugins'
|
|
9
|
+
import {withPlugins} from '../../editor/plugins/with-plugins'
|
|
14
10
|
import {getPortableTextMemberSchemaTypes} from '../getPortableTextMemberSchemaTypes'
|
|
15
11
|
import {createOperationToPatches} from '../operationToPatches'
|
|
16
12
|
|
|
17
|
-
const
|
|
13
|
+
const schemaTypes = getPortableTextMemberSchemaTypes(schemaType)
|
|
18
14
|
|
|
19
|
-
const operationToPatches = createOperationToPatches(
|
|
15
|
+
const operationToPatches = createOperationToPatches(schemaTypes)
|
|
20
16
|
|
|
21
|
-
const
|
|
17
|
+
const editor = withPlugins(createEditor(), {
|
|
22
18
|
editorActor: createActor(editorMachine, {
|
|
23
19
|
input: {
|
|
24
20
|
behaviors: coreBehaviors,
|
|
25
|
-
schema:
|
|
21
|
+
schema: schemaTypes,
|
|
26
22
|
keyGenerator: defaultKeyGenerator,
|
|
27
23
|
},
|
|
28
24
|
}),
|
|
29
|
-
|
|
30
|
-
schemaType,
|
|
31
|
-
} as PortableTextEditorProps),
|
|
32
|
-
readOnly: false,
|
|
25
|
+
subscriptions: [],
|
|
33
26
|
})
|
|
34
27
|
|
|
35
28
|
const createDefaultValue = () =>
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import type {Patch} from '@portabletext/patches'
|
|
2
|
-
import {noop} from 'lodash'
|
|
3
2
|
import {createEditor, type Descendant} from 'slate'
|
|
4
3
|
import {beforeEach, describe, expect, it} from 'vitest'
|
|
5
4
|
import {createActor} from 'xstate'
|
|
6
|
-
import {editorMachine
|
|
5
|
+
import {editorMachine} from '../..'
|
|
7
6
|
import {schemaType} from '../../editor/__tests__/PortableTextEditorTester'
|
|
8
7
|
import {coreBehaviors} from '../../editor/behavior/behavior.core'
|
|
9
8
|
import {defaultKeyGenerator} from '../../editor/key-generator'
|
|
10
|
-
import {withPlugins} from '../../editor/plugins'
|
|
9
|
+
import {withPlugins} from '../../editor/plugins/with-plugins'
|
|
11
10
|
import {createApplyPatch} from '../applyPatch'
|
|
12
11
|
import {getPortableTextMemberSchemaTypes} from '../getPortableTextMemberSchemaTypes'
|
|
13
12
|
import {VOID_CHILD_KEY} from '../values'
|
|
@@ -15,9 +14,8 @@ import {VOID_CHILD_KEY} from '../values'
|
|
|
15
14
|
const schemaTypes = getPortableTextMemberSchemaTypes(schemaType)
|
|
16
15
|
|
|
17
16
|
const patchToOperations = createApplyPatch(schemaTypes)
|
|
18
|
-
const portableTextEditor = new PortableTextEditor({schemaType, onChange: noop})
|
|
19
17
|
|
|
20
|
-
const
|
|
18
|
+
const editor = withPlugins(createEditor(), {
|
|
21
19
|
editorActor: createActor(editorMachine, {
|
|
22
20
|
input: {
|
|
23
21
|
behaviors: coreBehaviors,
|
|
@@ -25,8 +23,7 @@ const {editor} = withPlugins(createEditor(), {
|
|
|
25
23
|
keyGenerator: defaultKeyGenerator,
|
|
26
24
|
},
|
|
27
25
|
}),
|
|
28
|
-
|
|
29
|
-
readOnly: false,
|
|
26
|
+
subscriptions: [],
|
|
30
27
|
})
|
|
31
28
|
|
|
32
29
|
const createDefaultValue = (): Descendant[] => [
|