@portabletext/editor 1.5.6 → 1.6.1
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 +452 -28
- package/lib/index.d.ts +452 -28
- package/lib/index.esm.js +2553 -2405
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +2553 -2405
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +2553 -2405
- package/lib/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/editor/Editable.tsx +21 -24
- package/src/editor/__tests__/self-solving.test.tsx +9 -9
- package/src/editor/behavior/behavior.actions.ts +51 -4
- package/src/editor/behavior/behavior.core.decorators.ts +52 -0
- package/src/editor/behavior/behavior.core.ts +5 -0
- package/src/editor/behavior/behavior.markdown.ts +7 -6
- package/src/editor/behavior/behavior.types.ts +15 -0
- package/src/editor/editor-machine.ts +32 -4
- package/src/editor/plugins/create-with-event-listeners.ts +24 -0
- package/src/editor/plugins/createWithEditableAPI.ts +10 -2
- package/src/editor/plugins/createWithHotKeys.ts +10 -1
- package/src/editor/plugins/createWithPortableTextMarkModel.ts +215 -220
- package/src/editor/withSyncRangeDecorations.ts +20 -0
- package/src/types/editor.ts +0 -14
package/package.json
CHANGED
package/src/editor/Editable.tsx
CHANGED
|
@@ -69,6 +69,7 @@ import {usePortableTextEditor} from './hooks/usePortableTextEditor'
|
|
|
69
69
|
import {usePortableTextEditorReadOnlyStatus} from './hooks/usePortableTextReadOnly'
|
|
70
70
|
import {createWithHotkeys, createWithInsertData} from './plugins'
|
|
71
71
|
import {PortableTextEditor} from './PortableTextEditor'
|
|
72
|
+
import {withSyncRangeDecorations} from './withSyncRangeDecorations'
|
|
72
73
|
|
|
73
74
|
const debug = debugWithName('component:Editable')
|
|
74
75
|
|
|
@@ -163,27 +164,33 @@ export const PortableTextEditable = forwardRef<
|
|
|
163
164
|
|
|
164
165
|
const blockTypeName = schemaTypes.block.name
|
|
165
166
|
|
|
166
|
-
// React/UI-specific plugins
|
|
167
|
-
const withInsertData = useMemo(
|
|
168
|
-
() => createWithInsertData(editorActor, schemaTypes),
|
|
169
|
-
[editorActor, schemaTypes],
|
|
170
|
-
)
|
|
171
|
-
const withHotKeys = useMemo(
|
|
172
|
-
() => createWithHotkeys(portableTextEditor, hotkeys),
|
|
173
|
-
[hotkeys, portableTextEditor],
|
|
174
|
-
)
|
|
175
|
-
|
|
176
167
|
// Output a minimal React editor inside Editable when in readOnly mode.
|
|
177
168
|
// NOTE: make sure all the plugins used here can be safely run over again at any point.
|
|
178
169
|
// There will be a problem if they redefine editor methods and then calling the original method within themselves.
|
|
179
170
|
useMemo(() => {
|
|
171
|
+
// React/UI-specific plugins
|
|
172
|
+
const withInsertData = createWithInsertData(editorActor, schemaTypes)
|
|
173
|
+
|
|
180
174
|
if (readOnly) {
|
|
181
175
|
debug('Editable is in read only mode')
|
|
182
176
|
return withInsertData(slateEditor)
|
|
183
177
|
}
|
|
178
|
+
const withHotKeys = createWithHotkeys(
|
|
179
|
+
editorActor,
|
|
180
|
+
portableTextEditor,
|
|
181
|
+
hotkeys,
|
|
182
|
+
)
|
|
183
|
+
|
|
184
184
|
debug('Editable is in edit mode')
|
|
185
185
|
return withInsertData(withHotKeys(slateEditor))
|
|
186
|
-
}, [
|
|
186
|
+
}, [
|
|
187
|
+
editorActor,
|
|
188
|
+
hotkeys,
|
|
189
|
+
portableTextEditor,
|
|
190
|
+
readOnly,
|
|
191
|
+
schemaTypes,
|
|
192
|
+
slateEditor,
|
|
193
|
+
])
|
|
187
194
|
|
|
188
195
|
const renderElement = useCallback(
|
|
189
196
|
(eProps: RenderElementProps) => (
|
|
@@ -381,9 +388,6 @@ export const PortableTextEditable = forwardRef<
|
|
|
381
388
|
}
|
|
382
389
|
}, [hasInvalidValue, propsSelection, restoreSelectionFromProps])
|
|
383
390
|
|
|
384
|
-
// Store reference to original apply function (see below for usage in useEffect)
|
|
385
|
-
const originalApply = useMemo(() => slateEditor.apply, [slateEditor])
|
|
386
|
-
|
|
387
391
|
const [syncedRangeDecorations, setSyncedRangeDecorations] = useState(false)
|
|
388
392
|
useEffect(() => {
|
|
389
393
|
if (!syncedRangeDecorations) {
|
|
@@ -402,16 +406,9 @@ export const PortableTextEditable = forwardRef<
|
|
|
402
406
|
|
|
403
407
|
// Sync range decorations after an operation is applied
|
|
404
408
|
useEffect(() => {
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
syncRangeDecorations(op)
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
return () => {
|
|
412
|
-
slateEditor.apply = originalApply
|
|
413
|
-
}
|
|
414
|
-
}, [originalApply, slateEditor, syncRangeDecorations])
|
|
409
|
+
const teardown = withSyncRangeDecorations(slateEditor, syncRangeDecorations)
|
|
410
|
+
return () => teardown()
|
|
411
|
+
}, [slateEditor, syncRangeDecorations])
|
|
415
412
|
|
|
416
413
|
// Handle from props onCopy function
|
|
417
414
|
const handleCopy = useCallback(
|
|
@@ -127,23 +127,23 @@ describe('Feature: Self-solving', () => {
|
|
|
127
127
|
},
|
|
128
128
|
})
|
|
129
129
|
expect(onChange).toHaveBeenNthCalledWith(4, {
|
|
130
|
-
type: '
|
|
131
|
-
|
|
130
|
+
type: 'selection',
|
|
131
|
+
selection: {
|
|
132
|
+
...getTextSelection(initialValue, 'foo'),
|
|
133
|
+
backward: false,
|
|
134
|
+
},
|
|
132
135
|
})
|
|
133
136
|
expect(onChange).toHaveBeenNthCalledWith(5, {
|
|
134
137
|
type: 'patch',
|
|
135
|
-
patch:
|
|
138
|
+
patch: spanPatch,
|
|
136
139
|
})
|
|
137
140
|
expect(onChange).toHaveBeenNthCalledWith(6, {
|
|
138
141
|
type: 'patch',
|
|
139
|
-
patch:
|
|
142
|
+
patch: blockPatch,
|
|
140
143
|
})
|
|
141
144
|
expect(onChange).toHaveBeenNthCalledWith(7, {
|
|
142
|
-
type: '
|
|
143
|
-
|
|
144
|
-
...getTextSelection(initialValue, 'foo'),
|
|
145
|
-
backward: false,
|
|
146
|
-
},
|
|
145
|
+
type: 'patch',
|
|
146
|
+
patch: strongPatch,
|
|
147
147
|
})
|
|
148
148
|
expect(onChange).toHaveBeenNthCalledWith(8, {
|
|
149
149
|
type: 'selection',
|
|
@@ -7,6 +7,11 @@ import {
|
|
|
7
7
|
} from 'slate'
|
|
8
8
|
import type {PortableTextMemberSchemaTypes} from '../../types/editor'
|
|
9
9
|
import {toSlateRange} from '../../utils/ranges'
|
|
10
|
+
import {
|
|
11
|
+
addDecoratorActionImplementation,
|
|
12
|
+
removeDecoratorActionImplementation,
|
|
13
|
+
toggleDecoratorActionImplementation,
|
|
14
|
+
} from '../plugins/createWithPortableTextMarkModel'
|
|
10
15
|
import {insertBreakActionImplementation} from './behavior.action.insert-break'
|
|
11
16
|
import type {
|
|
12
17
|
BehaviorAction,
|
|
@@ -36,6 +41,9 @@ type BehaviourActionImplementations = {
|
|
|
36
41
|
}
|
|
37
42
|
|
|
38
43
|
const behaviorActionImplementations: BehaviourActionImplementations = {
|
|
44
|
+
'decorator.add': addDecoratorActionImplementation,
|
|
45
|
+
'decorator.remove': removeDecoratorActionImplementation,
|
|
46
|
+
'decorator.toggle': toggleDecoratorActionImplementation,
|
|
39
47
|
'set block': ({action}) => {
|
|
40
48
|
for (const path of action.paths) {
|
|
41
49
|
const at = toSlateRange(
|
|
@@ -116,10 +124,21 @@ const behaviorActionImplementations: BehaviourActionImplementations = {
|
|
|
116
124
|
action.effect()
|
|
117
125
|
},
|
|
118
126
|
'select': ({action}) => {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
127
|
+
const newSelection = toSlateRange(action.selection, action.editor)
|
|
128
|
+
|
|
129
|
+
if (newSelection) {
|
|
130
|
+
Transforms.select(action.editor, newSelection)
|
|
131
|
+
} else {
|
|
132
|
+
Transforms.deselect(action.editor)
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
'reselect': ({action}) => {
|
|
136
|
+
const selection = action.editor.selection
|
|
137
|
+
|
|
138
|
+
if (selection) {
|
|
139
|
+
Transforms.select(action.editor, {...selection})
|
|
140
|
+
action.editor.selection = {...selection}
|
|
141
|
+
}
|
|
123
142
|
},
|
|
124
143
|
}
|
|
125
144
|
|
|
@@ -173,6 +192,13 @@ export function performAction({
|
|
|
173
192
|
})
|
|
174
193
|
break
|
|
175
194
|
}
|
|
195
|
+
case 'reselect': {
|
|
196
|
+
behaviorActionImplementations.reselect({
|
|
197
|
+
context,
|
|
198
|
+
action,
|
|
199
|
+
})
|
|
200
|
+
break
|
|
201
|
+
}
|
|
176
202
|
default: {
|
|
177
203
|
performDefaultAction({context, action})
|
|
178
204
|
}
|
|
@@ -187,6 +213,27 @@ export function performDefaultAction({
|
|
|
187
213
|
action: PickFromUnion<BehaviorAction, 'type', BehaviorEvent['type']>
|
|
188
214
|
}) {
|
|
189
215
|
switch (action.type) {
|
|
216
|
+
case 'decorator.add': {
|
|
217
|
+
behaviorActionImplementations['decorator.add']({
|
|
218
|
+
context,
|
|
219
|
+
action,
|
|
220
|
+
})
|
|
221
|
+
break
|
|
222
|
+
}
|
|
223
|
+
case 'decorator.remove': {
|
|
224
|
+
behaviorActionImplementations['decorator.remove']({
|
|
225
|
+
context,
|
|
226
|
+
action,
|
|
227
|
+
})
|
|
228
|
+
break
|
|
229
|
+
}
|
|
230
|
+
case 'decorator.toggle': {
|
|
231
|
+
behaviorActionImplementations['decorator.toggle']({
|
|
232
|
+
context,
|
|
233
|
+
action,
|
|
234
|
+
})
|
|
235
|
+
break
|
|
236
|
+
}
|
|
190
237
|
case 'delete backward': {
|
|
191
238
|
behaviorActionImplementations['delete backward']({
|
|
192
239
|
context,
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import {defineBehavior} from './behavior.types'
|
|
2
|
+
|
|
3
|
+
const decoratorAdd = defineBehavior({
|
|
4
|
+
on: 'decorator.add',
|
|
5
|
+
actions: [
|
|
6
|
+
({event}) => [
|
|
7
|
+
{
|
|
8
|
+
type: 'decorator.add',
|
|
9
|
+
decorator: event.decorator,
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
type: 'reselect',
|
|
13
|
+
},
|
|
14
|
+
],
|
|
15
|
+
],
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
const decoratorRemove = defineBehavior({
|
|
19
|
+
on: 'decorator.remove',
|
|
20
|
+
actions: [
|
|
21
|
+
({event}) => [
|
|
22
|
+
{
|
|
23
|
+
type: 'decorator.remove',
|
|
24
|
+
decorator: event.decorator,
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
type: 'reselect',
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
],
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
const decoratorToggle = defineBehavior({
|
|
34
|
+
on: 'decorator.toggle',
|
|
35
|
+
actions: [
|
|
36
|
+
({event}) => [
|
|
37
|
+
{
|
|
38
|
+
type: 'decorator.toggle',
|
|
39
|
+
decorator: event.decorator,
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
type: 'reselect',
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
],
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
export const coreDecoratorBehaviors = {
|
|
49
|
+
decoratorAdd,
|
|
50
|
+
decoratorRemove,
|
|
51
|
+
decoratorToggle,
|
|
52
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {coreBlockObjectBehaviors} from './behavior.core.block-objects'
|
|
2
|
+
import {coreDecoratorBehaviors} from './behavior.core.decorators'
|
|
2
3
|
import {coreListBehaviors} from './behavior.core.lists'
|
|
3
4
|
import {defineBehavior} from './behavior.types'
|
|
4
5
|
|
|
@@ -12,6 +13,9 @@ const softReturn = defineBehavior({
|
|
|
12
13
|
*/
|
|
13
14
|
export const coreBehaviors = [
|
|
14
15
|
softReturn,
|
|
16
|
+
coreDecoratorBehaviors.decoratorAdd,
|
|
17
|
+
coreDecoratorBehaviors.decoratorRemove,
|
|
18
|
+
coreDecoratorBehaviors.decoratorToggle,
|
|
15
19
|
coreBlockObjectBehaviors.breakingBlockObject,
|
|
16
20
|
coreBlockObjectBehaviors.deletingEmptyTextBlockAfterBlockObject,
|
|
17
21
|
coreBlockObjectBehaviors.deletingEmptyTextBlockBeforeBlockObject,
|
|
@@ -24,6 +28,7 @@ export const coreBehaviors = [
|
|
|
24
28
|
*/
|
|
25
29
|
export const coreBehavior = {
|
|
26
30
|
softReturn,
|
|
31
|
+
decorators: coreDecoratorBehaviors,
|
|
27
32
|
blockObjects: coreBlockObjectBehaviors,
|
|
28
33
|
lists: coreListBehaviors,
|
|
29
34
|
}
|
|
@@ -227,11 +227,13 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
|
|
|
227
227
|
return false
|
|
228
228
|
}
|
|
229
229
|
|
|
230
|
+
const defaultStyle = config.mapDefaultStyle(context.schema)
|
|
230
231
|
const looksLikeUnorderedList = /^(-|\*)/.test(focusSpan.node.text)
|
|
231
232
|
const unorderedListStyle = config.mapUnorderedListStyle(context.schema)
|
|
232
233
|
const caretAtTheEndOfUnorderedList = context.selection.focus.offset === 1
|
|
233
234
|
|
|
234
235
|
if (
|
|
236
|
+
defaultStyle &&
|
|
235
237
|
caretAtTheEndOfUnorderedList &&
|
|
236
238
|
looksLikeUnorderedList &&
|
|
237
239
|
unorderedListStyle !== undefined
|
|
@@ -241,6 +243,7 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
|
|
|
241
243
|
focusSpan,
|
|
242
244
|
listItem: unorderedListStyle,
|
|
243
245
|
listItemLength: 1,
|
|
246
|
+
style: defaultStyle,
|
|
244
247
|
}
|
|
245
248
|
}
|
|
246
249
|
|
|
@@ -249,6 +252,7 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
|
|
|
249
252
|
const caretAtTheEndOfOrderedList = context.selection.focus.offset === 2
|
|
250
253
|
|
|
251
254
|
if (
|
|
255
|
+
defaultStyle &&
|
|
252
256
|
caretAtTheEndOfOrderedList &&
|
|
253
257
|
looksLikeOrderedList &&
|
|
254
258
|
orderedListStyle !== undefined
|
|
@@ -258,6 +262,7 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
|
|
|
258
262
|
focusSpan,
|
|
259
263
|
listItem: orderedListStyle,
|
|
260
264
|
listItemLength: 2,
|
|
265
|
+
style: defaultStyle,
|
|
261
266
|
}
|
|
262
267
|
}
|
|
263
268
|
|
|
@@ -270,16 +275,12 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
|
|
|
270
275
|
text: ' ',
|
|
271
276
|
},
|
|
272
277
|
],
|
|
273
|
-
(_, {focusTextBlock, focusSpan, listItem, listItemLength}) => [
|
|
274
|
-
{
|
|
275
|
-
type: 'unset block',
|
|
276
|
-
props: ['style'],
|
|
277
|
-
paths: [focusTextBlock.path],
|
|
278
|
-
},
|
|
278
|
+
(_, {focusTextBlock, focusSpan, style, listItem, listItemLength}) => [
|
|
279
279
|
{
|
|
280
280
|
type: 'set block',
|
|
281
281
|
listItem,
|
|
282
282
|
level: 1,
|
|
283
|
+
style,
|
|
283
284
|
paths: [focusTextBlock.path],
|
|
284
285
|
},
|
|
285
286
|
{
|
|
@@ -20,6 +20,18 @@ export type BehaviorContext = {
|
|
|
20
20
|
* @alpha
|
|
21
21
|
*/
|
|
22
22
|
export type BehaviorEvent =
|
|
23
|
+
| {
|
|
24
|
+
type: 'decorator.add'
|
|
25
|
+
decorator: string
|
|
26
|
+
}
|
|
27
|
+
| {
|
|
28
|
+
type: 'decorator.remove'
|
|
29
|
+
decorator: string
|
|
30
|
+
}
|
|
31
|
+
| {
|
|
32
|
+
type: 'decorator.toggle'
|
|
33
|
+
decorator: string
|
|
34
|
+
}
|
|
23
35
|
| {
|
|
24
36
|
type: 'delete backward'
|
|
25
37
|
unit: TextUnit
|
|
@@ -87,6 +99,9 @@ export type BehaviorActionIntend =
|
|
|
87
99
|
type: 'select'
|
|
88
100
|
selection: EditorSelection
|
|
89
101
|
}
|
|
102
|
+
| {
|
|
103
|
+
type: 'reselect'
|
|
104
|
+
}
|
|
90
105
|
|
|
91
106
|
/**
|
|
92
107
|
* @alpha
|
|
@@ -20,7 +20,7 @@ import type {
|
|
|
20
20
|
import {toPortableTextRange} from '../utils/ranges'
|
|
21
21
|
import {fromSlateValue} from '../utils/values'
|
|
22
22
|
import {KEY_TO_VALUE_ELEMENT} from '../utils/weakMaps'
|
|
23
|
-
import {performAction
|
|
23
|
+
import {performAction} from './behavior/behavior.actions'
|
|
24
24
|
import {coreBehaviors} from './behavior/behavior.core'
|
|
25
25
|
import type {
|
|
26
26
|
Behavior,
|
|
@@ -197,7 +197,11 @@ export const editorMachine = setup({
|
|
|
197
197
|
)
|
|
198
198
|
|
|
199
199
|
if (eventBehaviors.length === 0) {
|
|
200
|
-
|
|
200
|
+
enqueue.raise({
|
|
201
|
+
type: 'behavior action intends',
|
|
202
|
+
editor: event.editor,
|
|
203
|
+
actionIntends: [defaultAction],
|
|
204
|
+
})
|
|
201
205
|
return
|
|
202
206
|
}
|
|
203
207
|
|
|
@@ -216,7 +220,11 @@ export const editorMachine = setup({
|
|
|
216
220
|
console.warn(
|
|
217
221
|
`Unable to handle event ${event.type} due to missing selection`,
|
|
218
222
|
)
|
|
219
|
-
|
|
223
|
+
enqueue.raise({
|
|
224
|
+
type: 'behavior action intends',
|
|
225
|
+
editor: event.editor,
|
|
226
|
+
actionIntends: [defaultAction],
|
|
227
|
+
})
|
|
220
228
|
return
|
|
221
229
|
}
|
|
222
230
|
|
|
@@ -264,7 +272,11 @@ export const editorMachine = setup({
|
|
|
264
272
|
}
|
|
265
273
|
|
|
266
274
|
if (!behaviorOverwritten) {
|
|
267
|
-
|
|
275
|
+
enqueue.raise({
|
|
276
|
+
type: 'behavior action intends',
|
|
277
|
+
editor: event.editor,
|
|
278
|
+
actionIntends: [defaultAction],
|
|
279
|
+
})
|
|
268
280
|
}
|
|
269
281
|
}),
|
|
270
282
|
},
|
|
@@ -315,6 +327,22 @@ export const editorMachine = setup({
|
|
|
315
327
|
})
|
|
316
328
|
event.editor.onChange()
|
|
317
329
|
},
|
|
330
|
+
enqueueActions(({context, event, enqueue}) => {
|
|
331
|
+
if (
|
|
332
|
+
event.actionIntends.some(
|
|
333
|
+
(actionIntend) => actionIntend.type === 'reselect',
|
|
334
|
+
)
|
|
335
|
+
) {
|
|
336
|
+
enqueue.raise({
|
|
337
|
+
type: 'selection',
|
|
338
|
+
selection: toPortableTextRange(
|
|
339
|
+
event.editor.children,
|
|
340
|
+
event.editor.selection,
|
|
341
|
+
context.schema,
|
|
342
|
+
),
|
|
343
|
+
})
|
|
344
|
+
}
|
|
345
|
+
}),
|
|
318
346
|
],
|
|
319
347
|
},
|
|
320
348
|
},
|
|
@@ -3,6 +3,30 @@ import type {EditorActor} from '../editor-machine'
|
|
|
3
3
|
|
|
4
4
|
export function createWithEventListeners(editorActor: EditorActor) {
|
|
5
5
|
return function withEventListeners(editor: Editor) {
|
|
6
|
+
editor.addMark = (mark) => {
|
|
7
|
+
editorActor.send({
|
|
8
|
+
type: 'behavior event',
|
|
9
|
+
behaviorEvent: {
|
|
10
|
+
type: 'decorator.add',
|
|
11
|
+
decorator: mark,
|
|
12
|
+
},
|
|
13
|
+
editor,
|
|
14
|
+
})
|
|
15
|
+
return
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
editor.removeMark = (mark) => {
|
|
19
|
+
editorActor.send({
|
|
20
|
+
type: 'behavior event',
|
|
21
|
+
behaviorEvent: {
|
|
22
|
+
type: 'decorator.remove',
|
|
23
|
+
decorator: mark,
|
|
24
|
+
},
|
|
25
|
+
editor,
|
|
26
|
+
})
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
|
|
6
30
|
editor.deleteBackward = (unit) => {
|
|
7
31
|
editorActor.send({
|
|
8
32
|
type: 'behavior event',
|
|
@@ -38,6 +38,7 @@ import {
|
|
|
38
38
|
} from '../../utils/weakMaps'
|
|
39
39
|
import type {EditorActor} from '../editor-machine'
|
|
40
40
|
import type {PortableTextEditor} from '../PortableTextEditor'
|
|
41
|
+
import {isDecoratorActive} from './createWithPortableTextMarkModel'
|
|
41
42
|
|
|
42
43
|
const debug = debugWithName('API:editable')
|
|
43
44
|
|
|
@@ -57,7 +58,14 @@ export function createWithEditableAPI(
|
|
|
57
58
|
ReactEditor.blur(editor)
|
|
58
59
|
},
|
|
59
60
|
toggleMark: (mark: string): void => {
|
|
60
|
-
|
|
61
|
+
editorActor.send({
|
|
62
|
+
type: 'behavior event',
|
|
63
|
+
behaviorEvent: {
|
|
64
|
+
type: 'decorator.toggle',
|
|
65
|
+
decorator: mark,
|
|
66
|
+
},
|
|
67
|
+
editor,
|
|
68
|
+
})
|
|
61
69
|
},
|
|
62
70
|
toggleList: (listStyle: string): void => {
|
|
63
71
|
editor.pteToggleListItem(listStyle)
|
|
@@ -69,7 +77,7 @@ export function createWithEditableAPI(
|
|
|
69
77
|
// Try/catch this, as Slate may error because the selection is currently wrong
|
|
70
78
|
// TODO: catch only relevant error from Slate
|
|
71
79
|
try {
|
|
72
|
-
return editor
|
|
80
|
+
return isDecoratorActive({editor, decorator: mark})
|
|
73
81
|
} catch (err) {
|
|
74
82
|
console.warn(err)
|
|
75
83
|
return false
|
|
@@ -7,6 +7,7 @@ import type {PortableTextSlateEditor} from '../../types/editor'
|
|
|
7
7
|
import type {HotkeyOptions} from '../../types/options'
|
|
8
8
|
import type {SlateTextBlock, VoidElement} from '../../types/slate'
|
|
9
9
|
import {debugWithName} from '../../utils/debug'
|
|
10
|
+
import type {EditorActor} from '../editor-machine'
|
|
10
11
|
import type {PortableTextEditor} from '../PortableTextEditor'
|
|
11
12
|
|
|
12
13
|
const debug = debugWithName('plugin:withHotKeys')
|
|
@@ -26,6 +27,7 @@ const DEFAULT_HOTKEYS: HotkeyOptions = {
|
|
|
26
27
|
*
|
|
27
28
|
*/
|
|
28
29
|
export function createWithHotkeys(
|
|
30
|
+
editorActor: EditorActor,
|
|
29
31
|
portableTextEditor: PortableTextEditor,
|
|
30
32
|
hotkeysFromOptions?: HotkeyOptions,
|
|
31
33
|
): (editor: PortableTextSlateEditor & ReactEditor) => any {
|
|
@@ -46,7 +48,14 @@ export function createWithHotkeys(
|
|
|
46
48
|
if (possibleMark) {
|
|
47
49
|
const mark = possibleMark[hotkey]
|
|
48
50
|
debug(`HotKey ${hotkey} to toggle ${mark}`)
|
|
49
|
-
|
|
51
|
+
editorActor.send({
|
|
52
|
+
type: 'behavior event',
|
|
53
|
+
behaviorEvent: {
|
|
54
|
+
type: 'decorator.toggle',
|
|
55
|
+
decorator: mark,
|
|
56
|
+
},
|
|
57
|
+
editor,
|
|
58
|
+
})
|
|
50
59
|
}
|
|
51
60
|
}
|
|
52
61
|
}
|