@portabletext/editor 1.24.0 → 1.25.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 (37) hide show
  1. package/lib/_chunks-cjs/behavior.core.cjs +186 -62
  2. package/lib/_chunks-cjs/behavior.core.cjs.map +1 -1
  3. package/lib/_chunks-cjs/{selector.is-selection-collapsed.cjs → selector.is-active-style.cjs} +158 -3
  4. package/lib/_chunks-cjs/selector.is-active-style.cjs.map +1 -0
  5. package/lib/_chunks-es/behavior.core.js +162 -38
  6. package/lib/_chunks-es/behavior.core.js.map +1 -1
  7. package/lib/_chunks-es/{selector.is-selection-collapsed.js → selector.is-active-style.js} +159 -4
  8. package/lib/_chunks-es/selector.is-active-style.js.map +1 -0
  9. package/lib/behaviors/index.cjs +27 -27
  10. package/lib/behaviors/index.cjs.map +1 -1
  11. package/lib/behaviors/index.d.cts +1718 -94
  12. package/lib/behaviors/index.d.ts +1718 -94
  13. package/lib/behaviors/index.js +1 -1
  14. package/lib/index.cjs +178 -211
  15. package/lib/index.cjs.map +1 -1
  16. package/lib/index.d.cts +8792 -245
  17. package/lib/index.d.ts +8792 -245
  18. package/lib/index.js +174 -207
  19. package/lib/index.js.map +1 -1
  20. package/lib/selectors/index.cjs +24 -171
  21. package/lib/selectors/index.cjs.map +1 -1
  22. package/lib/selectors/index.js +3 -151
  23. package/lib/selectors/index.js.map +1 -1
  24. package/package.json +6 -6
  25. package/src/behavior-actions/behavior.actions.ts +99 -98
  26. package/src/behaviors/behavior.core.annotations.ts +29 -0
  27. package/src/behaviors/behavior.core.block-objects.ts +13 -13
  28. package/src/behaviors/behavior.core.decorators.ts +19 -0
  29. package/src/behaviors/behavior.core.lists.ts +57 -23
  30. package/src/behaviors/behavior.core.style.ts +19 -0
  31. package/src/behaviors/behavior.core.ts +12 -0
  32. package/src/behaviors/behavior.types.ts +87 -87
  33. package/src/editor/create-editor.ts +46 -6
  34. package/src/editor/editor-machine.ts +38 -1
  35. package/src/editor/plugins/create-with-event-listeners.ts +38 -106
  36. package/lib/_chunks-cjs/selector.is-selection-collapsed.cjs.map +0 -1
  37. package/lib/_chunks-es/selector.is-selection-collapsed.js.map +0 -1
@@ -0,0 +1,19 @@
1
+ import * as selectors from '../selectors'
2
+ import {defineBehavior, raise} from './behavior.types'
3
+
4
+ const toggleStyleOff = defineBehavior({
5
+ on: 'style.toggle',
6
+ guard: ({context, event}) => selectors.isActiveStyle(event.style)({context}),
7
+ actions: [({event}) => [raise({type: 'style.remove', style: event.style})]],
8
+ })
9
+
10
+ const toggleStyleOn = defineBehavior({
11
+ on: 'style.toggle',
12
+ guard: ({context, event}) => !selectors.isActiveStyle(event.style)({context}),
13
+ actions: [({event}) => [raise({type: 'style.add', style: event.style})]],
14
+ })
15
+
16
+ export const coreStyleBehaviors = {
17
+ toggleStyleOff,
18
+ toggleStyleOn,
19
+ }
@@ -1,8 +1,10 @@
1
+ import {coreAnnotationBehaviors} from './behavior.core.annotations'
1
2
  import {coreBlockObjectBehaviors} from './behavior.core.block-objects'
2
3
  import {coreDecoratorBehaviors} from './behavior.core.decorators'
3
4
  import {coreDeserializeBehavior} from './behavior.core.deserialize'
4
5
  import {coreListBehaviors} from './behavior.core.lists'
5
6
  import {coreSerializeBehaviors} from './behavior.core.serialize'
7
+ import {coreStyleBehaviors} from './behavior.core.style'
6
8
  import {defineBehavior} from './behavior.types'
