@portabletext/editor 2.21.2 → 3.0.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 (79) hide show
  1. package/lib/_chunks-dts/index.d.ts +50 -210
  2. package/lib/_chunks-es/selector.is-at-the-start-of-block.js +103 -20
  3. package/lib/_chunks-es/selector.is-at-the-start-of-block.js.map +1 -1
  4. package/lib/_chunks-es/{util.get-text-block-text.js → util.slice-blocks.js} +29 -5
  5. package/lib/_chunks-es/util.slice-blocks.js.map +1 -0
  6. package/lib/_chunks-es/util.slice-text-block.js +13 -2
  7. package/lib/_chunks-es/util.slice-text-block.js.map +1 -1
  8. package/lib/behaviors/index.d.ts +1 -1
  9. package/lib/index.d.ts +2 -2
  10. package/lib/index.js +323 -320
  11. package/lib/index.js.map +1 -1
  12. package/lib/plugins/index.d.ts +2 -133
  13. package/lib/plugins/index.js +2 -796
  14. package/lib/plugins/index.js.map +1 -1
  15. package/lib/selectors/index.d.ts +2 -24
  16. package/lib/selectors/index.js +28 -130
  17. package/lib/selectors/index.js.map +1 -1
  18. package/lib/utils/index.d.ts +3 -3
  19. package/lib/utils/index.js +97 -9
  20. package/lib/utils/index.js.map +1 -1
  21. package/package.json +7 -9
  22. package/src/behaviors/behavior.perform-event.ts +7 -7
  23. package/src/editor/PortableTextEditor.tsx +0 -19
  24. package/src/editor/create-editor.ts +0 -3
  25. package/src/editor/editor-machine.ts +0 -10
  26. package/src/editor/event-to-change.tsx +5 -1
  27. package/src/editor/plugins/create-with-event-listeners.ts +0 -4
  28. package/src/editor/plugins/createWithObjectKeys.ts +2 -1
  29. package/src/editor/plugins/createWithPatches.ts +3 -3
  30. package/src/editor/plugins/createWithPlaceholderBlock.ts +2 -1
  31. package/src/editor/plugins/createWithPortableTextMarkModel.ts +2 -1
  32. package/src/editor/plugins/with-plugins.ts +10 -14
  33. package/src/editor/relay-machine.ts +0 -4
  34. package/src/editor/sync-machine.ts +2 -2
  35. package/src/editor.ts +0 -4
  36. package/src/history/behavior.operation.history.redo.ts +67 -0
  37. package/src/history/behavior.operation.history.undo.ts +71 -0
  38. package/src/history/event.history.undo.test.tsx +672 -0
  39. package/src/history/history.preserving-keys.test.tsx +112 -0
  40. package/src/history/remote-patches.ts +20 -0
  41. package/src/history/slate-plugin.history.ts +146 -0
  42. package/src/history/slate-plugin.redoing.ts +21 -0
  43. package/src/history/slate-plugin.undoing.ts +21 -0
  44. package/src/history/slate-plugin.without-history.ts +23 -0
  45. package/src/history/transform-operation.ts +245 -0
  46. package/src/history/undo-redo-collaboration.test.tsx +541 -0
  47. package/src/history/undo-redo.feature +125 -0
  48. package/src/history/undo-redo.test.tsx +195 -0
  49. package/src/history/undo-step.ts +148 -0
  50. package/src/index.ts +0 -1
  51. package/src/internal-utils/applyPatch.ts +46 -1
  52. package/src/operations/behavior.operations.ts +2 -4
  53. package/src/plugins/index.ts +0 -3
  54. package/src/selectors/index.ts +0 -3
  55. package/src/test/vitest/step-definitions.tsx +88 -8
  56. package/src/test/vitest/test-editor.tsx +1 -1
  57. package/lib/_chunks-es/selector.get-selection-text.js +0 -92
  58. package/lib/_chunks-es/selector.get-selection-text.js.map +0 -1
  59. package/lib/_chunks-es/selector.get-text-before.js +0 -36
  60. package/lib/_chunks-es/selector.get-text-before.js.map +0 -1
  61. package/lib/_chunks-es/util.get-text-block-text.js.map +0 -1
  62. package/lib/_chunks-es/util.is-empty-text-block.js +0 -40
  63. package/lib/_chunks-es/util.is-empty-text-block.js.map +0 -1
  64. package/lib/_chunks-es/util.merge-text-blocks.js +0 -101
  65. package/lib/_chunks-es/util.merge-text-blocks.js.map +0 -1
  66. package/src/editor/plugins/createWithMaxBlocks.ts +0 -53
  67. package/src/editor/plugins/createWithUndoRedo.ts +0 -628
  68. package/src/editor/with-undo-step.ts +0 -37
  69. package/src/editor/withUndoRedo.ts +0 -34
  70. package/src/editor-event-listener.tsx +0 -28
  71. package/src/plugins/plugin.decorator-shortcut.ts +0 -238
  72. package/src/plugins/plugin.markdown.test.tsx +0 -42
  73. package/src/plugins/plugin.markdown.tsx +0 -131
  74. package/src/plugins/plugin.one-line.tsx +0 -123
  75. package/src/selectors/selector.get-list-state.test.ts +0 -189
  76. package/src/selectors/selector.get-list-state.ts +0 -96
  77. package/src/selectors/selector.get-selected-slice.ts +0 -13
  78. package/src/selectors/selector.get-trimmed-selection.test.ts +0 -657
  79. package/src/selectors/selector.get-trimmed-selection.ts +0 -189
