@portabletext/editor 1.15.3 → 1.16.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 (71) hide show
  1. package/lib/_chunks-cjs/behavior.core.cjs +25 -25
  2. package/lib/_chunks-cjs/behavior.core.cjs.map +1 -1
  3. package/lib/_chunks-cjs/selector.get-text-before.cjs +14 -14
  4. package/lib/_chunks-cjs/selector.get-text-before.cjs.map +1 -1
  5. package/lib/_chunks-cjs/{selectors.cjs → selector.is-selection-collapsed.cjs} +8 -8
  6. package/lib/_chunks-cjs/selector.is-selection-collapsed.cjs.map +1 -0
  7. package/lib/_chunks-es/behavior.core.js +7 -7
  8. package/lib/_chunks-es/behavior.core.js.map +1 -1
  9. package/lib/_chunks-es/selector.get-text-before.js +14 -14
  10. package/lib/_chunks-es/selector.get-text-before.js.map +1 -1
  11. package/lib/_chunks-es/{selectors.js → selector.is-selection-collapsed.js} +8 -8
  12. package/lib/_chunks-es/selector.is-selection-collapsed.js.map +1 -0
  13. package/lib/behaviors/index.cjs +23 -23
  14. package/lib/behaviors/index.cjs.map +1 -1
  15. package/lib/behaviors/index.d.cts +1 -0
  16. package/lib/behaviors/index.d.ts +1 -0
  17. package/lib/behaviors/index.js +8 -8
  18. package/lib/behaviors/index.js.map +1 -1
  19. package/lib/index.cjs +863 -516
  20. package/lib/index.cjs.map +1 -1
  21. package/lib/index.d.cts +3816 -4457
  22. package/lib/index.d.ts +3816 -4457
  23. package/lib/index.js +860 -515
  24. package/lib/index.js.map +1 -1
  25. package/lib/selectors/index.cjs +166 -16
  26. package/lib/selectors/index.cjs.map +1 -1
  27. package/lib/selectors/index.d.cts +54 -5
  28. package/lib/selectors/index.d.ts +54 -5
  29. package/lib/selectors/index.js +154 -3
  30. package/lib/selectors/index.js.map +1 -1
  31. package/package.json +11 -11
  32. package/src/behaviors/behavior.code-editor.ts +5 -9
  33. package/src/behaviors/behavior.core.block-objects.ts +13 -19
  34. package/src/behaviors/behavior.core.lists.ts +11 -17
  35. package/src/behaviors/behavior.links.ts +4 -4
  36. package/src/behaviors/behavior.markdown.ts +16 -21
  37. package/src/editor/Editable.tsx +11 -4
  38. package/src/editor/PortableTextEditor.tsx +4 -4
  39. package/src/editor/{hooks/useSyncValue.test.tsx → __tests__/sync-value.test.tsx} +42 -23
  40. package/src/editor/components/Synchronizer.tsx +53 -80
  41. package/src/editor/create-editor.ts +4 -1
  42. package/src/editor/editor-machine.ts +135 -83
  43. package/src/editor/editor-provider.tsx +0 -3
  44. package/src/editor/editor-selector.ts +5 -0
  45. package/src/editor/editor-snapshot.ts +1 -0
  46. package/src/editor/get-active-decorators.ts +20 -0
  47. package/src/editor/mutation-machine.ts +100 -0
  48. package/src/editor/plugins/__tests__/withPortableTextMarkModel.test.tsx +21 -15
  49. package/src/editor/plugins/createWithMaxBlocks.ts +1 -1
  50. package/src/editor/plugins/createWithPatches.ts +0 -4
  51. package/src/editor/plugins/createWithPlaceholderBlock.ts +1 -1
  52. package/src/editor/plugins/createWithPortableTextSelections.ts +4 -1
  53. package/src/editor/plugins/createWithUndoRedo.ts +3 -3
  54. package/src/editor/sync-machine.ts +661 -0
  55. package/src/editor/withSyncRangeDecorations.ts +17 -5
  56. package/src/selectors/_exports/index.ts +1 -0
  57. package/src/selectors/index.ts +9 -1
  58. package/src/selectors/selector.get-active-style.ts +37 -0
  59. package/src/selectors/selector.get-selected-spans.ts +136 -0
  60. package/src/selectors/selector.is-active-annotation.ts +49 -0
  61. package/src/selectors/selector.is-active-decorator.ts +21 -0
  62. package/src/selectors/selector.is-active-list-item.ts +13 -0
  63. package/src/selectors/selector.is-active-style.ts +13 -0
  64. package/src/selectors/selector.is-selection-collapsed.ts +12 -0
  65. package/src/selectors/selector.is-selection-expanded.ts +9 -0
  66. package/src/selectors/selectors.ts +0 -11
  67. package/src/utils/weakMaps.ts +0 -3
  68. package/src/utils/withChanges.ts +1 -8
  69. package/lib/_chunks-cjs/selectors.cjs.map +0 -1
  70. package/lib/_chunks-es/selectors.js.map +0 -1
  71. package/src/editor/hooks/useSyncValue.ts +0 -426
