@portabletext/editor 1.52.3 → 1.52.5
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.cjs +91 -54
- package/lib/index.cjs.map +1 -1
- package/lib/index.js +91 -54
- package/lib/index.js.map +1 -1
- package/package.json +2 -2
- package/src/editor/Editable.tsx +1 -16
- package/src/editor/plugins/slate-plugin.update-selection.ts +51 -0
- package/src/editor/plugins/with-plugins.ts +5 -6
- package/src/editor/relay-machine.ts +49 -2
- package/src/editor/plugins/createWithPortableTextSelections.ts +0 -60
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@portabletext/editor",
|
|
3
|
-
"version": "1.52.
|
|
3
|
+
"version": "1.52.5",
|
|
4
4
|
"description": "Portable Text Editor made in React",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sanity",
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"slate": "0.115.1",
|
|
79
79
|
"slate-dom": "^0.114.0",
|
|
80
80
|
"slate-react": "0.114.2",
|
|
81
|
-
"use-effect-event": "^
|
|
81
|
+
"use-effect-event": "^1.0.2",
|
|
82
82
|
"xstate": "^5.19.4",
|
|
83
83
|
"@portabletext/block-tools": "1.1.30",
|
|
84
84
|
"@portabletext/patches": "1.1.4"
|
package/src/editor/Editable.tsx
CHANGED
|
@@ -534,24 +534,9 @@ export const PortableTextEditable = forwardRef<
|
|
|
534
534
|
|
|
535
535
|
if (!event.isDefaultPrevented()) {
|
|
536
536
|
relayActor.send({type: 'focused', event})
|
|
537
|
-
|
|
538
|
-
const selection = slateEditor.selection
|
|
539
|
-
? slateRangeToSelection({
|
|
540
|
-
schema: editorActor.getSnapshot().context.schema,
|
|
541
|
-
editor: slateEditor,
|
|
542
|
-
range: slateEditor.selection,
|
|
543
|
-
})
|
|
544
|
-
: null
|
|
545
|
-
|
|
546
|
-
if (selection) {
|
|
547
|
-
editorActor.send({
|
|
548
|
-
type: 'update selection',
|
|
549
|
-
selection,
|
|
550
|
-
})
|
|
551
|
-
}
|
|
552
537
|
}
|
|
553
538
|
},
|
|
554
|
-
[
|
|
539
|
+
[onFocus, relayActor],
|
|
555
540
|
)
|
|
556
541
|
|
|
557
542
|
const handleClick = useCallback(
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import {slateRangeToSelection} from '../../internal-utils/slate-utils'
|
|
2
|
+
import {SLATE_TO_PORTABLE_TEXT_RANGE} from '../../internal-utils/weakMaps'
|
|
3
|
+
import type {PortableTextSlateEditor} from '../../types/editor'
|
|
4
|
+
import type {EditorActor} from '../editor-machine'
|
|
5
|
+
|
|
6
|
+
export function pluginUpdateSelection({
|
|
7
|
+
editor,
|
|
8
|
+
editorActor,
|
|
9
|
+
}: {
|
|
10
|
+
editor: PortableTextSlateEditor
|
|
11
|
+
editorActor: EditorActor
|
|
12
|
+
}) {
|
|
13
|
+
const updateSelection = () => {
|
|
14
|
+
if (editor.selection) {
|
|
15
|
+
const existingSelection = SLATE_TO_PORTABLE_TEXT_RANGE.get(
|
|
16
|
+
editor.selection,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
if (existingSelection) {
|
|
20
|
+
editorActor.send({
|
|
21
|
+
type: 'update selection',
|
|
22
|
+
selection: existingSelection,
|
|
23
|
+
})
|
|
24
|
+
} else {
|
|
25
|
+
const selection = slateRangeToSelection({
|
|
26
|
+
schema: editorActor.getSnapshot().context.schema,
|
|
27
|
+
editor,
|
|
28
|
+
range: editor.selection,
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
SLATE_TO_PORTABLE_TEXT_RANGE.set(editor.selection, selection)
|
|
32
|
+
|
|
33
|
+
editorActor.send({type: 'update selection', selection})
|
|
34
|
+
}
|
|
35
|
+
} else {
|
|
36
|
+
editorActor.send({type: 'update selection', selection: null})
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const {onChange} = editor
|
|
41
|
+
|
|
42
|
+
editor.onChange = () => {
|
|
43
|
+
onChange()
|
|
44
|
+
|
|
45
|
+
if (!editorActor.getSnapshot().matches({setup: 'setting up'})) {
|
|
46
|
+
updateSelection()
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return editor
|
|
51
|
+
}
|
|
@@ -8,11 +8,11 @@ import {createWithObjectKeys} from './createWithObjectKeys'
|
|
|
8
8
|
import {createWithPatches} from './createWithPatches'
|
|
9
9
|
import {createWithPlaceholderBlock} from './createWithPlaceholderBlock'
|
|
10
10
|
import {createWithPortableTextMarkModel} from './createWithPortableTextMarkModel'
|
|
11
|
-
import {createWithPortableTextSelections} from './createWithPortableTextSelections'
|
|
12
11
|
import {createWithSchemaTypes} from './createWithSchemaTypes'
|
|
13
12
|
import {createWithUndoRedo} from './createWithUndoRedo'
|
|
14
13
|
import {createWithUtils} from './createWithUtils'
|
|
15
14
|
import {pluginUpdateMarkState} from './slate-plugin.update-mark-state'
|
|
15
|
+
import {pluginUpdateSelection} from './slate-plugin.update-selection'
|
|
16
16
|
import {pluginUpdateValue} from './slate-plugin.update-value'
|
|
17
17
|
|
|
18
18
|
export interface OriginalEditorFunctions {
|
|
@@ -54,8 +54,6 @@ export const withPlugins = <T extends Editor>(
|
|
|
54
54
|
const withUtils = createWithUtils({
|
|
55
55
|
editorActor,
|
|
56
56
|
})
|
|
57
|
-
const withPortableTextSelections =
|
|
58
|
-
createWithPortableTextSelections(editorActor)
|
|
59
57
|
const withEventListeners = createWithEventListeners(editorActor)
|
|
60
58
|
|
|
61
59
|
// Ordering is important here, selection dealing last, data manipulation in the middle and core model stuff first.
|
|
@@ -68,15 +66,16 @@ export const withPlugins = <T extends Editor>(
|
|
|
68
66
|
withMaxBlocks(
|
|
69
67
|
withUndoRedo(
|
|
70
68
|
withPatches(
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
pluginUpdateSelection({
|
|
70
|
+
editorActor,
|
|
71
|
+
editor: pluginUpdateValue(
|
|
73
72
|
editorActor.getSnapshot().context,
|
|
74
73
|
pluginUpdateMarkState(
|
|
75
74
|
editorActor.getSnapshot().context,
|
|
76
75
|
e,
|
|
77
76
|
),
|
|
78
77
|
),
|
|
79
|
-
),
|
|
78
|
+
}),
|
|
80
79
|
),
|
|
81
80
|
),
|
|
82
81
|
),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type {Patch} from '@portabletext/patches'
|
|
2
2
|
import type {PortableTextBlock} from '@sanity/types'
|
|
3
3
|
import type {FocusEvent} from 'react'
|
|
4
|
-
import {emit, setup, type ActorRefFrom} from 'xstate'
|
|
4
|
+
import {assign, emit, setup, type ActorRefFrom} from 'xstate'
|
|
5
5
|
import type {EditorSelection, InvalidValueResolution} from '../types/editor'
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -96,14 +96,61 @@ export type RelayActor = ActorRefFrom<typeof relayMachine>
|
|
|
96
96
|
|
|
97
97
|
export const relayMachine = setup({
|
|
98
98
|
types: {
|
|
99
|
+
context: {} as {
|
|
100
|
+
prevSelection: EditorSelection
|
|
101
|
+
lastEventWasFocused: boolean
|
|
102
|
+
},
|
|
99
103
|
events: {} as InternalEditorEmittedEvent,
|
|
100
104
|
emitted: {} as InternalEditorEmittedEvent,
|
|
101
105
|
},
|
|
102
106
|
}).createMachine({
|
|
103
107
|
id: 'relay',
|
|
108
|
+
context: {
|
|
109
|
+
prevSelection: null,
|
|
110
|
+
lastEventWasFocused: false,
|
|
111
|
+
},
|
|
104
112
|
on: {
|
|
113
|
+
'focused': {
|
|
114
|
+
actions: [
|
|
115
|
+
assign({
|
|
116
|
+
lastEventWasFocused: true,
|
|
117
|
+
}),
|
|
118
|
+
emit(({event}) => event),
|
|
119
|
+
],
|
|
120
|
+
},
|
|
121
|
+
'selection': [
|
|
122
|
+
{
|
|
123
|
+
guard: ({context}) => context.lastEventWasFocused,
|
|
124
|
+
actions: [
|
|
125
|
+
assign({
|
|
126
|
+
prevSelection: ({event}) => event.selection,
|
|
127
|
+
}),
|
|
128
|
+
emit(({event}) => event),
|
|
129
|
+
assign({
|
|
130
|
+
lastEventWasFocused: false,
|
|
131
|
+
}),
|
|
132
|
+
],
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
guard: ({context, event}) => context.prevSelection !== event.selection,
|
|
136
|
+
actions: [
|
|
137
|
+
assign({
|
|
138
|
+
prevSelection: ({event}) => event.selection,
|
|
139
|
+
}),
|
|
140
|
+
emit(({event}) => event),
|
|
141
|
+
assign({
|
|
142
|
+
lastEventWasFocused: false,
|
|
143
|
+
}),
|
|
144
|
+
],
|
|
145
|
+
},
|
|
146
|
+
],
|
|
105
147
|
'*': {
|
|
106
|
-
actions:
|
|
148
|
+
actions: [
|
|
149
|
+
emit(({event}) => event),
|
|
150
|
+
assign({
|
|
151
|
+
lastEventWasFocused: false,
|
|
152
|
+
}),
|
|
153
|
+
],
|
|
107
154
|
},
|
|
108
155
|
},
|
|
109
156
|
})
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import type {BaseRange} from 'slate'
|
|
2
|
-
import {debugWithName} from '../../internal-utils/debug'
|
|
3
|
-
import {slateRangeToSelection} from '../../internal-utils/slate-utils'
|
|
4
|
-
import {SLATE_TO_PORTABLE_TEXT_RANGE} from '../../internal-utils/weakMaps'
|
|
5
|
-
import type {EditorSelection, PortableTextSlateEditor} from '../../types/editor'
|
|
6
|
-
import type {EditorActor} from '../editor-machine'
|
|
7
|
-
|
|
8
|
-
const debug = debugWithName('plugin:withPortableTextSelections')
|
|
9
|
-
const debugVerbose = debug.enabled && false
|
|
10
|
-
|
|
11
|
-
// This plugin will make sure that we emit a PT selection whenever the editor has changed.
|
|
12
|
-
export function createWithPortableTextSelections(
|
|
13
|
-
editorActor: EditorActor,
|
|
14
|
-
): (editor: PortableTextSlateEditor) => PortableTextSlateEditor {
|
|
15
|
-
let prevSelection: BaseRange | null = null
|
|
16
|
-
return function withPortableTextSelections(
|
|
17
|
-
editor: PortableTextSlateEditor,
|
|
18
|
-
): PortableTextSlateEditor {
|
|
19
|
-
const emitPortableTextSelection = () => {
|
|
20
|
-
if (prevSelection !== editor.selection) {
|
|
21
|
-
let ptRange: EditorSelection | null = null
|
|
22
|
-
if (editor.selection) {
|
|
23
|
-
const existing = SLATE_TO_PORTABLE_TEXT_RANGE.get(editor.selection)
|
|
24
|
-
if (existing) {
|
|
25
|
-
ptRange = existing
|
|
26
|
-
} else {
|
|
27
|
-
ptRange = slateRangeToSelection({
|
|
28
|
-
schema: editorActor.getSnapshot().context.schema,
|
|
29
|
-
editor,
|
|
30
|
-
range: editor.selection,
|
|
31
|
-
})
|
|
32
|
-
SLATE_TO_PORTABLE_TEXT_RANGE.set(editor.selection, ptRange)
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
if (debugVerbose) {
|
|
36
|
-
debug(
|
|
37
|
-
`Emitting selection ${JSON.stringify(ptRange || null)} (${JSON.stringify(
|
|
38
|
-
editor.selection,
|
|
39
|
-
)})`,
|
|
40
|
-
)
|
|
41
|
-
}
|
|
42
|
-
if (ptRange) {
|
|
43
|
-
editorActor.send({type: 'update selection', selection: ptRange})
|
|
44
|
-
} else {
|
|
45
|
-
editorActor.send({type: 'update selection', selection: null})
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
prevSelection = editor.selection
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const {onChange} = editor
|
|
52
|
-
editor.onChange = () => {
|
|
53
|
-
onChange()
|
|
54
|
-
if (!editorActor.getSnapshot().matches({setup: 'setting up'})) {
|
|
55
|
-
emitPortableTextSelection()
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
return editor
|
|
59
|
-
}
|
|
60
|
-
}
|