@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
|
@@ -1,61 +1,61 @@
|
|
|
1
1
|
import {isPortableTextTextBlock} from '@sanity/types'
|
|
2
|
-
import {isHotkey} from '../../utils/is-hotkey'
|
|
3
|
-
import {defineBehavior} from './behavior.types'
|
|
4
2
|
import {
|
|
5
3
|
getFocusBlockObject,
|
|
6
4
|
getFocusTextBlock,
|
|
7
5
|
getNextBlock,
|
|
8
6
|
getPreviousBlock,
|
|
9
|
-
isEmptyTextBlock,
|
|
10
7
|
selectionIsCollapsed,
|
|
11
|
-
} from '
|
|
8
|
+
} from '../../selectors/selectors'
|
|
9
|
+
import {isHotkey} from '../../utils/is-hotkey'
|
|
10
|
+
import {isEmptyTextBlock} from '../utils/utils'
|
|
11
|
+
import {defineBehavior} from './behavior.types'
|
|
12
12
|
|
|
13
13
|
const arrowDownOnLonelyBlockObject = defineBehavior({
|
|
14
14
|
on: 'key.down',
|
|
15
15
|
guard: ({context, event}) => {
|
|
16
16
|
const isArrowDown = isHotkey('ArrowDown', event.keyboardEvent)
|
|
17
|
-
const focusBlockObject = getFocusBlockObject(context)
|
|
18
|
-
const nextBlock = getNextBlock(context)
|
|
17
|
+
const focusBlockObject = getFocusBlockObject({context})
|
|
18
|
+
const nextBlock = getNextBlock({context})
|
|
19
19
|
|
|
20
20
|
return isArrowDown && focusBlockObject && !nextBlock
|
|
21
21
|
},
|
|
22
|
-
actions: [() => [{type: 'insert
|
|
22
|
+
actions: [() => [{type: 'insert.text block', placement: 'after'}]],
|
|
23
23
|
})
|
|
24
24
|
|
|
25
25
|
const arrowUpOnLonelyBlockObject = defineBehavior({
|
|
26
26
|
on: 'key.down',
|
|
27
27
|
guard: ({context, event}) => {
|
|
28
28
|
const isArrowUp = isHotkey('ArrowUp', event.keyboardEvent)
|
|
29
|
-
const focusBlockObject = getFocusBlockObject(context)
|
|
30
|
-
const previousBlock = getPreviousBlock(context)
|
|
29
|
+
const focusBlockObject = getFocusBlockObject({context})
|
|
30
|
+
const previousBlock = getPreviousBlock({context})
|
|
31
31
|
|
|
32
32
|
return isArrowUp && focusBlockObject && !previousBlock
|
|
33
33
|
},
|
|
34
34
|
actions: [
|
|
35
35
|
() => [
|
|
36
|
-
{type: 'insert
|
|
36
|
+
{type: 'insert.text block', placement: 'before'},
|
|
37
37
|
{type: 'select previous block'},
|
|
38
38
|
],
|
|
39
39
|
],
|
|
40
40
|
})
|
|
41
41
|
|
|
42
42
|
const breakingBlockObject = defineBehavior({
|
|
43
|
-
on: 'insert
|
|
43
|
+
on: 'insert.break',
|
|
44
44
|
guard: ({context}) => {
|
|
45
|
-
const focusBlockObject = getFocusBlockObject(context)
|
|
46
|
-
const collapsedSelection = selectionIsCollapsed(context)
|
|
45
|
+
const focusBlockObject = getFocusBlockObject({context})
|
|
46
|
+
const collapsedSelection = selectionIsCollapsed({context})
|
|
47
47
|
|
|
48
48
|
return collapsedSelection && focusBlockObject !== undefined
|
|
49
49
|
},
|
|
50
|
-
actions: [() => [{type: 'insert
|
|
50
|
+
actions: [() => [{type: 'insert.text block', placement: 'after'}]],
|
|
51
51
|
})
|
|
52
52
|
|
|
53
53
|
const deletingEmptyTextBlockAfterBlockObject = defineBehavior({
|
|
54
|
-
on: 'delete
|
|
54
|
+
on: 'delete.backward',
|
|
55
55
|
guard: ({context}) => {
|
|
56
|
-
const focusTextBlock = getFocusTextBlock(context)
|
|
57
|
-
const selectionCollapsed = selectionIsCollapsed(context)
|
|
58
|
-
const previousBlock = getPreviousBlock(context)
|
|
56
|
+
const focusTextBlock = getFocusTextBlock({context})
|
|
57
|
+
const selectionCollapsed = selectionIsCollapsed({context})
|
|
58
|
+
const previousBlock = getPreviousBlock({context})
|
|
59
59
|
|
|
60
60
|
if (!focusTextBlock || !selectionCollapsed || !previousBlock) {
|
|
61
61
|
return false
|
|
@@ -71,9 +71,9 @@ const deletingEmptyTextBlockAfterBlockObject = defineBehavior({
|
|
|
71
71
|
return false
|
|
72
72
|
},
|
|
73
73
|
actions: [
|
|
74
|
-
(
|
|
74
|
+
({focusTextBlock, previousBlock}) => [
|
|
75
75
|
{
|
|
76
|
-
type: 'delete
|
|
76
|
+
type: 'delete.block',
|
|
77
77
|
blockPath: focusTextBlock.path,
|
|
78
78
|
},
|
|
79
79
|
{
|
|
@@ -88,11 +88,11 @@ const deletingEmptyTextBlockAfterBlockObject = defineBehavior({
|
|
|
88
88
|
})
|
|
89
89
|
|
|
90
90
|
const deletingEmptyTextBlockBeforeBlockObject = defineBehavior({
|
|
91
|
-
on: 'delete
|
|
91
|
+
on: 'delete.forward',
|
|
92
92
|
guard: ({context}) => {
|
|
93
|
-
const focusTextBlock = getFocusTextBlock(context)
|
|
94
|
-
const selectionCollapsed = selectionIsCollapsed(context)
|
|
95
|
-
const nextBlock = getNextBlock(context)
|
|
93
|
+
const focusTextBlock = getFocusTextBlock({context})
|
|
94
|
+
const selectionCollapsed = selectionIsCollapsed({context})
|
|
95
|
+
const nextBlock = getNextBlock({context})
|
|
96
96
|
|
|
97
97
|
if (!focusTextBlock || !selectionCollapsed || !nextBlock) {
|
|
98
98
|
return false
|
|
@@ -108,9 +108,9 @@ const deletingEmptyTextBlockBeforeBlockObject = defineBehavior({
|
|
|
108
108
|
return false
|
|
109
109
|
},
|
|
110
110
|
actions: [
|
|
111
|
-
(
|
|
111
|
+
({focusTextBlock, nextBlock}) => [
|
|
112
112
|
{
|
|
113
|
-
type: 'delete
|
|
113
|
+
type: 'delete.block',
|
|
114
114
|
blockPath: focusTextBlock.path,
|
|
115
115
|
},
|
|
116
116
|
{
|
|
@@ -2,11 +2,12 @@ import {defineBehavior} from './behavior.types'
|
|
|
2
2
|
|
|
3
3
|
const decoratorAdd = defineBehavior({
|
|
4
4
|
on: 'decorator.add',
|
|
5
|
+
guard: ({event}) => ({decorator: event.decorator}),
|
|
5
6
|
actions: [
|
|
6
|
-
({
|
|
7
|
+
({decorator}) => [
|
|
7
8
|
{
|
|
8
9
|
type: 'decorator.add',
|
|
9
|
-
decorator
|
|
10
|
+
decorator,
|
|
10
11
|
},
|
|
11
12
|
{
|
|
12
13
|
type: 'reselect',
|
|
@@ -17,11 +18,12 @@ const decoratorAdd = defineBehavior({
|
|
|
17
18
|
|
|
18
19
|
const decoratorRemove = defineBehavior({
|
|
19
20
|
on: 'decorator.remove',
|
|
21
|
+
guard: ({event}) => ({decorator: event.decorator}),
|
|
20
22
|
actions: [
|
|
21
|
-
({
|
|
23
|
+
({decorator}) => [
|
|
22
24
|
{
|
|
23
25
|
type: 'decorator.remove',
|
|
24
|
-
decorator
|
|
26
|
+
decorator,
|
|
25
27
|
},
|
|
26
28
|
{
|
|
27
29
|
type: 'reselect',
|
|
@@ -32,11 +34,12 @@ const decoratorRemove = defineBehavior({
|
|
|
32
34
|
|
|
33
35
|
const decoratorToggle = defineBehavior({
|
|
34
36
|
on: 'decorator.toggle',
|
|
37
|
+
guard: ({event}) => ({decorator: event.decorator}),
|
|
35
38
|
actions: [
|
|
36
|
-
({
|
|
39
|
+
({decorator}) => [
|
|
37
40
|
{
|
|
38
41
|
type: 'decorator.toggle',
|
|
39
|
-
decorator
|
|
42
|
+
decorator,
|
|
40
43
|
},
|
|
41
44
|
{
|
|
42
45
|
type: 'reselect',
|
|
@@ -1,16 +1,23 @@
|
|
|
1
|
-
import {defineBehavior} from './behavior.types'
|
|
2
1
|
import {
|
|
2
|
+
getFocusListBlock,
|
|
3
3
|
getFocusSpan,
|
|
4
4
|
getFocusTextBlock,
|
|
5
|
+
getSelectedBlocks,
|
|
5
6
|
selectionIsCollapsed,
|
|
6
|
-
} from '
|
|
7
|
+
} from '../../selectors/selectors'
|
|
8
|
+
import {isHotkey} from '../../utils/is-hotkey'
|
|
9
|
+
import {isEmptyTextBlock} from '../utils/utils'
|
|
10
|
+
import {createGuards} from './behavior.guards'
|
|
11
|
+
import {defineBehavior} from './behavior.types'
|
|
12
|
+
|
|
13
|
+
const MAX_LIST_LEVEL = 10
|
|
7
14
|
|
|
8
15
|
const clearListOnBackspace = defineBehavior({
|
|
9
|
-
on: 'delete
|
|
16
|
+
on: 'delete.backward',
|
|
10
17
|
guard: ({context}) => {
|
|
11
|
-
const selectionCollapsed = selectionIsCollapsed(context)
|
|
12
|
-
const focusTextBlock = getFocusTextBlock(context)
|
|
13
|
-
const focusSpan = getFocusSpan(context)
|
|
18
|
+
const selectionCollapsed = selectionIsCollapsed({context})
|
|
19
|
+
const focusTextBlock = getFocusTextBlock({context})
|
|
20
|
+
const focusSpan = getFocusSpan({context})
|
|
14
21
|
|
|
15
22
|
if (!selectionCollapsed || !focusTextBlock || !focusSpan) {
|
|
16
23
|
return false
|
|
@@ -27,22 +34,22 @@ const clearListOnBackspace = defineBehavior({
|
|
|
27
34
|
return false
|
|
28
35
|
},
|
|
29
36
|
actions: [
|
|
30
|
-
(
|
|
37
|
+
({focusTextBlock}) => [
|
|
31
38
|
{
|
|
32
|
-
type: '
|
|
39
|
+
type: 'text block.unset',
|
|
33
40
|
props: ['listItem', 'level'],
|
|
34
|
-
|
|
41
|
+
at: focusTextBlock.path,
|
|
35
42
|
},
|
|
36
43
|
],
|
|
37
44
|
],
|
|
38
45
|
})
|
|
39
46
|
|
|
40
47
|
const unindentListOnBackspace = defineBehavior({
|
|
41
|
-
on: 'delete
|
|
48
|
+
on: 'delete.backward',
|
|
42
49
|
guard: ({context}) => {
|
|
43
|
-
const selectionCollapsed = selectionIsCollapsed(context)
|
|
44
|
-
const focusTextBlock = getFocusTextBlock(context)
|
|
45
|
-
const focusSpan = getFocusSpan(context)
|
|
50
|
+
const selectionCollapsed = selectionIsCollapsed({context})
|
|
51
|
+
const focusTextBlock = getFocusTextBlock({context})
|
|
52
|
+
const focusSpan = getFocusSpan({context})
|
|
46
53
|
|
|
47
54
|
if (!selectionCollapsed || !focusTextBlock || !focusSpan) {
|
|
48
55
|
return false
|
|
@@ -63,14 +70,129 @@ const unindentListOnBackspace = defineBehavior({
|
|
|
63
70
|
return false
|
|
64
71
|
},
|
|
65
72
|
actions: [
|
|
66
|
-
(
|
|
73
|
+
({focusTextBlock, level}) => [
|
|
67
74
|
{
|
|
68
|
-
type: '
|
|
75
|
+
type: 'text block.set',
|
|
69
76
|
level,
|
|
70
|
-
|
|
77
|
+
at: focusTextBlock.path,
|
|
71
78
|
},
|
|
72
79
|
],
|
|
73
80
|
],
|
|
74
81
|
})
|
|
75
82
|
|
|
76
|
-
|
|
83
|
+
const clearListOnEnter = defineBehavior({
|
|
84
|
+
on: 'insert.break',
|
|
85
|
+
guard: ({context}) => {
|
|
86
|
+
const focusListBlock = getFocusListBlock({context})
|
|
87
|
+
const selectionCollapsed = selectionIsCollapsed({context})
|
|
88
|
+
|
|
89
|
+
if (!focusListBlock || !selectionCollapsed) {
|
|
90
|
+
return false
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (!isEmptyTextBlock(focusListBlock.node)) {
|
|
94
|
+
return false
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return {focusListBlock}
|
|
98
|
+
},
|
|
99
|
+
actions: [
|
|
100
|
+
({focusListBlock}) => [
|
|
101
|
+
{
|
|
102
|
+
type: 'text block.unset',
|
|
103
|
+
props: ['listItem', 'level'],
|
|
104
|
+
at: focusListBlock.path,
|
|
105
|
+
},
|
|
106
|
+
],
|
|
107
|
+
],
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
const indentListOnTab = defineBehavior({
|
|
111
|
+
on: 'key.down',
|
|
112
|
+
guard: ({context, event}) => {
|
|
113
|
+
const isTab = isHotkey('Tab', event.keyboardEvent)
|
|
114
|
+
|
|
115
|
+
if (!isTab) {
|
|
116
|
+
return false
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const selectedBlocks = getSelectedBlocks({context})
|
|
120
|
+
const guards = createGuards(context)
|
|
121
|
+
const selectedListBlocks = selectedBlocks.flatMap((block) =>
|
|
122
|
+
guards.isListBlock(block.node)
|
|
123
|
+
? [
|
|
124
|
+
{
|
|
125
|
+
node: block.node,
|
|
126
|
+
path: block.path,
|
|
127
|
+
},
|
|
128
|
+
]
|
|
129
|
+
: [],
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
if (selectedListBlocks.length === selectedBlocks.length) {
|
|
133
|
+
return {selectedListBlocks}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return false
|
|
137
|
+
},
|
|
138
|
+
actions: [
|
|
139
|
+
({selectedListBlocks}) =>
|
|
140
|
+
selectedListBlocks.map((selectedListBlock) => ({
|
|
141
|
+
type: 'text block.set',
|
|
142
|
+
level: Math.min(
|
|
143
|
+
MAX_LIST_LEVEL,
|
|
144
|
+
Math.max(1, selectedListBlock.node.level + 1),
|
|
145
|
+
),
|
|
146
|
+
at: selectedListBlock.path,
|
|
147
|
+
})),
|
|
148
|
+
],
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
const unindentListOnShiftTab = defineBehavior({
|
|
152
|
+
on: 'key.down',
|
|
153
|
+
guard: ({context, event}) => {
|
|
154
|
+
const isShiftTab = isHotkey('Shift+Tab', event.keyboardEvent)
|
|
155
|
+
|
|
156
|
+
if (!isShiftTab) {
|
|
157
|
+
return false
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const selectedBlocks = getSelectedBlocks({context})
|
|
161
|
+
const guards = createGuards(context)
|
|
162
|
+
const selectedListBlocks = selectedBlocks.flatMap((block) =>
|
|
163
|
+
guards.isListBlock(block.node)
|
|
164
|
+
? [
|
|
165
|
+
{
|
|
166
|
+
node: block.node,
|
|
167
|
+
path: block.path,
|
|
168
|
+
},
|
|
169
|
+
]
|
|
170
|
+
: [],
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
if (selectedListBlocks.length === selectedBlocks.length) {
|
|
174
|
+
return {selectedListBlocks}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return false
|
|
178
|
+
},
|
|
179
|
+
actions: [
|
|
180
|
+
({selectedListBlocks}) =>
|
|
181
|
+
selectedListBlocks.map((selectedListBlock) => ({
|
|
182
|
+
type: 'text block.set',
|
|
183
|
+
level: Math.min(
|
|
184
|
+
MAX_LIST_LEVEL,
|
|
185
|
+
Math.max(1, selectedListBlock.node.level - 1),
|
|
186
|
+
),
|
|
187
|
+
at: selectedListBlock.path,
|
|
188
|
+
})),
|
|
189
|
+
],
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
export const coreListBehaviors = {
|
|
193
|
+
clearListOnBackspace,
|
|
194
|
+
unindentListOnBackspace,
|
|
195
|
+
clearListOnEnter,
|
|
196
|
+
indentListOnTab,
|
|
197
|
+
unindentListOnShiftTab,
|
|
198
|
+
}
|
|
@@ -4,8 +4,8 @@ import {coreListBehaviors} from './behavior.core.lists'
|
|
|
4
4
|
import {defineBehavior} from './behavior.types'
|
|
5
5
|
|
|
6
6
|
const softReturn = defineBehavior({
|
|
7
|
-
on: 'insert
|
|
8
|
-
actions: [() => [{type: 'insert
|
|
7
|
+
on: 'insert.soft break',
|
|
8
|
+
actions: [() => [{type: 'insert.text', text: '\n'}]],
|
|
9
9
|
})
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -23,6 +23,9 @@ export const coreBehaviors = [
|
|
|
23
23
|
coreBlockObjectBehaviors.deletingEmptyTextBlockBeforeBlockObject,
|
|
24
24
|
coreListBehaviors.clearListOnBackspace,
|
|
25
25
|
coreListBehaviors.unindentListOnBackspace,
|
|
26
|
+
coreListBehaviors.clearListOnEnter,
|
|
27
|
+
coreListBehaviors.indentListOnTab,
|
|
28
|
+
coreListBehaviors.unindentListOnShiftTab,
|
|
26
29
|
]
|
|
27
30
|
|
|
28
31
|
/**
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isPortableTextListBlock,
|
|
3
|
+
isPortableTextTextBlock,
|
|
4
|
+
type PortableTextListBlock,
|
|
5
|
+
type PortableTextTextBlock,
|
|
6
|
+
} from '@sanity/types'
|
|
7
|
+
import type {PortableTextMemberSchemaTypes} from '../../types/editor'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @alpha
|
|
11
|
+
*/
|
|
12
|
+
export type BehaviorGuards = ReturnType<typeof createGuards>
|
|
13
|
+
|
|
14
|
+
export function createGuards({
|
|
15
|
+
schema,
|
|
16
|
+
}: {
|
|
17
|
+
schema: PortableTextMemberSchemaTypes
|
|
18
|
+
}) {
|
|
19
|
+
function isListBlock(block: unknown): block is PortableTextListBlock {
|
|
20
|
+
return isPortableTextListBlock(block) && block._type === schema.block.name
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function isTextBlock(block: unknown): block is PortableTextTextBlock {
|
|
24
|
+
return isPortableTextTextBlock(block) && block._type === schema.block.name
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return {isListBlock, isTextBlock}
|
|
28
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import {getFocusSpan, selectionIsCollapsed} from '../../selectors/selectors'
|
|
1
2
|
import type {PortableTextMemberSchemaTypes} from '../../types/editor'
|
|
2
3
|
import {defineBehavior} from './behavior.types'
|
|
3
|
-
import {getFocusSpan, selectionIsCollapsed} from './behavior.utils'
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @alpha
|
|
@@ -19,7 +19,7 @@ export function createLinkBehaviors(config: LinkBehaviorsConfig) {
|
|
|
19
19
|
const pasteLinkOnSelection = defineBehavior({
|
|
20
20
|
on: 'paste',
|
|
21
21
|
guard: ({context, event}) => {
|
|
22
|
-
const selectionCollapsed = selectionIsCollapsed(context)
|
|
22
|
+
const selectionCollapsed = selectionIsCollapsed({context})
|
|
23
23
|
const text = event.data.getData('text/plain')
|
|
24
24
|
const url = looksLikeUrl(text) ? text : undefined
|
|
25
25
|
const annotation =
|
|
@@ -34,7 +34,7 @@ export function createLinkBehaviors(config: LinkBehaviorsConfig) {
|
|
|
34
34
|
return false
|
|
35
35
|
},
|
|
36
36
|
actions: [
|
|
37
|
-
(
|
|
37
|
+
({annotation}) => [
|
|
38
38
|
{
|
|
39
39
|
type: 'annotation.add',
|
|
40
40
|
annotation,
|
|
@@ -45,8 +45,8 @@ export function createLinkBehaviors(config: LinkBehaviorsConfig) {
|
|
|
45
45
|
const pasteLinkAtCaret = defineBehavior({
|
|
46
46
|
on: 'paste',
|
|
47
47
|
guard: ({context, event}) => {
|
|
48
|
-
const focusSpan = getFocusSpan(context)
|
|
49
|
-
const selectionCollapsed = selectionIsCollapsed(context)
|
|
48
|
+
const focusSpan = getFocusSpan({context})
|
|
49
|
+
const selectionCollapsed = selectionIsCollapsed({context})
|
|
50
50
|
|
|
51
51
|
if (!focusSpan || !selectionCollapsed) {
|
|
52
52
|
return false
|
|
@@ -66,9 +66,9 @@ export function createLinkBehaviors(config: LinkBehaviorsConfig) {
|
|
|
66
66
|
return false
|
|
67
67
|
},
|
|
68
68
|
actions: [
|
|
69
|
-
(
|
|
69
|
+
({annotation, url}) => [
|
|
70
70
|
{
|
|
71
|
-
type: 'insert
|
|
71
|
+
type: 'insert.span',
|
|
72
72
|
text: url,
|
|
73
73
|
annotations: [annotation],
|
|
74
74
|
},
|