@portabletext/editor 1.13.0 → 1.14.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/README.md +1 -1
- package/lib/_chunks-cjs/selector.get-text-before.cjs +320 -0
- package/lib/_chunks-cjs/selector.get-text-before.cjs.map +1 -0
- package/lib/_chunks-es/selector.get-text-before.js +321 -0
- package/lib/_chunks-es/selector.get-text-before.js.map +1 -0
- package/lib/{index.esm.js → index.cjs} +1703 -1431
- package/lib/index.cjs.map +1 -0
- package/lib/{index.d.mts → index.d.cts} +4038 -313
- package/lib/index.d.ts +4038 -313
- package/lib/index.js +1724 -1407
- package/lib/index.js.map +1 -1
- package/lib/selectors/index.cjs +35 -0
- package/lib/selectors/index.cjs.map +1 -0
- package/lib/selectors/index.d.cts +243 -0
- package/lib/selectors/index.d.ts +243 -0
- package/lib/selectors/index.js +36 -0
- package/lib/selectors/index.js.map +1 -0
- package/package.json +21 -13
- package/src/editor/Editable.tsx +1 -1
- package/src/editor/PortableTextEditor.tsx +19 -4
- package/src/editor/__tests__/handleClick.test.tsx +4 -4
- package/src/editor/behavior/behavior.action.insert-block-object.ts +1 -1
- package/src/editor/behavior/behavior.action.insert-break.ts +3 -3
- package/src/editor/behavior/behavior.action.insert-inline-object.ts +58 -0
- package/src/editor/behavior/behavior.action.insert-span.ts +1 -1
- package/src/editor/behavior/behavior.action.list-item.ts +100 -0
- package/src/editor/behavior/behavior.action.style.ts +108 -0
- package/src/editor/behavior/behavior.action.text-block.set.ts +25 -0
- package/src/editor/behavior/behavior.action.text-block.unset.ts +17 -0
- package/src/editor/behavior/behavior.actions.ts +178 -109
- package/src/editor/behavior/behavior.code-editor.ts +30 -40
- package/src/editor/behavior/behavior.core.block-objects.ts +26 -26
- package/src/editor/behavior/behavior.core.decorators.ts +9 -6
- package/src/editor/behavior/behavior.core.lists.ts +139 -17
- package/src/editor/behavior/behavior.core.ts +5 -2
- package/src/editor/behavior/behavior.guards.ts +28 -0
- package/src/editor/behavior/behavior.links.ts +7 -7
- package/src/editor/behavior/behavior.markdown.ts +68 -79
- package/src/editor/behavior/behavior.types.ts +86 -60
- package/src/editor/{use-editor.ts → create-editor.ts} +13 -8
- package/src/editor/editor-event-listener.tsx +2 -2
- package/src/editor/editor-machine.ts +54 -15
- package/src/editor/editor-provider.tsx +5 -5
- package/src/editor/editor-selector.ts +49 -0
- package/src/editor/editor-snapshot.ts +22 -0
- package/src/editor/get-value.ts +11 -0
- package/src/editor/plugins/create-with-event-listeners.ts +93 -5
- package/src/editor/plugins/createWithEditableAPI.ts +69 -20
- package/src/editor/plugins/createWithHotKeys.ts +0 -54
- package/src/editor/plugins/createWithPortableTextBlockStyle.ts +1 -55
- package/src/editor/plugins/with-plugins.ts +4 -8
- package/src/editor/{behavior/behavior.utils.block-offset.test.ts → utils/utils.block-offset.test.ts} +1 -1
- package/src/editor/{behavior/behavior.utils.block-offset.ts → utils/utils.block-offset.ts} +1 -8
- package/src/editor/{behavior/behavior.utils.reverse-selection.ts → utils/utils.reverse-selection.ts} +3 -5
- package/src/editor/utils/utils.ts +21 -0
- package/src/index.ts +13 -13
- package/src/selectors/index.ts +15 -0
- package/src/selectors/selector.get-active-list-item.ts +37 -0
- package/src/{editor/behavior/behavior.utils.get-selection-text.ts → selectors/selector.get-selection-text.ts} +10 -15
- package/src/selectors/selector.get-text-before.ts +41 -0
- package/src/selectors/selectors.ts +329 -0
- package/src/types/editor.ts +0 -60
- package/src/utils/is-hotkey.test.ts +2 -0
- package/src/utils/operationToPatches.ts +5 -0
- package/src/utils/paths.ts +4 -11
- package/src/utils/ranges.ts +3 -3
- package/lib/index.esm.js.map +0 -1
- package/lib/index.mjs +0 -7541
- package/lib/index.mjs.map +0 -1
- package/src/editor/behavior/behavior.utils.ts +0 -218
- package/src/editor/behavior/behavior.utilts.get-text-before.ts +0 -31
- package/src/editor/plugins/createWithPortableTextLists.ts +0 -172
- /package/src/editor/{behavior/behavior.utils.get-start-point.ts → utils/utils.get-start-point.ts} +0 -0
- /package/src/editor/{behavior/behavior.utils.is-keyed-segment.ts → utils/utils.is-keyed-segment.ts} +0 -0
|
@@ -28,13 +28,13 @@ import {debugWithName} from '../utils/debug'
|
|
|
28
28
|
import {getPortableTextMemberSchemaTypes} from '../utils/getPortableTextMemberSchemaTypes'
|
|
29
29
|
import {compileType} from '../utils/schema'
|
|
30
30
|
import {Synchronizer} from './components/Synchronizer'
|
|
31
|
+
import {createEditor, type Editor} from './create-editor'
|
|
31
32
|
import {EditorActorContext} from './editor-actor-context'
|
|
32
33
|
import type {EditorActor} from './editor-machine'
|
|
33
34
|
import {PortableTextEditorContext} from './hooks/usePortableTextEditor'
|
|
34
35
|
import {PortableTextEditorSelectionProvider} from './hooks/usePortableTextEditorSelection'
|
|
35
36
|
import {defaultKeyGenerator} from './key-generator'
|
|
36
37
|
import type {AddedAnnotationPaths} from './plugins/createWithEditableAPI'
|
|
37
|
-
import {createEditor, type Editor} from './use-editor'
|
|
38
38
|
|
|
39
39
|
const debug = debugWithName('component:PortableTextEditor')
|
|
40
40
|
|
|
@@ -148,7 +148,7 @@ export class PortableTextEditor extends Component<
|
|
|
148
148
|
|
|
149
149
|
this.schemaTypes =
|
|
150
150
|
this.editor._internal.editorActor.getSnapshot().context.schema
|
|
151
|
-
this.editable = this.editor.editable
|
|
151
|
+
this.editable = this.editor._internal.editable
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
componentDidUpdate(prevProps: PortableTextEditorProps) {
|
|
@@ -204,7 +204,10 @@ export class PortableTextEditor extends Component<
|
|
|
204
204
|
}
|
|
205
205
|
|
|
206
206
|
public setEditable = (editable: EditableAPI) => {
|
|
207
|
-
this.editor.editable = {
|
|
207
|
+
this.editor._internal.editable = {
|
|
208
|
+
...this.editor._internal.editable,
|
|
209
|
+
...editable,
|
|
210
|
+
}
|
|
208
211
|
}
|
|
209
212
|
|
|
210
213
|
render() {
|
|
@@ -235,7 +238,7 @@ export class PortableTextEditor extends Component<
|
|
|
235
238
|
/>
|
|
236
239
|
<Synchronizer
|
|
237
240
|
editorActor={this.editor._internal.editorActor}
|
|
238
|
-
getValue={this.editor.editable.getValue}
|
|
241
|
+
getValue={this.editor._internal.editable.getValue}
|
|
239
242
|
portableTextEditor={this}
|
|
240
243
|
slateEditor={this.editor._internal.slateEditor.instance}
|
|
241
244
|
/>
|
|
@@ -442,6 +445,10 @@ export function RouteEventsToChanges(props: {
|
|
|
442
445
|
debug('Subscribing to editor changes')
|
|
443
446
|
const sub = props.editorActor.on('*', (event) => {
|
|
444
447
|
switch (event.type) {
|
|
448
|
+
case 'blurred': {
|
|
449
|
+
handleChange({type: 'blur', event: event.event})
|
|
450
|
+
break
|
|
451
|
+
}
|
|
445
452
|
case 'patch':
|
|
446
453
|
handleChange(event)
|
|
447
454
|
break
|
|
@@ -479,7 +486,15 @@ export function RouteEventsToChanges(props: {
|
|
|
479
486
|
case 'annotation.add':
|
|
480
487
|
case 'annotation.remove':
|
|
481
488
|
case 'annotation.toggle':
|
|
489
|
+
case 'blur':
|
|
490
|
+
case 'decorator.add':
|
|
491
|
+
case 'decorator.remove':
|
|
492
|
+
case 'decorator.toggle':
|
|
482
493
|
case 'focus':
|
|
494
|
+
case 'insert.block object':
|
|
495
|
+
case 'insert.inline object':
|
|
496
|
+
case 'list item.toggle':
|
|
497
|
+
case 'style.toggle':
|
|
483
498
|
case 'patches':
|
|
484
499
|
case 'readOnly toggled':
|
|
485
500
|
break
|
|
@@ -76,7 +76,7 @@ describe('adds empty text block if its needed', () => {
|
|
|
76
76
|
|
|
77
77
|
const element = await getEditableElement(component)
|
|
78
78
|
|
|
79
|
-
await waitFor(
|
|
79
|
+
await waitFor(() => {
|
|
80
80
|
if (editorRef.current && element) {
|
|
81
81
|
PortableTextEditor.focus(editorRef.current)
|
|
82
82
|
PortableTextEditor.select(editorRef.current, initialSelection)
|
|
@@ -127,7 +127,7 @@ describe('adds empty text block if its needed', () => {
|
|
|
127
127
|
)
|
|
128
128
|
const element = await getEditableElement(component)
|
|
129
129
|
|
|
130
|
-
await waitFor(
|
|
130
|
+
await waitFor(() => {
|
|
131
131
|
if (editorRef.current && element) {
|
|
132
132
|
PortableTextEditor.focus(editorRef.current)
|
|
133
133
|
PortableTextEditor.select(editorRef.current, initialSelection)
|
|
@@ -193,7 +193,7 @@ describe('adds empty text block if its needed', () => {
|
|
|
193
193
|
|
|
194
194
|
const element = await getEditableElement(component)
|
|
195
195
|
|
|
196
|
-
await waitFor(
|
|
196
|
+
await waitFor(() => {
|
|
197
197
|
if (editorRef.current && element) {
|
|
198
198
|
PortableTextEditor.focus(editorRef.current)
|
|
199
199
|
PortableTextEditor.select(editorRef.current, initialSelection)
|
|
@@ -263,7 +263,7 @@ describe('adds empty text block if its needed', () => {
|
|
|
263
263
|
const inlineType = editor?.schemaTypes.inlineObjects.find(
|
|
264
264
|
(t) => t.name === 'someObject',
|
|
265
265
|
)
|
|
266
|
-
await waitFor(
|
|
266
|
+
await waitFor(() => {
|
|
267
267
|
if (editor && inlineType && element) {
|
|
268
268
|
PortableTextEditor.focus(editor)
|
|
269
269
|
PortableTextEditor.select(editor, initialSelection)
|
|
@@ -3,7 +3,7 @@ import {insertBlock} from './behavior.action-utils.insert-block'
|
|
|
3
3
|
import type {BehaviorActionImplementation} from './behavior.actions'
|
|
4
4
|
|
|
5
5
|
export const insertBlockObjectActionImplementation: BehaviorActionImplementation<
|
|
6
|
-
'insert
|
|
6
|
+
'insert.block object'
|
|
7
7
|
> = ({context, action}) => {
|
|
8
8
|
const block = toSlateValue(
|
|
9
9
|
[
|
|
@@ -4,7 +4,7 @@ import type {SlateTextBlock, VoidElement} from '../../types/slate'
|
|
|
4
4
|
import type {BehaviorActionImplementation} from './behavior.actions'
|
|
5
5
|
|
|
6
6
|
export const insertBreakActionImplementation: BehaviorActionImplementation<
|
|
7
|
-
'insert
|
|
7
|
+
'insert.break'
|
|
8
8
|
> = ({context, action}) => {
|
|
9
9
|
const keyGenerator = context.keyGenerator
|
|
10
10
|
const schema = context.schema
|
|
@@ -202,12 +202,12 @@ export const insertBreakActionImplementation: BehaviorActionImplementation<
|
|
|
202
202
|
}
|
|
203
203
|
|
|
204
204
|
export const insertSoftBreakActionImplementation: BehaviorActionImplementation<
|
|
205
|
-
'insert
|
|
205
|
+
'insert.soft break'
|
|
206
206
|
> = ({context, action}) => {
|
|
207
207
|
// This mimics Slate's internal which also just does a regular insert break
|
|
208
208
|
// when soft-breaking
|
|
209
209
|
insertBreakActionImplementation({
|
|
210
210
|
context,
|
|
211
|
-
action: {...action, type: 'insert
|
|
211
|
+
action: {...action, type: 'insert.break'},
|
|
212
212
|
})
|
|
213
213
|
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import {Editor, Transforms, type Element} from 'slate'
|
|
2
|
+
import {toSlateValue} from '../../utils/values'
|
|
3
|
+
import type {BehaviorActionImplementation} from './behavior.actions'
|
|
4
|
+
|
|
5
|
+
export const insertInlineObjectActionImplementation: BehaviorActionImplementation<
|
|
6
|
+
'insert.inline object'
|
|
7
|
+
> = ({context, action}) => {
|
|
8
|
+
if (
|
|
9
|
+
!context.schema.inlineObjects.some(
|
|
10
|
+
(inlineObject) => inlineObject.name === action.inlineObject.name,
|
|
11
|
+
)
|
|
12
|
+
) {
|
|
13
|
+
console.error('Unable to insert unknown inline object')
|
|
14
|
+
return
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (!action.editor.selection) {
|
|
18
|
+
console.error('Unable to insert inline object without selection')
|
|
19
|
+
return
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const [focusTextBlock] = Array.from(
|
|
23
|
+
Editor.nodes(action.editor, {
|
|
24
|
+
at: action.editor.selection.focus.path,
|
|
25
|
+
match: (node) => action.editor.isTextBlock(node),
|
|
26
|
+
}),
|
|
27
|
+
).at(0) ?? [undefined, undefined]
|
|
28
|
+
|
|
29
|
+
if (!focusTextBlock) {
|
|
30
|
+
console.error('Unable to perform action without focus text block')
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const block = toSlateValue(
|
|
35
|
+
[
|
|
36
|
+
{
|
|
37
|
+
_type: context.schema.block.name,
|
|
38
|
+
_key: context.keyGenerator(),
|
|
39
|
+
children: [
|
|
40
|
+
{
|
|
41
|
+
_type: action.inlineObject.name,
|
|
42
|
+
_key: context.keyGenerator(),
|
|
43
|
+
...(action.inlineObject.value ?? {}),
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
{schemaTypes: context.schema},
|
|
49
|
+
).at(0) as unknown as Element
|
|
50
|
+
const child = block?.children.at(0)
|
|
51
|
+
|
|
52
|
+
if (!child) {
|
|
53
|
+
console.error('Unable to insert inline object')
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
Transforms.insertNodes(action.editor, child)
|
|
58
|
+
}
|
|
@@ -2,7 +2,7 @@ import {Editor, Transforms} from 'slate'
|
|
|
2
2
|
import type {BehaviorActionImplementation} from './behavior.actions'
|
|
3
3
|
|
|
4
4
|
export const insertSpanActionImplementation: BehaviorActionImplementation<
|
|
5
|
-
'insert
|
|
5
|
+
'insert.span'
|
|
6
6
|
> = ({context, action}) => {
|
|
7
7
|
if (!action.editor.selection) {
|
|
8
8
|
console.error('Unable to perform action without selection', action)
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import {Editor, Transforms} from 'slate'
|
|
2
|
+
import type {BehaviorActionImplementation} from '../behavior/behavior.actions'
|
|
3
|
+
import {createGuards} from '../behavior/behavior.guards'
|
|
4
|
+
|
|
5
|
+
export const toggleListItemActionImplementation: BehaviorActionImplementation<
|
|
6
|
+
'list item.toggle'
|
|
7
|
+
> = ({context, action}) => {
|
|
8
|
+
const isActive = isListItemActive({
|
|
9
|
+
editor: action.editor,
|
|
10
|
+
listItem: action.listItem,
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
if (isActive) {
|
|
14
|
+
removeListItemActionImplementation({
|
|
15
|
+
context,
|
|
16
|
+
action: {...action, type: 'list item.remove'},
|
|
17
|
+
})
|
|
18
|
+
} else {
|
|
19
|
+
addListItemActionImplementation({
|
|
20
|
+
context,
|
|
21
|
+
action: {...action, type: 'list item.add'},
|
|
22
|
+
})
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const removeListItemActionImplementation: BehaviorActionImplementation<
|
|
27
|
+
'list item.remove'
|
|
28
|
+
> = ({context, action}) => {
|
|
29
|
+
if (!action.editor.selection) {
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const guards = createGuards(context)
|
|
34
|
+
|
|
35
|
+
const selectedBlocks = [
|
|
36
|
+
...Editor.nodes(action.editor, {
|
|
37
|
+
at: action.editor.selection,
|
|
38
|
+
match: (node) => guards.isListBlock(node),
|
|
39
|
+
}),
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
for (const [, at] of selectedBlocks) {
|
|
43
|
+
Transforms.unsetNodes(action.editor, ['listItem', 'level'], {at})
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export const addListItemActionImplementation: BehaviorActionImplementation<
|
|
48
|
+
'list item.add'
|
|
49
|
+
> = ({context, action}) => {
|
|
50
|
+
if (!action.editor.selection) {
|
|
51
|
+
return
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const guards = createGuards(context)
|
|
55
|
+
|
|
56
|
+
const selectedBlocks = [
|
|
57
|
+
...Editor.nodes(action.editor, {
|
|
58
|
+
at: action.editor.selection,
|
|
59
|
+
match: (node) => guards.isTextBlock(node),
|
|
60
|
+
}),
|
|
61
|
+
]
|
|
62
|
+
|
|
63
|
+
for (const [, at] of selectedBlocks) {
|
|
64
|
+
Transforms.setNodes(
|
|
65
|
+
action.editor,
|
|
66
|
+
{
|
|
67
|
+
level: 1,
|
|
68
|
+
listItem: action.listItem,
|
|
69
|
+
},
|
|
70
|
+
{at},
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function isListItemActive({
|
|
76
|
+
editor,
|
|
77
|
+
listItem,
|
|
78
|
+
}: {
|
|
79
|
+
editor: Editor
|
|
80
|
+
listItem: string
|
|
81
|
+
}): boolean {
|
|
82
|
+
if (!editor.selection) {
|
|
83
|
+
return false
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const selectedBlocks = [
|
|
87
|
+
...Editor.nodes(editor, {
|
|
88
|
+
at: editor.selection,
|
|
89
|
+
match: (node) => editor.isTextBlock(node),
|
|
90
|
+
}),
|
|
91
|
+
]
|
|
92
|
+
|
|
93
|
+
if (selectedBlocks.length > 0) {
|
|
94
|
+
return selectedBlocks.every(
|
|
95
|
+
([node]) => editor.isListBlock(node) && node.listItem === listItem,
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return false
|
|
100
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import {Editor, Transforms} from 'slate'
|
|
2
|
+
import type {BehaviorActionImplementation} from './behavior.actions'
|
|
3
|
+
import {createGuards} from './behavior.guards'
|
|
4
|
+
|
|
5
|
+
export const toggleStyleActionImplementation: BehaviorActionImplementation<
|
|
6
|
+
'style.toggle'
|
|
7
|
+
> = ({context, action}) => {
|
|
8
|
+
const isActive = isStyleActive({
|
|
9
|
+
editor: action.editor,
|
|
10
|
+
style: action.style,
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
if (isActive) {
|
|
14
|
+
removeStyleActionImplementation({
|
|
15
|
+
context,
|
|
16
|
+
action: {...action, type: 'style.remove'},
|
|
17
|
+
})
|
|
18
|
+
} else {
|
|
19
|
+
addStyleActionImplementation({
|
|
20
|
+
context,
|
|
21
|
+
action: {...action, type: 'style.add'},
|
|
22
|
+
})
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const removeStyleActionImplementation: BehaviorActionImplementation<
|
|
27
|
+
'style.remove'
|
|
28
|
+
> = ({context, action}) => {
|
|
29
|
+
if (!action.editor.selection) {
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const defaultStyle = context.schema.styles[0].value
|
|
34
|
+
const guards = createGuards(context)
|
|
35
|
+
|
|
36
|
+
const selectedBlocks = [
|
|
37
|
+
...Editor.nodes(action.editor, {
|
|
38
|
+
at: action.editor.selection,
|
|
39
|
+
match: (node) => guards.isTextBlock(node),
|
|
40
|
+
}),
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
for (const [, at] of selectedBlocks) {
|
|
44
|
+
Transforms.setNodes(
|
|
45
|
+
action.editor,
|
|
46
|
+
{
|
|
47
|
+
style: defaultStyle,
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
at,
|
|
51
|
+
},
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export const addStyleActionImplementation: BehaviorActionImplementation<
|
|
57
|
+
'style.add'
|
|
58
|
+
> = ({context, action}) => {
|
|
59
|
+
if (!action.editor.selection) {
|
|
60
|
+
return
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const guards = createGuards(context)
|
|
64
|
+
|
|
65
|
+
const selectedBlocks = [
|
|
66
|
+
...Editor.nodes(action.editor, {
|
|
67
|
+
at: action.editor.selection,
|
|
68
|
+
match: (node) => guards.isTextBlock(node),
|
|
69
|
+
}),
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
for (const [, at] of selectedBlocks) {
|
|
73
|
+
Transforms.setNodes(
|
|
74
|
+
action.editor,
|
|
75
|
+
{
|
|
76
|
+
style: action.style,
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
at,
|
|
80
|
+
},
|
|
81
|
+
)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function isStyleActive({
|
|
86
|
+
editor,
|
|
87
|
+
style,
|
|
88
|
+
}: {
|
|
89
|
+
editor: Editor
|
|
90
|
+
style: string
|
|
91
|
+
}): boolean {
|
|
92
|
+
if (!editor.selection) {
|
|
93
|
+
return false
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const selectedBlocks = [
|
|
97
|
+
...Editor.nodes(editor, {
|
|
98
|
+
at: editor.selection,
|
|
99
|
+
match: (node) => editor.isTextBlock(node),
|
|
100
|
+
}),
|
|
101
|
+
]
|
|
102
|
+
|
|
103
|
+
if (selectedBlocks.length > 0) {
|
|
104
|
+
return selectedBlocks.every(([node]) => node.style === style)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return false
|
|
108
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {Transforms} from 'slate'
|
|
2
|
+
import {toSlateRange} from '../../utils/ranges'
|
|
3
|
+
import type {BehaviorActionImplementation} from './behavior.actions'
|
|
4
|
+
|
|
5
|
+
export const textBlockSetActionImplementation: BehaviorActionImplementation<
|
|
6
|
+
'text block.set'
|
|
7
|
+
> = ({action}) => {
|
|
8
|
+
const at = toSlateRange(
|
|
9
|
+
{
|
|
10
|
+
anchor: {path: action.at, offset: 0},
|
|
11
|
+
focus: {path: action.at, offset: 0},
|
|
12
|
+
},
|
|
13
|
+
action.editor,
|
|
14
|
+
)!
|
|
15
|
+
|
|
16
|
+
Transforms.setNodes(
|
|
17
|
+
action.editor,
|
|
18
|
+
{
|
|
19
|
+
...(action.style ? {style: action.style} : {}),
|
|
20
|
+
...(action.listItem ? {listItem: action.listItem} : {}),
|
|
21
|
+
...(action.level ? {level: action.level} : {}),
|
|
22
|
+
},
|
|
23
|
+
{at},
|
|
24
|
+
)
|
|
25
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {Transforms} from 'slate'
|
|
2
|
+
import {toSlateRange} from '../../utils/ranges'
|
|
3
|
+
import type {BehaviorActionImplementation} from './behavior.actions'
|
|
4
|
+
|
|
5
|
+
export const textBlockUnsetActionImplementation: BehaviorActionImplementation<
|
|
6
|
+
'text block.unset'
|
|
7
|
+
> = ({action}) => {
|
|
8
|
+
const at = toSlateRange(
|
|
9
|
+
{
|
|
10
|
+
anchor: {path: action.at, offset: 0},
|
|
11
|
+
focus: {path: action.at, offset: 0},
|
|
12
|
+
},
|
|
13
|
+
action.editor,
|
|
14
|
+
)!
|
|
15
|
+
|
|
16
|
+
Transforms.unsetNodes(action.editor, action.props, {at})
|
|
17
|
+
}
|