@portabletext/editor 1.1.1 → 1.1.3

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.
Files changed (53) hide show
  1. package/README.md +3 -0
  2. package/lib/index.d.mts +1668 -1
  3. package/lib/index.d.ts +1668 -1
  4. package/lib/index.esm.js +320 -172
  5. package/lib/index.esm.js.map +1 -1
  6. package/lib/index.js +320 -173
  7. package/lib/index.js.map +1 -1
  8. package/lib/index.mjs +320 -172
  9. package/lib/index.mjs.map +1 -1
  10. package/package.json +23 -23
  11. package/src/editor/Editable.tsx +32 -34
  12. package/src/editor/PortableTextEditor.tsx +23 -7
  13. package/src/editor/__tests__/PortableTextEditor.test.tsx +9 -9
  14. package/src/editor/__tests__/PortableTextEditorTester.tsx +2 -5
  15. package/src/editor/__tests__/RangeDecorations.test.tsx +2 -2
  16. package/src/editor/__tests__/handleClick.test.tsx +27 -7
  17. package/src/editor/__tests__/insert-block.test.tsx +4 -4
  18. package/src/editor/__tests__/pteWarningsSelfSolving.test.tsx +7 -7
  19. package/src/editor/__tests__/self-solving.test.tsx +176 -0
  20. package/src/editor/components/Leaf.tsx +28 -23
  21. package/src/editor/components/Synchronizer.tsx +60 -32
  22. package/src/editor/editor-machine.ts +195 -0
  23. package/src/editor/hooks/usePortableTextEditorSelection.tsx +12 -14
  24. package/src/editor/hooks/useSyncValue.test.tsx +9 -9
  25. package/src/editor/hooks/useSyncValue.ts +14 -13
  26. package/src/editor/plugins/__tests__/createWithInsertData.test.tsx +1 -1
  27. package/src/editor/plugins/__tests__/withEditableAPIDelete.test.tsx +28 -28
  28. package/src/editor/plugins/__tests__/withEditableAPIGetFragment.test.tsx +17 -17
  29. package/src/editor/plugins/__tests__/withEditableAPIInsert.test.tsx +8 -8
  30. package/src/editor/plugins/__tests__/withEditableAPISelectionsOverlapping.test.tsx +5 -5
  31. package/src/editor/plugins/__tests__/withPortableTextLists.test.tsx +2 -2
  32. package/src/editor/plugins/__tests__/withPortableTextMarkModel.test.tsx +46 -46
  33. package/src/editor/plugins/__tests__/withPortableTextSelections.test.tsx +22 -11
  34. package/src/editor/plugins/__tests__/withUndoRedo.test.tsx +9 -9
  35. package/src/editor/plugins/createWithEditableAPI.ts +5 -7
  36. package/src/editor/plugins/createWithInsertData.ts +4 -9
  37. package/src/editor/plugins/createWithObjectKeys.ts +7 -0
  38. package/src/editor/plugins/createWithPatches.ts +5 -6
  39. package/src/editor/plugins/createWithPortableTextBlockStyle.ts +10 -2
  40. package/src/editor/plugins/createWithPortableTextMarkModel.ts +40 -36
  41. package/src/editor/plugins/createWithPortableTextSelections.ts +4 -5
  42. package/src/editor/plugins/createWithSchemaTypes.ts +9 -0
  43. package/src/editor/plugins/index.ts +18 -8
  44. package/src/index.ts +9 -3
  45. package/src/utils/__tests__/dmpToOperations.test.ts +1 -1
  46. package/src/utils/__tests__/operationToPatches.test.ts +61 -61
  47. package/src/utils/__tests__/patchToOperations.test.ts +39 -39
  48. package/src/utils/__tests__/ranges.test.ts +1 -1
  49. package/src/utils/__tests__/valueNormalization.test.tsx +13 -2
  50. package/src/utils/__tests__/values.test.ts +17 -17
  51. package/src/utils/applyPatch.ts +4 -10
  52. package/src/utils/validateValue.ts +0 -22
  53. package/src/editor/__tests__/utils.ts +0 -44
