@portabletext/editor 1.1.0 → 1.1.2
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 +3 -0
- package/lib/index.d.mts +1680 -12
- package/lib/index.d.ts +1680 -12
- package/lib/index.esm.js +310 -162
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +310 -163
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +310 -162
- package/lib/index.mjs.map +1 -1
- package/package.json +25 -38
- package/src/editor/Editable.tsx +51 -50
- package/src/editor/PortableTextEditor.tsx +42 -26
- package/src/editor/__tests__/PortableTextEditor.test.tsx +11 -12
- package/src/editor/__tests__/PortableTextEditorTester.tsx +2 -5
- package/src/editor/__tests__/RangeDecorations.test.tsx +6 -7
- package/src/editor/__tests__/handleClick.test.tsx +27 -7
- package/src/editor/__tests__/insert-block.test.tsx +6 -6
- package/src/editor/__tests__/pteWarningsSelfSolving.test.tsx +8 -8
- package/src/editor/__tests__/self-solving.test.tsx +176 -0
- package/src/editor/components/Element.tsx +15 -17
- package/src/editor/components/Leaf.tsx +40 -35
- package/src/editor/components/SlateContainer.tsx +2 -2
- package/src/editor/components/Synchronizer.tsx +62 -34
- package/src/editor/editor-machine.ts +195 -0
- package/src/editor/hooks/usePortableTextEditor.ts +1 -1
- package/src/editor/hooks/usePortableTextEditorSelection.tsx +12 -14
- package/src/editor/hooks/useSyncValue.test.tsx +9 -9
- package/src/editor/hooks/useSyncValue.ts +16 -19
- package/src/editor/nodes/DefaultAnnotation.tsx +1 -2
- package/src/editor/nodes/DefaultObject.tsx +1 -1
- package/src/editor/plugins/__tests__/createWithInsertData.test.tsx +2 -5
- package/src/editor/plugins/__tests__/withEditableAPIDelete.test.tsx +28 -28
- package/src/editor/plugins/__tests__/withEditableAPIGetFragment.test.tsx +17 -17
- package/src/editor/plugins/__tests__/withEditableAPIInsert.test.tsx +8 -8
- package/src/editor/plugins/__tests__/withEditableAPISelectionsOverlapping.test.tsx +6 -6
- package/src/editor/plugins/__tests__/withPortableTextLists.test.tsx +2 -2
- package/src/editor/plugins/__tests__/withPortableTextMarkModel.test.tsx +47 -49
- package/src/editor/plugins/__tests__/withPortableTextSelections.test.tsx +22 -11
- package/src/editor/plugins/__tests__/withUndoRedo.test.tsx +9 -9
- package/src/editor/plugins/createWithEditableAPI.ts +8 -8
- package/src/editor/plugins/createWithHotKeys.ts +8 -12
- package/src/editor/plugins/createWithInsertBreak.ts +4 -4
- package/src/editor/plugins/createWithInsertData.ts +11 -16
- package/src/editor/plugins/createWithMaxBlocks.ts +1 -1
- package/src/editor/plugins/createWithObjectKeys.ts +10 -3
- package/src/editor/plugins/createWithPatches.ts +9 -12
- package/src/editor/plugins/createWithPlaceholderBlock.ts +2 -2
- package/src/editor/plugins/createWithPortableTextBlockStyle.ts +13 -5
- package/src/editor/plugins/createWithPortableTextLists.ts +3 -4
- package/src/editor/plugins/createWithPortableTextMarkModel.ts +24 -10
- package/src/editor/plugins/createWithPortableTextSelections.ts +9 -10
- package/src/editor/plugins/createWithSchemaTypes.ts +13 -4
- package/src/editor/plugins/createWithUndoRedo.ts +3 -7
- package/src/editor/plugins/createWithUtils.ts +6 -6
- package/src/editor/plugins/index.ts +21 -11
- package/src/index.ts +9 -3
- package/src/types/editor.ts +33 -33
- package/src/types/options.ts +3 -3
- package/src/types/slate.ts +4 -4
- package/src/utils/__tests__/dmpToOperations.test.ts +4 -4
- package/src/utils/__tests__/operationToPatches.test.ts +62 -62
- package/src/utils/__tests__/patchToOperations.test.ts +40 -40
- package/src/utils/__tests__/ranges.test.ts +2 -2
- package/src/utils/__tests__/valueNormalization.test.tsx +14 -2
- package/src/utils/__tests__/values.test.ts +17 -17
- package/src/utils/applyPatch.ts +10 -12
- package/src/utils/getPortableTextMemberSchemaTypes.ts +8 -8
- package/src/utils/operationToPatches.ts +5 -9
- package/src/utils/paths.ts +5 -5
- package/src/utils/ranges.ts +4 -5
- package/src/utils/selection.ts +2 -2
- package/src/utils/ucs2Indices.ts +2 -2
- package/src/utils/validateValue.ts +3 -25
- package/src/utils/values.ts +7 -8
- package/src/utils/weakMaps.ts +2 -2
- package/src/utils/withChanges.ts +1 -1
- package/src/utils/withUndoRedo.ts +1 -1
- package/src/utils/withoutPatching.ts +1 -1
- package/src/editor/__tests__/utils.ts +0 -45
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import type {Patch} from '@portabletext/patches'
|
|
2
|
+
import type {PortableTextBlock} from '@sanity/types'
|
|
3
|
+
import type {FocusEvent} from 'react'
|
|
4
|
+
import {
|
|
5
|
+
assertEvent,
|
|
6
|
+
assign,
|
|
7
|
+
emit,
|
|
8
|
+
enqueueActions,
|
|
9
|
+
fromCallback,
|
|
10
|
+
setup,
|
|
11
|
+
type ActorRefFrom,
|
|
12
|
+
} from 'xstate'
|
|
13
|
+
import type {EditorSelection, InvalidValueResolution} from '../types/editor'
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
export type EditorActor = ActorRefFrom<typeof editorMachine>
|
|
19
|
+
|
|
20
|
+
const networkLogic = fromCallback(({sendBack}) => {
|
|
21
|
+
const onlineHandler = () => {
|
|
22
|
+
sendBack({type: 'online'})
|
|
23
|
+
}
|
|
24
|
+
const offlineHandler = () => {
|
|
25
|
+
sendBack({type: 'offline'})
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
window.addEventListener('online', onlineHandler)
|
|
29
|
+
window.addEventListener('offline', offlineHandler)
|
|
30
|
+
|
|
31
|
+
return () => {
|
|
32
|
+
window.removeEventListener('online', onlineHandler)
|
|
33
|
+
window.removeEventListener('offline', offlineHandler)
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @internal
|
|
39
|
+
*/
|
|
40
|
+
export type PatchEvent = {type: 'patch'; patch: Patch}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @internal
|
|
44
|
+
*/
|
|
45
|
+
export type MutationEvent = {
|
|
46
|
+
type: 'mutation'
|
|
47
|
+
patches: Array<Patch>
|
|
48
|
+
snapshot: Array<PortableTextBlock> | undefined
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
type EditorEvent =
|
|
52
|
+
| {type: 'normalizing'}
|
|
53
|
+
| {type: 'done normalizing'}
|
|
54
|
+
| EditorEmittedEvent
|
|
55
|
+
|
|
56
|
+
type EditorEmittedEvent =
|
|
57
|
+
| {type: 'ready'}
|
|
58
|
+
| PatchEvent
|
|
59
|
+
| MutationEvent
|
|
60
|
+
| {
|
|
61
|
+
type: 'unset'
|
|
62
|
+
previousValue: Array<PortableTextBlock>
|
|
63
|
+
}
|
|
64
|
+
| {
|
|
65
|
+
type: 'value changed'
|
|
66
|
+
value: Array<PortableTextBlock> | undefined
|
|
67
|
+
}
|
|
68
|
+
| {
|
|
69
|
+
type: 'invalid value'
|
|
70
|
+
resolution: InvalidValueResolution | null
|
|
71
|
+
value: Array<PortableTextBlock> | undefined
|
|
72
|
+
}
|
|
73
|
+
| {
|
|
74
|
+
type: 'error'
|
|
75
|
+
name: string
|
|
76
|
+
description: string
|
|
77
|
+
data: unknown
|
|
78
|
+
}
|
|
79
|
+
| {type: 'selection'; selection: EditorSelection}
|
|
80
|
+
| {type: 'blur'; event: FocusEvent<HTMLDivElement, Element>}
|
|
81
|
+
| {type: 'focus'; event: FocusEvent<HTMLDivElement, Element>}
|
|
82
|
+
| {type: 'online'}
|
|
83
|
+
| {type: 'offline'}
|
|
84
|
+
| {type: 'loading'}
|
|
85
|
+
| {type: 'done loading'}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @internal
|
|
89
|
+
*/
|
|
90
|
+
export const editorMachine = setup({
|
|
91
|
+
types: {
|
|
92
|
+
context: {} as {
|
|
93
|
+
pendingEvents: Array<PatchEvent | MutationEvent>
|
|
94
|
+
},
|
|
95
|
+
events: {} as EditorEvent,
|
|
96
|
+
emitted: {} as EditorEmittedEvent,
|
|
97
|
+
},
|
|
98
|
+
actions: {
|
|
99
|
+
'emit patch event': emit(({event}) => {
|
|
100
|
+
assertEvent(event, 'patch')
|
|
101
|
+
return event
|
|
102
|
+
}),
|
|
103
|
+
'emit mutation event': emit(({event}) => {
|
|
104
|
+
assertEvent(event, 'mutation')
|
|
105
|
+
return event
|
|
106
|
+
}),
|
|
107
|
+
'defer event': assign({
|
|
108
|
+
pendingEvents: ({context, event}) => {
|
|
109
|
+
assertEvent(event, ['patch', 'mutation'])
|
|
110
|
+
return [...context.pendingEvents, event]
|
|
111
|
+
},
|
|
112
|
+
}),
|
|
113
|
+
'emit pending events': enqueueActions(({context, enqueue}) => {
|
|
114
|
+
for (const event of context.pendingEvents) {
|
|
115
|
+
enqueue(emit(event))
|
|
116
|
+
}
|
|
117
|
+
}),
|
|
118
|
+
'clear pending events': assign({
|
|
119
|
+
pendingEvents: [],
|
|
120
|
+
}),
|
|
121
|
+
},
|
|
122
|
+
actors: {
|
|
123
|
+
networkLogic,
|
|
124
|
+
},
|
|
125
|
+
}).createMachine({
|
|
126
|
+
id: 'editor',
|
|
127
|
+
context: {
|
|
128
|
+
pendingEvents: [],
|
|
129
|
+
},
|
|
130
|
+
invoke: {
|
|
131
|
+
id: 'networkLogic',
|
|
132
|
+
src: 'networkLogic',
|
|
133
|
+
},
|
|
134
|
+
on: {
|
|
135
|
+
'ready': {actions: emit(({event}) => event)},
|
|
136
|
+
'unset': {actions: emit(({event}) => event)},
|
|
137
|
+
'value changed': {actions: emit(({event}) => event)},
|
|
138
|
+
'invalid value': {actions: emit(({event}) => event)},
|
|
139
|
+
'error': {actions: emit(({event}) => event)},
|
|
140
|
+
'selection': {actions: emit(({event}) => event)},
|
|
141
|
+
'blur': {actions: emit(({event}) => event)},
|
|
142
|
+
'focus': {actions: emit(({event}) => event)},
|
|
143
|
+
'online': {actions: emit({type: 'online'})},
|
|
144
|
+
'offline': {actions: emit({type: 'offline'})},
|
|
145
|
+
'loading': {actions: emit({type: 'loading'})},
|
|
146
|
+
'done loading': {actions: emit({type: 'done loading'})},
|
|
147
|
+
},
|
|
148
|
+
initial: 'pristine',
|
|
149
|
+
states: {
|
|
150
|
+
pristine: {
|
|
151
|
+
initial: 'idle',
|
|
152
|
+
states: {
|
|
153
|
+
idle: {
|
|
154
|
+
on: {
|
|
155
|
+
normalizing: {
|
|
156
|
+
target: 'normalizing',
|
|
157
|
+
},
|
|
158
|
+
patch: {
|
|
159
|
+
actions: 'defer event',
|
|
160
|
+
target: '#editor.dirty',
|
|
161
|
+
},
|
|
162
|
+
mutation: {
|
|
163
|
+
actions: 'defer event',
|
|
164
|
+
target: '#editor.dirty',
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
normalizing: {
|
|
169
|
+
on: {
|
|
170
|
+
'done normalizing': {
|
|
171
|
+
target: 'idle',
|
|
172
|
+
},
|
|
173
|
+
'patch': {
|
|
174
|
+
actions: 'defer event',
|
|
175
|
+
},
|
|
176
|
+
'mutation': {
|
|
177
|
+
actions: 'defer event',
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
dirty: {
|
|
184
|
+
entry: ['emit pending events', 'clear pending events'],
|
|
185
|
+
on: {
|
|
186
|
+
patch: {
|
|
187
|
+
actions: 'emit patch event',
|
|
188
|
+
},
|
|
189
|
+
mutation: {
|
|
190
|
+
actions: 'emit mutation event',
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
})
|
|
@@ -5,8 +5,9 @@ import {
|
|
|
5
5
|
useEffect,
|
|
6
6
|
useState,
|
|
7
7
|
} from 'react'
|
|
8
|
-
import
|
|
8
|
+
import type {EditorChanges, EditorSelection} from '../../types/editor'
|
|
9
9
|
import {debugWithName} from '../../utils/debug'
|
|
10
|
+
import type {EditorActor} from '../editor-machine'
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* A React context for sharing the editor selection.
|
|
@@ -36,30 +37,27 @@ const debugVerbose = debug.enabled && false
|
|
|
36
37
|
*/
|
|
37
38
|
export function PortableTextEditorSelectionProvider(
|
|
38
39
|
props: React.PropsWithChildren<{
|
|
39
|
-
|
|
40
|
+
editorActor: EditorActor
|
|
40
41
|
}>,
|
|
41
42
|
) {
|
|
42
|
-
const {change$} = props
|
|
43
43
|
const [selection, setSelection] = useState<EditorSelection>(null)
|
|
44
44
|
|
|
45
45
|
// Subscribe to, and handle changes from the editor
|
|
46
46
|
useEffect(() => {
|
|
47
|
-
debug('Subscribing to selection changes
|
|
48
|
-
const subscription =
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
})
|
|
55
|
-
}
|
|
47
|
+
debug('Subscribing to selection changes')
|
|
48
|
+
const subscription = props.editorActor.on('selection', (event) => {
|
|
49
|
+
// Set the selection state in a transition, we don't need the state immediately.
|
|
50
|
+
startTransition(() => {
|
|
51
|
+
if (debugVerbose) debug('Setting selection')
|
|
52
|
+
setSelection(event.selection)
|
|
53
|
+
})
|
|
56
54
|
})
|
|
57
55
|
|
|
58
56
|
return () => {
|
|
59
|
-
debug('Unsubscribing to selection changes
|
|
57
|
+
debug('Unsubscribing to selection changes')
|
|
60
58
|
subscription.unsubscribe()
|
|
61
59
|
}
|
|
62
|
-
}, [
|
|
60
|
+
}, [props.editorActor])
|
|
63
61
|
|
|
64
62
|
return (
|
|
65
63
|
<PortableTextEditorSelectionContext.Provider value={selection}>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {describe, expect, it, jest} from '@jest/globals'
|
|
2
1
|
import {render, waitFor} from '@testing-library/react'
|
|
3
2
|
import {createRef, type RefObject} from 'react'
|
|
3
|
+
import {describe, expect, it, vi} from 'vitest'
|
|
4
4
|
import {
|
|
5
5
|
PortableTextEditorTester,
|
|
6
6
|
schemaType,
|
|
@@ -27,7 +27,7 @@ const initialValue = [
|
|
|
27
27
|
describe('useSyncValue', () => {
|
|
28
28
|
it('updates span text', async () => {
|
|
29
29
|
const editorRef: RefObject<PortableTextEditor> = createRef()
|
|
30
|
-
const onChange =
|
|
30
|
+
const onChange = vi.fn()
|
|
31
31
|
const syncedValue = [
|
|
32
32
|
{
|
|
33
33
|
_key: '77071c3af231',
|
|
@@ -70,7 +70,7 @@ describe('useSyncValue', () => {
|
|
|
70
70
|
})
|
|
71
71
|
it('replaces span nodes with different keys inside the same children array', async () => {
|
|
72
72
|
const editorRef: RefObject<PortableTextEditor> = createRef()
|
|
73
|
-
const onChange =
|
|
73
|
+
const onChange = vi.fn()
|
|
74
74
|
const syncedValue = [
|
|
75
75
|
{
|
|
76
76
|
_key: '77071c3af231',
|
|
@@ -107,19 +107,19 @@ describe('useSyncValue', () => {
|
|
|
107
107
|
if (editorRef.current) {
|
|
108
108
|
expect(PortableTextEditor.getValue(editorRef.current))
|
|
109
109
|
.toMatchInlineSnapshot(`
|
|
110
|
-
|
|
111
|
-
|
|
110
|
+
[
|
|
111
|
+
{
|
|
112
112
|
"_key": "77071c3af231",
|
|
113
113
|
"_type": "myTestBlockType",
|
|
114
|
-
"children":
|
|
115
|
-
|
|
114
|
+
"children": [
|
|
115
|
+
{
|
|
116
116
|
"_key": "c001f0e92c1f0__NEW_KEY_YA!",
|
|
117
117
|
"_type": "span",
|
|
118
|
-
"marks":
|
|
118
|
+
"marks": [],
|
|
119
119
|
"text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. ",
|
|
120
120
|
},
|
|
121
121
|
],
|
|
122
|
-
"markDefs":
|
|
122
|
+
"markDefs": [],
|
|
123
123
|
"style": "normal",
|
|
124
124
|
},
|
|
125
125
|
]
|
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
import {type PortableTextBlock} from '@sanity/types'
|
|
1
|
+
import type {PortableTextBlock} from '@sanity/types'
|
|
3
2
|
import {debounce, isEqual} from 'lodash'
|
|
4
3
|
import {useCallback, useMemo, useRef} from 'react'
|
|
5
4
|
import {Editor, Text, Transforms, type Descendant, type Node} from 'slate'
|
|
6
5
|
import {useSlate} from 'slate-react'
|
|
7
|
-
import {
|
|
8
|
-
type EditorChange,
|
|
9
|
-
type PortableTextSlateEditor,
|
|
10
|
-
} from '../../types/editor'
|
|
6
|
+
import type {PortableTextSlateEditor} from '../../types/editor'
|
|
11
7
|
import {debugWithName} from '../../utils/debug'
|
|
12
8
|
import {validateValue} from '../../utils/validateValue'
|
|
13
9
|
import {toSlateValue, VOID_CHILD_KEY} from '../../utils/values'
|
|
@@ -17,8 +13,9 @@ import {
|
|
|
17
13
|
withRemoteChanges,
|
|
18
14
|
} from '../../utils/withChanges'
|
|
19
15
|
import {withoutPatching} from '../../utils/withoutPatching'
|
|
16
|
+
import type {EditorActor} from '../editor-machine'
|
|
20
17
|
import {withoutSaving} from '../plugins/createWithUndoRedo'
|
|
21
|
-
import
|
|
18
|
+
import type {PortableTextEditor} from '../PortableTextEditor'
|
|
22
19
|
|
|
23
20
|
const debug = debugWithName('hook:useSyncValue')
|
|
24
21
|
|
|
@@ -26,8 +23,8 @@ const debug = debugWithName('hook:useSyncValue')
|
|
|
26
23
|
* @internal
|
|
27
24
|
*/
|
|
28
25
|
export interface UseSyncValueProps {
|
|
26
|
+
editorActor: EditorActor
|
|
29
27
|
keyGenerator: () => string
|
|
30
|
-
onChange: (change: EditorChange) => void
|
|
31
28
|
portableTextEditor: PortableTextEditor
|
|
32
29
|
readOnly: boolean
|
|
33
30
|
}
|
|
@@ -55,8 +52,8 @@ export function useSyncValue(
|
|
|
55
52
|
value: PortableTextBlock[] | undefined,
|
|
56
53
|
userCallbackFn?: () => void,
|
|
57
54
|
) => void {
|
|
58
|
-
const {portableTextEditor, readOnly, keyGenerator} = props
|
|
59
|
-
const {
|
|
55
|
+
const {editorActor, portableTextEditor, readOnly, keyGenerator} = props
|
|
56
|
+
const {schemaTypes} = portableTextEditor
|
|
60
57
|
const previousValue = useRef<PortableTextBlock[] | undefined>()
|
|
61
58
|
const slateEditor = useSlate()
|
|
62
59
|
const updateValueFunctionRef =
|
|
@@ -184,7 +181,7 @@ export function useSyncValue(
|
|
|
184
181
|
`${validation.resolution.action} for block with _key '${validationValue[0]._key}'. ${validation.resolution?.description}`,
|
|
185
182
|
)
|
|
186
183
|
validation.resolution.patches.forEach((patch) => {
|
|
187
|
-
|
|
184
|
+
editorActor.send({type: 'patch', patch})
|
|
188
185
|
})
|
|
189
186
|
}
|
|
190
187
|
}
|
|
@@ -212,8 +209,8 @@ export function useSyncValue(
|
|
|
212
209
|
}
|
|
213
210
|
isChanged = true
|
|
214
211
|
} else {
|
|
215
|
-
|
|
216
|
-
type: '
|
|
212
|
+
editorActor.send({
|
|
213
|
+
type: 'invalid value',
|
|
217
214
|
resolution: validation.resolution,
|
|
218
215
|
value,
|
|
219
216
|
})
|
|
@@ -241,8 +238,8 @@ export function useSyncValue(
|
|
|
241
238
|
})
|
|
242
239
|
} else {
|
|
243
240
|
debug('Invalid', validation)
|
|
244
|
-
|
|
245
|
-
type: '
|
|
241
|
+
editorActor.send({
|
|
242
|
+
type: 'invalid value',
|
|
246
243
|
resolution: validation.resolution,
|
|
247
244
|
value,
|
|
248
245
|
})
|
|
@@ -267,8 +264,8 @@ export function useSyncValue(
|
|
|
267
264
|
slateEditor.onChange()
|
|
268
265
|
} catch (err) {
|
|
269
266
|
console.error(err)
|
|
270
|
-
|
|
271
|
-
type: '
|
|
267
|
+
editorActor.send({
|
|
268
|
+
type: 'invalid value',
|
|
272
269
|
resolution: null,
|
|
273
270
|
value,
|
|
274
271
|
})
|
|
@@ -281,7 +278,7 @@ export function useSyncValue(
|
|
|
281
278
|
})
|
|
282
279
|
slateEditor.onChange()
|
|
283
280
|
}
|
|
284
|
-
|
|
281
|
+
editorActor.send({type: 'value changed', value})
|
|
285
282
|
} else {
|
|
286
283
|
debug('Server value and editor value is equal, no need to sync.')
|
|
287
284
|
}
|
|
@@ -290,7 +287,7 @@ export function useSyncValue(
|
|
|
290
287
|
updateValueFunctionRef.current = updateFunction
|
|
291
288
|
return updateFunction
|
|
292
289
|
}, [
|
|
293
|
-
|
|
290
|
+
editorActor,
|
|
294
291
|
keyGenerator,
|
|
295
292
|
portableTextEditor,
|
|
296
293
|
readOnly,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type {PortableTextObject} from '@sanity/types'
|
|
2
2
|
import {useCallback, type ReactNode} from 'react'
|
|
3
3
|
|
|
4
4
|
type Props = {
|
|
@@ -7,7 +7,6 @@ type Props = {
|
|
|
7
7
|
}
|
|
8
8
|
export function DefaultAnnotation(props: Props) {
|
|
9
9
|
const handleClick = useCallback(
|
|
10
|
-
// eslint-disable-next-line no-alert
|
|
11
10
|
() => alert(JSON.stringify(props.annotation)),
|
|
12
11
|
[props.annotation],
|
|
13
12
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {describe, expect, it} from '@jest/globals'
|
|
2
1
|
import {isPortableTextSpan, isPortableTextTextBlock} from '@sanity/types'
|
|
3
|
-
import
|
|
2
|
+
import type {Descendant} from 'slate'
|
|
3
|
+
import {describe, expect, it} from 'vitest'
|
|
4
4
|
import {exportedForTesting} from '../createWithInsertData'
|
|
5
5
|
|
|
6
6
|
const initialValue = [
|
|
@@ -60,14 +60,12 @@ describe('plugin: createWithInsertData _regenerateKeys', () => {
|
|
|
60
60
|
name: 'color',
|
|
61
61
|
jsonType: 'object',
|
|
62
62
|
fields: [],
|
|
63
|
-
// eslint-disable-next-line camelcase
|
|
64
63
|
__experimental_search: [],
|
|
65
64
|
},
|
|
66
65
|
{
|
|
67
66
|
name: 'link',
|
|
68
67
|
jsonType: 'object',
|
|
69
68
|
fields: [],
|
|
70
|
-
// eslint-disable-next-line camelcase
|
|
71
69
|
__experimental_search: [],
|
|
72
70
|
},
|
|
73
71
|
],
|
|
@@ -155,7 +153,6 @@ describe('plugin: createWithInsertData _regenerateKeys', () => {
|
|
|
155
153
|
name: 'color',
|
|
156
154
|
jsonType: 'object',
|
|
157
155
|
fields: [],
|
|
158
|
-
// eslint-disable-next-line camelcase
|
|
159
156
|
__experimental_search: [],
|
|
160
157
|
},
|
|
161
158
|
],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {describe, expect, it, jest} from '@jest/globals'
|
|
2
1
|
import {render, waitFor} from '@testing-library/react'
|
|
3
2
|
import {createRef, type RefObject} from 'react'
|
|
3
|
+
import {describe, expect, it, vi} from 'vitest'
|
|
4
4
|
import {
|
|
5
5
|
PortableTextEditorTester,
|
|
6
6
|
schemaType,
|
|
@@ -46,7 +46,7 @@ const initialSelection = {
|
|
|
46
46
|
describe('plugin:withEditableAPI: .delete()', () => {
|
|
47
47
|
it('deletes block', async () => {
|
|
48
48
|
const editorRef: RefObject<PortableTextEditor> = createRef()
|
|
49
|
-
const onChange =
|
|
49
|
+
const onChange = vi.fn()
|
|
50
50
|
render(
|
|
51
51
|
<PortableTextEditorTester
|
|
52
52
|
onChange={onChange}
|
|
@@ -77,19 +77,19 @@ describe('plugin:withEditableAPI: .delete()', () => {
|
|
|
77
77
|
)
|
|
78
78
|
expect(PortableTextEditor.getValue(editorRef.current))
|
|
79
79
|
.toMatchInlineSnapshot(`
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
[
|
|
81
|
+
{
|
|
82
82
|
"_key": "a",
|
|
83
83
|
"_type": "myTestBlockType",
|
|
84
|
-
"children":
|
|
85
|
-
|
|
84
|
+
"children": [
|
|
85
|
+
{
|
|
86
86
|
"_key": "a1",
|
|
87
87
|
"_type": "span",
|
|
88
|
-
"marks":
|
|
88
|
+
"marks": [],
|
|
89
89
|
"text": "Block A",
|
|
90
90
|
},
|
|
91
91
|
],
|
|
92
|
-
"markDefs":
|
|
92
|
+
"markDefs": [],
|
|
93
93
|
"style": "normal",
|
|
94
94
|
},
|
|
95
95
|
]
|
|
@@ -100,7 +100,7 @@ describe('plugin:withEditableAPI: .delete()', () => {
|
|
|
100
100
|
|
|
101
101
|
it('deletes all the blocks, but leaves a placeholder block', async () => {
|
|
102
102
|
const editorRef: RefObject<PortableTextEditor> = createRef()
|
|
103
|
-
const onChange =
|
|
103
|
+
const onChange = vi.fn()
|
|
104
104
|
render(
|
|
105
105
|
<PortableTextEditorTester
|
|
106
106
|
onChange={onChange}
|
|
@@ -135,19 +135,19 @@ describe('plugin:withEditableAPI: .delete()', () => {
|
|
|
135
135
|
// New keys here confirms that a placeholder block has been created
|
|
136
136
|
expect(PortableTextEditor.getValue(editorRef.current))
|
|
137
137
|
.toMatchInlineSnapshot(`
|
|
138
|
-
|
|
139
|
-
|
|
138
|
+
[
|
|
139
|
+
{
|
|
140
140
|
"_key": "1",
|
|
141
141
|
"_type": "myTestBlockType",
|
|
142
|
-
"children":
|
|
143
|
-
|
|
142
|
+
"children": [
|
|
143
|
+
{
|
|
144
144
|
"_key": "2",
|
|
145
145
|
"_type": "span",
|
|
146
|
-
"marks":
|
|
146
|
+
"marks": [],
|
|
147
147
|
"text": "",
|
|
148
148
|
},
|
|
149
149
|
],
|
|
150
|
-
"markDefs":
|
|
150
|
+
"markDefs": [],
|
|
151
151
|
"style": "normal",
|
|
152
152
|
},
|
|
153
153
|
]
|
|
@@ -158,7 +158,7 @@ describe('plugin:withEditableAPI: .delete()', () => {
|
|
|
158
158
|
|
|
159
159
|
it('deletes children', async () => {
|
|
160
160
|
const editorRef: RefObject<PortableTextEditor> = createRef()
|
|
161
|
-
const onChange =
|
|
161
|
+
const onChange = vi.fn()
|
|
162
162
|
|
|
163
163
|
render(
|
|
164
164
|
<PortableTextEditorTester
|
|
@@ -202,33 +202,33 @@ describe('plugin:withEditableAPI: .delete()', () => {
|
|
|
202
202
|
if (editorRef.current) {
|
|
203
203
|
expect(PortableTextEditor.getValue(editorRef.current))
|
|
204
204
|
.toMatchInlineSnapshot(`
|
|
205
|
-
|
|
206
|
-
|
|
205
|
+
[
|
|
206
|
+
{
|
|
207
207
|
"_key": "a",
|
|
208
208
|
"_type": "myTestBlockType",
|
|
209
|
-
"children":
|
|
210
|
-
|
|
209
|
+
"children": [
|
|
210
|
+
{
|
|
211
211
|
"_key": "a1",
|
|
212
212
|
"_type": "span",
|
|
213
|
-
"marks":
|
|
213
|
+
"marks": [],
|
|
214
214
|
"text": "Block A",
|
|
215
215
|
},
|
|
216
216
|
],
|
|
217
|
-
"markDefs":
|
|
217
|
+
"markDefs": [],
|
|
218
218
|
"style": "normal",
|
|
219
219
|
},
|
|
220
|
-
|
|
220
|
+
{
|
|
221
221
|
"_key": "b",
|
|
222
222
|
"_type": "myTestBlockType",
|
|
223
|
-
"children":
|
|
224
|
-
|
|
223
|
+
"children": [
|
|
224
|
+
{
|
|
225
225
|
"_key": "1",
|
|
226
226
|
"_type": "span",
|
|
227
|
-
"marks":
|
|
227
|
+
"marks": [],
|
|
228
228
|
"text": "",
|
|
229
229
|
},
|
|
230
230
|
],
|
|
231
|
-
"markDefs":
|
|
231
|
+
"markDefs": [],
|
|
232
232
|
"style": "normal",
|
|
233
233
|
},
|
|
234
234
|
]
|
|
@@ -239,7 +239,7 @@ describe('plugin:withEditableAPI: .delete()', () => {
|
|
|
239
239
|
|
|
240
240
|
it('deletes selected', async () => {
|
|
241
241
|
const editorRef: RefObject<PortableTextEditor> = createRef()
|
|
242
|
-
const onChange =
|
|
242
|
+
const onChange = vi.fn()
|
|
243
243
|
|
|
244
244
|
render(
|
|
245
245
|
<PortableTextEditorTester
|