@portabletext/editor 2.7.2 → 2.8.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.
Files changed (72) hide show
  1. package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs +3 -1
  2. package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs.map +1 -1
  3. package/lib/_chunks-cjs/selector.is-selection-expanded.cjs +10 -4
  4. package/lib/_chunks-cjs/selector.is-selection-expanded.cjs.map +1 -1
  5. package/lib/_chunks-cjs/util.merge-text-blocks.cjs +0 -1
  6. package/lib/_chunks-cjs/util.merge-text-blocks.cjs.map +1 -1
  7. package/lib/_chunks-cjs/util.slice-blocks.cjs +60 -9
  8. package/lib/_chunks-cjs/util.slice-blocks.cjs.map +1 -1
  9. package/lib/_chunks-dts/behavior.types.action.d.cts +149 -149
  10. package/lib/_chunks-dts/behavior.types.action.d.ts +86 -86
  11. package/lib/_chunks-es/selector.is-selecting-entire-blocks.js +4 -2
  12. package/lib/_chunks-es/selector.is-selecting-entire-blocks.js.map +1 -1
  13. package/lib/_chunks-es/selector.is-selection-expanded.js +10 -4
  14. package/lib/_chunks-es/selector.is-selection-expanded.js.map +1 -1
  15. package/lib/_chunks-es/util.merge-text-blocks.js +0 -1
  16. package/lib/_chunks-es/util.merge-text-blocks.js.map +1 -1
  17. package/lib/_chunks-es/util.slice-blocks.js +56 -8
  18. package/lib/_chunks-es/util.slice-blocks.js.map +1 -1
  19. package/lib/index.cjs +94 -131
  20. package/lib/index.cjs.map +1 -1
  21. package/lib/index.js +90 -128
  22. package/lib/index.js.map +1 -1
  23. package/lib/plugins/index.d.cts +3 -3
  24. package/lib/selectors/index.d.cts +13 -3
  25. package/lib/selectors/index.d.ts +13 -3
  26. package/package.json +13 -14
  27. package/src/behaviors/behavior.abstract.insert.ts +58 -1
  28. package/src/behaviors/behavior.abstract.split.ts +0 -1
  29. package/src/behaviors/behavior.core.annotations.ts +24 -2
  30. package/src/behaviors/behavior.core.ts +1 -1
  31. package/src/behaviors/behavior.types.event.ts +18 -18
  32. package/src/converters/converter.portable-text.ts +0 -1
  33. package/src/converters/converter.text-html.serialize.test.ts +27 -17
  34. package/src/converters/converter.text-html.ts +0 -1
  35. package/src/converters/converter.text-plain.test.ts +1 -1
  36. package/src/converters/converter.text-plain.ts +0 -1
  37. package/src/editor/Editable.tsx +0 -1
  38. package/src/editor/plugins/createWithEditableAPI.ts +16 -0
  39. package/src/internal-utils/parse-blocks.test.ts +23 -23
  40. package/src/internal-utils/parse-blocks.ts +13 -24
  41. package/src/internal-utils/test-editor.tsx +15 -21
  42. package/src/operations/behavior.operation.annotation.add.ts +2 -13
  43. package/src/operations/behavior.operation.block.set.ts +1 -1
  44. package/src/operations/behavior.operation.block.unset.ts +2 -2
  45. package/src/operations/behavior.operation.insert.block.ts +1 -1
  46. package/src/operations/behavior.operations.ts +0 -18
  47. package/src/plugins/plugin.internal.auto-close-brackets.test.tsx +25 -71
  48. package/src/plugins/plugin.markdown.test.tsx +12 -30
  49. package/src/selectors/selector.get-selected-value.test.ts +748 -0
  50. package/src/selectors/selector.get-selected-value.ts +28 -7
  51. package/src/selectors/selector.get-trimmed-selection.test.ts +0 -1
  52. package/src/selectors/selector.is-active-annotation.test.ts +320 -0
  53. package/src/selectors/selector.is-active-annotation.ts +24 -0
  54. package/src/utils/util.merge-text-blocks.ts +1 -1
  55. package/src/utils/util.slice-blocks.ts +36 -3
  56. package/src/editor/__tests__/PortableTextEditor.test.tsx +0 -430
  57. package/src/editor/__tests__/PortableTextEditorTester.tsx +0 -58
  58. package/src/editor/__tests__/RangeDecorations.test.tsx +0 -213
  59. package/src/editor/__tests__/insert-block.test.tsx +0 -224
  60. package/src/editor/__tests__/self-solving.test.tsx +0 -183
  61. package/src/editor/plugins/__tests__/withEditableAPIDelete.test.tsx +0 -298
  62. package/src/editor/plugins/__tests__/withEditableAPIGetFragment.test.tsx +0 -177
  63. package/src/editor/plugins/__tests__/withEditableAPIInsert.test.tsx +0 -538
  64. package/src/editor/plugins/__tests__/withEditableAPISelectionsOverlapping.test.tsx +0 -162
  65. package/src/editor/plugins/__tests__/withPortableTextLists.test.tsx +0 -65
  66. package/src/editor/plugins/__tests__/withPortableTextMarkModel.test.tsx +0 -612
  67. package/src/editor/plugins/__tests__/withPortableTextSelections.test.tsx +0 -103
  68. package/src/editor/plugins/__tests__/withUndoRedo.test.tsx +0 -147
  69. package/src/internal-utils/__tests__/valueNormalization.test.tsx +0 -79
  70. package/src/operations/behavior.operation.insert-inline-object.ts +0 -59
  71. package/src/operations/behavior.operation.insert-span.ts +0 -48
  72. package/src/utils/util.slice-blocks.test.ts +0 -465