@@ -1,7 +1,7 @@
1
- import {beforeEach, describe, expect, it} from '@jest/globals'
2
1
  import type {Patch} from '@portabletext/patches'
3
2
  import {noop} from 'lodash'
4
3
  import {createEditor, type Descendant} from 'slate'
4
+ import {beforeEach, describe, expect, it} from 'vitest'
5
5
  import {keyGenerator, PortableTextEditor} from '../..'
6
6
  import {schemaType} from '../../editor/__tests__/PortableTextEditorTester'
7
7
  import {withPlugins} from '../../editor/plugins'
@@ -70,21 +70,21 @@ describe('operationToPatches', () => {
70
70
  patchToOperations(editor, p)
71
71
  })
72
72
  expect(editor.children).toMatchInlineSnapshot(`
73
- Array [
74
- Object {
73
+ [
74
+ {
75
75
  "__inline": false,
76
76
  "_key": "c01739b0d03b",
77
77
  "_type": "image",
78
- "children": Array [
79
- Object {
78
+ "children": [
79
+ {
80
80
  "_key": "${VOID_CHILD_KEY}",
81
81
  "_type": "span",
82
- "marks": Array [],
82
+ "marks": [],
83
83
  "text": "",
84
84
  },
85
85
  ],
86
- "value": Object {
87
- "asset": Object {
86
+ "value": {
87
+ "asset": {
88
88
  "_ref": "image-f52f71bc1df46e080dabe43a8effe8ccfb5f21de-4032x3024-png",
89
89
  "_type": "reference",
90
90
  },
@@ -93,7 +93,7 @@ describe('operationToPatches', () => {
93
93
  ]
94
94
  `)
95
95
  })
