@portabletext/editor 1.0.18 → 1.1.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 +140 -66
- package/lib/index.d.ts +140 -66
- package/lib/index.esm.js +1164 -410
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +1164 -410
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +1164 -410
- package/lib/index.mjs.map +1 -1
- package/package.json +8 -4
- package/src/editor/Editable.tsx +107 -36
- package/src/editor/PortableTextEditor.tsx +47 -12
- package/src/editor/__tests__/PortableTextEditor.test.tsx +42 -15
- package/src/editor/__tests__/PortableTextEditorTester.tsx +50 -38
- package/src/editor/__tests__/RangeDecorations.test.tsx +0 -1
- package/src/editor/__tests__/handleClick.test.tsx +28 -9
- package/src/editor/__tests__/insert-block.test.tsx +22 -6
- package/src/editor/__tests__/pteWarningsSelfSolving.test.tsx +30 -62
- package/src/editor/__tests__/utils.ts +10 -3
- package/src/editor/components/DraggableBlock.tsx +36 -13
- package/src/editor/components/Element.tsx +59 -17
- package/src/editor/components/Leaf.tsx +106 -68
- package/src/editor/components/SlateContainer.tsx +12 -5
- package/src/editor/components/Synchronizer.tsx +5 -2
- package/src/editor/hooks/usePortableTextEditor.ts +2 -2
- package/src/editor/hooks/usePortableTextEditorSelection.tsx +9 -3
- package/src/editor/hooks/useSyncValue.test.tsx +9 -4
- package/src/editor/hooks/useSyncValue.ts +199 -130
- package/src/editor/nodes/DefaultAnnotation.tsx +6 -3
- package/src/editor/plugins/__tests__/createWithInsertData.test.tsx +25 -7
- package/src/editor/plugins/__tests__/withEditableAPIDelete.test.tsx +26 -9
- package/src/editor/plugins/__tests__/withEditableAPIGetFragment.test.tsx +15 -5
- package/src/editor/plugins/__tests__/withEditableAPIInsert.test.tsx +60 -19
- package/src/editor/plugins/__tests__/withEditableAPISelectionsOverlapping.test.tsx +4 -2
- package/src/editor/plugins/__tests__/withPortableTextLists.test.tsx +4 -2
- package/src/editor/plugins/__tests__/withPortableTextMarkModel.test.tsx +61 -550
- package/src/editor/plugins/__tests__/withPortableTextSelections.test.tsx +6 -3
- package/src/editor/plugins/__tests__/withUndoRedo.test.tsx +30 -13
- package/src/editor/plugins/createWithEditableAPI.ts +354 -115
- package/src/editor/plugins/createWithHotKeys.ts +41 -121
- package/src/editor/plugins/createWithInsertBreak.ts +166 -27
- package/src/editor/plugins/createWithInsertData.ts +60 -23
- package/src/editor/plugins/createWithMaxBlocks.ts +5 -2
- package/src/editor/plugins/createWithObjectKeys.ts +7 -3
- package/src/editor/plugins/createWithPatches.ts +60 -16
- package/src/editor/plugins/createWithPlaceholderBlock.ts +7 -3
- package/src/editor/plugins/createWithPortableTextBlockStyle.ts +17 -7
- package/src/editor/plugins/createWithPortableTextLists.ts +21 -8
- package/src/editor/plugins/createWithPortableTextMarkModel.ts +301 -155
- package/src/editor/plugins/createWithPortableTextSelections.ts +4 -2
- package/src/editor/plugins/createWithSchemaTypes.ts +25 -9
- package/src/editor/plugins/createWithUndoRedo.ts +107 -24
- package/src/editor/plugins/createWithUtils.ts +32 -10
- package/src/editor/plugins/index.ts +31 -10
- package/src/types/editor.ts +44 -15
- package/src/types/options.ts +4 -2
- package/src/types/slate.ts +2 -2
- package/src/utils/__tests__/dmpToOperations.test.ts +38 -13
- package/src/utils/__tests__/operationToPatches.test.ts +3 -2
- package/src/utils/__tests__/patchToOperations.test.ts +15 -4
- package/src/utils/__tests__/ranges.test.ts +8 -3
- package/src/utils/__tests__/valueNormalization.test.tsx +12 -4
- package/src/utils/__tests__/values.test.ts +0 -1
- package/src/utils/applyPatch.ts +71 -20
- package/src/utils/getPortableTextMemberSchemaTypes.ts +30 -15
- package/src/utils/operationToPatches.ts +126 -43
- package/src/utils/paths.ts +24 -7
- package/src/utils/ranges.ts +12 -5
- package/src/utils/selection.ts +19 -7
- package/src/utils/validateValue.ts +118 -45
- package/src/utils/values.ts +31 -10
- package/src/utils/weakMaps.ts +18 -8
- package/src/utils/withChanges.ts +4 -2
- package/src/editor/plugins/__tests__/withHotkeys.test.tsx +0 -212
- package/src/editor/plugins/__tests__/withInsertBreak.test.tsx +0 -220
- package/src/editor/plugins/__tests__/withPlaceholderBlock.test.tsx +0 -133
|
@@ -6,10 +6,14 @@ import {
|
|
|
6
6
|
type PortableTextObject,
|
|
7
7
|
type PortableTextTextBlock,
|
|
8
8
|
} from '@sanity/types'
|
|
9
|
-
import {type FunctionComponent, type ReactElement
|
|
10
|
-
import {Editor, Element as SlateElement
|
|
11
|
-
import {
|
|
12
|
-
|
|
9
|
+
import {useMemo, useRef, type FunctionComponent, type ReactElement} from 'react'
|
|
10
|
+
import {Editor, Range, Element as SlateElement} from 'slate'
|
|
11
|
+
import {
|
|
12
|
+
ReactEditor,
|
|
13
|
+
useSelected,
|
|
14
|
+
useSlateStatic,
|
|
15
|
+
type RenderElementProps,
|
|
16
|
+
} from 'slate-react'
|
|
13
17
|
import {
|
|
14
18
|
type BlockRenderProps,
|
|
15
19
|
type PortableTextMemberSchemaTypes,
|
|
@@ -22,7 +26,11 @@ import {debugWithName} from '../../utils/debug'
|
|
|
22
26
|
import {fromSlateValue} from '../../utils/values'
|
|
23
27
|
import {KEY_TO_VALUE_ELEMENT} from '../../utils/weakMaps'
|
|
24
28
|
import ObjectNode from '../nodes/DefaultObject'
|
|
25
|
-
import {
|
|
29
|
+
import {
|
|
30
|
+
DefaultBlockObject,
|
|
31
|
+
DefaultListItem,
|
|
32
|
+
DefaultListItemInner,
|
|
33
|
+
} from '../nodes/index'
|
|
26
34
|
import {DraggableBlock} from './DraggableBlock'
|
|
27
35
|
|
|
28
36
|
const debug = debugWithName('components:Element')
|
|
@@ -67,10 +75,17 @@ export const Element: FunctionComponent<ElementProps> = ({
|
|
|
67
75
|
const selected = useSelected()
|
|
68
76
|
const blockRef = useRef<HTMLDivElement | null>(null)
|
|
69
77
|
const inlineBlockObjectRef = useRef(null)
|
|
70
|
-
const focused =
|
|
78
|
+
const focused =
|
|
79
|
+
(selected && editor.selection && Range.isCollapsed(editor.selection)) ||
|
|
80
|
+
false
|
|
71
81
|
|
|
72
82
|
const value = useMemo(
|
|
73
|
-
() =>
|
|
83
|
+
() =>
|
|
84
|
+
fromSlateValue(
|
|
85
|
+
[element],
|
|
86
|
+
schemaTypes.block.name,
|
|
87
|
+
KEY_TO_VALUE_ELEMENT.get(editor),
|
|
88
|
+
)[0],
|
|
74
89
|
[editor, element, schemaTypes.block.name],
|
|
75
90
|
)
|
|
76
91
|
|
|
@@ -92,12 +107,18 @@ export const Element: FunctionComponent<ElementProps> = ({
|
|
|
92
107
|
if (editor.isInline(element)) {
|
|
93
108
|
const path = ReactEditor.findPath(editor, element)
|
|
94
109
|
const [block] = Editor.node(editor, path, {depth: 1})
|
|
95
|
-
const schemaType = schemaTypes.inlineObjects.find(
|
|
110
|
+
const schemaType = schemaTypes.inlineObjects.find(
|
|
111
|
+
(_type) => _type.name === element._type,
|
|
112
|
+
)
|
|
96
113
|
if (!schemaType) {
|
|
97
114
|
throw new Error('Could not find type for inline block element')
|
|
98
115
|
}
|
|
99
116
|
if (SlateElement.isElement(block)) {
|
|
100
|
-
const elmPath: Path = [
|
|
117
|
+
const elmPath: Path = [
|
|
118
|
+
{_key: block._key},
|
|
119
|
+
'children',
|
|
120
|
+
{_key: element._key},
|
|
121
|
+
]
|
|
101
122
|
if (debugRenders) {
|
|
102
123
|
debug(`Render ${element._key} (inline object)`)
|
|
103
124
|
}
|
|
@@ -144,7 +165,9 @@ export const Element: FunctionComponent<ElementProps> = ({
|
|
|
144
165
|
}
|
|
145
166
|
const style = ('style' in element && element.style) || 'normal'
|
|
146
167
|
className = `pt-block pt-text-block pt-text-block-style-${style}`
|
|
147
|
-
const blockStyleType = schemaTypes.styles.find(
|
|
168
|
+
const blockStyleType = schemaTypes.styles.find(
|
|
169
|
+
(item) => item.value === style,
|
|
170
|
+
)
|
|
148
171
|
if (renderStyle && blockStyleType) {
|
|
149
172
|
renderedBlock = renderStyle({
|
|
150
173
|
block: element as PortableTextTextBlock,
|
|
@@ -165,7 +188,9 @@ export const Element: FunctionComponent<ElementProps> = ({
|
|
|
165
188
|
className += ` pt-list-item pt-list-item-${element.listItem} pt-list-item-level-${level || 1}`
|
|
166
189
|
}
|
|
167
190
|
if (editor.isListBlock(value) && isListItem && element.listItem) {
|
|
168
|
-
const listType = schemaTypes.lists.find(
|
|
191
|
+
const listType = schemaTypes.lists.find(
|
|
192
|
+
(item) => item.value === element.listItem,
|
|
193
|
+
)
|
|
169
194
|
if (renderListItem && listType) {
|
|
170
195
|
renderedBlock = renderListItem({
|
|
171
196
|
block: value,
|
|
@@ -206,7 +231,9 @@ export const Element: FunctionComponent<ElementProps> = ({
|
|
|
206
231
|
{
|
|
207
232
|
enumerable: false,
|
|
208
233
|
get() {
|
|
209
|
-
console.warn(
|
|
234
|
+
console.warn(
|
|
235
|
+
"Property 'type' is deprecated, use 'schemaType' instead.",
|
|
236
|
+
)
|
|
210
237
|
return schemaTypes.block
|
|
211
238
|
},
|
|
212
239
|
},
|
|
@@ -216,16 +243,29 @@ export const Element: FunctionComponent<ElementProps> = ({
|
|
|
216
243
|
? renderBlock(renderProps as BlockRenderProps)
|
|
217
244
|
: children
|
|
218
245
|
return (
|
|
219
|
-
<div
|
|
220
|
-
|
|
246
|
+
<div
|
|
247
|
+
key={element._key}
|
|
248
|
+
{...attributes}
|
|
249
|
+
className={className}
|
|
250
|
+
spellCheck={spellCheck}
|
|
251
|
+
>
|
|
252
|
+
<DraggableBlock
|
|
253
|
+
element={element}
|
|
254
|
+
readOnly={readOnly}
|
|
255
|
+
blockRef={blockRef}
|
|
256
|
+
>
|
|
221
257
|
<div ref={blockRef}>{propsOrDefaultRendered}</div>
|
|
222
258
|
</DraggableBlock>
|
|
223
259
|
</div>
|
|
224
260
|
)
|
|
225
261
|
}
|
|
226
|
-
const schemaType = schemaTypes.blockObjects.find(
|
|
262
|
+
const schemaType = schemaTypes.blockObjects.find(
|
|
263
|
+
(_type) => _type.name === element._type,
|
|
264
|
+
)
|
|
227
265
|
if (!schemaType) {
|
|
228
|
-
throw new Error(
|
|
266
|
+
throw new Error(
|
|
267
|
+
`Could not find schema type for block element of _type ${element._type}`,
|
|
268
|
+
)
|
|
229
269
|
}
|
|
230
270
|
if (debugRenders) {
|
|
231
271
|
debug(`Render ${element._key} (object block)`)
|
|
@@ -252,7 +292,9 @@ export const Element: FunctionComponent<ElementProps> = ({
|
|
|
252
292
|
{
|
|
253
293
|
enumerable: false,
|
|
254
294
|
get() {
|
|
255
|
-
console.warn(
|
|
295
|
+
console.warn(
|
|
296
|
+
"Property 'type' is deprecated, use 'schemaType' instead.",
|
|
297
|
+
)
|
|
256
298
|
return schemaType
|
|
257
299
|
},
|
|
258
300
|
},
|
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
type Path,
|
|
3
|
+
type PortableTextObject,
|
|
4
|
+
type PortableTextTextBlock,
|
|
5
|
+
} from '@sanity/types'
|
|
2
6
|
import {isEqual, uniq} from 'lodash'
|
|
3
7
|
import {
|
|
4
|
-
type ReactElement,
|
|
5
8
|
startTransition,
|
|
6
9
|
useCallback,
|
|
7
10
|
useEffect,
|
|
8
11
|
useMemo,
|
|
9
12
|
useRef,
|
|
10
13
|
useState,
|
|
14
|
+
type ReactElement,
|
|
11
15
|
} from 'react'
|
|
12
16
|
import {Text} from 'slate'
|
|
13
|
-
import {type RenderLeafProps
|
|
14
|
-
|
|
17
|
+
import {useSelected, type RenderLeafProps} from 'slate-react'
|
|
15
18
|
import {
|
|
16
19
|
type BlockAnnotationRenderProps,
|
|
17
20
|
type BlockChildRenderProps,
|
|
@@ -47,8 +50,15 @@ export interface LeafProps extends RenderLeafProps {
|
|
|
47
50
|
* @internal
|
|
48
51
|
*/
|
|
49
52
|
export const Leaf = (props: LeafProps) => {
|
|
50
|
-
const {
|
|
51
|
-
|
|
53
|
+
const {
|
|
54
|
+
attributes,
|
|
55
|
+
children,
|
|
56
|
+
leaf,
|
|
57
|
+
schemaTypes,
|
|
58
|
+
renderChild,
|
|
59
|
+
renderDecorator,
|
|
60
|
+
renderAnnotation,
|
|
61
|
+
} = props
|
|
52
62
|
const spanRef = useRef<HTMLElement>(null)
|
|
53
63
|
const portableTextEditor = usePortableTextEditor()
|
|
54
64
|
const blockSelected = useSelected()
|
|
@@ -64,7 +74,12 @@ export const Leaf = (props: LeafProps) => {
|
|
|
64
74
|
[schemaTypes.decorators],
|
|
65
75
|
)
|
|
66
76
|
const marks: string[] = useMemo(
|
|
67
|
-
() =>
|
|
77
|
+
() =>
|
|
78
|
+
uniq(
|
|
79
|
+
(leaf.marks || EMPTY_MARKS).filter((mark) =>
|
|
80
|
+
decoratorValues.includes(mark),
|
|
81
|
+
),
|
|
82
|
+
),
|
|
68
83
|
[decoratorValues, leaf.marks],
|
|
69
84
|
)
|
|
70
85
|
const annotationMarks = Array.isArray(leaf.marks) ? leaf.marks : EMPTY_MARKS
|
|
@@ -73,7 +88,8 @@ export const Leaf = (props: LeafProps) => {
|
|
|
73
88
|
annotationMarks
|
|
74
89
|
.map(
|
|
75
90
|
(mark) =>
|
|
76
|
-
!decoratorValues.includes(mark) &&
|
|
91
|
+
!decoratorValues.includes(mark) &&
|
|
92
|
+
block?.markDefs?.find((def) => def._key === mark),
|
|
77
93
|
)
|
|
78
94
|
.filter(Boolean) as PortableTextObject[],
|
|
79
95
|
[annotationMarks, block, decoratorValues],
|
|
@@ -159,7 +175,12 @@ export const Leaf = (props: LeafProps) => {
|
|
|
159
175
|
return () => {
|
|
160
176
|
sub.unsubscribe()
|
|
161
177
|
}
|
|
162
|
-
}, [
|
|
178
|
+
}, [
|
|
179
|
+
path,
|
|
180
|
+
portableTextEditor,
|
|
181
|
+
setSelectedFromRange,
|
|
182
|
+
shouldTrackSelectionAndFocus,
|
|
183
|
+
])
|
|
163
184
|
|
|
164
185
|
useEffect(() => setSelectedFromRange(), [setSelectedFromRange])
|
|
165
186
|
|
|
@@ -168,59 +189,73 @@ export const Leaf = (props: LeafProps) => {
|
|
|
168
189
|
// Render text nodes
|
|
169
190
|
if (Text.isText(leaf) && leaf._type === schemaTypes.span.name) {
|
|
170
191
|
marks.forEach((mark) => {
|
|
171
|
-
const schemaType = schemaTypes.decorators.find(
|
|
192
|
+
const schemaType = schemaTypes.decorators.find(
|
|
193
|
+
(dec) => dec.value === mark,
|
|
194
|
+
)
|
|
172
195
|
if (schemaType && renderDecorator) {
|
|
173
|
-
const _props: Omit<BlockDecoratorRenderProps, 'type'> =
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
196
|
+
const _props: Omit<BlockDecoratorRenderProps, 'type'> =
|
|
197
|
+
Object.defineProperty(
|
|
198
|
+
{
|
|
199
|
+
children: returnedChildren,
|
|
200
|
+
editorElementRef: spanRef,
|
|
201
|
+
focused,
|
|
202
|
+
path,
|
|
203
|
+
selected,
|
|
204
|
+
schemaType,
|
|
205
|
+
value: mark,
|
|
206
|
+
},
|
|
207
|
+
'type',
|
|
208
|
+
{
|
|
209
|
+
enumerable: false,
|
|
210
|
+
get() {
|
|
211
|
+
console.warn(
|
|
212
|
+
"Property 'type' is deprecated, use 'schemaType' instead.",
|
|
213
|
+
)
|
|
214
|
+
return schemaType
|
|
215
|
+
},
|
|
189
216
|
},
|
|
190
|
-
|
|
217
|
+
)
|
|
218
|
+
returnedChildren = renderDecorator(
|
|
219
|
+
_props as BlockDecoratorRenderProps,
|
|
191
220
|
)
|
|
192
|
-
returnedChildren = renderDecorator(_props as BlockDecoratorRenderProps)
|
|
193
221
|
}
|
|
194
222
|
})
|
|
195
223
|
|
|
196
224
|
if (block && annotations.length > 0) {
|
|
197
225
|
annotations.forEach((annotation) => {
|
|
198
|
-
const schemaType = schemaTypes.annotations.find(
|
|
226
|
+
const schemaType = schemaTypes.annotations.find(
|
|
227
|
+
(t) => t.name === annotation._type,
|
|
228
|
+
)
|
|
199
229
|
if (schemaType) {
|
|
200
230
|
if (renderAnnotation) {
|
|
201
|
-
const _props: Omit<BlockAnnotationRenderProps, 'type'> =
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
'type',
|
|
213
|
-
{
|
|
214
|
-
enumerable: false,
|
|
215
|
-
get() {
|
|
216
|
-
console.warn("Property 'type' is deprecated, use 'schemaType' instead.")
|
|
217
|
-
return schemaType
|
|
231
|
+
const _props: Omit<BlockAnnotationRenderProps, 'type'> =
|
|
232
|
+
Object.defineProperty(
|
|
233
|
+
{
|
|
234
|
+
block,
|
|
235
|
+
children: returnedChildren,
|
|
236
|
+
editorElementRef: spanRef,
|
|
237
|
+
focused,
|
|
238
|
+
path,
|
|
239
|
+
selected,
|
|
240
|
+
schemaType,
|
|
241
|
+
value: annotation,
|
|
218
242
|
},
|
|
219
|
-
|
|
220
|
-
|
|
243
|
+
'type',
|
|
244
|
+
{
|
|
245
|
+
enumerable: false,
|
|
246
|
+
get() {
|
|
247
|
+
console.warn(
|
|
248
|
+
"Property 'type' is deprecated, use 'schemaType' instead.",
|
|
249
|
+
)
|
|
250
|
+
return schemaType
|
|
251
|
+
},
|
|
252
|
+
},
|
|
253
|
+
)
|
|
221
254
|
|
|
222
255
|
returnedChildren = (
|
|
223
|
-
<span ref={spanRef}>
|
|
256
|
+
<span ref={spanRef}>
|
|
257
|
+
{renderAnnotation(_props as BlockAnnotationRenderProps)}
|
|
258
|
+
</span>
|
|
224
259
|
)
|
|
225
260
|
} else {
|
|
226
261
|
returnedChildren = (
|
|
@@ -236,26 +271,29 @@ export const Leaf = (props: LeafProps) => {
|
|
|
236
271
|
const child = block.children.find((_child) => _child._key === leaf._key) // Ensure object equality
|
|
237
272
|
if (child) {
|
|
238
273
|
const defaultRendered = <>{returnedChildren}</>
|
|
239
|
-
const _props: Omit<BlockChildRenderProps, 'type'> =
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
'type',
|
|
251
|
-
{
|
|
252
|
-
enumerable: false,
|
|
253
|
-
get() {
|
|
254
|
-
console.warn("Property 'type' is deprecated, use 'schemaType' instead.")
|
|
255
|
-
return schemaTypes.span
|
|
274
|
+
const _props: Omit<BlockChildRenderProps, 'type'> =
|
|
275
|
+
Object.defineProperty(
|
|
276
|
+
{
|
|
277
|
+
annotations,
|
|
278
|
+
children: defaultRendered,
|
|
279
|
+
editorElementRef: spanRef,
|
|
280
|
+
focused,
|
|
281
|
+
path,
|
|
282
|
+
schemaType: schemaTypes.span,
|
|
283
|
+
selected,
|
|
284
|
+
value: child,
|
|
256
285
|
},
|
|
257
|
-
|
|
258
|
-
|
|
286
|
+
'type',
|
|
287
|
+
{
|
|
288
|
+
enumerable: false,
|
|
289
|
+
get() {
|
|
290
|
+
console.warn(
|
|
291
|
+
"Property 'type' is deprecated, use 'schemaType' instead.",
|
|
292
|
+
)
|
|
293
|
+
return schemaTypes.span
|
|
294
|
+
},
|
|
295
|
+
},
|
|
296
|
+
)
|
|
259
297
|
returnedChildren = renderChild(_props as BlockChildRenderProps)
|
|
260
298
|
}
|
|
261
299
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {useEffect, useMemo, useState, type PropsWithChildren} from 'react'
|
|
2
2
|
import {createEditor} from 'slate'
|
|
3
3
|
import {Slate, withReact} from 'slate-react'
|
|
4
|
-
|
|
5
4
|
import {type PatchObservable} from '../../types/editor'
|
|
6
5
|
import {debugWithName} from '../../utils/debug'
|
|
7
6
|
import {KEY_TO_SLATE_ELEMENT, KEY_TO_VALUE_ELEMENT} from '../../utils/weakMaps'
|
|
@@ -26,7 +25,8 @@ export interface SlateContainerProps extends PropsWithChildren {
|
|
|
26
25
|
* @internal
|
|
27
26
|
*/
|
|
28
27
|
export function SlateContainer(props: SlateContainerProps) {
|
|
29
|
-
const {patches$, portableTextEditor, readOnly, maxBlocks, keyGenerator} =
|
|
28
|
+
const {patches$, portableTextEditor, readOnly, maxBlocks, keyGenerator} =
|
|
29
|
+
props
|
|
30
30
|
|
|
31
31
|
// Create the slate instance, using `useState` ensures setup is only run once, initially
|
|
32
32
|
const [[slateEditor, subscribe]] = useState(() => {
|
|
@@ -60,10 +60,17 @@ export function SlateContainer(props: SlateContainerProps) {
|
|
|
60
60
|
portableTextEditor,
|
|
61
61
|
readOnly,
|
|
62
62
|
})
|
|
63
|
-
}, [
|
|
63
|
+
}, [
|
|
64
|
+
keyGenerator,
|
|
65
|
+
portableTextEditor,
|
|
66
|
+
maxBlocks,
|
|
67
|
+
readOnly,
|
|
68
|
+
patches$,
|
|
69
|
+
slateEditor,
|
|
70
|
+
])
|
|
64
71
|
|
|
65
72
|
const initialValue = useMemo(() => {
|
|
66
|
-
return [slateEditor.
|
|
73
|
+
return [slateEditor.pteCreateTextBlock({decorators: []})]
|
|
67
74
|
}, [slateEditor])
|
|
68
75
|
|
|
69
76
|
useEffect(() => {
|
|
@@ -4,7 +4,6 @@ import {throttle} from 'lodash'
|
|
|
4
4
|
import {useCallback, useEffect, useMemo, useRef} from 'react'
|
|
5
5
|
import {Editor} from 'slate'
|
|
6
6
|
import {useSlate} from 'slate-react'
|
|
7
|
-
|
|
8
7
|
import {type EditorChange, type EditorChanges} from '../../types/editor'
|
|
9
8
|
import {debugWithName} from '../../utils/debug'
|
|
10
9
|
import {IS_PROCESSING_LOCAL_CHANGES} from '../../utils/weakMaps'
|
|
@@ -61,7 +60,11 @@ export function Synchronizer(props: SynchronizerProps) {
|
|
|
61
60
|
debug(`Patches:\n${JSON.stringify(pendingPatches.current, null, 2)}`)
|
|
62
61
|
}
|
|
63
62
|
const snapshot = getValue()
|
|
64
|
-
change$.next({
|
|
63
|
+
change$.next({
|
|
64
|
+
type: 'mutation',
|
|
65
|
+
patches: pendingPatches.current,
|
|
66
|
+
snapshot,
|
|
67
|
+
})
|
|
65
68
|
pendingPatches.current = []
|
|
66
69
|
}
|
|
67
70
|
IS_PROCESSING_LOCAL_CHANGES.set(slateEditor, false)
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {createContext, useContext} from 'react'
|
|
2
|
-
|
|
3
2
|
import {type PortableTextEditor} from '../PortableTextEditor'
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
5
|
* A React context for sharing the editor object.
|
|
7
6
|
*/
|
|
8
|
-
export const PortableTextEditorContext =
|
|
7
|
+
export const PortableTextEditorContext =
|
|
8
|
+
createContext<PortableTextEditor | null>(null)
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* @public
|
|
@@ -1,12 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
createContext,
|
|
3
|
+
startTransition,
|
|
4
|
+
useContext,
|
|
5
|
+
useEffect,
|
|
6
|
+
useState,
|
|
7
|
+
} from 'react'
|
|
3
8
|
import {type EditorChanges, type EditorSelection} from '../../types/editor'
|
|
4
9
|
import {debugWithName} from '../../utils/debug'
|
|
5
10
|
|
|
6
11
|
/**
|
|
7
12
|
* A React context for sharing the editor selection.
|
|
8
13
|
*/
|
|
9
|
-
const PortableTextEditorSelectionContext =
|
|
14
|
+
const PortableTextEditorSelectionContext =
|
|
15
|
+
createContext<EditorSelection | null>(null)
|
|
10
16
|
|
|
11
17
|
/**
|
|
12
18
|
* @public
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import {describe, expect, it, jest} from '@jest/globals'
|
|
2
2
|
import {render, waitFor} from '@testing-library/react'
|
|
3
3
|
import {createRef, type RefObject} from 'react'
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
import {
|
|
5
|
+
PortableTextEditorTester,
|
|
6
|
+
schemaType,
|
|
7
|
+
} from '../__tests__/PortableTextEditorTester'
|
|
6
8
|
import {PortableTextEditor} from '../PortableTextEditor'
|
|
7
9
|
|
|
8
10
|
const initialValue = [
|
|
@@ -60,7 +62,9 @@ describe('useSyncValue', () => {
|
|
|
60
62
|
)
|
|
61
63
|
await waitFor(() => {
|
|
62
64
|
if (editorRef.current) {
|
|
63
|
-
expect(PortableTextEditor.getValue(editorRef.current)).toEqual(
|
|
65
|
+
expect(PortableTextEditor.getValue(editorRef.current)).toEqual(
|
|
66
|
+
syncedValue,
|
|
67
|
+
)
|
|
64
68
|
}
|
|
65
69
|
})
|
|
66
70
|
})
|
|
@@ -101,7 +105,8 @@ describe('useSyncValue', () => {
|
|
|
101
105
|
)
|
|
102
106
|
await waitFor(() => {
|
|
103
107
|
if (editorRef.current) {
|
|
104
|
-
expect(PortableTextEditor.getValue(editorRef.current))
|
|
108
|
+
expect(PortableTextEditor.getValue(editorRef.current))
|
|
109
|
+
.toMatchInlineSnapshot(`
|
|
105
110
|
Array [
|
|
106
111
|
Object {
|
|
107
112
|
"_key": "77071c3af231",
|