@@ -1,147 +0,0 @@
1
- import {createTestKeyGenerator} from '@portabletext/test'
2
- import {render, waitFor} from '@testing-library/react'
3
- import {createRef, type RefObject} from 'react'
4
- import {describe, expect, it, vi} from 'vitest'
5
- import {PortableTextEditorTester} from '../../__tests__/PortableTextEditorTester'
6
- import {PortableTextEditor} from '../../PortableTextEditor'
7
-
8
- const initialValue = [
9
- {
10
- _key: 'a',
11
- _type: 'block',
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: 'block',
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
- const initialSelection = {
40
- focus: {path: [{_key: 'b'}, 'children', {_key: 'b1'}], offset: 7},
41
- anchor: {path: [{_key: 'b'}, 'children', {_key: 'b1'}], offset: 7},
42
- }
43
-
44
- describe('plugin:withUndoRedo', () => {
45
- it('preserves the keys when undoing ', async () => {
46
- const editorRef: RefObject<PortableTextEditor | null> = createRef()
47
- const onChange = vi.fn()
48
- render(
49
- <PortableTextEditorTester
50
- keyGenerator={createTestKeyGenerator()}
51
- onChange={onChange}
52
- ref={editorRef}
53
- value={initialValue}
54
- />,
55
- )
56
-
57
- await waitFor(() => {
58
- if (editorRef.current) {
59
- expect(onChange).toHaveBeenCalledWith({
60
- type: 'value',
61
- value: initialValue,
62
- })
63
- expect(onChange).toHaveBeenCalledWith({type: 'ready'})
64
- }
65
- })
66
-
67
- await waitFor(() => {
68
- if (editorRef.current) {
69
- PortableTextEditor.focus(editorRef.current)
70
- PortableTextEditor.select(editorRef.current, initialSelection)
71
- PortableTextEditor.delete(
72
- editorRef.current,
73
- PortableTextEditor.getSelection(editorRef.current),
74
- {mode: 'blocks'},
75
- )
76
- expect(PortableTextEditor.getValue(editorRef.current))
77
- .toMatchInlineSnapshot(`
78
- [
79
- {
80
- "_key": "a",
81
- "_type": "block",
82
- "children": [
83
- {
84
- "_key": "a1",
85
- "_type": "span",
86
- "marks": [],
87
- "text": "Block A",
88
- },
89
- ],
90
- "markDefs": [],
91
- "style": "normal",
92
- },
93
- ]
94
- `)
95
- PortableTextEditor.undo(editorRef.current)
96
- expect(PortableTextEditor.getValue(editorRef.current)).toEqual(
97
- initialValue,
98
- )
99
- }
100
- })
101
- })
102
- it('preserves the keys when redoing ', async () => {
103
- const editorRef: RefObject<PortableTextEditor | null> = createRef()
104
- const onChange = vi.fn()
105
-
106
- render(
107
- <PortableTextEditorTester
108
- keyGenerator={createTestKeyGenerator()}
109
- onChange={onChange}
110
- ref={editorRef}
111
- value={initialValue}
112
- />,
113
- )
114
-
115
- await waitFor(() => {
116
- if (editorRef.current) {
117
- expect(onChange).toHaveBeenCalledWith({
118
- type: 'value',
119
- value: initialValue,
120
- })
121
- expect(onChange).toHaveBeenCalledWith({type: 'ready'})
122
- }
123
- })
124
-
125
- await waitFor(() => {
126
- if (editorRef.current) {
127
- PortableTextEditor.focus(editorRef.current)
128
- PortableTextEditor.select(editorRef.current, initialSelection)
129
- PortableTextEditor.insertBlock(
130
- editorRef.current,
131
- editorRef.current.schemaTypes.block,
132
- {
133
- children: [{_key: 'c1', _type: 'span', marks: [], text: 'Block C'}],
134
- },
135
- )
136
- const producedKey = PortableTextEditor.getValue(
137
- editorRef.current,
138
- )?.slice(-1)[0]?._key
139
- PortableTextEditor.undo(editorRef.current)
140
- PortableTextEditor.redo(editorRef.current)
141
- expect(
142
- PortableTextEditor.getValue(editorRef.current)?.slice(-1)[0]?._key,
143
- ).toEqual(producedKey)
144
- }
145
- })
146
- })
147
- })
@@ -1,79 +0,0 @@
1
- import {createTestKeyGenerator} from '@portabletext/test'
2
- import {render, waitFor} from '@testing-library/react'
3
- import {createRef, type RefObject} from 'react'
4
- import {describe, expect, it, vi} from 'vitest'
5
- import {PortableTextEditorTester} from '../../editor/__tests__/PortableTextEditorTester'
6
- import {PortableTextEditor} from '../../editor/PortableTextEditor'
7
-
8
- describe('values: normalization', () => {
9
- it("accepts incoming value with blocks without a style or markDefs prop, but doesn't leave them without them when editing them", async () => {
10
- const editorRef: RefObject<PortableTextEditor | null> = createRef()
11
- const initialValue = [
12
- {
13
- _key: '5fc57af23597',
14
- _type: 'block',
15
- children: [
16
- {
17
- _key: 'be1c67c6971a',
18
- _type: 'span',
19
- marks: [],
20
- text: 'Hello',
21
- },
22
- ],
23
- markDefs: [],
24
- },
25
- ]
26
- const onChange = vi.fn()
27
- render(
28
- <PortableTextEditorTester
29
- keyGenerator={createTestKeyGenerator()}
30
- onChange={onChange}
31
- ref={editorRef}
32
- value={initialValue}
33
- />,
34
- )
35
-
36
- await waitFor(() => {
37
- if (editorRef.current) {
38
- expect(onChange).toHaveBeenCalledWith({
39
- type: 'value',
40
- value: initialValue,
41
- })
42
- expect(onChange).toHaveBeenCalledWith({type: 'ready'})
43
- }
44
- })
45
-
46
- await waitFor(() => {
47
- if (editorRef.current) {
48
- PortableTextEditor.focus(editorRef.current)
49
- PortableTextEditor.select(editorRef.current, {
50
- focus: {
51
- path: [{_key: '5fc57af23597'}, 'children', {_key: 'be1c67c6971a'}],
52
- offset: 0,
53
- },
54
- anchor: {
55
- path: [{_key: '5fc57af23597'}, 'children', {_key: 'be1c67c6971a'}],
56
- offset: 5,
57
- },
58
- })
59
- PortableTextEditor.toggleMark(editorRef.current, 'strong')
60
- expect(PortableTextEditor.getValue(editorRef.current)).toEqual([
61
- {
62
- _key: '5fc57af23597',
63
- _type: 'block',
64
- children: [
65
- {
66
- _key: 'be1c67c6971a',
67
- _type: 'span',
68
- marks: ['strong'],
69
- text: 'Hello',
70
- },
71
- ],
72
- markDefs: [],
73
- style: 'normal',
74
- },
75
- ])
76
- }
77
- })
78
- })
79
- })
@@ -1,59 +0,0 @@
1
- import {Editor, Transforms, type Element} from 'slate'
2
- import {parseInlineObject} from '../internal-utils/parse-blocks'
3
- import {toSlateValue} from '../internal-utils/values'
4
- import type {BehaviorOperationImplementation} from './behavior.operations'
5
-
6
- export const insertInlineObjectOperationImplementation: BehaviorOperationImplementation<
7
- 'insert.inline object'
8
- > = ({context, operation}) => {
9
- const parsedInlineObject = parseInlineObject({
10
- context,
11
- inlineObject: {
12
- _type: operation.inlineObject.name,
13
- ...(operation.inlineObject.value ?? {}),
14
- },
15
- options: {refreshKeys: false, validateFields: true},
16
- })
17
-
18
- if (!parsedInlineObject) {
19
- throw new Error(
20
- `Failed to parse inline object ${JSON.stringify(operation.inlineObject)}`,
21
- )
22
- }
23
-
24
- if (!operation.editor.selection) {
25
- console.error('Unable to insert inline object without selection')
26
- return
27
- }
28
-
29
- const [focusTextBlock] = Array.from(
30
- Editor.nodes(operation.editor, {
31
- at: operation.editor.selection.focus.path,
32
- match: (node) => operation.editor.isTextBlock(node),
33
- }),
34
- ).at(0) ?? [undefined, undefined]
35
-
36
- if (!focusTextBlock) {
37
- console.error('Unable to perform action without focus text block')
38
- return
39
- }
40
-
41
- const block = toSlateValue(
42
- [
43
- {
44
- _type: context.schema.block.name,
45
- _key: context.keyGenerator(),
46
- children: [parsedInlineObject],
47
- },
48
- ],
49
- {schemaTypes: context.schema},
50
- ).at(0) as unknown as Element
51
- const child = block?.children.at(0)
52
-
53
- if (!child) {
54
- console.error('Unable to insert inline object')
55
- return
56
- }
57
-
58
- Transforms.insertNodes(operation.editor, child)
59
- }
@@ -1,48 +0,0 @@
1
- import {Editor, Transforms} from 'slate'
2
- import type {BehaviorOperationImplementation} from './behavior.operations'
3
-
4
- export const insertSpanOperationImplementation: BehaviorOperationImplementation<
5
- 'insert.span'
6
- > = ({context, operation}) => {
7
- if (!operation.editor.selection) {
8
- console.error('Unable to perform action without selection', operation)
9
- return
10
- }
11
-
12
- const [focusBlock, focusBlockPath] = Array.from(
13
- Editor.nodes(operation.editor, {
14
- at: operation.editor.selection.focus.path,
15
- match: (node) => operation.editor.isTextBlock(node),
16
- }),
17
- )[0] ?? [undefined, undefined]
18
-
19
- if (!focusBlock || !focusBlockPath) {
20
- console.error('Unable to perform action without focus block', operation)
21
- return
22
- }
23
-
24
- const markDefs = focusBlock.markDefs ?? []
25
- const annotations = operation.annotations
26
- ? operation.annotations.map((annotation) => ({
27
- _type: annotation.name,
28
- _key: context.keyGenerator(),
29
- ...annotation.value,
30
- }))
31
- : undefined
32
-
33
- if (annotations && annotations.length > 0) {
34
- Transforms.setNodes(operation.editor, {
35
- markDefs: [...markDefs, ...annotations],
36
- })
37
- }
38
-
39
- Transforms.insertNodes(operation.editor, {
40
- _type: 'span',
41
- _key: context.keyGenerator(),
42
- text: operation.text,
43
- marks: [
44
- ...(annotations?.map((annotation) => annotation._key) ?? []),
45
- ...(operation.decorators ?? []),
46
- ],
47
- })
48
- }