@@ -0,0 +1,100 @@
1
+ import type {Patch} from '@portabletext/patches'
2
+ import type {PortableTextBlock} from '@sanity/types'
3
+ import {Editor} from 'slate'
4
+ import {assign, emit, setup} from 'xstate'
5
+ import type {PortableTextSlateEditor} from '../types/editor'
6
+ import {fromSlateValue} from '../utils/values'
7
+ import {KEY_TO_VALUE_ELEMENT} from '../utils/weakMaps'
8
+ import type {EditorSchema} from './define-schema'
9
+
10
+ const FLUSH_PATCHES_THROTTLED_MS = process.env.NODE_ENV === 'test' ? 500 : 1000
11
+
12
+ /**
13
+ * Makes sure editor mutation events are debounced
14
+ */
15
+ export const mutationMachine = setup({
16
+ types: {
17
+ context: {} as {
18
+ pendingPatches: Array<Patch>
19
+ schema: EditorSchema
20
+ slateEditor: PortableTextSlateEditor
21
+ },
22
+ events: {} as {type: 'patch'; patch: Patch},
23
+ input: {} as {
24
+ schema: EditorSchema
25
+ slateEditor: PortableTextSlateEditor
26
+ },
27
+ emitted: {} as
28
+ | {
29
+ type: 'has pending patches'
30
+ }
31
+ | {
32
+ type: 'mutation'
33
+ patches: Array<Patch>
34
+ snapshot: Array<PortableTextBlock> | undefined
35
+ },
36
+ },
37
+ actions: {
38
+ 'emit has pending patches': emit({type: 'has pending patches'}),
39
+ 'emit mutation': emit(({context}) => ({
40
+ type: 'mutation' as const,
41
+ patches: context.pendingPatches,
42
+ snapshot: fromSlateValue(
43
+ context.slateEditor.children,
44
+ context.schema.block.name,
45
+ KEY_TO_VALUE_ELEMENT.get(context.slateEditor),
46
+ ),
47
+ })),
48
+ 'clear pending patches': assign({
49
+ pendingPatches: [],
50
+ }),
51
+ 'defer patch': assign({
52
+ pendingPatches: ({context, event}) => [
53
+ ...context.pendingPatches,
54
+ event.patch,
55
+ ],
56
+ }),
57
+ },
58
+ guards: {
59
+ 'slate is normalizing': ({context}) =>
60
+ Editor.isNormalizing(context.slateEditor),
61
+ },
62
+ }).createMachine({
63
+ id: 'mutation',
64
+ context: ({input}) => ({
65
+ pendingPatches: [],
66
+ schema: input.schema,
67
+ slateEditor: input.slateEditor,
68
+ }),
69
+ initial: 'idle',
70
+ states: {
71
+ 'idle': {
72
+ on: {
73
+ patch: {
74
+ actions: ['defer patch', 'emit has pending patches'],
75
+ target: 'has pending patches',
76
+ },
77
+ },
78
+ },
79
+ 'has pending patches': {
80
+ after: {
81
+ [FLUSH_PATCHES_THROTTLED_MS]: [
82
+ {
83
+ guard: 'slate is normalizing',
84
+ target: 'idle',
85
+ actions: ['emit mutation', 'clear pending patches'],
86
+ },
87
+ {
88
+ reenter: true,
89
+ },
90
+ ],
91
+ },
92
+ on: {
93
+ patch: {
94
+ actions: ['defer patch'],
95
+ reenter: true,
96
+ },
97
+ },
98
+ },
99
+ },
100
+ })
@@ -49,26 +49,22 @@ describe('plugin:withPortableTextMarksModel', () => {
49
49
  anchor: {path: [{_key: 'a'}, 'children', {_key: 'a1'}], offset: 4},
50
50
  })
51
51
  PortableTextEditor.toggleMark(editor, 'strong')
