@portabletext/editor 1.25.0 → 1.26.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/_chunks-cjs/behavior.core.cjs +131 -36
- package/lib/_chunks-cjs/behavior.core.cjs.map +1 -1
- package/lib/_chunks-cjs/selector.get-text-before.cjs +8 -8
- package/lib/_chunks-cjs/selector.get-text-before.cjs.map +1 -1
- package/lib/_chunks-cjs/{selector.is-active-style.cjs → selector.is-at-the-start-of-block.cjs} +29 -3
- package/lib/_chunks-cjs/selector.is-at-the-start-of-block.cjs.map +1 -0
- package/lib/_chunks-cjs/util.is-empty-text-block.cjs +2 -2
- package/lib/_chunks-cjs/util.is-empty-text-block.cjs.map +1 -1
- package/lib/_chunks-cjs/util.is-equal-selection-points.cjs +46 -0
- package/lib/_chunks-cjs/util.is-equal-selection-points.cjs.map +1 -0
- package/lib/_chunks-cjs/util.reverse-selection.cjs +0 -16
- package/lib/_chunks-cjs/util.reverse-selection.cjs.map +1 -1
- package/lib/_chunks-es/behavior.core.js +99 -4
- package/lib/_chunks-es/behavior.core.js.map +1 -1
- package/lib/_chunks-es/selector.get-text-before.js +2 -2
- package/lib/_chunks-es/{selector.is-active-style.js → selector.is-at-the-start-of-block.js} +29 -2
- package/lib/_chunks-es/selector.is-at-the-start-of-block.js.map +1 -0
- package/lib/_chunks-es/util.is-empty-text-block.js +1 -1
- package/lib/_chunks-es/util.is-equal-selection-points.js +47 -0
- package/lib/_chunks-es/util.is-equal-selection-points.js.map +1 -0
- package/lib/_chunks-es/util.reverse-selection.js +0 -16
- package/lib/_chunks-es/util.reverse-selection.js.map +1 -1
- package/lib/behaviors/index.cjs +27 -27
- package/lib/behaviors/index.cjs.map +1 -1
- package/lib/behaviors/index.d.cts +413 -0
- package/lib/behaviors/index.d.ts +413 -0
- package/lib/behaviors/index.js +1 -1
- package/lib/index.cjs +184 -116
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +1653 -222
- package/lib/index.d.ts +1653 -222
- package/lib/index.js +180 -112
- package/lib/index.js.map +1 -1
- package/lib/selectors/index.cjs +25 -23
- package/lib/selectors/index.cjs.map +1 -1
- package/lib/selectors/index.d.cts +16 -0
- package/lib/selectors/index.d.ts +16 -0
- package/lib/selectors/index.js +3 -1
- package/lib/utils/index.cjs +5 -3
- package/lib/utils/index.cjs.map +1 -1
- package/lib/utils/index.d.cts +19 -0
- package/lib/utils/index.d.ts +19 -0
- package/lib/utils/index.js +4 -2
- package/package.json +6 -6
- package/src/behavior-actions/behavior.action-utils.insert-block.ts +3 -3
- package/src/behavior-actions/behavior.action.block.set.ts +23 -0
- package/src/behavior-actions/behavior.action.block.unset.ts +21 -0
- package/src/behavior-actions/behavior.action.insert-break.ts +2 -69
- package/src/behavior-actions/behavior.action.insert.block.ts +33 -0
- package/src/behavior-actions/behavior.actions.ts +28 -9
- package/src/behaviors/behavior.core.insert-break.ts +122 -0
- package/src/behaviors/behavior.core.ts +6 -2
- package/src/behaviors/behavior.types.ts +16 -1
- package/src/converters/converter.json.ts +4 -4
- package/src/converters/converter.portable-text.deserialize.test.ts +1 -1
- package/src/converters/converter.portable-text.ts +9 -5
- package/src/converters/converter.text-html.deserialize.test.ts +1 -1
- package/src/converters/converter.text-html.serialize.test.ts +1 -1
- package/src/converters/converter.text-html.ts +4 -4
- package/src/converters/converter.text-plain.test.ts +1 -1
- package/src/converters/converter.text-plain.ts +3 -3
- package/src/converters/{converter.ts → converter.types.ts} +6 -0
- package/src/editor/__tests__/handleClick.test.tsx +2 -2
- package/src/editor/__tests__/pteWarningsSelfSolving.test.tsx +1 -1
- package/src/editor/create-editor.ts +4 -1
- package/src/editor/editor-machine.ts +8 -2
- package/src/editor/editor-snapshot.ts +1 -1
- package/src/editor/plugins/__tests__/withEditableAPIInsert.test.tsx +12 -12
- package/src/editor/plugins/__tests__/withPortableTextMarkModel.test.tsx +29 -36
- package/src/editor/plugins/create-with-event-listeners.ts +3 -0
- package/src/editor/plugins/createWithObjectKeys.ts +18 -2
- package/src/editor/plugins/createWithPortableTextMarkModel.ts +3 -0
- package/src/internal-utils/parse-blocks.ts +36 -6
- package/src/selectors/index.ts +2 -0
- package/src/selectors/selector.is-at-the-end-of-block.ts +22 -0
- package/src/selectors/selector.is-at-the-start-of-block.ts +25 -0
- package/src/selectors/selector.is-selection-collapsed.ts +6 -2
- package/src/utils/index.ts +2 -0
- package/src/utils/util.get-block-end-point.ts +34 -0
- package/src/utils/util.is-equal-selection-points.ts +13 -0
- package/lib/_chunks-cjs/selector.is-active-style.cjs.map +0 -1
- package/lib/_chunks-cjs/util.is-keyed-segment.cjs +0 -6
- package/lib/_chunks-cjs/util.is-keyed-segment.cjs.map +0 -1
- package/lib/_chunks-es/selector.is-active-style.js.map +0 -1
- package/lib/_chunks-es/util.is-keyed-segment.js +0 -7
- package/lib/_chunks-es/util.is-keyed-segment.js.map +0 -1
- /package/src/converters/{converters.ts → converters.core.ts} +0 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import * as selectors from '../selectors'
|
|
2
|
+
import {defineBehavior, raise} from './behavior.types'
|
|
3
|
+
|
|
4
|
+
const atTheEndOfTextBlock = defineBehavior({
|
|
5
|
+
on: 'insert.break',
|
|
6
|
+
guard: ({context}) => {
|
|
7
|
+
const focusTextBlock = selectors.getFocusTextBlock({context})
|
|
8
|
+
const selectionCollapsed = selectors.isSelectionCollapsed({context})
|
|
9
|
+
|
|
10
|
+
if (!context.selection || !focusTextBlock || !selectionCollapsed) {
|
|
11
|
+
return false
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const atTheEndOfBlock = selectors.isAtTheEndOfBlock(focusTextBlock)({
|
|
15
|
+
context,
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
const focusListItem = focusTextBlock.node.listItem
|
|
19
|
+
const focusLevel = focusTextBlock.node.level
|
|
20
|
+
|
|
21
|
+
if (atTheEndOfBlock) {
|
|
22
|
+
return {focusListItem, focusLevel}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return false
|
|
26
|
+
},
|
|
27
|
+
actions: [
|
|
28
|
+
({context}, {focusListItem, focusLevel}) => [
|
|
29
|
+
raise({
|
|
30
|
+
type: 'insert.block',
|
|
31
|
+
block: {
|
|
32
|
+
_type: context.schema.block.name,
|
|
33
|
+
_key: context.keyGenerator(),
|
|
34
|
+
children: [
|
|
35
|
+
{
|
|
36
|
+
_key: context.keyGenerator(),
|
|
37
|
+
_type: context.schema.span.name,
|
|
38
|
+
text: '',
|
|
39
|
+
marks: [],
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
markDefs: [],
|
|
43
|
+
listItem: focusListItem,
|
|
44
|
+
level: focusLevel,
|
|
45
|
+
style: context.schema.styles[0]?.value,
|
|
46
|
+
},
|
|
47
|
+
placement: 'after',
|
|
48
|
+
}),
|
|
49
|
+
],
|
|
50
|
+
],
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
const atTheStartOfTextBlock = defineBehavior({
|
|
54
|
+
on: 'insert.break',
|
|
55
|
+
guard: ({context}) => {
|
|
56
|
+
const focusTextBlock = selectors.getFocusTextBlock({context})
|
|
57
|
+
const selectionCollapsed = selectors.isSelectionCollapsed({context})
|
|
58
|
+
|
|
59
|
+
if (!context.selection || !focusTextBlock || !selectionCollapsed) {
|
|
60
|
+
return false
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const focusSpan = selectors.getFocusSpan({context})
|
|
64
|
+
|
|
65
|
+
const focusDecorators = focusSpan?.node.marks?.filter(
|
|
66
|
+
(mark) =>
|
|
67
|
+
context.schema.decorators.some(
|
|
68
|
+
(decorator) => decorator.value === mark,
|
|
69
|
+
) ?? [],
|
|
70
|
+
)
|
|
71
|
+
const focusAnnotations =
|
|
72
|
+
focusSpan?.node.marks?.filter(
|
|
73
|
+
(mark) =>
|
|
74
|
+
!context.schema.decorators.some(
|
|
75
|
+
(decorator) => decorator.value === mark,
|
|
76
|
+
),
|
|
77
|
+
) ?? []
|
|
78
|
+
const focusListItem = focusTextBlock.node.listItem
|
|
79
|
+
const focusLevel = focusTextBlock.node.level
|
|
80
|
+
|
|
81
|
+
const atTheStartOfBlock = selectors.isAtTheStartOfBlock(focusTextBlock)({
|
|
82
|
+
context,
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
if (atTheStartOfBlock) {
|
|
86
|
+
return {focusAnnotations, focusDecorators, focusListItem, focusLevel}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return false
|
|
90
|
+
},
|
|
91
|
+
actions: [
|
|
92
|
+
(
|
|
93
|
+
{context},
|
|
94
|
+
{focusAnnotations, focusDecorators, focusListItem, focusLevel},
|
|
95
|
+
) => [
|
|
96
|
+
raise({
|
|
97
|
+
type: 'insert.block',
|
|
98
|
+
block: {
|
|
99
|
+
_key: context.keyGenerator(),
|
|
100
|
+
_type: context.schema.block.name,
|
|
101
|
+
children: [
|
|
102
|
+
{
|
|
103
|
+
_key: context.keyGenerator(),
|
|
104
|
+
_type: context.schema.span.name,
|
|
105
|
+
marks: focusAnnotations.length === 0 ? focusDecorators : [],
|
|
106
|
+
text: '',
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
listItem: focusListItem,
|
|
110
|
+
level: focusLevel,
|
|
111
|
+
style: context.schema.styles[0]?.value,
|
|
112
|
+
},
|
|
113
|
+
placement: 'before',
|
|
114
|
+
}),
|
|
115
|
+
],
|
|
116
|
+
],
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
export const coreInsertBreakBehaviors = {
|
|
120
|
+
atTheEndOfTextBlock,
|
|
121
|
+
atTheStartOfTextBlock,
|
|
122
|
+
}
|
|
@@ -2,14 +2,15 @@ import {coreAnnotationBehaviors} from './behavior.core.annotations'
|
|
|
2
2
|
import {coreBlockObjectBehaviors} from './behavior.core.block-objects'
|
|
3
3
|
import {coreDecoratorBehaviors} from './behavior.core.decorators'
|
|
4
4
|
import {coreDeserializeBehavior} from './behavior.core.deserialize'
|
|
5
|
+
import {coreInsertBreakBehaviors} from './behavior.core.insert-break'
|
|
5
6
|
import {coreListBehaviors} from './behavior.core.lists'
|
|
6
7
|
import {coreSerializeBehaviors} from './behavior.core.serialize'
|
|
7
8
|
import {coreStyleBehaviors} from './behavior.core.style'
|
|
8
|
-
import {defineBehavior} from './behavior.types'
|
|
9
|
+
import {defineBehavior, raise} from './behavior.types'
|
|
9
10
|
|
|
10
11
|
const softReturn = defineBehavior({
|
|
11
12
|
on: 'insert.soft break',
|
|
12
|
-
actions: [() => [{type: 'insert.text', text: '\n'}]],
|
|
13
|
+
actions: [() => [raise({type: 'insert.text', text: '\n'})]],
|
|
13
14
|
})
|
|
14
15
|
|
|
15
16
|
/**
|
|
@@ -38,6 +39,8 @@ export const coreBehaviors = [
|
|
|
38
39
|
coreListBehaviors.clearListOnEnter,
|
|
39
40
|
coreListBehaviors.indentListOnTab,
|
|
40
41
|
coreListBehaviors.unindentListOnShiftTab,
|
|
42
|
+
coreInsertBreakBehaviors.atTheEndOfTextBlock,
|
|
43
|
+
coreInsertBreakBehaviors.atTheStartOfTextBlock,
|
|
41
44
|
coreSerializeBehaviors.serialize,
|
|
42
45
|
coreSerializeBehaviors['serialization.success'],
|
|
43
46
|
coreStyleBehaviors.toggleStyleOff,
|
|
@@ -53,6 +56,7 @@ export const coreBehavior = {
|
|
|
53
56
|
decorators: coreDecoratorBehaviors,
|
|
54
57
|
deserialize: coreDeserializeBehavior,
|
|
55
58
|
blockObjects: coreBlockObjectBehaviors,
|
|
59
|
+
insertBreak: coreInsertBreakBehaviors,
|
|
56
60
|
lists: coreListBehaviors,
|
|
57
61
|
...coreSerializeBehaviors,
|
|
58
62
|
style: coreSerializeBehaviors,
|
|
@@ -5,7 +5,7 @@ import type {
|
|
|
5
5
|
} from '@sanity/types'
|
|
6
6
|
import type {TextUnit} from 'slate'
|
|
7
7
|
import type {TextInsertTextOptions} from 'slate/dist/interfaces/transforms/text'
|
|
8
|
-
import type {ConverterEvent} from '../converters/converter'
|
|
8
|
+
import type {ConverterEvent} from '../converters/converter.types'
|
|
9
9
|
import type {EditorContext} from '../editor/editor-snapshot'
|
|
10
10
|
import type {MIMEType} from '../internal-utils/mime-type'
|
|
11
11
|
import type {OmitFromUnion, PickFromUnion} from '../type-utils'
|
|
@@ -35,6 +35,16 @@ export type SyntheticBehaviorEvent =
|
|
|
35
35
|
value: {[prop: string]: unknown}
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
+
| {
|
|
39
|
+
type: 'block.set'
|
|
40
|
+
at: [KeyedSegment]
|
|
41
|
+
[props: string]: unknown
|
|
42
|
+
}
|
|
43
|
+
| {
|
|
44
|
+
type: 'block.unset'
|
|
45
|
+
at: [KeyedSegment]
|
|
46
|
+
props: Array<string>
|
|
47
|
+
}
|
|
38
48
|
| {
|
|
39
49
|
type: 'blur'
|
|
40
50
|
}
|
|
@@ -101,6 +111,11 @@ export type SyntheticBehaviorEvent =
|
|
|
101
111
|
| {
|
|
102
112
|
type: 'insert.soft break'
|
|
103
113
|
}
|
|
114
|
+
| {
|
|
115
|
+
type: 'insert.block'
|
|
116
|
+
block: PortableTextBlock
|
|
117
|
+
placement: 'auto' | 'after' | 'before'
|
|
118
|
+
}
|
|
104
119
|
| {
|
|
105
120
|
type: 'insert.span'
|
|
106
121
|
text: string
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {defineConverter} from './converter.types'
|
|
2
2
|
|
|
3
|
-
export const converterJson
|
|
3
|
+
export const converterJson = defineConverter({
|
|
4
|
+
mimeType: 'application/json',
|
|
4
5
|
serialize: ({context, event}) => {
|
|
5
6
|
const portableTextConverter = context.converters.find(
|
|
6
7
|
(converter) => converter.mimeType === 'application/x-portable-text',
|
|
@@ -49,5 +50,4 @@ export const converterJson: Converter<'application/json'> = {
|
|
|
49
50
|
mimeType: 'application/json',
|
|
50
51
|
}
|
|
51
52
|
},
|
|
52
|
-
|
|
53
|
-
}
|
|
53
|
+
})
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from '../editor/define-schema'
|
|
7
7
|
import {createTestKeyGenerator} from '../internal-utils/test-key-generator'
|
|
8
8
|
import {converterPortableText} from './converter.portable-text'
|
|
9
|
-
import {coreConverters} from './converters'
|
|
9
|
+
import {coreConverters} from './converters.core'
|
|
10
10
|
|
|
11
11
|
function createContext(schema: SchemaDefinition) {
|
|
12
12
|
return {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import {parseBlock} from '../internal-utils/parse-blocks'
|
|
2
2
|
import {sliceBlocks} from '../utils'
|
|
3
|
-
import
|
|
3
|
+
import {defineConverter} from './converter.types'
|
|
4
4
|
|
|
5
|
-
export const converterPortableText
|
|
5
|
+
export const converterPortableText = defineConverter({
|
|
6
|
+
mimeType: 'application/x-portable-text',
|
|
6
7
|
serialize: ({context, event}) => {
|
|
7
8
|
if (!context.selection) {
|
|
8
9
|
return {
|
|
@@ -37,7 +38,11 @@ export const converterPortableText: Converter<'application/x-portable-text'> = {
|
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
const parsedBlocks = blocks.flatMap((block) => {
|
|
40
|
-
const parsedBlock = parseBlock({
|
|
41
|
+
const parsedBlock = parseBlock({
|
|
42
|
+
context,
|
|
43
|
+
block,
|
|
44
|
+
options: {refreshKeys: true},
|
|
45
|
+
})
|
|
41
46
|
return parsedBlock ? [parsedBlock] : []
|
|
42
47
|
})
|
|
43
48
|
|
|
@@ -55,5 +60,4 @@ export const converterPortableText: Converter<'application/x-portable-text'> = {
|
|
|
55
60
|
mimeType: 'application/x-portable-text',
|
|
56
61
|
}
|
|
57
62
|
},
|
|
58
|
-
|
|
59
|
-
}
|
|
63
|
+
})
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from '../editor/define-schema'
|
|
7
7
|
import {createTestKeyGenerator} from '../internal-utils/test-key-generator'
|
|
8
8
|
import {converterTextHtml} from './converter.text-html'
|
|
9
|
-
import {coreConverters} from './converters'
|
|
9
|
+
import {coreConverters} from './converters.core'
|
|
10
10
|
|
|
11
11
|
function createContext(schema: SchemaDefinition) {
|
|
12
12
|
return {
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
import {createTestKeyGenerator} from '../internal-utils/test-key-generator'
|
|
9
9
|
import type {EditorSelection} from '../utils'
|
|
10
10
|
import {converterTextHtml} from './converter.text-html'
|
|
11
|
-
import {coreConverters} from './converters'
|
|
11
|
+
import {coreConverters} from './converters.core'
|
|
12
12
|
|
|
13
13
|
const decoratedParagraph: PortableTextTextBlock = {
|
|
14
14
|
_key: 'k0',
|
|
@@ -2,9 +2,10 @@ import {htmlToBlocks} from '@portabletext/block-tools'
|
|
|
2
2
|
import {toHTML} from '@portabletext/to-html'
|
|
3
3
|
import type {PortableTextBlock} from '@sanity/types'
|
|
4
4
|
import {sliceBlocks} from '../utils'
|
|
5
|
-
import
|
|
5
|
+
import {defineConverter} from './converter.types'
|
|
6
6
|
|
|
7
|
-
export const converterTextHtml
|
|
7
|
+
export const converterTextHtml = defineConverter({
|
|
8
|
+
mimeType: 'text/html',
|
|
8
9
|
serialize: ({context, event}) => {
|
|
9
10
|
if (!context.selection) {
|
|
10
11
|
return {
|
|
@@ -57,5 +58,4 @@ export const converterTextHtml: Converter<'text/html'> = {
|
|
|
57
58
|
mimeType: 'text/html',
|
|
58
59
|
}
|
|
59
60
|
},
|
|
60
|
-
|
|
61
|
-
}
|
|
61
|
+
})
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
import type {EditorContext} from '../editor/editor-snapshot'
|
|
9
9
|
import type {EditorSelection} from '../utils'
|
|
10
10
|
import {converterTextPlain} from './converter.text-plain'
|
|
11
|
-
import {coreConverters} from './converters'
|
|
11
|
+
import {coreConverters} from './converters.core'
|
|
12
12
|
|
|
13
13
|
const b1: PortableTextTextBlock = {
|
|
14
14
|
_type: 'block',
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {htmlToBlocks} from '@portabletext/block-tools'
|
|
2
2
|
import {isPortableTextTextBlock, type PortableTextBlock} from '@sanity/types'
|
|
3
3
|
import {sliceBlocks} from '../utils'
|
|
4
|
-
import
|
|
4
|
+
import {defineConverter} from './converter.types'
|
|
5
5
|
|
|
6
|
-
export const converterTextPlain
|
|
6
|
+
export const converterTextPlain = defineConverter({
|
|
7
7
|
mimeType: 'text/plain',
|
|
8
8
|
serialize: ({context, event}) => {
|
|
9
9
|
if (!context.selection) {
|
|
@@ -73,7 +73,7 @@ export const converterTextPlain: Converter<'text/plain'> = {
|
|
|
73
73
|
mimeType: 'text/plain',
|
|
74
74
|
}
|
|
75
75
|
},
|
|
76
|
-
}
|
|
76
|
+
})
|
|
77
77
|
|
|
78
78
|
const entityMap: Record<string, string> = {
|
|
79
79
|
'&': '&',
|
|
@@ -9,6 +9,12 @@ export type Converter<TMIMEType extends MIMEType = MIMEType> = {
|
|
|
9
9
|
deserialize: Deserializer<TMIMEType>
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
export function defineConverter<TMIMEType extends MIMEType>(
|
|
13
|
+
converter: Converter<TMIMEType>,
|
|
14
|
+
): Converter<TMIMEType> {
|
|
15
|
+
return converter
|
|
16
|
+
}
|
|
17
|
+
|
|
12
18
|
export type ConverterEvent<TMIMEType extends MIMEType = MIMEType> =
|
|
13
19
|
| {
|
|
14
20
|
type: 'serialize'
|
|
@@ -28,7 +28,7 @@ async function getEditableElement(
|
|
|
28
28
|
describe('adds empty text block if its needed', () => {
|
|
29
29
|
const newBlock = {
|
|
30
30
|
_type: 'myTestBlockType',
|
|
31
|
-
_key: '
|
|
31
|
+
_key: '1',
|
|
32
32
|
style: 'normal',
|
|
33
33
|
markDefs: [],
|
|
34
34
|
children: [
|
|
@@ -96,7 +96,7 @@ describe('adds empty text block if its needed', () => {
|
|
|
96
96
|
},
|
|
97
97
|
{
|
|
98
98
|
_type: 'myTestBlockType',
|
|
99
|
-
_key: '
|
|
99
|
+
_key: '1',
|
|
100
100
|
style: 'normal',
|
|
101
101
|
markDefs: [],
|
|
102
102
|
children: [
|
|
@@ -337,7 +337,7 @@ describe('when PTE would display warnings, instead it self solves', () => {
|
|
|
337
337
|
PortableTextEditor.focus(editorRef.current)
|
|
338
338
|
expect(PortableTextEditor.getValue(editorRef.current)).toEqual([
|
|
339
339
|
{
|
|
340
|
-
_key: '
|
|
340
|
+
_key: '3',
|
|
341
341
|
_type: 'myTestBlockType',
|
|
342
342
|
children: [{_key: '4', _type: 'span', marks: [], text: ''}],
|
|
343
343
|
markDefs: [],
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
type Snapshot,
|
|
13
13
|
} from 'xstate'
|
|
14
14
|
import type {Behavior, CustomBehaviorEvent} from '../behaviors/behavior.types'
|
|
15
|
-
import {coreConverters} from '../converters/converters'
|
|
15
|
+
import {coreConverters} from '../converters/converters.core'
|
|
16
16
|
import {compileType} from '../internal-utils/schema'
|
|
17
17
|
import type {PickFromUnion} from '../type-utils'
|
|
18
18
|
import type {EditableAPI} from '../types/editor'
|
|
@@ -66,6 +66,8 @@ export type EditorEvent =
|
|
|
66
66
|
| 'annotation.add'
|
|
67
67
|
| 'annotation.remove'
|
|
68
68
|
| 'annotation.toggle'
|
|
69
|
+
| 'block.set'
|
|
70
|
+
| 'block.unset'
|
|
69
71
|
| 'blur'
|
|
70
72
|
| 'data transfer.set'
|
|
71
73
|
| 'decorator.add'
|
|
@@ -76,6 +78,7 @@ export type EditorEvent =
|
|
|
76
78
|
| 'deserialization.failure'
|
|
77
79
|
| 'deserialization.success'
|
|
78
80
|
| 'focus'
|
|
81
|
+
| 'insert.block'
|
|
79
82
|
| 'insert.block object'
|
|
80
83
|
| 'insert.inline object'
|
|
81
84
|
| 'insert.span'
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
type NativeBehaviorEvent,
|
|
21
21
|
type SyntheticBehaviorEvent,
|
|
22
22
|
} from '../behaviors/behavior.types'
|
|
23
|
-
import type {Converter} from '../converters/converter'
|
|
23
|
+
import type {Converter} from '../converters/converter.types'
|
|
24
24
|
import type {OmitFromUnion, PickFromUnion} from '../type-utils'
|
|
25
25
|
import type {
|
|
26
26
|
EditorSelection,
|
|
@@ -172,7 +172,6 @@ export type InternalEditorEmittedEvent =
|
|
|
172
172
|
description: string
|
|
173
173
|
data: unknown
|
|
174
174
|
}
|
|
175
|
-
| {type: 'select'; selection: EditorSelection}
|
|
176
175
|
| {type: 'selection'; selection: EditorSelection}
|
|
177
176
|
| {type: 'blurred'; event: FocusEvent<HTMLDivElement, Element>}
|
|
178
177
|
| {type: 'focused'; event: FocusEvent<HTMLDivElement, Element>}
|
|
@@ -186,6 +185,8 @@ export type InternalEditorEmittedEvent =
|
|
|
186
185
|
| 'annotation.add'
|
|
187
186
|
| 'annotation.remove'
|
|
188
187
|
| 'annotation.toggle'
|
|
188
|
+
| 'block.set'
|
|
189
|
+
| 'block.unset'
|
|
189
190
|
| 'blur'
|
|
190
191
|
| 'data transfer.set'
|
|
191
192
|
| 'decorator.add'
|
|
@@ -198,6 +199,7 @@ export type InternalEditorEmittedEvent =
|
|
|
198
199
|
| 'deserialization.failure'
|
|
199
200
|
| 'deserialization.success'
|
|
200
201
|
| 'focus'
|
|
202
|
+
| 'insert.block'
|
|
201
203
|
| 'insert.block object'
|
|
202
204
|
| 'insert.inline object'
|
|
203
205
|
| 'insert.span'
|
|
@@ -208,6 +210,7 @@ export type InternalEditorEmittedEvent =
|
|
|
208
210
|
| 'move.block'
|
|
209
211
|
| 'move.block down'
|
|
210
212
|
| 'move.block up'
|
|
213
|
+
| 'select'
|
|
211
214
|
| 'select.next block'
|
|
212
215
|
| 'select.previous block'
|
|
213
216
|
| 'serialization.failure'
|
|
@@ -596,6 +599,9 @@ export const editorMachine = setup({
|
|
|
596
599
|
'annotation.*': {
|
|
597
600
|
actions: emit(({event}) => event),
|
|
598
601
|
},
|
|
602
|
+
'block.*': {
|
|
603
|
+
actions: emit(({event}) => event),
|
|
604
|
+
},
|
|
599
605
|
'blur': {
|
|
600
606
|
actions: emit(({event}) => event),
|
|
601
607
|
},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type {PortableTextBlock} from '@sanity/types'
|
|
2
|
-
import type {Converter} from '../converters/converter'
|
|
2
|
+
import type {Converter} from '../converters/converter.types'
|
|
3
3
|
import {toPortableTextRange} from '../internal-utils/ranges'
|
|
4
4
|
import {fromSlateValue} from '../internal-utils/values'
|
|
5
5
|
import {KEY_TO_VALUE_ELEMENT} from '../internal-utils/weakMaps'
|
|
@@ -111,12 +111,12 @@ describe('plugin:withEditableAPI: .insertChild()', () => {
|
|
|
111
111
|
text: 'Block A',
|
|
112
112
|
},
|
|
113
113
|
{
|
|
114
|
-
_key: '
|
|
114
|
+
_key: '2',
|
|
115
115
|
_type: 'someObject',
|
|
116
116
|
color: 'red',
|
|
117
117
|
},
|
|
118
118
|
{
|
|
119
|
-
_key: '
|
|
119
|
+
_key: '3',
|
|
120
120
|
_type: 'span',
|
|
121
121
|
marks: [],
|
|
122
122
|
text: '',
|
|
@@ -155,12 +155,12 @@ describe('plugin:withEditableAPI: .insertChild()', () => {
|
|
|
155
155
|
text: 'Block A',
|
|
156
156
|
},
|
|
157
157
|
{
|
|
158
|
-
_key: '
|
|
158
|
+
_key: '2',
|
|
159
159
|
_type: 'someObject',
|
|
160
160
|
color: 'red',
|
|
161
161
|
},
|
|
162
162
|
{
|
|
163
|
-
_key: '
|
|
163
|
+
_key: '5',
|
|
164
164
|
_type: 'span',
|
|
165
165
|
marks: [],
|
|
166
166
|
text: ' ',
|
|
@@ -172,8 +172,8 @@ describe('plugin:withEditableAPI: .insertChild()', () => {
|
|
|
172
172
|
])
|
|
173
173
|
|
|
174
174
|
expect(PortableTextEditor.getSelection(editorRef.current)).toEqual({
|
|
175
|
-
anchor: {path: [{_key: 'a'}, 'children', {_key: '
|
|
176
|
-
focus: {path: [{_key: 'a'}, 'children', {_key: '
|
|
175
|
+
anchor: {path: [{_key: 'a'}, 'children', {_key: '5'}], offset: 1},
|
|
176
|
+
focus: {path: [{_key: 'a'}, 'children', {_key: '5'}], offset: 1},
|
|
177
177
|
backward: false,
|
|
178
178
|
})
|
|
179
179
|
}
|
|
@@ -240,7 +240,7 @@ describe('plugin:withEditableAPI: .insertBlock()', () => {
|
|
|
240
240
|
await waitFor(() => {
|
|
241
241
|
if (editorRef.current) {
|
|
242
242
|
expect(PortableTextEditor.getValue(editorRef.current)).toEqual([
|
|
243
|
-
{_key: '
|
|
243
|
+
{_key: '1', _type: 'someObject', color: 'red'},
|
|
244
244
|
])
|
|
245
245
|
}
|
|
246
246
|
})
|
|
@@ -292,7 +292,7 @@ describe('plugin:withEditableAPI: .insertBlock()', () => {
|
|
|
292
292
|
if (editorRef.current) {
|
|
293
293
|
expect(PortableTextEditor.getValue(editorRef.current)).toEqual([
|
|
294
294
|
...initialValue,
|
|
295
|
-
{_key: '
|
|
295
|
+
{_key: '1', _type: 'someObject', color: 'red'},
|
|
296
296
|
])
|
|
297
297
|
}
|
|
298
298
|
})
|
|
@@ -345,7 +345,7 @@ describe('plugin:withEditableAPI: .insertBlock()', () => {
|
|
|
345
345
|
await waitFor(() => {
|
|
346
346
|
if (editorRef.current) {
|
|
347
347
|
expect(PortableTextEditor.getValue(editorRef.current)).toEqual([
|
|
348
|
-
{_key: '
|
|
348
|
+
{_key: '1', _type: 'someObject', color: 'red'},
|
|
349
349
|
...initialValue,
|
|
350
350
|
])
|
|
351
351
|
}
|
|
@@ -402,7 +402,7 @@ describe('plugin:withEditableAPI: .insertBlock()', () => {
|
|
|
402
402
|
if (editorRef.current) {
|
|
403
403
|
expect(PortableTextEditor.getValue(editorRef.current)).toEqual([
|
|
404
404
|
...value,
|
|
405
|
-
{_key: '
|
|
405
|
+
{_key: '1', _type: 'someObject', color: 'yellow'},
|
|
406
406
|
])
|
|
407
407
|
}
|
|
408
408
|
})
|
|
@@ -455,7 +455,7 @@ describe('plugin:withEditableAPI: .insertBlock()', () => {
|
|
|
455
455
|
if (editorRef.current) {
|
|
456
456
|
expect(PortableTextEditor.getValue(editorRef.current)).toEqual([
|
|
457
457
|
value[0],
|
|
458
|
-
{_key: '
|
|
458
|
+
{_key: '1', _type: 'someObject', color: 'yellow'},
|
|
459
459
|
value[1],
|
|
460
460
|
])
|
|
461
461
|
}
|
|
@@ -504,7 +504,7 @@ describe('plugin:withEditableAPI: .insertBlock()', () => {
|
|
|
504
504
|
if (editorRef.current) {
|
|
505
505
|
expect(PortableTextEditor.getValue(editorRef.current)).toEqual([
|
|
506
506
|
value[0],
|
|
507
|
-
{_key: '
|
|
507
|
+
{_key: '1', _type: 'someObject', color: 'yellow'},
|
|
508
508
|
])
|
|
509
509
|
}
|
|
510
510
|
})
|
|
@@ -73,41 +73,34 @@ describe('plugin:withPortableTextMarksModel', () => {
|
|
|
73
73
|
anchor: {path: [{_key: 'a'}, 'children', {_key: 'a1'}], offset: 3},
|
|
74
74
|
})
|
|
75
75
|
PortableTextEditor.toggleMark(editorRef.current, 'strong')
|
|
76
|
-
expect(PortableTextEditor.getValue(editorRef.current))
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
},
|
|
105
|
-
],
|
|
106
|
-
"markDefs": [],
|
|
107
|
-
"style": "normal",
|
|
108
|
-
},
|
|
109
|
-
]
|
|
110
|
-
`)
|
|
76
|
+
expect(PortableTextEditor.getValue(editorRef.current)).toEqual([
|
|
77
|
+
{
|
|
78
|
+
_key: 'a',
|
|
79
|
+
_type: 'myTestBlockType',
|
|
80
|
+
children: [
|
|
81
|
+
{
|
|
82
|
+
_key: 'a1',
|
|
83
|
+
_type: 'span',
|
|
84
|
+
marks: ['strong'],
|
|
85
|
+
text: '1',
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
_key: '2',
|
|
89
|
+
_type: 'span',
|
|
90
|
+
marks: [],
|
|
91
|
+
text: '23',
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
_key: '1',
|
|
95
|
+
_type: 'span',
|
|
96
|
+
marks: ['strong'],
|
|
97
|
+
text: '4',
|
|
98
|
+
},
|
|
99
|
+
],
|
|
100
|
+
markDefs: [],
|
|
101
|
+
style: 'normal',
|
|
102
|
+
},
|
|
103
|
+
])
|
|
111
104
|
}
|
|
112
105
|
})
|
|
113
106
|
await waitFor(() => {
|
|
@@ -461,7 +454,7 @@ describe('plugin:withPortableTextMarksModel', () => {
|
|
|
461
454
|
style: 'normal',
|
|
462
455
|
},
|
|
463
456
|
{
|
|
464
|
-
_key: '
|
|
457
|
+
_key: '1',
|
|
465
458
|
_type: 'myTestBlockType',
|
|
466
459
|
children: [
|
|
467
460
|
{
|
|
@@ -28,6 +28,8 @@ export function createWithEventListeners(
|
|
|
28
28
|
case 'annotation.add':
|
|
29
29
|
case 'annotation.remove':
|
|
30
30
|
case 'annotation.toggle':
|
|
31
|
+
case 'block.set':
|
|
32
|
+
case 'block.unset':
|
|
31
33
|
case 'blur':
|
|
32
34
|
case 'data transfer.set':
|
|
33
35
|
case 'decorator.add':
|
|
@@ -40,6 +42,7 @@ export function createWithEventListeners(
|
|
|
40
42
|
case 'deserialization.failure':
|
|
41
43
|
case 'deserialization.success':
|
|
42
44
|
case 'focus':
|
|
45
|
+
case 'insert.block':
|
|
43
46
|
case 'insert.block object':
|
|
44
47
|
case 'insert.inline object':
|
|
45
48
|
case 'insert.span':
|