@portabletext/editor 2.7.2 → 2.8.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.
Files changed (50) 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/util.slice-blocks.cjs +60 -6
  4. package/lib/_chunks-cjs/util.slice-blocks.cjs.map +1 -1
  5. package/lib/_chunks-dts/behavior.types.action.d.cts +95 -95
  6. package/lib/_chunks-dts/behavior.types.action.d.ts +95 -95
  7. package/lib/_chunks-es/selector.is-selecting-entire-blocks.js +4 -2
  8. package/lib/_chunks-es/selector.is-selecting-entire-blocks.js.map +1 -1
  9. package/lib/_chunks-es/util.slice-blocks.js +56 -5
  10. package/lib/_chunks-es/util.slice-blocks.js.map +1 -1
  11. package/lib/index.cjs +94 -121
  12. package/lib/index.cjs.map +1 -1
  13. package/lib/index.js +90 -118
  14. package/lib/index.js.map +1 -1
  15. package/lib/plugins/index.d.cts +3 -3
  16. package/lib/plugins/index.d.ts +3 -3
  17. package/lib/selectors/index.d.cts +13 -3
  18. package/lib/selectors/index.d.ts +13 -3
  19. package/lib/utils/index.d.ts +2 -2
  20. package/package.json +13 -14
  21. package/src/behaviors/behavior.abstract.insert.ts +58 -1
  22. package/src/behaviors/behavior.core.annotations.ts +24 -2
  23. package/src/behaviors/behavior.core.ts +1 -1
  24. package/src/behaviors/behavior.types.event.ts +18 -18
  25. package/src/converters/converter.text-html.serialize.test.ts +27 -17
  26. package/src/converters/converter.text-plain.test.ts +1 -1
  27. package/src/editor/plugins/createWithEditableAPI.ts +16 -0
  28. package/src/internal-utils/parse-blocks.ts +2 -1
  29. package/src/operations/behavior.operation.annotation.add.ts +1 -12
  30. package/src/operations/behavior.operations.ts +0 -18
  31. package/src/selectors/selector.is-active-annotation.test.ts +320 -0
  32. package/src/selectors/selector.is-active-annotation.ts +24 -0
  33. package/src/utils/util.slice-blocks.test.ts +39 -5
  34. package/src/utils/util.slice-blocks.ts +36 -3
  35. package/src/editor/__tests__/PortableTextEditor.test.tsx +0 -430
  36. package/src/editor/__tests__/PortableTextEditorTester.tsx +0 -58
  37. package/src/editor/__tests__/RangeDecorations.test.tsx +0 -213
  38. package/src/editor/__tests__/insert-block.test.tsx +0 -224
  39. package/src/editor/__tests__/self-solving.test.tsx +0 -183
  40. package/src/editor/plugins/__tests__/withEditableAPIDelete.test.tsx +0 -298
  41. package/src/editor/plugins/__tests__/withEditableAPIGetFragment.test.tsx +0 -177
  42. package/src/editor/plugins/__tests__/withEditableAPIInsert.test.tsx +0 -538
  43. package/src/editor/plugins/__tests__/withEditableAPISelectionsOverlapping.test.tsx +0 -162
  44. package/src/editor/plugins/__tests__/withPortableTextLists.test.tsx +0 -65
  45. package/src/editor/plugins/__tests__/withPortableTextMarkModel.test.tsx +0 -612
  46. package/src/editor/plugins/__tests__/withPortableTextSelections.test.tsx +0 -103
  47. package/src/editor/plugins/__tests__/withUndoRedo.test.tsx +0 -147
  48. package/src/internal-utils/__tests__/valueNormalization.test.tsx +0 -79
  49. package/src/operations/behavior.operation.insert-inline-object.ts +0 -59
  50. package/src/operations/behavior.operation.insert-span.ts +0 -48
@@ -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
- }