@portabletext/editor 1.1.0 → 1.1.2

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 (79) hide show
  1. package/README.md +3 -0
  2. package/lib/index.d.mts +1680 -12
  3. package/lib/index.d.ts +1680 -12
  4. package/lib/index.esm.js +310 -162
  5. package/lib/index.esm.js.map +1 -1
  6. package/lib/index.js +310 -163
  7. package/lib/index.js.map +1 -1
  8. package/lib/index.mjs +310 -162
  9. package/lib/index.mjs.map +1 -1
  10. package/package.json +25 -38
  11. package/src/editor/Editable.tsx +51 -50
  12. package/src/editor/PortableTextEditor.tsx +42 -26
  13. package/src/editor/__tests__/PortableTextEditor.test.tsx +11 -12
  14. package/src/editor/__tests__/PortableTextEditorTester.tsx +2 -5
  15. package/src/editor/__tests__/RangeDecorations.test.tsx +6 -7
  16. package/src/editor/__tests__/handleClick.test.tsx +27 -7
  17. package/src/editor/__tests__/insert-block.test.tsx +6 -6
  18. package/src/editor/__tests__/pteWarningsSelfSolving.test.tsx +8 -8
  19. package/src/editor/__tests__/self-solving.test.tsx +176 -0
  20. package/src/editor/components/Element.tsx +15 -17
  21. package/src/editor/components/Leaf.tsx +40 -35
  22. package/src/editor/components/SlateContainer.tsx +2 -2
  23. package/src/editor/components/Synchronizer.tsx +62 -34
  24. package/src/editor/editor-machine.ts +195 -0
  25. package/src/editor/hooks/usePortableTextEditor.ts +1 -1
  26. package/src/editor/hooks/usePortableTextEditorSelection.tsx +12 -14
  27. package/src/editor/hooks/useSyncValue.test.tsx +9 -9
  28. package/src/editor/hooks/useSyncValue.ts +16 -19
  29. package/src/editor/nodes/DefaultAnnotation.tsx +1 -2
  30. package/src/editor/nodes/DefaultObject.tsx +1 -1
  31. package/src/editor/plugins/__tests__/createWithInsertData.test.tsx +2 -5
  32. package/src/editor/plugins/__tests__/withEditableAPIDelete.test.tsx +28 -28
  33. package/src/editor/plugins/__tests__/withEditableAPIGetFragment.test.tsx +17 -17
  34. package/src/editor/plugins/__tests__/withEditableAPIInsert.test.tsx +8 -8
  35. package/src/editor/plugins/__tests__/withEditableAPISelectionsOverlapping.test.tsx +6 -6
  36. package/src/editor/plugins/__tests__/withPortableTextLists.test.tsx +2 -2
  37. package/src/editor/plugins/__tests__/withPortableTextMarkModel.test.tsx +47 -49
  38. package/src/editor/plugins/__tests__/withPortableTextSelections.test.tsx +22 -11
  39. package/src/editor/plugins/__tests__/withUndoRedo.test.tsx +9 -9
  40. package/src/editor/plugins/createWithEditableAPI.ts +8 -8
  41. package/src/editor/plugins/createWithHotKeys.ts +8 -12
  42. package/src/editor/plugins/createWithInsertBreak.ts +4 -4
  43. package/src/editor/plugins/createWithInsertData.ts +11 -16
  44. package/src/editor/plugins/createWithMaxBlocks.ts +1 -1
  45. package/src/editor/plugins/createWithObjectKeys.ts +10 -3
  46. package/src/editor/plugins/createWithPatches.ts +9 -12
  47. package/src/editor/plugins/createWithPlaceholderBlock.ts +2 -2
  48. package/src/editor/plugins/createWithPortableTextBlockStyle.ts +13 -5
  49. package/src/editor/plugins/createWithPortableTextLists.ts +3 -4
  50. package/src/editor/plugins/createWithPortableTextMarkModel.ts +24 -10
  51. package/src/editor/plugins/createWithPortableTextSelections.ts +9 -10
  52. package/src/editor/plugins/createWithSchemaTypes.ts +13 -4
  53. package/src/editor/plugins/createWithUndoRedo.ts +3 -7
  54. package/src/editor/plugins/createWithUtils.ts +6 -6
  55. package/src/editor/plugins/index.ts +21 -11
  56. package/src/index.ts +9 -3
  57. package/src/types/editor.ts +33 -33
  58. package/src/types/options.ts +3 -3
  59. package/src/types/slate.ts +4 -4
  60. package/src/utils/__tests__/dmpToOperations.test.ts +4 -4
  61. package/src/utils/__tests__/operationToPatches.test.ts +62 -62
  62. package/src/utils/__tests__/patchToOperations.test.ts +40 -40
  63. package/src/utils/__tests__/ranges.test.ts +2 -2
  64. package/src/utils/__tests__/valueNormalization.test.tsx +14 -2
  65. package/src/utils/__tests__/values.test.ts +17 -17
  66. package/src/utils/applyPatch.ts +10 -12
  67. package/src/utils/getPortableTextMemberSchemaTypes.ts +8 -8
  68. package/src/utils/operationToPatches.ts +5 -9
  69. package/src/utils/paths.ts +5 -5
  70. package/src/utils/ranges.ts +4 -5
  71. package/src/utils/selection.ts +2 -2
  72. package/src/utils/ucs2Indices.ts +2 -2
  73. package/src/utils/validateValue.ts +3 -25
  74. package/src/utils/values.ts +7 -8
  75. package/src/utils/weakMaps.ts +2 -2
  76. package/src/utils/withChanges.ts +1 -1
  77. package/src/utils/withUndoRedo.ts +1 -1
  78. package/src/utils/withoutPatching.ts +1 -1
  79. package/src/editor/__tests__/utils.ts +0 -45