52
- expect(PortableTextEditor.getValue(editor)).toMatchInlineSnapshot(`
53
- [
52
+ expect(PortableTextEditor.getValue(editor)).toEqual([
54
53
  {
55
- "_key": "a",
56
- "_type": "myTestBlockType",
57
- "children": [
54
+ _key: 'a',
55
+ _type: 'myTestBlockType',
56
+ children: [
58
57
  {
59
- "_key": "a1",
60
- "_type": "span",
61
- "marks": [
62
- "strong",
63
- ],
64
- "text": "1234",
58
+ _key: 'a1',
59
+ _type: 'span',
60
+ marks: ['strong'],
61
+ text: '1234',
65
62
  },
66
63
  ],
67
- "markDefs": [],
68
- "style": "normal",
64
+ markDefs: [],
65
+ style: 'normal',
69
66
  },
70
- ]
71
- `)
67
+ ])
72
68
  })
73
69
  await waitFor(() => {
74
70
  if (editorRef.current) {
@@ -871,6 +867,16 @@ describe('plugin:withPortableTextMarksModel', () => {
871
867
  )
872
868
  })
873
869
 
870
+ await waitFor(() => {
871
+ if (editorRef.current) {
872
+ expect(onChange).toHaveBeenCalledWith({
873
+ type: 'value',
874
+ value: initialValue,
875
+ })
876
+ expect(onChange).toHaveBeenCalledWith({type: 'ready'})
877
+ }
878
+ })
879
+
874
880
  await waitFor(() => {
875
881
  if (editorRef.current) {
876
882
  PortableTextEditor.focus(editorRef.current)
@@ -13,7 +13,7 @@ export function createWithMaxBlocks(editorActor: EditorActor) {
13
13
  ): PortableTextSlateEditor {
14
14
  const {apply} = editor
15
15
  editor.apply = (operation) => {
16
- if (editorActor.getSnapshot().context.readOnly) {
16
+ if (editorActor.getSnapshot().matches({'edit mode': 'read only'})) {
17
17
  apply(operation)
18
18
  return
19
19
  }
@@ -150,10 +150,6 @@ export function createWithPatches({
150
150
  })
151
151
 
152
152
  editor.apply = (operation: Operation): void | Editor => {
153
- if (editorActor.getSnapshot().context.readOnly) {
154
- apply(operation)
155
- return editor
156
- }
157
153
  let patches: Patch[] = []
158
154
 
159
155
  // Update previous children here before we apply
@@ -21,7 +21,7 @@ export function createWithPlaceholderBlock(
21
21
  const {apply} = editor
22
22
 
23
23
  editor.apply = (op) => {
24
- if (editorActor.getSnapshot().context.readOnly) {
24
+ if (editorActor.getSnapshot().matches({'edit mode': 'read only'})) {
25
25
  apply(op)
26
26
  return
27
27
  }
@@ -57,7 +57,10 @@ export function createWithPortableTextSelections(
57
57
  editor.onChange = () => {
58
58
  const hasChanges = editor.operations.length > 0
59
59
  onChange()
60
- if (hasChanges) {
60
+ if (
61
+ hasChanges &&
62
+ !editorActor.getSnapshot().matches({setup: 'setting up'})
63
+ ) {
61
64
  emitPortableTextSelection()
62
65
  }
63
66
  }
@@ -114,7 +114,7 @@ export function createWithUndoRedo(
114
114
  editor.history = {undos: [], redos: []}
115
115
  const {apply} = editor
116
116
  editor.apply = (op: Operation) => {
117
- if (editorActor.getSnapshot().context.readOnly) {
117
+ if (editorActor.getSnapshot().matches({'edit mode': 'read only'})) {
118
118
  apply(op)
119
119
  return
120
120
  }
@@ -181,7 +181,7 @@ export function createWithUndoRedo(
181
181
  }
182
182
 
183
183
  editor.undo = () => {
184
- if (editorActor.getSnapshot().context.readOnly) {
184
+ if (editorActor.getSnapshot().matches({'edit mode': 'read only'})) {
185
185
  return
186
186
  }
187
187
  const {undos} = editor.history
@@ -239,7 +239,7 @@ export function createWithUndoRedo(
239
239
  }
240
240
 
241
241
  editor.redo = () => {
242
- if (editorActor.getSnapshot().context.readOnly) {
242
+ if (editorActor.getSnapshot().matches({'edit mode': 'read only'})) {
243
243
  return
244
244
  }
245
245
  const {redos} = editor.history