@portabletext/editor 1.0.18 → 1.0.19
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.esm.js +47 -56
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +47 -56
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +47 -56
- package/lib/index.mjs.map +1 -1
- package/package.json +7 -3
- package/src/editor/plugins/__tests__/withPortableTextMarkModel.test.tsx +0 -533
- package/src/editor/plugins/createWithEditableAPI.ts +10 -1
- package/src/editor/plugins/createWithPortableTextMarkModel.ts +97 -118
- package/src/utils/values.ts +0 -1
- package/src/editor/plugins/__tests__/withHotkeys.test.tsx +0 -212
- package/src/editor/plugins/__tests__/withInsertBreak.test.tsx +0 -220
- package/src/editor/plugins/__tests__/withPlaceholderBlock.test.tsx +0 -133
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
import {describe, expect, it, jest} from '@jest/globals'
|
|
2
|
-
import {render, waitFor} from '@testing-library/react'
|
|
3
|
-
import {createRef, type RefObject} from 'react'
|
|
4
|
-
|
|
5
|
-
import {PortableTextEditorTester, schemaType} from '../../__tests__/PortableTextEditorTester'
|
|
6
|
-
import {PortableTextEditor} from '../../PortableTextEditor'
|
|
7
|
-
|
|
8
|
-
const initialValue = [
|
|
9
|
-
{
|
|
10
|
-
_key: 'a',
|
|
11
|
-
_type: 'myTestBlockType',
|
|
12
|
-
children: [
|
|
13
|
-
{
|
|
14
|
-
_key: 'a1',
|
|
15
|
-
_type: 'span',
|
|
16
|
-
marks: [],
|
|
17
|
-
text: 'Block A',
|
|
18
|
-
},
|
|
19
|
-
],
|
|
20
|
-
markDefs: [],
|
|
21
|
-
style: 'normal',
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
_key: 'b',
|
|
25
|
-
_type: 'myTestBlockType',
|
|
26
|
-
children: [
|
|
27
|
-
{
|
|
28
|
-
_key: 'b1',
|
|
29
|
-
_type: 'span',
|
|
30
|
-
marks: [],
|
|
31
|
-
text: 'Block B',
|
|
32
|
-
},
|
|
33
|
-
],
|
|
34
|
-
markDefs: [],
|
|
35
|
-
style: 'normal',
|
|
36
|
-
},
|
|
37
|
-
]
|
|
38
|
-
|
|
39
|
-
describe('plugin:withInsertBreak: "enter"', () => {
|
|
40
|
-
it('keeps text block key if enter is pressed at the start of the block, creating a new one in "before" position', async () => {
|
|
41
|
-
const initialSelection = {
|
|
42
|
-
focus: {path: [{_key: 'b'}, 'children', {_key: 'b1'}], offset: 0},
|
|
43
|
-
anchor: {path: [{_key: 'b'}, 'children', {_key: 'b1'}], offset: 0},
|
|
44
|
-
}
|
|
45
|
-
const editorRef: RefObject<PortableTextEditor> = createRef()
|
|
46
|
-
const onChange = jest.fn()
|
|
47
|
-
|
|
48
|
-
render(
|
|
49
|
-
<PortableTextEditorTester
|
|
50
|
-
onChange={onChange}
|
|
51
|
-
ref={editorRef}
|
|
52
|
-
schemaType={schemaType}
|
|
53
|
-
value={initialValue}
|
|
54
|
-
/>,
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
await waitFor(() => {
|
|
58
|
-
if (editorRef.current) {
|
|
59
|
-
expect(onChange).toHaveBeenCalledWith({type: 'value', value: initialValue})
|
|
60
|
-
expect(onChange).toHaveBeenCalledWith({type: 'ready'})
|
|
61
|
-
}
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
const editor = editorRef.current
|
|
65
|
-
const inlineType = editor?.schemaTypes.inlineObjects.find((t) => t.name === 'someObject')
|
|
66
|
-
await waitFor(async () => {
|
|
67
|
-
if (editor && inlineType) {
|
|
68
|
-
PortableTextEditor.focus(editor)
|
|
69
|
-
PortableTextEditor.select(editor, initialSelection)
|
|
70
|
-
PortableTextEditor.insertBreak(editor)
|
|
71
|
-
|
|
72
|
-
const value = PortableTextEditor.getValue(editor)
|
|
73
|
-
expect(value).toEqual([
|
|
74
|
-
initialValue[0],
|
|
75
|
-
{
|
|
76
|
-
_type: 'myTestBlockType',
|
|
77
|
-
_key: '3',
|
|
78
|
-
style: 'normal',
|
|
79
|
-
markDefs: [],
|
|
80
|
-
children: [
|
|
81
|
-
{
|
|
82
|
-
_type: 'span',
|
|
83
|
-
_key: '2',
|
|
84
|
-
text: '',
|
|
85
|
-
marks: [],
|
|
86
|
-
},
|
|
87
|
-
],
|
|
88
|
-
},
|
|
89
|
-
initialValue[1],
|
|
90
|
-
])
|
|
91
|
-
}
|
|
92
|
-
})
|
|
93
|
-
})
|
|
94
|
-
it('inserts the new block after if key enter is pressed at the start of the block, creating a new one in "after" position if the block is empty', async () => {
|
|
95
|
-
const initialSelection = {
|
|
96
|
-
focus: {path: [{_key: 'a'}, 'children', {_key: 'a1'}], offset: 0},
|
|
97
|
-
anchor: {path: [{_key: 'a'}, 'children', {_key: 'a1'}], offset: 0},
|
|
98
|
-
}
|
|
99
|
-
const emptyBlock = {
|
|
100
|
-
_key: 'a',
|
|
101
|
-
_type: 'myTestBlockType',
|
|
102
|
-
children: [
|
|
103
|
-
{
|
|
104
|
-
_key: 'a1',
|
|
105
|
-
_type: 'span',
|
|
106
|
-
marks: [],
|
|
107
|
-
text: '',
|
|
108
|
-
},
|
|
109
|
-
],
|
|
110
|
-
markDefs: [],
|
|
111
|
-
style: 'normal',
|
|
112
|
-
}
|
|
113
|
-
const editorRef: RefObject<PortableTextEditor> = createRef()
|
|
114
|
-
const onChange = jest.fn()
|
|
115
|
-
|
|
116
|
-
render(
|
|
117
|
-
<PortableTextEditorTester
|
|
118
|
-
onChange={onChange}
|
|
119
|
-
ref={editorRef}
|
|
120
|
-
schemaType={schemaType}
|
|
121
|
-
value={[emptyBlock]}
|
|
122
|
-
/>,
|
|
123
|
-
)
|
|
124
|
-
|
|
125
|
-
await waitFor(() => {
|
|
126
|
-
if (editorRef.current) {
|
|
127
|
-
expect(onChange).toHaveBeenCalledWith({type: 'value', value: [emptyBlock]})
|
|
128
|
-
expect(onChange).toHaveBeenCalledWith({type: 'ready'})
|
|
129
|
-
}
|
|
130
|
-
})
|
|
131
|
-
|
|
132
|
-
const editor = editorRef.current
|
|
133
|
-
const inlineType = editor?.schemaTypes.inlineObjects.find((t) => t.name === 'someObject')
|
|
134
|
-
await waitFor(async () => {
|
|
135
|
-
if (editor && inlineType) {
|
|
136
|
-
PortableTextEditor.focus(editor)
|
|
137
|
-
PortableTextEditor.select(editor, initialSelection)
|
|
138
|
-
PortableTextEditor.insertBreak(editor)
|
|
139
|
-
|
|
140
|
-
const value = PortableTextEditor.getValue(editor)
|
|
141
|
-
expect(value).toEqual([
|
|
142
|
-
emptyBlock,
|
|
143
|
-
{
|
|
144
|
-
_key: '2',
|
|
145
|
-
_type: 'myTestBlockType',
|
|
146
|
-
markDefs: [],
|
|
147
|
-
style: 'normal',
|
|
148
|
-
children: [
|
|
149
|
-
{
|
|
150
|
-
_key: '1',
|
|
151
|
-
_type: 'span',
|
|
152
|
-
marks: [],
|
|
153
|
-
text: '',
|
|
154
|
-
},
|
|
155
|
-
],
|
|
156
|
-
},
|
|
157
|
-
])
|
|
158
|
-
}
|
|
159
|
-
})
|
|
160
|
-
})
|
|
161
|
-
it('splits the text block key if enter is pressed at the middle of the block', async () => {
|
|
162
|
-
const initialSelection = {
|
|
163
|
-
focus: {path: [{_key: 'b'}, 'children', {_key: 'b1'}], offset: 2},
|
|
164
|
-
anchor: {path: [{_key: 'b'}, 'children', {_key: 'b1'}], offset: 2},
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
const editorRef: RefObject<PortableTextEditor> = createRef()
|
|
168
|
-
const onChange = jest.fn()
|
|
169
|
-
render(
|
|
170
|
-
<PortableTextEditorTester
|
|
171
|
-
onChange={onChange}
|
|
172
|
-
ref={editorRef}
|
|
173
|
-
schemaType={schemaType}
|
|
174
|
-
value={initialValue}
|
|
175
|
-
/>,
|
|
176
|
-
)
|
|
177
|
-
const editor = editorRef.current
|
|
178
|
-
const inlineType = editor?.schemaTypes.inlineObjects.find((t) => t.name === 'someObject')
|
|
179
|
-
await waitFor(async () => {
|
|
180
|
-
if (editor && inlineType) {
|
|
181
|
-
PortableTextEditor.focus(editor)
|
|
182
|
-
PortableTextEditor.select(editor, initialSelection)
|
|
183
|
-
PortableTextEditor.insertBreak(editor)
|
|
184
|
-
|
|
185
|
-
const value = PortableTextEditor.getValue(editor)
|
|
186
|
-
expect(value).toEqual([
|
|
187
|
-
initialValue[0],
|
|
188
|
-
{
|
|
189
|
-
_key: 'b',
|
|
190
|
-
_type: 'myTestBlockType',
|
|
191
|
-
children: [
|
|
192
|
-
{
|
|
193
|
-
_key: 'b1',
|
|
194
|
-
_type: 'span',
|
|
195
|
-
marks: [],
|
|
196
|
-
text: 'Bl',
|
|
197
|
-
},
|
|
198
|
-
],
|
|
199
|
-
markDefs: [],
|
|
200
|
-
style: 'normal',
|
|
201
|
-
},
|
|
202
|
-
{
|
|
203
|
-
_key: '2',
|
|
204
|
-
_type: 'myTestBlockType',
|
|
205
|
-
markDefs: [],
|
|
206
|
-
style: 'normal',
|
|
207
|
-
children: [
|
|
208
|
-
{
|
|
209
|
-
_key: '1',
|
|
210
|
-
_type: 'span',
|
|
211
|
-
marks: [],
|
|
212
|
-
text: 'ock B',
|
|
213
|
-
},
|
|
214
|
-
],
|
|
215
|
-
},
|
|
216
|
-
])
|
|
217
|
-
}
|
|
218
|
-
})
|
|
219
|
-
})
|
|
220
|
-
})
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import {describe, expect, it, jest} from '@jest/globals'
|
|
2
|
-
/* eslint-disable max-nested-callbacks */
|
|
3
|
-
import {render, waitFor} from '@testing-library/react'
|
|
4
|
-
import {createRef, type RefObject} from 'react'
|
|
5
|
-
|
|
6
|
-
import {PortableTextEditorTester, schemaType} from '../../__tests__/PortableTextEditorTester'
|
|
7
|
-
import {PortableTextEditor} from '../../PortableTextEditor'
|
|
8
|
-
|
|
9
|
-
describe('plugin:withPlaceholderBlock', () => {
|
|
10
|
-
describe('removing nodes', () => {
|
|
11
|
-
it("should insert an empty text block if it's removing the only block", async () => {
|
|
12
|
-
const editorRef: RefObject<PortableTextEditor> = createRef()
|
|
13
|
-
const initialValue = [
|
|
14
|
-
{
|
|
15
|
-
_key: '5fc57af23597',
|
|
16
|
-
_type: 'someObject',
|
|
17
|
-
},
|
|
18
|
-
]
|
|
19
|
-
const onChange = jest.fn()
|
|
20
|
-
await waitFor(() => {
|
|
21
|
-
render(
|
|
22
|
-
<PortableTextEditorTester
|
|
23
|
-
onChange={onChange}
|
|
24
|
-
ref={editorRef}
|
|
25
|
-
schemaType={schemaType}
|
|
26
|
-
value={initialValue}
|
|
27
|
-
/>,
|
|
28
|
-
)
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
await waitFor(() => {
|
|
32
|
-
if (editorRef.current) {
|
|
33
|
-
PortableTextEditor.focus(editorRef.current)
|
|
34
|
-
|
|
35
|
-
PortableTextEditor.delete(
|
|
36
|
-
editorRef.current,
|
|
37
|
-
{
|
|
38
|
-
focus: {path: [{_key: '5fc57af23597'}], offset: 0},
|
|
39
|
-
anchor: {path: [{_key: '5fc57af23597'}], offset: 0},
|
|
40
|
-
},
|
|
41
|
-
{mode: 'blocks'},
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
const value = PortableTextEditor.getValue(editorRef.current)
|
|
45
|
-
|
|
46
|
-
expect(value).toEqual([
|
|
47
|
-
{
|
|
48
|
-
_type: 'myTestBlockType',
|
|
49
|
-
_key: '3',
|
|
50
|
-
style: 'normal',
|
|
51
|
-
markDefs: [],
|
|
52
|
-
children: [
|
|
53
|
-
{
|
|
54
|
-
_type: 'span',
|
|
55
|
-
_key: '2',
|
|
56
|
-
text: '',
|
|
57
|
-
marks: [],
|
|
58
|
-
},
|
|
59
|
-
],
|
|
60
|
-
},
|
|
61
|
-
])
|
|
62
|
-
}
|
|
63
|
-
})
|
|
64
|
-
})
|
|
65
|
-
it('should not insert a new block if we have more blocks available', async () => {
|
|
66
|
-
const editorRef: RefObject<PortableTextEditor> = createRef()
|
|
67
|
-
const initialValue = [
|
|
68
|
-
{
|
|
69
|
-
_key: '5fc57af23597',
|
|
70
|
-
_type: 'someObject',
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
_type: 'myTestBlockType',
|
|
74
|
-
_key: 'existingBlock',
|
|
75
|
-
style: 'normal',
|
|
76
|
-
markDefs: [],
|
|
77
|
-
children: [
|
|
78
|
-
{
|
|
79
|
-
_type: 'span',
|
|
80
|
-
_key: '2',
|
|
81
|
-
text: '',
|
|
82
|
-
marks: [],
|
|
83
|
-
},
|
|
84
|
-
],
|
|
85
|
-
},
|
|
86
|
-
]
|
|
87
|
-
const onChange = jest.fn()
|
|
88
|
-
await waitFor(() => {
|
|
89
|
-
render(
|
|
90
|
-
<PortableTextEditorTester
|
|
91
|
-
onChange={onChange}
|
|
92
|
-
ref={editorRef}
|
|
93
|
-
schemaType={schemaType}
|
|
94
|
-
value={initialValue}
|
|
95
|
-
/>,
|
|
96
|
-
)
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
await waitFor(() => {
|
|
100
|
-
if (editorRef.current) {
|
|
101
|
-
PortableTextEditor.focus(editorRef.current)
|
|
102
|
-
|
|
103
|
-
PortableTextEditor.delete(
|
|
104
|
-
editorRef.current,
|
|
105
|
-
{
|
|
106
|
-
focus: {path: [{_key: '5fc57af23597'}], offset: 0},
|
|
107
|
-
anchor: {path: [{_key: '5fc57af23597'}], offset: 0},
|
|
108
|
-
},
|
|
109
|
-
{mode: 'blocks'},
|
|
110
|
-
)
|
|
111
|
-
|
|
112
|
-
const value = PortableTextEditor.getValue(editorRef.current)
|
|
113
|
-
expect(value).toEqual([
|
|
114
|
-
{
|
|
115
|
-
_type: 'myTestBlockType',
|
|
116
|
-
_key: 'existingBlock',
|
|
117
|
-
style: 'normal',
|
|
118
|
-
markDefs: [],
|
|
119
|
-
children: [
|
|
120
|
-
{
|
|
121
|
-
_type: 'span',
|
|
122
|
-
_key: '2',
|
|
123
|
-
text: '',
|
|
124
|
-
marks: [],
|
|
125
|
-
},
|
|
126
|
-
],
|
|
127
|
-
},
|
|
128
|
-
])
|
|
129
|
-
}
|
|
130
|
-
})
|
|
131
|
-
})
|
|
132
|
-
})
|
|
133
|
-
})
|