@@ -1,6 +1,7 @@
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 * as React from 'react'
4
+ import {describe, expect, it, vi} from 'vitest'
4
5
  import {
5
6
  PortableTextEditorTester,
6
7
  schemaType,
@@ -25,7 +26,7 @@ describe('values: normalization', () => {
25
26
  markDefs: [],
26
27
  },
27
28
  ]
28
- const onChange = jest.fn()
29
+ const onChange = vi.fn()
29
30
  render(
30
31
  <PortableTextEditorTester
31
32
  onChange={onChange}
@@ -34,6 +35,17 @@ describe('values: normalization', () => {
34
35
  value={initialValue}
35
36
  />,
36
37
  )
38
+
39
+ await waitFor(() => {
40
+ if (editorRef.current) {
41
+ expect(onChange).toHaveBeenCalledWith({
42
+ type: 'value',
43
+ value: initialValue,
44
+ })
45
+ expect(onChange).toHaveBeenCalledWith({type: 'ready'})
46
+ }
47
+ })
48
+
37
49
  await waitFor(() => {
38
50
  if (editorRef.current) {
39
51
  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
  {
@@ -1,4 +1,3 @@
1
- /* eslint-disable max-statements */
2
1
  import {
3
2
  applyAll,
4
3
  type DiffMatchPatch,
@@ -16,12 +15,12 @@ import {
16
15
  makeDiff,
17
16
  parsePatch,
18
17
  } from '@sanity/diff-match-patch'
19
- import {
20
- type KeyedSegment,
21
- type Path,
22
- type PathSegment,
23
- type PortableTextBlock,
24
- type PortableTextChild,
18
+ import type {
19
+ KeyedSegment,
20
+ Path,
21
+ PathSegment,
22
+ PortableTextBlock,
23
+ PortableTextChild,
25
24
  } from '@sanity/types'
26
25
  import {
27
26
  Element,
@@ -31,9 +30,9 @@ import {
31
30
  type Node,
32
31
  type Path as SlatePath,
33
32
  } from 'slate'
34
- import {
35
- type PortableTextMemberSchemaTypes,
36
- type PortableTextSlateEditor,
33
+ import type {
34
+ PortableTextMemberSchemaTypes,
35
+ PortableTextSlateEditor,
37
36
  } from '../types/editor'
38
37
  import {debugWithName} from './debug'
39
38
  import {toSlateValue} from './values'
@@ -50,7 +49,7 @@ export function createApplyPatch(
50
49
  ): (editor: PortableTextSlateEditor, patch: Patch) => boolean {
51
50
  let previousPatch: Patch | undefined
52
51
 
53
- return function (editor: PortableTextSlateEditor, patch: Patch): boolean {
52
+ return (editor: PortableTextSlateEditor, patch: Patch): boolean => {
54
53
  let changed = false
55
54
 
56
55
  // Save some CPU cycles by not stringifying unless enabled
@@ -273,7 +272,6 @@ function setPatch(editor: PortableTextSlateEditor, patch: SetPatch) {
273
272
  } else if (Element.isElement(block) && patch.path.length === 1 && blockPath) {
274
273
  debug('Setting block property')
275
274
  const {children, ...nextRest} = value as unknown as PortableTextBlock
276
- // eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-vars
277
275
  const {children: prevChildren, ...prevRest} = block || {children: undefined}
278
276
  // Set any block properties
279
277
  editor.apply({
@@ -1,12 +1,12 @@
1
- import {
2
- type ArraySchemaType,
3
- type BlockSchemaType,
4
- type ObjectSchemaType,
5
- type PortableTextBlock,
6
- type SchemaType,
7
- type SpanSchemaType,
1
+ import type {
2
+ ArraySchemaType,
3
+ BlockSchemaType,
4
+ ObjectSchemaType,
5
+ PortableTextBlock,
6
+ SchemaType,
7
+ SpanSchemaType,
8
8
  } from '@sanity/types'
9
- import {type PortableTextMemberSchemaTypes} from '../types/editor'
9
+ import type {PortableTextMemberSchemaTypes} from '../types/editor'
10
10
 
11
11
  export function getPortableTextMemberSchemaTypes(
12
12
  portableTextType: ArraySchemaType<PortableTextBlock>,
@@ -7,11 +7,7 @@ import {
7
7
  type InsertPosition,
8
8
  type Patch,
9
9
  } from '@portabletext/patches'
10
- import {
11
- type Path,
12
- type PortableTextSpan,
13
- type PortableTextTextBlock,
14
- } from '@sanity/types'
10
+ import type {Path, PortableTextSpan, PortableTextTextBlock} from '@sanity/types'
15
11
  import {get, isUndefined, omitBy} from 'lodash'
16
12
  import {
17
13
  Text,
@@ -25,10 +21,10 @@ import {
25
21
  type SetNodeOperation,
26
22
  type SplitNodeOperation,
27
23
  } from 'slate'
28
- import {type PatchFunctions} from '../editor/plugins/createWithPatches'
29
- import {
30
- type PortableTextMemberSchemaTypes,
31
- type PortableTextSlateEditor,
24
+ import type {PatchFunctions} from '../editor/plugins/createWithPatches'
25
+ import type {
26
+ PortableTextMemberSchemaTypes,
27
+ PortableTextSlateEditor,
32
28
  } from '../types/editor'
33
29
  import {debugWithName} from './debug'
34
30
  import {fromSlateValue} from './values'
@@ -7,11 +7,11 @@ import {
7
7
  type Point,
8
8
  type Path as SlatePath,
9
9
  } from 'slate'
10
- import {
11
- type EditorSelectionPoint,
12
- type PortableTextMemberSchemaTypes,
10
+ import type {
11
+ EditorSelectionPoint,
12
+ PortableTextMemberSchemaTypes,
13
13
  } from '../types/editor'
14
- import {type ObjectWithKeyAndType} from './ranges'
14
+ import type {ObjectWithKeyAndType} from './ranges'
15
15
 
16
16
  export function createKeyedPath(
17
17
  point: Point,
@@ -30,7 +30,7 @@ export function createKeyedPath(
30
30
  if (block._type !== types.block.name) {
31
31
  return keyedBlockPath as Path
32
32
  }
33
- let keyedChildPath
33
+ let keyedChildPath: Path | undefined
34
34
  const childPath = point.path.slice(0, 2)
35
35
  const child = Array.isArray(block.children) && block.children[childPath[1]]
36
36
  if (child) {
@@ -1,9 +1,8 @@
1
- /* eslint-disable complexity */
2
1
  import {Point, Range, type BaseRange, type Editor, type Operation} from 'slate'
3
- import {
4
- type EditorSelection,
5
- type EditorSelectionPoint,
6
- type PortableTextMemberSchemaTypes,
2
+ import type {
3
+ EditorSelection,
4
+ EditorSelectionPoint,
5
+ PortableTextMemberSchemaTypes,
7
6
  } from '../types/editor'
8
7
  import {createArrayedPath, createKeyedPath} from './paths'
9
8
 
@@ -1,6 +1,6 @@
1
- import {type Path, type PortableTextBlock} from '@sanity/types'
1
+ import type {Path, PortableTextBlock} from '@sanity/types'
2
2
  import {isEqual} from 'lodash'
3
- import {type EditorSelection, type EditorSelectionPoint} from '../types/editor'
3
+ import type {EditorSelection, EditorSelectionPoint} from '../types/editor'
4
4
 
5
5
  export function normalizePoint(
6
6
  point: EditorSelectionPoint,
@@ -1,4 +1,4 @@
1
- import {type Patch} from '@sanity/diff-match-patch'
1
+ import type {Patch} from '@sanity/diff-match-patch'
2
2
 
3
3
  /**
4
4
  * Takes a `patches` array as produced by diff-match-patch and adjusts the
@@ -15,7 +15,7 @@ export function adjustIndiciesToUcs2(patches: Patch[], base: string): Patch[] {
15
15
  let idx = 0 // index into the input.
16
16
 
17
17
  function advanceTo(target: number) {
18
- for (; byteOffset < target; ) {
18
+ while (byteOffset < target) {
19
19
  const codePoint = base.codePointAt(idx)
20
20
  if (typeof codePoint === 'undefined') {
21
21
  // Reached the end of the base string - the indicies won't be correct,
@@ -6,11 +6,10 @@ import {
6
6
  type PortableTextTextBlock,
7
7
  } from '@sanity/types'
8
8
  import {flatten, isPlainObject, uniq} from 'lodash'
9
- import {
10
- type InvalidValueResolution,
11
- type PortableTextMemberSchemaTypes,
9
+ import type {
10
+ InvalidValueResolution,
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,13 +1,13 @@
1
- import {
2
- type PathSegment,
3
- type PortableTextBlock,
4
- type PortableTextChild,
5
- type PortableTextObject,
6
- type PortableTextTextBlock,
1
+ import type {
2
+ PathSegment,
3
+ PortableTextBlock,
4
+ PortableTextChild,
5
+ PortableTextObject,
6
+ PortableTextTextBlock,
7
7
  } from '@sanity/types'
8
8
  import {isEqual} from 'lodash'
9
9
  import {Element, Text, type Descendant, type Node} from 'slate'
10
- import {type PortableTextMemberSchemaTypes} from '../types/editor'
10
+ import type {PortableTextMemberSchemaTypes} from '../types/editor'
11
11
 
12
12
  export const EMPTY_MARKDEFS: PortableTextObject[] = []
13
13
 
@@ -123,7 +123,6 @@ export function fromSlateValue(
123
123
  const {_type: _cType} = child
124
124
  if ('value' in child && _cType !== 'span') {
125
125
  hasInlines = true
126
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
127
126
  const {
128
127
  value: v,
129
128
  _key: k,
@@ -1,5 +1,5 @@
1
- import {type Editor, type Element, type Range} from 'slate'
2
- import {type EditorSelection} from '..'
1
+ import type {Editor, Element, Range} from 'slate'
2
+ import type {EditorSelection} from '..'
3
3
 
4
4
  // Is the editor currently receiving remote changes that are being applied to the content?
5
5
  export const IS_PROCESSING_REMOTE_CHANGES: WeakMap<Editor, boolean> =
@@ -1,4 +1,4 @@
1
- import {type Editor} from 'slate'
1
+ import type {Editor} from 'slate'
2
2
  import {
3
3
  IS_PROCESSING_LOCAL_CHANGES,
4
4
  IS_PROCESSING_REMOTE_CHANGES,
@@ -1,4 +1,4 @@
1
- import {type Editor} from 'slate'
1
+ import type {Editor} from 'slate'
2
2
 
3
3
  const IS_UDOING: WeakMap<Editor, boolean | undefined> = new WeakMap()
4
4
  const IS_REDOING: WeakMap<Editor, boolean | undefined> = new WeakMap()
@@ -1,4 +1,4 @@
1
- import {type Editor} from 'slate'
1
+ import type {Editor} from 'slate'
2
2
 
3
3
  export const PATCHING: WeakMap<Editor, boolean | undefined> = new WeakMap()
4
4
 
@@ -1,45 +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
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
42
- // @ts-ignore
43
- element.isContentEditable = true
44
- return element
45
- }