@portabletext/editor 1.26.3 → 1.28.0
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 +5 -5
- package/lib/_chunks-cjs/behavior.markdown.cjs +327 -0
- package/lib/_chunks-cjs/behavior.markdown.cjs.map +1 -0
- package/lib/_chunks-cjs/plugin.event-listener.cjs +6827 -0
- package/lib/_chunks-cjs/plugin.event-listener.cjs.map +1 -0
- package/lib/_chunks-cjs/selector.is-at-the-start-of-block.cjs +88 -88
- package/lib/_chunks-cjs/selector.is-at-the-start-of-block.cjs.map +1 -1
- package/lib/_chunks-es/behavior.markdown.js +332 -0
- package/lib/_chunks-es/behavior.markdown.js.map +1 -0
- package/lib/_chunks-es/plugin.event-listener.js +6851 -0
- package/lib/_chunks-es/plugin.event-listener.js.map +1 -0
- package/lib/_chunks-es/selector.is-at-the-start-of-block.js +88 -88
- package/lib/_chunks-es/selector.is-at-the-start-of-block.js.map +1 -1
- package/lib/behaviors/index.cjs +2 -325
- package/lib/behaviors/index.cjs.map +1 -1
- package/lib/behaviors/index.d.cts +1 -1
- package/lib/behaviors/index.d.ts +1 -1
- package/lib/behaviors/index.js +2 -326
- package/lib/behaviors/index.js.map +1 -1
- package/lib/index.cjs +261 -6782
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +3509 -2161
- package/lib/index.d.ts +3509 -2161
- package/lib/index.js +223 -6761
- package/lib/index.js.map +1 -1
- package/lib/plugins/index.cjs +29 -0
- package/lib/plugins/index.cjs.map +1 -0
- package/lib/plugins/index.d.cts +19411 -0
- package/lib/plugins/index.d.ts +19411 -0
- package/lib/plugins/index.js +29 -0
- package/lib/plugins/index.js.map +1 -0
- package/lib/selectors/index.cjs +15 -3
- package/lib/selectors/index.cjs.map +1 -1
- package/lib/selectors/index.d.cts +19 -1
- package/lib/selectors/index.d.ts +19 -1
- package/lib/selectors/index.js +17 -4
- package/lib/selectors/index.js.map +1 -1
- package/package.json +14 -8
- package/src/behavior-actions/behavior.action.insert-break.ts +93 -83
- package/src/editor/Editable.tsx +6 -6
- package/src/editor/PortableTextEditor.tsx +288 -1
- package/src/editor/__tests__/PortableTextEditor.test.tsx +0 -1
- package/src/editor/components/DefaultObject.tsx +21 -0
- package/src/editor/components/Element.tsx +5 -5
- package/src/editor/components/Leaf.tsx +1 -6
- package/src/editor/components/Synchronizer.tsx +16 -1
- package/src/editor/create-editor.ts +8 -48
- package/src/editor/editor-machine.ts +118 -131
- package/src/editor/plugins/create-with-event-listeners.ts +19 -38
- package/src/editor/plugins/createWithPatches.ts +1 -1
- package/src/editor/plugins/createWithPortableTextSelections.ts +2 -2
- package/src/editor/sync-machine.ts +3 -5
- package/src/index.ts +5 -11
- package/src/plugins/_exports/index.ts +1 -0
- package/src/plugins/index.ts +3 -0
- package/src/plugins/plugin.editor-ref.tsx +17 -0
- package/src/{editor/editor-event-listener.tsx → plugins/plugin.event-listener.tsx} +7 -6
- package/src/plugins/plugin.markdown.tsx +70 -0
- package/src/selectors/index.ts +4 -2
- package/src/selectors/selector.get-active-annotations.test.ts +122 -0
- package/src/selectors/selector.get-active-annotations.ts +30 -0
- package/src/selectors/selector.get-selection.ts +8 -0
- package/src/selectors/selector.get-value.ts +11 -0
- package/src/type-utils.ts +12 -2
- package/src/editor/nodes/DefaultAnnotation.tsx +0 -20
- package/src/editor/nodes/DefaultObject.tsx +0 -18
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import type {PortableTextBlock} from '@sanity/types'
|
|
2
|
+
import {expect, test} from 'vitest'
|
|
3
|
+
import type {EditorSchema} from '../editor/define-schema'
|
|
4
|
+
import type {EditorSnapshot} from '../editor/editor-snapshot'
|
|
5
|
+
import {createTestKeyGenerator} from '../internal-utils/test-key-generator'
|
|
6
|
+
import type {EditorSelection} from '../utils'
|
|
7
|
+
import {getActiveAnnotations} from './selector.get-active-annotations'
|
|
8
|
+
|
|
9
|
+
function snapshot(
|
|
10
|
+
value: Array<PortableTextBlock>,
|
|
11
|
+
selection: EditorSelection,
|
|
12
|
+
): EditorSnapshot {
|
|
13
|
+
return {
|
|
14
|
+
context: {
|
|
15
|
+
converters: [],
|
|
16
|
+
schema: {} as EditorSchema,
|
|
17
|
+
keyGenerator: createTestKeyGenerator(),
|
|
18
|
+
activeDecorators: [],
|
|
19
|
+
value,
|
|
20
|
+
selection,
|
|
21
|
+
},
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const link = {
|
|
26
|
+
_key: 'k4',
|
|
27
|
+
_type: 'link',
|
|
28
|
+
href: 'https://example.com',
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const comment = {
|
|
32
|
+
_key: 'k5',
|
|
33
|
+
_type: 'comment',
|
|
34
|
+
comment: 'Consider rewriting this',
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const block = {
|
|
38
|
+
_type: 'block',
|
|
39
|
+
_key: 'k0',
|
|
40
|
+
children: [
|
|
41
|
+
{
|
|
42
|
+
_key: 'k1',
|
|
43
|
+
_type: 'span',
|
|
44
|
+
text: 'foo',
|
|
45
|
+
marks: ['strong'],
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
_type: 'span',
|
|
49
|
+
_key: 'k2',
|
|
50
|
+
text: 'bar',
|
|
51
|
+
marks: [link._key, comment._key, 'strong'],
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
_key: 'k3',
|
|
55
|
+
_type: 'span',
|
|
56
|
+
text: 'baz',
|
|
57
|
+
marks: [comment._key, 'strong'],
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
markDefs: [link, comment],
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
test(getActiveAnnotations.name, () => {
|
|
64
|
+
expect(getActiveAnnotations(snapshot([], null))).toEqual([])
|
|
65
|
+
expect(getActiveAnnotations(snapshot([block], null))).toEqual([])
|
|
66
|
+
expect(
|
|
67
|
+
getActiveAnnotations(
|
|
68
|
+
snapshot([block], {
|
|
69
|
+
anchor: {
|
|
70
|
+
path: [{_key: 'k0'}, 'children', {_key: 'k1'}],
|
|
71
|
+
offset: 0,
|
|
72
|
+
},
|
|
73
|
+
focus: {
|
|
74
|
+
path: [{_key: 'k0'}, 'children', {_key: 'k1'}],
|
|
75
|
+
offset: 3,
|
|
76
|
+
},
|
|
77
|
+
}),
|
|
78
|
+
),
|
|
79
|
+
).toEqual([])
|
|
80
|
+
expect(
|
|
81
|
+
getActiveAnnotations(
|
|
82
|
+
snapshot([block], {
|
|
83
|
+
anchor: {
|
|
84
|
+
path: [{_key: 'k0'}, 'children', {_key: 'k1'}],
|
|
85
|
+
offset: 0,
|
|
86
|
+
},
|
|
87
|
+
focus: {
|
|
88
|
+
path: [{_key: 'k0'}, 'children', {_key: 'k2'}],
|
|
89
|
+
offset: 3,
|
|
90
|
+
},
|
|
91
|
+
}),
|
|
92
|
+
),
|
|
93
|
+
).toEqual([link, comment])
|
|
94
|
+
expect(
|
|
95
|
+
getActiveAnnotations(
|
|
96
|
+
snapshot([block], {
|
|
97
|
+
anchor: {
|
|
98
|
+
path: [{_key: 'k0'}, 'children', {_key: 'k1'}],
|
|
99
|
+
offset: 0,
|
|
100
|
+
},
|
|
101
|
+
focus: {
|
|
102
|
+
path: [{_key: 'k0'}, 'children', {_key: 'k3'}],
|
|
103
|
+
offset: 3,
|
|
104
|
+
},
|
|
105
|
+
}),
|
|
106
|
+
),
|
|
107
|
+
).toEqual([link, comment])
|
|
108
|
+
expect(
|
|
109
|
+
getActiveAnnotations(
|
|
110
|
+
snapshot([block], {
|
|
111
|
+
anchor: {
|
|
112
|
+
path: [{_key: 'k0'}, 'children', {_key: 'k3'}],
|
|
113
|
+
offset: 0,
|
|
114
|
+
},
|
|
115
|
+
focus: {
|
|
116
|
+
path: [{_key: 'k0'}, 'children', {_key: 'k3'}],
|
|
117
|
+
offset: 3,
|
|
118
|
+
},
|
|
119
|
+
}),
|
|
120
|
+
),
|
|
121
|
+
).toEqual([comment])
|
|
122
|
+
})
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import {isPortableTextTextBlock, type PortableTextObject} from '@sanity/types'
|
|
2
|
+
import type {EditorSelector} from '../editor/editor-selector'
|
|
3
|
+
import {getSelectedSpans} from './selector.get-selected-spans'
|
|
4
|
+
import {getSelectedBlocks} from './selectors'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
export const getActiveAnnotations: EditorSelector<Array<PortableTextObject>> = (
|
|
10
|
+
snapshot,
|
|
11
|
+
) => {
|
|
12
|
+
if (!snapshot.context.selection) {
|
|
13
|
+
return []
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const selectedBlocks = getSelectedBlocks(snapshot)
|
|
17
|
+
const selectedSpans = getSelectedSpans(snapshot)
|
|
18
|
+
|
|
19
|
+
if (selectedSpans.length === 0) {
|
|
20
|
+
return []
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const selectionMarkDefs = selectedBlocks.flatMap((block) =>
|
|
24
|
+
isPortableTextTextBlock(block.node) ? (block.node.markDefs ?? []) : [],
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
return selectionMarkDefs.filter((markDef) =>
|
|
28
|
+
selectedSpans.some((span) => span.node.marks?.includes(markDef._key)),
|
|
29
|
+
)
|
|
30
|
+
}
|
package/src/type-utils.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @
|
|
2
|
+
* @internal
|
|
3
3
|
*/
|
|
4
4
|
export type PickFromUnion<
|
|
5
5
|
TUnion,
|
|
@@ -8,10 +8,20 @@ export type PickFromUnion<
|
|
|
8
8
|
> = TUnion extends Record<TTagKey, TPickedTags> ? TUnion : never
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
* @
|
|
11
|
+
* @internal
|
|
12
12
|
*/
|
|
13
13
|
export type OmitFromUnion<
|
|
14
14
|
TUnion,
|
|
15
15
|
TTagKey extends keyof TUnion,
|
|
16
16
|
TOmittedTags extends TUnion[TTagKey],
|
|
17
17
|
> = TUnion extends Record<TTagKey, TOmittedTags> ? never : TUnion
|
|
18
|
+
|
|
19
|
+
export type NamespaceEvent<TEvent, TNamespace extends string> = TEvent extends {
|
|
20
|
+
type: infer TEventType
|
|
21
|
+
}
|
|
22
|
+
? {
|
|
23
|
+
[K in keyof TEvent]: K extends 'type'
|
|
24
|
+
? `${TNamespace}.${TEventType & string}`
|
|
25
|
+
: TEvent[K]
|
|
26
|
+
}
|
|
27
|
+
: never
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import type {PortableTextObject} from '@sanity/types'
|
|
2
|
-
import {useCallback, type ReactNode} from 'react'
|
|
3
|
-
|
|
4
|
-
type Props = {
|
|
5
|
-
annotation: PortableTextObject
|
|
6
|
-
children: ReactNode
|
|
7
|
-
}
|
|
8
|
-
export function DefaultAnnotation(props: Props) {
|
|
9
|
-
const handleClick = useCallback(
|
|
10
|
-
() => alert(JSON.stringify(props.annotation)),
|
|
11
|
-
[props.annotation],
|
|
12
|
-
)
|
|
13
|
-
return (
|
|
14
|
-
<span style={{color: 'blue'}} onClick={handleClick}>
|
|
15
|
-
{props.children}
|
|
16
|
-
</span>
|
|
17
|
-
)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
DefaultAnnotation.displayName = 'DefaultAnnotation'
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type {PortableTextBlock, PortableTextChild} from '@sanity/types'
|
|
2
|
-
import type {JSX} from 'react'
|
|
3
|
-
|
|
4
|
-
type Props = {
|
|
5
|
-
value: PortableTextBlock | PortableTextChild
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
const DefaultObject = (props: Props): JSX.Element => {
|
|
9
|
-
return (
|
|
10
|
-
<div style={{userSelect: 'none'}}>
|
|
11
|
-
[{props.value._type}: {props.value._key}]
|
|
12
|
-
</div>
|
|
13
|
-
)
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
DefaultObject.displayName = 'DefaultObject'
|
|
17
|
-
|
|
18
|
-
export default DefaultObject
|