96
- it('will not create operations for insertion inside object blocks', () => {
96
+ it('will not create operations for insertion inside blocks', () => {
97
97
  editor.children = [
98
98
  {
99
99
  _type: 'someType',
@@ -127,31 +127,31 @@ describe('operationToPatches', () => {
127
127
  patchToOperations(editor, p)
128
128
  })
129
129
  expect(editor.children).toMatchInlineSnapshot(`
130
- Array [
131
- Object {
130
+ [
131
+ {
132
132
  "__inline": false,
133
133
  "_key": "c01739b0d03b",
134
134
  "_type": "someType",
135
- "children": Array [
136
- Object {
135
+ "children": [
136
+ {
137
137
  "_key": "${VOID_CHILD_KEY}",
138
138
  "_type": "span",
139
- "marks": Array [],
139
+ "marks": [],
140
140
  "text": "",
141
141
  },
142
142
  ],
143
- "value": Object {
144
- "asset": Object {
143
+ "value": {
144
+ "asset": {
145
145
  "_ref": "image-f52f71bc1df46e080dabe43a8effe8ccfb5f21de-4032x3024-png",
146
146
  "_type": "reference",
147
147
  },
148
- "nestedArray": Array [],
148
+ "nestedArray": [],
149
149
  },
150
150
  },
151
151
  ]
152
152
  `)
153
153
  })
154
- it('will not create operations for removal inside object blocks', () => {
154
+ it('will not create operations for removal inside blocks', () => {
155
155
  editor.children = [
156
156
  {
157
157
  _type: 'someType',
@@ -190,26 +190,26 @@ describe('operationToPatches', () => {
190
190
  patchToOperations(editor, p)
191
191
  })
192
192
  expect(editor.children).toMatchInlineSnapshot(`
193
- Array [
194
- Object {
193
+ [
194
+ {
195
195
  "__inline": false,
196
196
  "_key": "c01739b0d03b",
197
197
  "_type": "someType",
198
- "children": Array [
199
- Object {
198
+ "children": [
199
+ {
200
200
  "_key": "${VOID_CHILD_KEY}",
201
201
  "_type": "span",
202
- "marks": Array [],
202
+ "marks": [],
203
203
  "text": "",
204
204
  },
205
205
  ],
206
- "value": Object {
207
- "asset": Object {
206
+ "value": {
207
+ "asset": {
208
208
  "_ref": "image-f52f71bc1df46e080dabe43a8effe8ccfb5f21de-4032x3024-png",
209
209
  "_type": "reference",
210
210
  },
211
- "nestedArray": Array [
212
- Object {
211
+ "nestedArray": [
212
+ {
213
213
  "_key": "foo",
214
214
  "_type": "nestedValue",
215
215
  },
@@ -219,7 +219,7 @@ describe('operationToPatches', () => {
219
219
  ]
220
220
  `)
221
221
  })
222
- it('will not create operations for setting data inside object blocks', () => {
222
+ it('will not create operations for setting data inside blocks', () => {
223
223
  editor.children = [
224
224
  {
225
225
  _key: '1335959d4d03',
@@ -265,34 +265,34 @@ describe('operationToPatches', () => {
265
265
  patchToOperations(editor, p)
266
266
  })
267
267
  expect(editor.children).toMatchInlineSnapshot(`
268
- Array [
269
- Object {
268
+ [
269
+ {
270
270
  "_key": "1335959d4d03",
271
271
  "_type": "block",
272
- "children": Array [
273
- Object {
272
+ "children": [
273
+ {
274
274
  "_key": "9bd868adcd6b",
275
275
  "_type": "span",
276
- "marks": Array [],
276
+ "marks": [],
277
277
  "text": "1 ",
278
278
  },
279
- Object {
279
+ {
280
280
  "_key": "6f75d593f3fc",
281
281
  "_type": "span",
282
- "marks": Array [
282
+ "marks": [
283
283
  "11de7fcea659",
284
284
  ],
285
285
  "text": "2",
286
286
  },
287
- Object {
287
+ {
288
288
  "_key": "033618a7f081",
289
289
  "_type": "span",
290
- "marks": Array [],
290
+ "marks": [],
291
291
  "text": " 3",
292
292
  },
293
293
  ],
294
- "markDefs": Array [
295
- Object {
294
+ "markDefs": [
295
+ {
296
296
  "_key": "11de7fcea659",
297
297
  "_type": "link",
298
298
  },
@@ -1,5 +1,5 @@
1
- import {describe, expect, it} from '@jest/globals'
2
1
  import type {InsertTextOperation, Range} from 'slate'
2
+ import {describe, expect, it} from 'vitest'
3
3
  import {moveRangeByOperation} from '../ranges'
4
4
 
5
5
  describe('moveRangeByOperation', () => {
@@ -1,6 +1,6 @@
1
- import {describe, expect, it, jest} from '@jest/globals'
2
1
  import {render, waitFor} from '@testing-library/react'
3
2
  import {createRef, type RefObject} from 'react'
3
+ import {describe, expect, it, vi} from 'vitest'
4
4
  import {
5
5
  PortableTextEditorTester,
6
6
  schemaType,
@@ -25,7 +25,7 @@ describe('values: normalization', () => {
25
25
  markDefs: [],
26
26
  },
27
27
  ]
28
- const onChange = jest.fn()
28
+ const onChange = vi.fn()
29
29
  render(
30
30
  <PortableTextEditorTester
31
31
  onChange={onChange}
@@ -34,6 +34,17 @@ describe('values: normalization', () => {
34
34
  value={initialValue}
35
35
  />,
36
36
  )
37
+
38
+ await waitFor(() => {
39
+ if (editorRef.current) {
40
+ expect(onChange).toHaveBeenCalledWith({
41
+ type: 'value',
42
+ value: initialValue,
43
+ })
44
+ expect(onChange).toHaveBeenCalledWith({type: 'ready'})
45
+ }
46
+ })
47
+
37
48
  await waitFor(() => {
38
49
  if (editorRef.current) {
39
50
  PortableTextEditor.focus(editorRef.current)
@@ -1,4 +1,4 @@
1
- import {describe, expect, it} from '@jest/globals'
1
+ import {describe, expect, it} from 'vitest'
2
2
  import {schemaType} from '../../editor/__tests__/PortableTextEditorTester'
3
3
  import {getPortableTextMemberSchemaTypes} from '../getPortableTextMemberSchemaTypes'
4
4
  import {fromSlateValue, toSlateValue} from '../values'
@@ -59,12 +59,12 @@ describe('toSlateValue', () => {
59
59
  {schemaTypes},
60
60
  )
61
61
  expect(result).toMatchInlineSnapshot(`
62
- Array [
63
- Object {
62
+ [
63
+ {
64
64
  "_key": "123",
65
65
  "_type": "myTestBlockType",
66
- "children": Array [
67
- Object {
66
+ "children": [
67
+ {
68
68
  "_key": "1231",
69
69
  "_type": "span",
70
70
  "text": "123",
@@ -76,7 +76,7 @@ Array [
76
76
  `)
77
77
  })
78
78
 
79
- it('given type is block and has custom object in children', () => {
79
+ it('given type is block and has custom in children', () => {
80
80
  const result = toSlateValue(
81
81
  [
82
82
  {
@@ -102,30 +102,30 @@ Array [
102
102
  )
103
103
 
104
104
  expect(result).toMatchInlineSnapshot(`
105
- Array [
106
- Object {
105
+ [
106
+ {
107
107
  "_key": "123",
108
108
  "_type": "myTestBlockType",
109
- "children": Array [
110
- Object {
109
+ "children": [
110
+ {
111
111
  "_key": "1231",
112
112
  "_type": "span",
113
113
  "text": "123",
114
114
  },
115
- Object {
115
+ {
116
116
  "__inline": true,
117
117
  "_key": "1232",
118
118
  "_type": "image",
119
- "children": Array [
120
- Object {
119
+ "children": [
120
+ {
121
121
  "_key": "void-child",
122
122
  "_type": "span",
123
- "marks": Array [],
123
+ "marks": [],
124
124
  "text": "",
125
125
  },
126
126
  ],
127
- "value": Object {
128
- "asset": Object {
127
+ "value": {
128
+ "asset": {
129
129
  "_ref": "ref-123",
130
130
  },
131
131
  },
@@ -213,7 +213,7 @@ describe('fromSlateValue', () => {
213
213
  ])
214
214
  })
215
215
 
216
- it('has object equality', () => {
216
+ it('has equality', () => {
217
217
  const keyMap = {}
218
218
  const value = [
219
219
  {
@@ -47,8 +47,6 @@ const debugVerbose = debug.enabled && true
47
47
  export function createApplyPatch(
48
48
  schemaTypes: PortableTextMemberSchemaTypes,
49
49
  ): (editor: PortableTextSlateEditor, patch: Patch) => boolean {
50
- let previousPatch: Patch | undefined
51
-
52
50
  return (editor: PortableTextSlateEditor, patch: Patch): boolean => {
53
51
  let changed = false
54
52
 
@@ -66,7 +64,7 @@ export function createApplyPatch(
66
64
  changed = insertPatch(editor, patch, schemaTypes)
67
65
  break
68
66
  case 'unset':
69
- changed = unsetPatch(editor, patch, previousPatch)
67
+ changed = unsetPatch(editor, patch)
70
68
  break
71
69
  case 'set':
72
70
  changed = setPatch(editor, patch)
@@ -80,7 +78,7 @@ export function createApplyPatch(
80
78
  } catch (err) {
81
79
  console.error(err)
82
80
  }
83
- previousPatch = patch
81
+
84
82
  return changed
85
83
  }
86
84
  }
@@ -308,18 +306,14 @@ function setPatch(editor: PortableTextSlateEditor, patch: SetPatch) {
308
306
  return true
309
307
  }
310
308
 
311
- function unsetPatch(
312
- editor: PortableTextSlateEditor,
313
- patch: UnsetPatch,
314
- previousPatch?: Patch,
315
- ) {
309
+ function unsetPatch(editor: PortableTextSlateEditor, patch: UnsetPatch) {
316
310
  // Value
317
311
  if (patch.path.length === 0) {
318
312
  debug('Removing everything')
319
313
  debugState(editor, 'before')
320
314
  const previousSelection = editor.selection
321
315
  Transforms.deselect(editor)
322
- editor.children.forEach((c, i) => {
316
+ editor.children.forEach((_child, i) => {
323
317
  Transforms.removeNodes(editor, {at: [i]})
324
318
  })
325
319
  Transforms.insertNodes(editor, editor.pteCreateTextBlock({decorators: []}))
@@ -10,7 +10,6 @@ import type {
10
10
  InvalidValueResolution,
11
11
  PortableTextMemberSchemaTypes,
12
12
  } from '../types/editor'
13
- import {EMPTY_MARKDEFS} from './values'
14
13
 
15
14
  export interface Validation {
16
15
  valid: boolean
@@ -227,28 +226,7 @@ export function validateValue(
227
226
  }
228
227
  return true
229
228
  }
230
- // Test that markDefs are valid if they exists
231
- if (blk.markDefs && !Array.isArray(blk.markDefs)) {
232
- resolution = {
233
- patches: [
234
- set({...textBlock, markDefs: EMPTY_MARKDEFS}, [
235
- {_key: textBlock._key},
236
- ]),
237
- ],
238
- description: `Block has invalid required property 'markDefs'.`,
239
- action: 'Add empty markDefs array',
240
- item: textBlock,
241
229
 
242
- i18n: {
243
- description:
244
- 'inputs.portable-text.invalid-value.missing-or-invalid-markdefs.description',
245
- action:
246
- 'inputs.portable-text.invalid-value.missing-or-invalid-markdefs.action',
247
- values: {key: textBlock._key},
248
- },
249
- }
250
- return true
251
- }
252
230
  const allUsedMarks = uniq(
253
231
  flatten(
254
232
  textBlock.children
@@ -1,44 +0,0 @@
1
- // This utils are inspired from https://github.dev/mwood23/slate-test-utils/blob/master/src/buildTestHarness.tsx
2
- import {fireEvent, type render} from '@testing-library/react'
3
- import {parseHotkey} from 'is-hotkey-esm'
4
- import {act} from 'react'
5
-
6
- export async function triggerKeyboardEvent(
7
- hotkey: string,
8
- element: Element,
9
- ): Promise<void> {
10
- const eventProps = parseHotkey(hotkey)
11
- const values = hotkey.split('+')
12
-
13
- fireEvent(
14
- element,
15
- new window.KeyboardEvent('keydown', {
16
- key: values[values.length - 1],
17
- code: `${eventProps.which}`,
18
- keyCode: eventProps.which,
19
- bubbles: true,
20
- ...eventProps,
21
- }),
22
- )
23
- }
24
-
25
- export async function getEditableElement(
26
- component: ReturnType<typeof render>,
27
- ): Promise<Element> {
28
- await act(async () => component)
29
- const element = component.container.querySelector(
30
- '[data-slate-editor="true"]',
31
- )
32
- if (!element) {
33
- throw new Error('Could not find element')
34
- }
35
- /**
36
- * Manually add this because JSDom doesn't implement this and Slate checks for it
37
- * internally before doing stuff.
38
- *
39
- * https://github.com/jsdom/jsdom/issues/1670
40
- */
41
- // @ts-ignore
42
- element.isContentEditable = true
43
- return element
44
- }