@@ -1,189 +0,0 @@
1
- import type {PortableTextBlock} from '@sanity/types'
2
- import {describe, expect, test} from 'vitest'
3
- import type {EditorSelector} from '../editor/editor-selector'
4
- import {createTestSnapshot} from '../internal-utils/create-test-snapshot'
5
- import {defaultKeyGenerator} from '../utils/key-generator'
6
- import {getListIndex} from './selector.get-list-state'
7
-
8
- function blockObject(_key: string, name: string) {
9
- return {
10
- _key,
11
- _type: name,
12
- }
13
- }
14
-
15
- function textBlock(
16
- _key: string,
17
- {
18
- listItem,
19
- level,
20
- }: {
21
- listItem?: 'bullet' | 'number'
22
- level?: number
23
- },
24
- ): PortableTextBlock {
25
- return {
26
- _key,
27
- _type: 'block',
28
- children: [
29
- {
30
- _key: defaultKeyGenerator(),
31
- _type: 'span',
32
- text: `${listItem}-${level}`,
33
- },
34
- ],
35
- style: 'normal',
36
- level,
37
- listItem,
38
- }
39
- }
40
-
41
- function createSnapshot(value: Array<PortableTextBlock>) {
42
- return createTestSnapshot({
43
- context: {
44
- value,
45
- },
46
- })
47
- }
48
-
49
- function getListStates(
50
- paths: Array<[{_key: string}]>,
51
- ): EditorSelector<Array<number | undefined>> {
52
- return (snapshot) => {
53
- return paths.map((path) => getListIndex({path})(snapshot))
54
- }
55
- }
56
-
57
- describe(getListIndex.name, () => {
58
- test('empty', () => {
59
- const snapshot = createSnapshot([])
60
-
61
- expect(getListIndex({path: [{_key: 'k0'}]})(snapshot)).toEqual(undefined)
62
- })
63
-
64
- test('single list item', () => {
65
- const snapshot = createSnapshot([
66
- textBlock('k0', {listItem: 'number', level: 1}),
67
- ])
68
-
69
- expect(getListIndex({path: [{_key: 'k0'}]})(snapshot)).toEqual(1)
70
- })
71
-
72
- test('single indented list item', () => {
73
- const snapshot = createSnapshot([
74
- textBlock('k0', {listItem: 'number', level: 2}),
75
- ])
76
-
77
- expect(getListIndex({path: [{_key: 'k0'}]})(snapshot)).toEqual(1)
78
- })
79
-
80
- test('two lists broken up by a paragraph', () => {
81
- const snapshot = createSnapshot([
82
- textBlock('k0', {listItem: 'number', level: 1}),
83
- textBlock('k1', {listItem: 'number', level: 1}),
84
- textBlock('k2', {}),
85
- textBlock('k3', {listItem: 'number', level: 1}),
86
- textBlock('k4', {listItem: 'number', level: 1}),
87
- ])
88
-
89
- expect(
90
- getListStates([
91
- [{_key: 'k0'}],
92
- [{_key: 'k1'}],
93
- [{_key: 'k2'}],
94
- [{_key: 'k3'}],
95
- [{_key: 'k4'}],
96
- ])(snapshot),
97
- ).toEqual([1, 2, undefined, 1, 2])
98
- })
99
-
100
- test('two lists broken up by an image', () => {
101
- const snapshot = createSnapshot([
102
- textBlock('k0', {listItem: 'number', level: 1}),
103
- textBlock('k1', {listItem: 'number', level: 1}),
104
- blockObject('k2', 'image'),
105
- textBlock('k3', {listItem: 'number', level: 1}),
106
- textBlock('k4', {listItem: 'number', level: 1}),
107
- ])
108
-
109
- expect(
110
- getListStates([
111
- [{_key: 'k0'}],
112
- [{_key: 'k1'}],
113
- [{_key: 'k2'}],
114
- [{_key: 'k3'}],
115
- [{_key: 'k4'}],
116
- ])(snapshot),
117
- ).toEqual([1, 2, undefined, 1, 2])
118
- })
119
-
120
- test('numbered lists broken up by a bulleted list', () => {
121
- const snapshot = createSnapshot([
122
- textBlock('k0', {listItem: 'number', level: 1}),
123
- textBlock('k1', {listItem: 'bullet', level: 1}),
124
- textBlock('k2', {listItem: 'number', level: 1}),
125
- ])
126
-
127
- expect(
128
- getListStates([[{_key: 'k0'}], [{_key: 'k1'}], [{_key: 'k2'}]])(snapshot),
129
- ).toEqual([1, 1, 1])
130
- })
131
-
132
- test('simple indented list', () => {
133
- const snapshot = createSnapshot([
134
- textBlock('k0', {listItem: 'number', level: 1}),
135
- textBlock('k1', {listItem: 'number', level: 2}),
136
- textBlock('k2', {listItem: 'number', level: 2}),
137
- textBlock('k3', {listItem: 'number', level: 1}),
138
- ])
139
-
140
- expect(
141
- getListStates([
142
- [{_key: 'k0'}],
143
- [{_key: 'k1'}],
144
- [{_key: 'k2'}],
145
- [{_key: 'k3'}],
146
- ])(snapshot),
147
- ).toEqual([1, 1, 2, 2])
148
- })
149
-
150
- test('reverse indented list', () => {
151
- const snapshot = createSnapshot([
152
- textBlock('k0', {listItem: 'number', level: 2}),
153
- textBlock('k1', {listItem: 'number', level: 1}),
154
- textBlock('k2', {listItem: 'number', level: 2}),
155
- ])
156
-
157
- expect(
158
- getListStates([[{_key: 'k0'}], [{_key: 'k1'}], [{_key: 'k2'}]])(snapshot),
159
- ).toEqual([1, 1, 1])
160
- })
161
-
162
- test('complex list', () => {
163
- const snapshot = createSnapshot([
164
- textBlock('k0', {listItem: 'number', level: 1}),
165
- textBlock('k1', {listItem: 'number', level: 3}),
166
- textBlock('k2', {listItem: 'number', level: 2}),
167
- textBlock('k3', {listItem: 'number', level: 3}),
168
- textBlock('k4', {listItem: 'number', level: 1}),
169
- textBlock('k5', {listItem: 'number', level: 3}),
170
- textBlock('k6', {listItem: 'number', level: 4}),
171
- textBlock('k7', {listItem: 'number', level: 3}),
172
- textBlock('k8', {listItem: 'number', level: 1}),
173
- ])
174
-
175
- expect(
176
- getListStates([
177
- [{_key: 'k0'}],
178
- [{_key: 'k1'}],
179
- [{_key: 'k2'}],
180
- [{_key: 'k3'}],
181
- [{_key: 'k4'}],
182
- [{_key: 'k5'}],
183
- [{_key: 'k6'}],
184
- [{_key: 'k7'}],
185
- [{_key: 'k8'}],
186
- ])(snapshot),
187
- ).toEqual([1, 1, 1, 1, 2, 1, 1, 2, 3])
188
- })
189
- })
@@ -1,96 +0,0 @@
1
- import {isTextBlock} from '@portabletext/schema'
2
- import type {EditorSelector} from '../editor/editor-selector'
3
- import type {BlockPath} from '../types/paths'
4
- import {getFocusTextBlock} from './selector.get-focus-text-block'
5
-
6
- /**
7
- * @beta
8
- * @deprecated Use the precomputed `data-list-index` on text blocks instead.
9
- * Given the `path` of a block, this selector will return the "list index" of
10
- * the block.
11
- */
12
- export function getListIndex({
13
- path,
14
- }: {
15
- path: BlockPath
16
- }): EditorSelector<number | undefined> {
17
- return (snapshot) => {
18
- const selection = {
19
- anchor: {
20
- path,
21
- offset: 0,
22
- },
23
- focus: {
24
- path,
25
- offset: 0,
26
- },
27
- }
28
-
29
- const focusTextBlock = getFocusTextBlock({
30
- ...snapshot,
31
- context: {
32
- ...snapshot.context,
33
- selection,
34
- },
35
- })
36
-
37
- if (!focusTextBlock) {
38
- return undefined
39
- }
40
-
41
- if (
42
- focusTextBlock.node.listItem === undefined ||
43
- focusTextBlock.node.level === undefined
44
- ) {
45
- return undefined
46
- }
47
-
48
- const targetListItem = focusTextBlock.node.listItem
49
- const targetLevel = focusTextBlock.node.level
50
- const targetKey = focusTextBlock.node._key
51
-
52
- // Find the target block's index
53
- const targetIndex = snapshot.blockIndexMap.get(targetKey)
54
-
55
- if (targetIndex === undefined) {
56
- return undefined
57
- }
58
-
59
- // Walk backwards from the target block and count consecutive list items
60
- // of the same type and level
61
- let listIndex = 1 // Start at 1 for the target block itself
62
-
63
- for (let i = targetIndex - 1; i >= 0; i--) {
64
- const block = snapshot.context.value[i]
65
-
66
- if (!isTextBlock(snapshot.context, block)) {
67
- // Non-text block breaks the sequence
68
- break
69
- }
70
-
71
- if (block.listItem === undefined || block.level === undefined) {
72
- // Non-list item breaks the sequence
73
- break
74
- }
75
-
76
- if (block.listItem !== targetListItem) {
77
- // Different list type breaks the sequence
78
- break
79
- }
80
-
81
- if (block.level < targetLevel) {
82
- // Lower level breaks the sequence
83
- break
84
- }
85
-
86
- if (block.level === targetLevel) {
87
- // Same level - continue counting
88
- listIndex++
89
- }
90
-
91
- // Higher level items don't affect the count for the target level
92
- }
93
-
94
- return listIndex
95
- }
96
- }
@@ -1,13 +0,0 @@
1
- import type {PortableTextBlock} from '@sanity/types'
2
- import type {EditorSelector} from '../editor/editor-selector'
3
- import {getSelectedValue} from './selector.get-selected-value'
4
-
5
- /**
6
- * @public
7
- * @deprecated Renamed to `getSelectedValue`.
8
- */
9
- export const getSelectedSlice: EditorSelector<Array<PortableTextBlock>> = (
10
- snapshot,
11
- ) => {
12
- return getSelectedValue(snapshot)
13
- }