7
9
 
8
10
  const softReturn = defineBehavior({
@@ -15,6 +17,10 @@ const softReturn = defineBehavior({
15
17
  */
16
18
  export const coreBehaviors = [
17
19
  softReturn,
20
+ coreAnnotationBehaviors.toggleAnnotationOff,
21
+ coreAnnotationBehaviors.toggleAnnotationOn,
22
+ coreDecoratorBehaviors.toggleDecoratorOff,
23
+ coreDecoratorBehaviors.toggleDecoratorOn,
18
24
  coreDecoratorBehaviors.strongShortcut,
19
25
  coreDecoratorBehaviors.emShortcut,
20
26
  coreDecoratorBehaviors.underlineShortcut,
@@ -25,6 +31,8 @@ export const coreBehaviors = [
25
31
  coreBlockObjectBehaviors.breakingBlockObject,
26
32
  coreBlockObjectBehaviors.deletingEmptyTextBlockAfterBlockObject,
27
33
  coreBlockObjectBehaviors.deletingEmptyTextBlockBeforeBlockObject,
34
+ coreListBehaviors.toggleListItemOff,
35
+ coreListBehaviors.toggleListItemOn,
28
36
  coreListBehaviors.clearListOnBackspace,
29
37
  coreListBehaviors.unindentListOnBackspace,
30
38
  coreListBehaviors.clearListOnEnter,
@@ -32,6 +40,8 @@ export const coreBehaviors = [
32
40
  coreListBehaviors.unindentListOnShiftTab,
33
41
  coreSerializeBehaviors.serialize,
34
42
  coreSerializeBehaviors['serialization.success'],
43
+ coreStyleBehaviors.toggleStyleOff,
44
+ coreStyleBehaviors.toggleStyleOn,
35
45
  ]
36
46
 
37
47
  /**
@@ -39,9 +49,11 @@ export const coreBehaviors = [
39
49
  */
40
50
  export const coreBehavior = {
41
51
  softReturn,
52
+ annotation: coreAnnotationBehaviors,
42
53
  decorators: coreDecoratorBehaviors,
43
54
  deserialize: coreDeserializeBehavior,
44
55
  blockObjects: coreBlockObjectBehaviors,
45
56
  lists: coreListBehaviors,
46
57
  ...coreSerializeBehaviors,
58
+ style: coreSerializeBehaviors,
47
59
  }
@@ -28,6 +28,13 @@ export type SyntheticBehaviorEvent =
28
28
  name: string
29
29
  }
30
30
  }
31
+ | {
32
+ type: 'annotation.toggle'
33
+ annotation: {
34
+ name: string
35
+ value: {[prop: string]: unknown}
36
+ }
37
+ }
31
38
  | {
32
39
  type: 'blur'
33
40
  }
@@ -37,6 +44,14 @@ export type SyntheticBehaviorEvent =
37
44
  dataTransfer: DataTransfer
38
45
  mimeType: MIMEType
39
46
  }
47
+ | {
48
+ type: 'decorator.add'
49
+ decorator: string
50
+ }
51
+ | {
52
+ type: 'decorator.remove'
53
+ decorator: string
54
+ }
40
55
  | {
41
56
  type: 'decorator.toggle'
42
57
  decorator: string
@@ -45,10 +60,19 @@ export type SyntheticBehaviorEvent =
45
60
  type: 'delete.backward'
46
61
  unit: TextUnit
47
62
  }
63
+ | {
64
+ type: 'delete.block'
65
+ blockPath: [KeyedSegment]
66
+ }
48
67
  | {
49
68
  type: 'delete.forward'
50
69
  unit: TextUnit
51
70
  }
71
+ | {
72
+ type: 'delete.text'
73
+ anchor: BlockOffset
74
+ focus: BlockOffset
75
+ }
52
76
  | {
53
77
  type: 'focus'
54
78
  }
@@ -77,23 +101,86 @@ export type SyntheticBehaviorEvent =
77
101
  | {
78
102
  type: 'insert.soft break'
79
103
  }
104
+ | {
105
+ type: 'insert.span'
106
+ text: string
107
+ annotations?: Array<{
108
+ name: string
109
+ value: {[prop: string]: unknown}
110
+ }>
111
+ decorators?: Array<string>
112
+ }
80
113
  | {
81
114
  type: 'insert.text'
82
115
  text: string
83
116
  options?: TextInsertTextOptions
84
117
  }
118
+ | {
119
+ type: 'insert.text block'
120
+ placement: 'auto' | 'after' | 'before'
121
+ textBlock?: {
122
+ children?: PortableTextTextBlock['children']
123
+ }
124
+ }
125
+ | {
126
+ type: 'list item.add'
127
+ listItem: string
128
+ }
129
+ | {
130
+ type: 'list item.remove'
131
+ listItem: string
132
+ }
85
133
  | {
86
134
  type: 'list item.toggle'
87
135
  listItem: string
88
136
  }
137
+ | {
138
+ type: 'move.block'
139
+ at: [KeyedSegment]
140
+ to: [KeyedSegment]
141
+ }
142
+ | {
143
+ type: 'move.block down'
144
+ at: [KeyedSegment]
145
+ }
146
+ | {
147
+ type: 'move.block up'
148
+ at: [KeyedSegment]
149
+ }
89
150
  | {
90
151
  type: 'select'
91
152
  selection: EditorSelection
92
153
  }
154
+ | {
155
+ type: 'select.previous block'
156
+ }
157
+ | {
158
+ type: 'select.next block'
159
+ }
160
+ | {
161
+ type: 'style.add'
162
+ style: string
163
+ }
164
+ | {
165
+ type: 'style.remove'
166
+ style: string
167
+ }
93
168
  | {
94
169
  type: 'style.toggle'
95
170
  style: string
96
171
  }
172
+ | {
173
+ type: 'text block.set'
174
+ at: [KeyedSegment]
175
+ level?: number
176
+ listItem?: string
177
+ style?: string
178
+ }
179
+ | {
180
+ type: 'text block.unset'
181
+ at: [KeyedSegment]
182
+ props: Array<'level' | 'listItem' | 'style'>
183
+ }
97
184
  | (PickFromUnion<
98
185
  ConverterEvent,
99
186
  'type',
@@ -165,100 +252,13 @@ export type BehaviorActionIntend =
165
252
  type: 'raise'
166
253
  event: SyntheticBehaviorEvent | CustomBehaviorEvent
167
254
  }
168
- | {
169
- type: 'annotation.toggle'
170
- annotation: {
171
- name: string
172
- value: {[prop: string]: unknown}
173
- }
174
- }
175
- | {
176
- type: 'decorator.add'
177
- decorator: string
178
- }
179
- | {
180
- type: 'decorator.remove'
181
- decorator: string
182
- }
183
- | {
184
- type: 'insert.span'
185
- text: string
186
- annotations?: Array<{
187
- name: string
188
- value: {[prop: string]: unknown}
189
- }>
190
- decorators?: Array<string>
191
- }
192
- | {
193
- type: 'insert.text block'
194
- placement: 'auto' | 'after' | 'before'
195
- textBlock?: {
196
- children?: PortableTextTextBlock['children']
197
- }
198
- }
199
- | {
200
- type: 'list item.add'
201
- listItem: string
202
- }
203
- | {
204
- type: 'list item.remove'
205
- listItem: string
206
- }
207
- | {
208
- type: 'move.block'
209
- at: [KeyedSegment]
210
- to: [KeyedSegment]
211
- }
212
- | {
213
- type: 'move.block down'
214
- at: [KeyedSegment]
215
- }
216
- | {
217
- type: 'move.block up'
218
- at: [KeyedSegment]
219
- }
220
255
  | {
221
256
  type: 'noop'
222
257
  }
223
- | {
224
- type: 'delete.block'
225
- blockPath: [KeyedSegment]
226
- }
227
- | {
228
- type: 'delete.text'
229
- anchor: BlockOffset
230
- focus: BlockOffset
231
- }
232
258
  | {
233
259
  type: 'effect'
234
260
  effect: () => void
235
261
  }
236
- | {
237
- type: 'select.previous block'
238
- }
239
- | {
240
- type: 'select.next block'
241
- }
242
- | {
243
- type: 'style.add'
244
- style: string
245
- }
246
- | {
247
- type: 'style.remove'
248
- style: string
249
- }
250
- | {
251
- type: 'text block.set'
252
- at: [KeyedSegment]
253
- level?: number
254
- listItem?: string
255
- style?: string
256
- }
257
- | {
258
- type: 'text block.unset'
259
- at: [KeyedSegment]
260
- props: Array<'level' | 'listItem' | 'style'>
261
- }
262
262
 
263
263
  /**
264
264
  * @beta
@@ -65,14 +65,37 @@ export type EditorEvent =
65
65
  'type',
66
66
  | 'annotation.add'
67
67
  | 'annotation.remove'
68
+ | 'annotation.toggle'
68
69
  | 'blur'
70
+ | 'data transfer.set'
71
+ | 'decorator.add'
72
+ | 'decorator.remove'
69
73
  | 'decorator.toggle'
74
+ | 'delete.block'
75
+ | 'delete.text'
76
+ | 'deserialization.failure'
77
+ | 'deserialization.success'
70
78
  | 'focus'
71
79
  | 'insert.block object'
72
80
  | 'insert.inline object'
81
+ | 'insert.span'
82
+ | 'insert.text block'
83
+ | 'list item.add'
84
+ | 'list item.remove'
73
85
  | 'list item.toggle'
86
+ | 'move.block'
87
+ | 'move.block down'
88
+ | 'move.block up'
74
89
  | 'select'
90
+ | 'select.next block'
91
+ | 'select.previous block'
92
+ | 'serialization.failure'
93
+ | 'serialization.success'
94
+ | 'style.add'
95
+ | 'style.remove'
75
96
  | 'style.toggle'
97
+ | 'text block.set'
98
+ | 'text block.unset'
76
99
  | 'patches'
77
100
  | 'update behaviors'
78
101
  | 'update key generator'
@@ -160,12 +183,29 @@ function createEditorFromActor(editorActor: EditorActor): Editor {
160
183
  send: (event) => {
161
184
  editorActor.send(event)
162
185
  },
163
- on: (event, listener) =>
164
- editorActor.on(
165
- event,
166
- // @ts-expect-error
167
- listener,
168
- ),
186
+ on: (event, listener) => {
187
+ const subscription = editorActor.on(event, (event) => {
188
+ switch (event.type) {
189
+ case 'blurred':
190
+ case 'done loading':
191
+ case 'editable':
192
+ case 'error':
193
+ case 'focused':
194
+ case 'invalid value':
195
+ case 'loading':
196
+ case 'mutation':
197
+ case 'patch':
198
+ case 'read only':
199
+ case 'ready':
200
+ case 'selection':
201
+ case 'value changed':
202
+ listener(event)
203
+ break
204
+ }
205
+ })
206
+
207
+ return subscription
208
+ },
169
209
  _internal: {
170
210
  editable,
171
211
  editorActor,
@@ -185,13 +185,38 @@ export type InternalEditorEmittedEvent =
185
185
  'type',
186
186
  | 'annotation.add'
187
187
  | 'annotation.remove'
188
+ | 'annotation.toggle'
188
189
  | 'blur'
190
+ | 'data transfer.set'
191
+ | 'decorator.add'
192
+ | 'decorator.remove'
189
193
  | 'decorator.toggle'
194
+ | 'delete.backward'
195
+ | 'delete.block'
196
+ | 'delete.forward'
197
+ | 'delete.text'
198
+ | 'deserialization.failure'
199
+ | 'deserialization.success'
200
+ | 'focus'
190
201
  | 'insert.block object'
191
202
  | 'insert.inline object'
203
+ | 'insert.span'
204
+ | 'insert.text block'
205
+ | 'list item.add'
206
+ | 'list item.remove'
192
207
  | 'list item.toggle'
193
- | 'focus'
208
+ | 'move.block'
209
+ | 'move.block down'
210
+ | 'move.block up'
211
+ | 'select.next block'
212
+ | 'select.previous block'
213
+ | 'serialization.failure'
214
+ | 'serialization.success'
215
+ | 'style.add'
216
+ | 'style.remove'
194
217
  | 'style.toggle'
218
+ | 'text block.set'
219
+ | 'text block.unset'
195
220
  >
196
221
  | {
197
222
  type: 'custom.*'
@@ -580,6 +605,9 @@ export const editorMachine = setup({
580
605
  'decorator.*': {
581
606
  actions: emit(({event}) => event),
582
607
  },
608
+ 'delete.*': {
609
+ actions: emit(({event}) => event),
610
+ },
583
611
  'focus': {
584
612
  actions: emit(({event}) => event),
585
613
  },
@@ -589,12 +617,21 @@ export const editorMachine = setup({
589
617
  'list item.*': {
590
618
  actions: emit(({event}) => event),
591
619
  },
620
+ 'move.*': {
621
+ actions: emit(({event}) => event),
622
+ },
592
623
  'select': {
593
624
  actions: emit(({event}) => event),
594
625
  },
626
+ 'select.*': {
627
+ actions: emit(({event}) => event),
628
+ },
595
629
  'style.*': {
596
630
  actions: emit(({event}) => event),
597
631
  },
632
+ 'text block.*': {
633
+ actions: emit(({event}) => event),
634
+ },
598
635
  },
599
636
  },
600
637
  },
@@ -17,123 +17,55 @@ export function createWithEventListeners(
17
17
  subscriptions.push(() => {
18
18
  const subscription = editorActor.on('*', (event) => {
19
19
  switch (event.type) {
20
- case 'annotation.add': {
21
- editorActor.send({
22
- type: 'behavior event',
23
- behaviorEvent: {
24
- type: 'annotation.add',
25
- annotation: event.annotation,
26
- },
27
- editor,
28
- })
29
- break
30
- }
31
- case 'annotation.remove': {
32
- editorActor.send({
33
- type: 'behavior event',
34
- behaviorEvent: {
35
- type: 'annotation.remove',
36
- annotation: event.annotation,
37
- },
38
- editor,
39
- })
40
- break
41
- }
42
- case 'blur': {
43
- editorActor.send({
44
- type: 'behavior event',
45
- behaviorEvent: {
46
- type: 'blur',
47
- },
48
- editor,
49
- })
50
- break
51
- }
52
- case 'custom.*': {
20
+ case 'custom.*':
53
21
  editorActor.send({
54
22
  type: 'custom behavior event',
55
23
  behaviorEvent: event.event,
56
24
  editor,
57
25
  })
58
26
  break
59
- }
60
- case 'decorator.toggle': {
61
- editorActor.send({
62
- type: 'behavior event',
63
- behaviorEvent: {
64
- type: 'decorator.toggle',
65
- decorator: event.decorator,
66
- },
67
- editor,
68
- })
69
- break
70
- }
71
- case 'focus': {
72
- editorActor.send({
73
- type: 'behavior event',
74
- behaviorEvent: {
75
- type: 'focus',
76
- },
77
- editor,
78
- })
79
- break
80
- }
81
- case 'insert.block object': {
82
- editorActor.send({
83
- type: 'behavior event',
84
- behaviorEvent: {
85
- type: 'insert.block object',
86
- placement: event.placement,
87
- blockObject: event.blockObject,
88
- },
89
- editor,
90
- })
91
- break
92
- }
93
- case 'insert.inline object': {
94
- editorActor.send({
95
- type: 'behavior event',
96
- behaviorEvent: {
97
- type: 'insert.inline object',
98
- inlineObject: event.inlineObject,
99
- },
100
- editor,
101
- })
102
- break
103
- }
104
- case 'list item.toggle': {
105
- editorActor.send({
106
- type: 'behavior event',
107
- behaviorEvent: {
108
- type: 'list item.toggle',
109
- listItem: event.listItem,
110
- },
111
- editor,
112
- })
113
- break
114
- }
115
- case 'select': {
116
- editorActor.send({
117
- type: 'behavior event',
118
- behaviorEvent: {
119
- type: 'select',
120
- selection: event.selection,
121
- },
122
- editor,
123
- })
124
- break
125
- }
126
- case 'style.toggle': {
27
+
28
+ case 'annotation.add':
29
+ case 'annotation.remove':
30
+ case 'annotation.toggle':
31
+ case 'blur':
32
+ case 'data transfer.set':
33
+ case 'decorator.add':
34
+ case 'decorator.remove':
35
+ case 'decorator.toggle':
36
+ case 'delete.backward':
37
+ case 'delete.block':
38
+ case 'delete.forward':
39
+ case 'delete.text':
40
+ case 'deserialization.failure':
41
+ case 'deserialization.success':
42
+ case 'focus':
43
+ case 'insert.block object':
44
+ case 'insert.inline object':
45
+ case 'insert.span':
46
+ case 'insert.text block':
47
+ case 'list item.add':
48
+ case 'list item.remove':
49
+ case 'list item.toggle':
50
+ case 'move.block':
51
+ case 'move.block down':
52
+ case 'move.block up':
53
+ case 'select':
54
+ case 'select.next block':
55
+ case 'select.previous block':
56
+ case 'serialization.failure':
57
+ case 'serialization.success':
58
+ case 'style.add':
59
+ case 'style.remove':
60
+ case 'style.toggle':
61
+ case 'text block.set':
62
+ case 'text block.unset':
127
63
  editorActor.send({
128
64
  type: 'behavior event',
129
- behaviorEvent: {
130
- type: 'style.toggle',
131
- style: event.style,
132
- },
65
+ behaviorEvent: event,
133
66
  editor,
134
67
  })
135
68
  break
136
- }
137
69
  }
138
70
  })
139
71
 
@@ -1 +0,0 @@
1
- {"version":3,"file":"selector.is-selection-collapsed.cjs","sources":["../../src/behavior-actions/behavior.guards.ts","../../src/selectors/selectors.ts","../../src/selectors/selector.is-selection-collapsed.ts"],"sourcesContent":["import {\n isPortableTextListBlock,\n isPortableTextTextBlock,\n type PortableTextListBlock,\n type PortableTextTextBlock,\n} from '@sanity/types'\nimport type {EditorSchema} from '../editor/define-schema'\n\n/**\n * @alpha\n */\nexport type BehaviorGuards = ReturnType<typeof createGuards>\n\nexport function createGuards({schema}: {schema: EditorSchema}) {\n function isListBlock(block: unknown): block is PortableTextListBlock {\n return isPortableTextListBlock(block) && block._type === schema.block.name\n }\n\n function isTextBlock(block: unknown): block is PortableTextTextBlock {\n return isPortableTextTextBlock(block) && block._type === schema.block.name\n }\n\n return {isListBlock, isTextBlock}\n}\n","import {\n isKeySegment,\n isPortableTextSpan,\n isPortableTextTextBlock,\n type KeyedSegment,\n type PortableTextBlock,\n type PortableTextListBlock,\n type PortableTextObject,\n type PortableTextSpan,\n type PortableTextTextBlock,\n} from '@sanity/types'\nimport {createGuards} from '../behavior-actions/behavior.guards'\nimport type {EditorSelector} from '../editor/editor-selector'\n\n/**\n * @public\n */\nexport const getFocusBlock: EditorSelector<\n {node: PortableTextBlock; path: [KeyedSegment]} | undefined\n> = ({context}) => {\n const key = context.selection\n ? isKeySegment(context.selection.focus.path[0])\n ? context.selection.focus.path[0]._key\n : undefined\n : undefined\n\n const node = key\n ? context.value.find((block) => block._key === key)\n : undefined\n\n return node && key ? {node, path: [{_key: key}]} : undefined\n}\n\n/**\n * @public\n */\nexport const getFocusListBlock: EditorSelector<\n {node: PortableTextListBlock; path: [KeyedSegment]} | undefined\n> = ({context}) => {\n const guards = createGuards(context)\n const focusBlock = getFocusBlock({context})\n\n return focusBlock && guards.isListBlock(focusBlock.node)\n ? {node: focusBlock.node, path: focusBlock.path}\n : undefined\n}\n\n/**\n * @public\n */\nexport const getFocusTextBlock: EditorSelector<\n {node: PortableTextTextBlock; path: [KeyedSegment]} | undefined\n> = ({context}) => {\n const focusBlock = getFocusBlock({context})\n\n return focusBlock && isPortableTextTextBlock(focusBlock.node)\n ? {node: focusBlock.node, path: focusBlock.path}\n : undefined\n}\n\n/**\n * @public\n */\nexport const getFocusBlockObject: EditorSelector<\n {node: PortableTextObject; path: [KeyedSegment]} | undefined\n> = ({context}) => {\n const focusBlock = getFocusBlock({context})\n\n return focusBlock && !isPortableTextTextBlock(focusBlock.node)\n ? {node: focusBlock.node, path: focusBlock.path}\n : undefined\n}\n\n/**\n * @public\n */\nexport const getFocusChild: EditorSelector<\n | {\n node: PortableTextObject | PortableTextSpan\n path: [KeyedSegment, 'children', KeyedSegment]\n }\n | undefined\n> = ({context}) => {\n const focusBlock = getFocusTextBlock({context})\n\n if (!focusBlock) {\n return undefined\n }\n\n const key = context.selection\n ? isKeySegment(context.selection.focus.path[2])\n ? context.selection.focus.path[2]._key\n : undefined\n : undefined\n\n const node = key\n ? focusBlock.node.children.find((span) => span._key === key)\n : undefined\n\n return node && key\n ? {node, path: [...focusBlock.path, 'children', {_key: key}]}\n : undefined\n}\n\n/**\n * @public\n */\nexport const getFocusSpan: EditorSelector<\n | {node: PortableTextSpan; path: [KeyedSegment, 'children', KeyedSegment]}\n | undefined\n> = ({context}) => {\n const focusChild = getFocusChild({context})\n\n return focusChild && isPortableTextSpan(focusChild.node)\n ? {node: focusChild.node, path: focusChild.path}\n : undefined\n}\n\n/**\n * @public\n */\nexport const getFirstBlock: EditorSelector<\n {node: PortableTextBlock; path: [KeyedSegment]} | undefined\n> = ({context}) => {\n const node = context.value[0]\n\n return node ? {node, path: [{_key: node._key}]} : undefined\n}\n\n/**\n * @public\n */\nexport const getLastBlock: EditorSelector<\n {node: PortableTextBlock; path: [KeyedSegment]} | undefined\n> = ({context}) => {\n const node = context.value[context.value.length - 1]\n ? context.value[context.value.length - 1]\n : undefined\n\n return node ? {node, path: [{_key: node._key}]} : undefined\n}\n\n/**\n * @public\n */\nexport const getSelectedBlocks: EditorSelector<\n Array<{node: PortableTextBlock; path: [KeyedSegment]}>\n> = ({context}) => {\n if (!context.selection) {\n return []\n }\n\n const selectedBlocks: Array<{node: PortableTextBlock; path: [KeyedSegment]}> =\n []\n const startKey = context.selection.backward\n ? isKeySegment(context.selection.focus.path[0])\n ? context.selection.focus.path[0]._key\n : undefined\n : isKeySegment(context.selection.anchor.path[0])\n ? context.selection.anchor.path[0]._key\n : undefined\n const endKey = context.selection.backward\n ? isKeySegment(context.selection.anchor.path[0])\n ? context.selection.anchor.path[0]._key\n : undefined\n : isKeySegment(context.selection.focus.path[0])\n ? context.selection.focus.path[0]._key\n : undefined\n\n if (!startKey || !endKey) {\n return selectedBlocks\n }\n\n for (const block of context.value) {\n if (block._key === startKey) {\n selectedBlocks.push({node: block, path: [{_key: block._key}]})\n\n if (startKey === endKey) {\n break\n }\n continue\n }\n\n if (block._key === endKey) {\n selectedBlocks.push({node: block, path: [{_key: block._key}]})\n break\n }\n\n if (selectedBlocks.length > 0) {\n selectedBlocks.push({node: block, path: [{_key: block._key}]})\n }\n }\n\n return selectedBlocks\n}\n\n/**\n * @public\n */\nexport const getSelectionStartBlock: EditorSelector<\n | {\n node: PortableTextBlock\n path: [KeyedSegment]\n }\n | undefined\n> = ({context}) => {\n if (!context.selection) {\n return undefined\n }\n\n const key = context.selection.backward\n ? isKeySegment(context.selection.focus.path[0])\n ? context.selection.focus.path[0]._key\n : undefined\n : isKeySegment(context.selection.anchor.path[0])\n ? context.selection.anchor.path[0]._key\n : undefined\n\n const node = key\n ? context.value.find((block) => block._key === key)\n : undefined\n\n return node && key ? {node, path: [{_key: key}]} : undefined\n}\n\n/**\n * @public\n */\nexport const getSelectionEndBlock: EditorSelector<\n | {\n node: PortableTextBlock\n path: [KeyedSegment]\n }\n | undefined\n> = ({context}) => {\n if (!context.selection) {\n return undefined\n }\n\n const key = context.selection.backward\n ? isKeySegment(context.selection.anchor.path[0])\n ? context.selection.anchor.path[0]._key\n : undefined\n : isKeySegment(context.selection.focus.path[0])\n ? context.selection.focus.path[0]._key\n : undefined\n\n const node = key\n ? context.value.find((block) => block._key === key)\n : undefined\n\n return node && key ? {node, path: [{_key: key}]} : undefined\n}\n\n/**\n * @public\n */\nexport const getPreviousBlock: EditorSelector<\n {node: PortableTextBlock; path: [KeyedSegment]} | undefined\n> = ({context}) => {\n let previousBlock: {node: PortableTextBlock; path: [KeyedSegment]} | undefined\n const selectionStartBlock = getSelectionStartBlock({context})\n\n if (!selectionStartBlock) {\n return undefined\n }\n\n let foundSelectionStartBlock = false\n\n for (const block of context.value) {\n if (block._key === selectionStartBlock.node._key) {\n foundSelectionStartBlock = true\n break\n }\n\n previousBlock = {node: block, path: [{_key: block._key}]}\n }\n\n if (foundSelectionStartBlock && previousBlock) {\n return previousBlock\n }\n\n return undefined\n}\n\n/**\n * @public\n */\nexport const getNextBlock: EditorSelector<\n {node: PortableTextBlock; path: [KeyedSegment]} | undefined\n> = ({context}) => {\n let nextBlock: {node: PortableTextBlock; path: [KeyedSegment]} | undefined\n const selectionEndBlock = getSelectionEndBlock({context})\n\n if (!selectionEndBlock) {\n return undefined\n }\n\n let foundSelectionEndBlock = false\n\n for (const block of context.value) {\n if (block._key === selectionEndBlock.node._key) {\n foundSelectionEndBlock = true\n continue\n }\n\n if (foundSelectionEndBlock) {\n nextBlock = {node: block, path: [{_key: block._key}]}\n break\n }\n }\n\n if (foundSelectionEndBlock && nextBlock) {\n return nextBlock\n }\n\n return undefined\n}\n","import type {EditorSelector} from '../editor/editor-selector'\n\n/**\n * @public\n */\nexport const isSelectionCollapsed: EditorSelector<boolean> = ({context}) => {\n return (\n JSON.stringify(context.selection?.anchor.path) ===\n JSON.stringify(context.selection?.focus.path) &&\n context.selection?.anchor.offset === context.selection?.focus.offset\n )\n}\n"],"names":["createGuards","schema","isListBlock","block","isPortableTextListBlock","_type","name","isTextBlock","isPortableTextTextBlock","getFocusBlock","context","key","selection","isKeySegment","focus","path","_key","undefined","node","value","find","getFocusListBlock","guards","focusBlock","getFocusTextBlock","getFocusBlockObject","getFocusChild","children","span","getFocusSpan","focusChild","isPortableTextSpan","getFirstBlock","getLastBlock","length","getSelectedBlocks","selectedBlocks","startKey","backward","anchor","endKey","push","getSelectionStartBlock","getSelectionEndBlock","getPreviousBlock","previousBlock","selectionStartBlock","foundSelectionStartBlock","getNextBlock","nextBlock","selectionEndBlock","foundSelectionEndBlock","isSelectionCollapsed","JSON","stringify","offset"],"mappings":"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"}