@portabletext/editor 2.8.1 → 2.8.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/lib/_chunks-dts/behavior.types.action.d.cts +82 -86
- package/lib/_chunks-dts/behavior.types.action.d.ts +27 -31
- package/lib/index.cjs +28 -41
- package/lib/index.cjs.map +1 -1
- package/lib/index.js +28 -41
- package/lib/index.js.map +1 -1
- package/lib/plugins/index.d.cts +3 -3
- package/lib/plugins/index.d.ts +3 -3
- package/package.json +3 -3
- package/src/editor/PortableTextEditor.tsx +1 -1
- package/src/editor/plugins/createWithEditableAPI.ts +70 -28
- package/src/index.ts +1 -1
- package/src/operations/behavior.operation.annotation.add.ts +1 -46
- package/src/operations/behavior.operations.ts +1 -2
- package/src/types/editor.ts +19 -3
package/lib/plugins/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Behavior, Editor, EditorEmittedEvent, EditorSchema } from "../_chunks-dts/behavior.types.action.cjs";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react12 from "react";
|
|
3
3
|
import React from "react";
|
|
4
4
|
/**
|
|
5
5
|
* @beta
|
|
@@ -181,7 +181,7 @@ type MarkdownPluginConfig = MarkdownBehaviorsConfig & {
|
|
|
181
181
|
*/
|
|
182
182
|
declare function MarkdownPlugin(props: {
|
|
183
183
|
config: MarkdownPluginConfig;
|
|
184
|
-
}):
|
|
184
|
+
}): react12.JSX.Element;
|
|
185
185
|
/**
|
|
186
186
|
* @beta
|
|
187
187
|
* Restrict the editor to one line. The plugin takes care of blocking
|
|
@@ -192,5 +192,5 @@ declare function MarkdownPlugin(props: {
|
|
|
192
192
|
*
|
|
193
193
|
* @deprecated Install the plugin from `@portabletext/plugin-one-line`
|
|
194
194
|
*/
|
|
195
|
-
declare function OneLinePlugin():
|
|
195
|
+
declare function OneLinePlugin(): react12.JSX.Element;
|
|
196
196
|
export { BehaviorPlugin, DecoratorShortcutPlugin, EditorRefPlugin, EventListenerPlugin, MarkdownPlugin, type MarkdownPluginConfig, OneLinePlugin };
|
package/lib/plugins/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Behavior, Editor, EditorEmittedEvent, EditorSchema } from "../_chunks-dts/behavior.types.action.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react22 from "react";
|
|
3
3
|
import React from "react";
|
|
4
4
|
/**
|
|
5
5
|
* @beta
|
|
@@ -181,7 +181,7 @@ type MarkdownPluginConfig = MarkdownBehaviorsConfig & {
|
|
|
181
181
|
*/
|
|
182
182
|
declare function MarkdownPlugin(props: {
|
|
183
183
|
config: MarkdownPluginConfig;
|
|
184
|
-
}):
|
|
184
|
+
}): react22.JSX.Element;
|
|
185
185
|
/**
|
|
186
186
|
* @beta
|
|
187
187
|
* Restrict the editor to one line. The plugin takes care of blocking
|
|
@@ -192,5 +192,5 @@ declare function MarkdownPlugin(props: {
|
|
|
192
192
|
*
|
|
193
193
|
* @deprecated Install the plugin from `@portabletext/plugin-one-line`
|
|
194
194
|
*/
|
|
195
|
-
declare function OneLinePlugin():
|
|
195
|
+
declare function OneLinePlugin(): react22.JSX.Element;
|
|
196
196
|
export { BehaviorPlugin, DecoratorShortcutPlugin, EditorRefPlugin, EventListenerPlugin, MarkdownPlugin, type MarkdownPluginConfig, OneLinePlugin };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@portabletext/editor",
|
|
3
|
-
"version": "2.8.
|
|
3
|
+
"version": "2.8.2",
|
|
4
4
|
"description": "Portable Text Editor made in React",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sanity",
|
|
@@ -81,8 +81,8 @@
|
|
|
81
81
|
"xstate": "^5.21.0",
|
|
82
82
|
"@portabletext/block-tools": "^3.5.3",
|
|
83
83
|
"@portabletext/keyboard-shortcuts": "^1.1.1",
|
|
84
|
-
"@portabletext/
|
|
85
|
-
"@portabletext/
|
|
84
|
+
"@portabletext/schema": "^1.2.0",
|
|
85
|
+
"@portabletext/patches": "^1.1.8"
|
|
86
86
|
},
|
|
87
87
|
"devDependencies": {
|
|
88
88
|
"@sanity/diff-match-patch": "^3.2.0",
|
|
@@ -16,8 +16,8 @@ import {Subject} from 'rxjs'
|
|
|
16
16
|
import {Slate} from 'slate-react'
|
|
17
17
|
import {debugWithName} from '../internal-utils/debug'
|
|
18
18
|
import {stopActor} from '../internal-utils/stop-actor'
|
|
19
|
-
import type {AddedAnnotationPaths} from '../operations/behavior.operation.annotation.add'
|
|
20
19
|
import type {
|
|
20
|
+
AddedAnnotationPaths,
|
|
21
21
|
EditableAPI,
|
|
22
22
|
EditableAPIDeleteOptions,
|
|
23
23
|
EditorChange,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {isTextBlock} from '@portabletext/schema'
|
|
1
2
|
import type {
|
|
2
3
|
Path,
|
|
3
4
|
PortableTextBlock,
|
|
@@ -29,8 +30,12 @@ import {
|
|
|
29
30
|
KEY_TO_VALUE_ELEMENT,
|
|
30
31
|
SLATE_TO_PORTABLE_TEXT_RANGE,
|
|
31
32
|
} from '../../internal-utils/weakMaps'
|
|
32
|
-
import {
|
|
33
|
-
|
|
33
|
+
import {
|
|
34
|
+
getFocusBlock,
|
|
35
|
+
getFocusSpan,
|
|
36
|
+
getSelectedValue,
|
|
37
|
+
isActiveAnnotation,
|
|
38
|
+
} from '../../selectors'
|
|
34
39
|
import {getActiveAnnotationsMarks} from '../../selectors/selector.get-active-annotation-marks'
|
|
35
40
|
import {getActiveDecorators} from '../../selectors/selector.get-active-decorators'
|
|
36
41
|
import type {
|
|
@@ -424,40 +429,77 @@ export function createEditableAPI(
|
|
|
424
429
|
return isActiveAnnotation(annotationType)(snapshot)
|
|
425
430
|
},
|
|
426
431
|
addAnnotation: (type, value) => {
|
|
427
|
-
|
|
432
|
+
const snapshotBefore = getEditorSnapshot({
|
|
433
|
+
editorActorSnapshot: editorActor.getSnapshot(),
|
|
434
|
+
slateEditorInstance: editor,
|
|
435
|
+
})
|
|
436
|
+
const selectedValueBefore = getSelectedValue(snapshotBefore)
|
|
437
|
+
const focusSpanBefore = getFocusSpan(snapshotBefore)
|
|
438
|
+
const markDefsBefore = selectedValueBefore.flatMap((block) => {
|
|
439
|
+
if (isTextBlock(snapshotBefore.context, block)) {
|
|
440
|
+
return block.markDefs ?? []
|
|
441
|
+
}
|
|
428
442
|
|
|
429
|
-
|
|
443
|
+
return []
|
|
444
|
+
})
|
|
445
|
+
|
|
446
|
+
editorActor.send({
|
|
447
|
+
type: 'behavior event',
|
|
448
|
+
behaviorEvent: {
|
|
449
|
+
type: 'annotation.add',
|
|
450
|
+
annotation: {name: type.name, value: value ?? {}},
|
|
451
|
+
},
|
|
452
|
+
editor,
|
|
453
|
+
})
|
|
454
|
+
|
|
455
|
+
const snapshotAfter = getEditorSnapshot({
|
|
430
456
|
editorActorSnapshot: editorActor.getSnapshot(),
|
|
431
457
|
slateEditorInstance: editor,
|
|
432
458
|
})
|
|
433
459
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
behaviorEvent: {
|
|
438
|
-
type: 'annotation.remove',
|
|
439
|
-
annotation: {name: type.name},
|
|
440
|
-
},
|
|
441
|
-
editor,
|
|
442
|
-
})
|
|
443
|
-
}
|
|
460
|
+
const selectedValueAfter = getSelectedValue(snapshotAfter)
|
|
461
|
+
const focusBlockAfter = getFocusBlock(snapshotAfter)
|
|
462
|
+
const focusSpanAfter = getFocusSpan(snapshotAfter)
|
|
444
463
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
464
|
+
const newMarkDefKeysOnFocusSpan = focusSpanAfter?.node.marks?.filter(
|
|
465
|
+
(mark) =>
|
|
466
|
+
!focusSpanBefore?.node.marks?.includes(mark) &&
|
|
467
|
+
!snapshotAfter.context.schema.decorators
|
|
468
|
+
.map((decorator) => decorator.name)
|
|
469
|
+
.includes(mark),
|
|
470
|
+
)
|
|
471
|
+
const markDefsAfter = selectedValueAfter.flatMap((block) => {
|
|
472
|
+
if (isTextBlock(snapshotAfter.context, block)) {
|
|
473
|
+
return (
|
|
474
|
+
block.markDefs?.map((markDef) => ({
|
|
475
|
+
markDef,
|
|
476
|
+
path: [{_key: block._key}, 'markDefs', {_key: markDef._key}],
|
|
477
|
+
})) ?? []
|
|
478
|
+
)
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
return []
|
|
457
482
|
})
|
|
458
|
-
|
|
483
|
+
const markDefs = markDefsAfter.filter(
|
|
484
|
+
(markDef) =>
|
|
485
|
+
!markDefsBefore.some(
|
|
486
|
+
(markDefBefore) => markDefBefore._key === markDef.markDef._key,
|
|
487
|
+
),
|
|
488
|
+
)
|
|
489
|
+
const spanPath = focusSpanAfter?.path
|
|
490
|
+
const markDef = markDefs.find((markDef) =>
|
|
491
|
+
newMarkDefKeysOnFocusSpan?.some(
|
|
492
|
+
(mark) => mark === markDef.markDef._key,
|
|
493
|
+
),
|
|
494
|
+
)
|
|
459
495
|
|
|
460
|
-
|
|
496
|
+
if (focusBlockAfter && spanPath && markDef) {
|
|
497
|
+
return {
|
|
498
|
+
markDefPath: markDef.path,
|
|
499
|
+
markDefPaths: markDefs.map((markDef) => markDef.path),
|
|
500
|
+
spanPath,
|
|
501
|
+
}
|
|
502
|
+
}
|
|
461
503
|
},
|
|
462
504
|
delete: (
|
|
463
505
|
selection: EditorSelection,
|
package/src/index.ts
CHANGED
|
@@ -45,7 +45,7 @@ export {PortableTextEditor} from './editor/PortableTextEditor'
|
|
|
45
45
|
export type {PortableTextEditorProps} from './editor/PortableTextEditor'
|
|
46
46
|
export type {EditorEmittedEvent, MutationEvent} from './editor/relay-machine'
|
|
47
47
|
export {useEditor} from './editor/use-editor'
|
|
48
|
-
export type {AddedAnnotationPaths} from './
|
|
48
|
+
export type {AddedAnnotationPaths} from './types/editor'
|
|
49
49
|
export type {BlockOffset} from './types/block-offset'
|
|
50
50
|
export type {
|
|
51
51
|
BlockAnnotationRenderProps,
|
|
@@ -1,29 +1,9 @@
|
|
|
1
|
-
import type {Path} from '@sanity/types'
|
|
2
1
|
import {Editor, Node, Range, Text, Transforms} from 'slate'
|
|
3
2
|
import {parseAnnotation} from '../internal-utils/parse-blocks'
|
|
4
3
|
import type {BehaviorOperationImplementation} from './behavior.operations'
|
|
5
4
|
|
|
6
|
-
/**
|
|
7
|
-
* @public
|
|
8
|
-
*/
|
|
9
|
-
export type AddedAnnotationPaths = {
|
|
10
|
-
/**
|
|
11
|
-
* @deprecated An annotation may be applied to multiple blocks, resulting
|
|
12
|
-
* in multiple `markDef`'s being created. Use `markDefPaths` instead.
|
|
13
|
-
*/
|
|
14
|
-
markDefPath: Path
|
|
15
|
-
markDefPaths: Array<Path>
|
|
16
|
-
/**
|
|
17
|
-
* @deprecated Does not return anything meaningful since an annotation
|
|
18
|
-
* can span multiple blocks and spans. If references the span closest
|
|
19
|
-
* to the focus point of the selection.
|
|
20
|
-
*/
|
|
21
|
-
spanPath: Path
|
|
22
|
-
}
|
|
23
|
-
|
|
24
5
|
export const addAnnotationOperationImplementation: BehaviorOperationImplementation<
|
|
25
|
-
'annotation.add'
|
|
26
|
-
AddedAnnotationPaths | undefined
|
|
6
|
+
'annotation.add'
|
|
27
7
|
> = ({context, operation}) => {
|
|
28
8
|
const parsedAnnotation = parseAnnotation({
|
|
29
9
|
annotation: {
|
|
@@ -46,11 +26,6 @@ export const addAnnotationOperationImplementation: BehaviorOperationImplementati
|
|
|
46
26
|
return
|
|
47
27
|
}
|
|
48
28
|
|
|
49
|
-
let paths: AddedAnnotationPaths | undefined
|
|
50
|
-
let spanPath: Path | undefined
|
|
51
|
-
let markDefPath: Path | undefined
|
|
52
|
-
const markDefPaths: Path[] = []
|
|
53
|
-
|
|
54
29
|
const selectedBlocks = Editor.nodes(editor, {
|
|
55
30
|
at: editor.selection,
|
|
56
31
|
match: (node) => editor.isTextBlock(node),
|
|
@@ -92,14 +67,6 @@ export const addAnnotationOperationImplementation: BehaviorOperationImplementati
|
|
|
92
67
|
},
|
|
93
68
|
{at: blockPath},
|
|
94
69
|
)
|
|
95
|
-
|
|
96
|
-
markDefPath = [{_key: block._key}, 'markDefs', {_key: annotationKey}]
|
|
97
|
-
|
|
98
|
-
if (Range.isBackward(editor.selection)) {
|
|
99
|
-
markDefPaths.unshift(markDefPath)
|
|
100
|
-
} else {
|
|
101
|
-
markDefPaths.push(markDefPath)
|
|
102
|
-
}
|
|
103
70
|
}
|
|
104
71
|
|
|
105
72
|
Transforms.setNodes(editor, {}, {match: Text.isText, split: true})
|
|
@@ -124,20 +91,8 @@ export const addAnnotationOperationImplementation: BehaviorOperationImplementati
|
|
|
124
91
|
},
|
|
125
92
|
{at: path},
|
|
126
93
|
)
|
|
127
|
-
|
|
128
|
-
spanPath = [{_key: block._key}, 'children', {_key: span._key}]
|
|
129
94
|
}
|
|
130
95
|
|
|
131
96
|
blockIndex++
|
|
132
97
|
}
|
|
133
|
-
|
|
134
|
-
if (markDefPath && spanPath) {
|
|
135
|
-
paths = {
|
|
136
|
-
markDefPath,
|
|
137
|
-
markDefPaths,
|
|
138
|
-
spanPath,
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
return paths
|
|
143
98
|
}
|
|
@@ -32,14 +32,13 @@ export type BehaviorOperationImplementationContext = Pick<
|
|
|
32
32
|
|
|
33
33
|
export type BehaviorOperationImplementation<
|
|
34
34
|
TBehaviorOperationType extends BehaviorOperation['type'],
|
|
35
|
-
TReturnType = void,
|
|
36
35
|
> = ({
|
|
37
36
|
context,
|
|
38
37
|
operation,
|
|
39
38
|
}: {
|
|
40
39
|
context: BehaviorOperationImplementationContext
|
|
41
40
|
operation: PickFromUnion<BehaviorOperation, 'type', TBehaviorOperationType>
|
|
42
|
-
}) =>
|
|
41
|
+
}) => void
|
|
43
42
|
|
|
44
43
|
type BehaviorOperation = OmitFromUnion<
|
|
45
44
|
SyntheticBehaviorEvent,
|
package/src/types/editor.ts
CHANGED
|
@@ -37,6 +37,24 @@ export interface EditableAPIDeleteOptions {
|
|
|
37
37
|
mode?: 'blocks' | 'children' | 'selected'
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
/**
|
|
41
|
+
* @public
|
|
42
|
+
*/
|
|
43
|
+
export type AddedAnnotationPaths = {
|
|
44
|
+
/**
|
|
45
|
+
* @deprecated An annotation may be applied to multiple blocks, resulting
|
|
46
|
+
* in multiple `markDef`'s being created. Use `markDefPaths` instead.
|
|
47
|
+
*/
|
|
48
|
+
markDefPath: Path
|
|
49
|
+
markDefPaths: Array<Path>
|
|
50
|
+
/**
|
|
51
|
+
* @deprecated Does not return anything meaningful since an annotation
|
|
52
|
+
* can span multiple blocks and spans. If references the span closest
|
|
53
|
+
* to the focus point of the selection.
|
|
54
|
+
*/
|
|
55
|
+
spanPath: Path
|
|
56
|
+
}
|
|
57
|
+
|
|
40
58
|
/** @beta */
|
|
41
59
|
export interface EditableAPI {
|
|
42
60
|
activeAnnotations: () => PortableTextObject[]
|
|
@@ -44,9 +62,7 @@ export interface EditableAPI {
|
|
|
44
62
|
addAnnotation: <TSchemaType extends {name: string}>(
|
|
45
63
|
type: TSchemaType,
|
|
46
64
|
value?: {[prop: string]: unknown},
|
|
47
|
-
) =>
|
|
48
|
-
| {markDefPath: Path; markDefPaths: Array<Path>; spanPath: Path}
|
|
49
|
-
| undefined
|
|
65
|
+
) => AddedAnnotationPaths | undefined
|
|
50
66
|
blur: () => void
|
|
51
67
|
delete: (
|
|
52
68
|
selection: EditorSelection,
|