@portabletext/editor 1.21.5 → 1.22.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 (53) hide show
  1. package/lib/_chunks-cjs/behavior.core.cjs.map +1 -1
  2. package/lib/_chunks-cjs/selector.get-text-before.cjs +4 -4
  3. package/lib/_chunks-cjs/selector.get-text-before.cjs.map +1 -1
  4. package/lib/_chunks-cjs/{util.get-block-start-point.cjs → util.reverse-selection.cjs} +12 -12
  5. package/lib/_chunks-cjs/util.reverse-selection.cjs.map +1 -0
  6. package/lib/_chunks-cjs/util.slice-blocks.cjs +75 -0
  7. package/lib/_chunks-cjs/util.slice-blocks.cjs.map +1 -0
  8. package/lib/_chunks-es/behavior.core.js.map +1 -1
  9. package/lib/_chunks-es/selector.get-text-before.js +1 -1
  10. package/lib/_chunks-es/{util.get-block-start-point.js → util.reverse-selection.js} +12 -12
  11. package/lib/_chunks-es/util.reverse-selection.js.map +1 -0
  12. package/lib/_chunks-es/util.slice-blocks.js +76 -0
  13. package/lib/_chunks-es/util.slice-blocks.js.map +1 -0
  14. package/lib/behaviors/index.cjs.map +1 -1
  15. package/lib/behaviors/index.d.cts +57 -0
  16. package/lib/behaviors/index.d.ts +57 -0
  17. package/lib/behaviors/index.js.map +1 -1
  18. package/lib/index.cjs +32 -19
  19. package/lib/index.cjs.map +1 -1
  20. package/lib/index.d.cts +130 -0
  21. package/lib/index.d.ts +130 -0
  22. package/lib/index.js +33 -20
  23. package/lib/index.js.map +1 -1
  24. package/lib/selectors/index.cjs +10 -4
  25. package/lib/selectors/index.cjs.map +1 -1
  26. package/lib/selectors/index.d.cts +5 -0
  27. package/lib/selectors/index.d.ts +5 -0
  28. package/lib/selectors/index.js +9 -2
  29. package/lib/selectors/index.js.map +1 -1
  30. package/lib/utils/index.cjs +4 -3
  31. package/lib/utils/index.cjs.map +1 -1
  32. package/lib/utils/index.d.cts +11 -0
  33. package/lib/utils/index.d.ts +11 -0
  34. package/lib/utils/index.js +3 -1
  35. package/lib/utils/index.js.map +1 -1
  36. package/package.json +11 -11
  37. package/src/behaviors/behavior.markdown.ts +42 -0
  38. package/src/behaviors/behavior.types.ts +15 -0
  39. package/src/editor/Editable.tsx +17 -0
  40. package/src/editor/define-schema.ts +24 -1
  41. package/src/editor/editor-event-listener.tsx +45 -0
  42. package/src/editor/editor-machine.ts +6 -26
  43. package/src/editor/editor-provider.tsx +27 -0
  44. package/src/editor/editor-selector.ts +21 -0
  45. package/src/editor/editor-snapshot.ts +37 -1
  46. package/src/editor/plugins/createWithInsertData.ts +6 -7
  47. package/src/selectors/index.ts +1 -0
  48. package/src/selectors/selector.get-selected-slice.ts +12 -0
  49. package/src/utils/index.ts +1 -0
  50. package/src/utils/util.slice-blocks.test.ts +163 -0
  51. package/src/utils/util.slice-blocks.ts +143 -0
  52. package/lib/_chunks-cjs/util.get-block-start-point.cjs.map +0 -1
  53. package/lib/_chunks-es/util.get-block-start-point.js.map +0 -1
@@ -5,6 +5,51 @@ import {useEditor} from './editor-provider'
5
5
 
6
6
  /**
7
7
  * @public
8
+ * Listen for events emitted by the editor. Must be used inside `EditorProvider`. Events available include:
9
+ * - 'blurred'
10
+ * - 'done loading'
11
+ * - 'editable'
12
+ * - 'error'
13
+ * - 'focused'
14
+ * - 'invalid value'
15
+ * - 'loading'
16
+ * - 'mutation'
17
+ * - 'patch'
18
+ * - 'read only'
19
+ * - 'ready'
20
+ * - 'selection'
21
+ * - 'value changed'
22
+ *
23
+ * @example
24
+ * Listen and log events.
25
+ * ```tsx
26
+ * import {EditorEventListener, EditorProvider} from '@portabletext/editor'
27
+ *
28
+ * function MyComponent() {
29
+ * return (
30
+ * <EditorProvider>
31
+ * <EditorEventListener
32
+ * on={(event) => {
33
+ * console.log(event)
34
+ * }
35
+ * } />
36
+ * { ... }
37
+ * </EditorProvider>
38
+ * )
39
+ * }
40
+ * ```
41
+ * @example
42
+ * Handle events when there is a mutation.
43
+ * ```tsx
44
+ * <EditorEventListener
45
+ * on={(event) => {
46
+ * if (event.type === 'mutation') {
47
+ * console.log('Value changed:', event.snapshot)
48
+ * }
49
+ * }}
50
+ * />
51
+ * ```
52
+ * @group Components
8
53
  */
9
54
  export function EditorEventListener(props: {
10
55
  on: (event: EditorEmittedEvent) => void
@@ -20,9 +20,6 @@ import {
20
20
  type NativeBehaviorEvent,
21
21
  type SyntheticBehaviorEvent,
22
22
  } from '../behaviors/behavior.types'
23
- import {toPortableTextRange} from '../internal-utils/ranges'
24
- import {fromSlateValue} from '../internal-utils/values'
25
- import {KEY_TO_VALUE_ELEMENT} from '../internal-utils/weakMaps'
26
23
  import type {OmitFromUnion, PickFromUnion} from '../type-utils'
27
24
  import type {
28
25
  EditorSelection,
@@ -30,8 +27,7 @@ import type {
30
27
  PortableTextSlateEditor,
31
28
  } from '../types/editor'
32
29
  import type {EditorSchema} from './define-schema'
33
- import type {EditorContext} from './editor-snapshot'
34
- import {getActiveDecorators} from './get-active-decorators'
30
+ import {createEditorSnapshot} from './editor-snapshot'
35
31
  import {withApplyingBehaviorActions} from './with-applying-behavior-actions'
36
32
 
37
33
  export * from 'xstate/guards'
@@ -342,27 +338,11 @@ export const editorMachine = setup({
342
338
  return
343
339
  }
344
340
 
345
- const value = fromSlateValue(
346
- event.editor.children,
347
- context.schema.block.name,
348
- KEY_TO_VALUE_ELEMENT.get(event.editor),
349
- )
350
- const selection = toPortableTextRange(
351
- value,
352
- event.editor.selection,
353
- context.schema,
354
- )
355
-
356
- const editorContext = {
357
- activeDecorators: getActiveDecorators({
358
- schema: context.schema,
359
- slateEditorInstance: event.editor,
360
- }),
341
+ const editorSnapshot = createEditorSnapshot({
342
+ editor: event.editor,
361
343
  keyGenerator: context.keyGenerator,
362
344
  schema: context.schema,
363
- selection,
364
- value,
365
- } satisfies EditorContext
345
+ })
366
346
 
367
347
  let behaviorOverwritten = false
368
348
 
@@ -370,7 +350,7 @@ export const editorMachine = setup({
370
350
  const shouldRun =
371
351
  eventBehavior.guard === undefined ||
372
352
  eventBehavior.guard({
373
- context: editorContext,
353
+ context: editorSnapshot.context,
374
354
  event: event.behaviorEvent,
375
355
  })
376
356
 
@@ -380,7 +360,7 @@ export const editorMachine = setup({
380
360
 
381
361
  const actionIntendSets = eventBehavior.actions.map((actionSet) =>
382
362
  actionSet(
383
- {context: editorContext, event: event.behaviorEvent},
363
+ {context: editorSnapshot.context, event: event.behaviorEvent},
384
364
  shouldRun,
385
365
  ),
386
366
  )
@@ -23,6 +23,21 @@ export type EditorProviderProps = {
23
23
 
24
24
  /**
25
25
  * @public
26
+ * The EditorProvider component is used to set up the editor context and configure the Portable Text Editor.
27
+ * @example
28
+ * ```tsx
29
+ * import {EditorProvider} from '@portabletext/editor'
30
+ *
31
+ * function App() {
32
+ * return (
33
+ * <EditorProvider initialConfig={{ ... }} >
34
+ * ...
35
+ * </EditorProvider>
36
+ * )
37
+ * }
38
+ *
39
+ * ```
40
+ * @group Components
26
41
  */
27
42
  export function EditorProvider(props: EditorProviderProps) {
28
43
  const editor = useCreateEditor(props.initialConfig)
@@ -66,6 +81,18 @@ export function EditorProvider(props: EditorProviderProps) {
66
81
 
67
82
  /**
68
83
  * @public
84
+ * Get the current editor context from the `EditorProvider`.
85
+ * Must be used inside the `EditorProvider` component.
86
+ * @returns The current editor object.
87
+ * @example
88
+ * ```tsx
89
+ * import { useEditor } from '@portabletext/editor'
90
+ *
91
+ * function MyComponent() {
92
+ * const editor = useEditor()
93
+ * }
94
+ * ```
95
+ * @group Hooks
69
96
  */
70
97
  export function useEditor() {
71
98
  const editor = React.useContext(EditorContext)
@@ -17,6 +17,27 @@ export type EditorSelector<TSelected> = (snapshot: EditorSnapshot) => TSelected
17
17
 
18
18
  /**
19
19
  * @public
20
+ * Hook to select a value from the editor state.
21
+ * @example
22
+ * Pass a selector as the second argument
23
+ * ```tsx
24
+ * import { useEditorSelector } from '@portabletext/editor'
25
+ *
26
+ * function MyComponent(editor) {
27
+ * const value = useEditorSelector(editor, selector)
28
+ * }
29
+ * ```
30
+ * @example
31
+ * Pass an inline selector as the second argument.
32
+ * In this case, use the editor context to obtain the schema.
33
+ * ```tsx
34
+ * import { useEditorSelector } from '@portabletext/editor'
35
+ *
36
+ * function MyComponent(editor) {
37
+ * const schema = useEditorSelector(editor, (snapshot) => snapshot.context.schema)
38
+ * }
39
+ * ```
40
+ * @group Hooks
20
41
  */
21
42
  export function useEditorSelector<TSelected>(
22
43
  editor: Editor,
@@ -1,6 +1,10 @@
1
1
  import type {PortableTextBlock} from '@sanity/types'
2
- import type {EditorSelection} from '../types/editor'
2
+ import {toPortableTextRange} from '../internal-utils/ranges'
3
+ import {fromSlateValue} from '../internal-utils/values'
4
+ import {KEY_TO_VALUE_ELEMENT} from '../internal-utils/weakMaps'
5
+ import type {EditorSelection, PortableTextSlateEditor} from '../types/editor'
3
6
  import type {EditorSchema} from './define-schema'
7
+ import {getActiveDecorators} from './get-active-decorators'
4
8
 
5
9
  /**
6
10
  * @public
@@ -19,3 +23,35 @@ export type EditorContext = {
19
23
  export type EditorSnapshot = {
20
24
  context: EditorContext
21
25
  }
26
+
27
+ export function createEditorSnapshot({
28
+ editor,
29
+ keyGenerator,
30
+ schema,
31
+ }: {
32
+ editor: PortableTextSlateEditor
33
+ keyGenerator: () => string
34
+ schema: EditorSchema
35
+ }) {
36
+ const value = fromSlateValue(
37
+ editor.children,
38
+ schema.block.name,
39
+ KEY_TO_VALUE_ELEMENT.get(editor),
40
+ )
41
+ const selection = toPortableTextRange(value, editor.selection, schema)
42
+
43
+ const context = {
44
+ activeDecorators: getActiveDecorators({
45
+ schema,
46
+ slateEditorInstance: editor,
47
+ }),
48
+ keyGenerator,
49
+ schema,
50
+ selection,
51
+ value,
52
+ } satisfies EditorContext
53
+
54
+ return {
55
+ context,
56
+ } satisfies EditorSnapshot
57
+ }
@@ -1,4 +1,4 @@
1
- import {htmlToBlocks, normalizeBlock} from '@portabletext/block-tools'
1
+ import {htmlToBlocks} from '@portabletext/block-tools'
2
2
  import type {PortableTextBlock, PortableTextChild} from '@sanity/types'
3
3
  import {isEqual, uniq} from 'lodash'
4
4
  import {Editor, Range, Transforms, type Descendant, type Node} from 'slate'
@@ -194,9 +194,8 @@ export function createWithInsertData(
194
194
  if (html) {
195
195
  portableText = htmlToBlocks(html, schemaTypes.portableText, {
196
196
  unstable_whitespaceOnPasteMode: whitespaceOnPasteMode,
197
- }).map((block) =>
198
- normalizeBlock(block, {blockTypeName}),
199
- ) as PortableTextBlock[]
197
+ keyGenerator: editorActor.getSnapshot().context.keyGenerator,
198
+ }) as PortableTextBlock[]
200
199
  fragment = toSlateValue(portableText, {schemaTypes})
201
200
  insertedType = 'HTML'
202
201
 
@@ -214,9 +213,9 @@ export function createWithInsertData(
214
213
  )
215
214
  .join('')
216
215
  const textToHtml = `<html><body>${blocks}</body></html>`
217
- portableText = htmlToBlocks(textToHtml, schemaTypes.portableText).map(
218
- (block) => normalizeBlock(block, {blockTypeName}),
219
- ) as PortableTextBlock[]
216
+ portableText = htmlToBlocks(textToHtml, schemaTypes.portableText, {
217
+ keyGenerator: editorActor.getSnapshot().context.keyGenerator,
218
+ }) as PortableTextBlock[]
220
219
  fragment = toSlateValue(portableText, {
221
220
  schemaTypes,
222
221
  })
@@ -9,6 +9,7 @@ export type {
9
9
  export type {EditorSchema} from '../editor/define-schema'
10
10
  export {getActiveListItem} from './selector.get-active-list-item'
11
11
  export {getActiveStyle} from './selector.get-active-style'
12
+ export {getSelectedSlice} from './selector.get-selected-slice'
12
13
  export {getSelectedSpans} from './selector.get-selected-spans'
13
14
  export {getSelectionText} from './selector.get-selection-text'
14
15
  export {getBlockTextBefore} from './selector.get-text-before'
@@ -0,0 +1,12 @@
1
+ import type {PortableTextBlock} from '@sanity/types'
2
+ import type {EditorSelector} from '../editor/editor-selector'
3
+ import {sliceBlocks} from '../utils'
4
+
5
+ /**
6
+ * @public
7
+ */
8
+ export const getSelectedSlice: EditorSelector<Array<PortableTextBlock>> = ({
9
+ context,
10
+ }) => {
11
+ return sliceBlocks({blocks: context.value, selection: context.selection})
12
+ }
@@ -9,3 +9,4 @@ export {getTextBlockText} from './util.get-text-block-text'
9
9
  export {isEmptyTextBlock} from './util.is-empty-text-block'
10
10
  export {isKeyedSegment} from './util.is-keyed-segment'
11
11
  export {reverseSelection} from './util.reverse-selection'
12
+ export {sliceBlocks} from './util.slice-blocks'
@@ -0,0 +1,163 @@
1
+ import type {PortableTextBlock, PortableTextTextBlock} from '@sanity/types'
2
+ import {describe, expect, test} from 'vitest'
3
+ import {sliceBlocks} from './util.slice-blocks'
4
+
5
+ const textBlock1: PortableTextTextBlock = {
6
+ _type: 'block',
7
+ _key: 'b1',
8
+ children: [
9
+ {
10
+ _type: 'span',
11
+ _key: 's1',
12
+ text: 'foo',
13
+ marks: ['strong'],
14
+ },
15
+ {
16
+ _type: 'span',
17
+ _key: 's2',
18
+ text: 'bar',
19
+ },
20
+ ],
21
+ }
22
+ const textBlock2: PortableTextTextBlock = {
23
+ _type: 'block',
24
+ _key: 'b3',
25
+ children: [
26
+ {
27
+ _type: 'span',
28
+ _key: 's3',
29
+ text: 'baz',
30
+ },
31
+ ],
32
+ }
33
+
34
+ const blocks: Array<PortableTextBlock> = [
35
+ textBlock1,
36
+ {
37
+ _type: 'image',
38
+ _key: 'b2',
39
+ },
40
+ textBlock2,
41
+ ]
42
+
43
+ describe(sliceBlocks.name, () => {
44
+ test('sensible defaults', () => {
45
+ expect(sliceBlocks({blocks: [], selection: null})).toEqual([])
46
+ expect(sliceBlocks({blocks, selection: null})).toEqual([])
47
+ })
48
+
49
+ test('slicing a single block', () => {
50
+ expect(
51
+ sliceBlocks({
52
+ blocks,
53
+ selection: {
54
+ anchor: {
55
+ path: [{_key: 'b1'}, 'children', {_key: 's1'}],
56
+ offset: 0,
57
+ },
58
+ focus: {
59
+ path: [{_key: 'b1'}, 'children', {_key: 's1'}],
60
+ offset: 3,
61
+ },
62
+ },
63
+ }),
64
+ ).toEqual([
65
+ {
66
+ ...textBlock1,
67
+ children: [textBlock1.children[0]],
68
+ },
69
+ ])
70
+ })
71
+
72
+ test('slicing a single span', () => {
73
+ expect(
74
+ sliceBlocks({
75
+ blocks,
76
+ selection: {
77
+ anchor: {
78
+ path: [{_key: 'b1'}, 'children', {_key: 's1'}],
79
+ offset: 1,
80
+ },
81
+ focus: {
82
+ path: [{_key: 'b1'}, 'children', {_key: 's1'}],
83
+ offset: 2,
84
+ },
85
+ },
86
+ }),
87
+ ).toEqual([
88
+ {
89
+ ...textBlock1,
90
+ children: [
91
+ {
92
+ ...textBlock1.children[0],
93
+ text: 'o',
94
+ },
95
+ ],
96
+ },
97
+ ])
98
+ })
99
+
100
+ test('ending selection on a block object', () => {
101
+ expect(
102
+ sliceBlocks({
103
+ blocks,
104
+ selection: {
105
+ anchor: {
106
+ path: [{_key: 'b1'}, 'children', {_key: 's1'}],
107
+ offset: 3,
108
+ },
109
+ focus: {
110
+ path: [{_key: 'b2'}],
111
+ offset: 0,
112
+ },
113
+ },
114
+ }),
115
+ ).toEqual([
116
+ {
117
+ ...textBlock1,
118
+ children: [
119
+ {
120
+ ...textBlock1.children[0],
121
+ text: '',
122
+ },
123
+ ],
124
+ },
125
+ blocks[1],
126
+ ])
127
+ })
128
+
129
+ test('starting and ending mid-span', () => {
130
+ expect(
131
+ sliceBlocks({
132
+ blocks,
133
+ selection: {
134
+ anchor: {
135
+ path: [{_key: 'b1'}, 'children', {_key: 's1'}],
136
+ offset: 2,
137
+ },
138
+ focus: {path: [{_key: 'b3'}, 'children', {_key: 's3'}], offset: 1},
139
+ },
140
+ }),
141
+ ).toEqual([
142
+ {
143
+ ...textBlock1,
144
+ children: [
145
+ {
146
+ ...textBlock1.children[0],
147
+ text: 'o',
148
+ },
149
+ ],
150
+ },
151
+ blocks[1],
152
+ {
153
+ ...textBlock2,
154
+ children: [
155
+ {
156
+ ...textBlock2.children[0],
157
+ text: 'az',
158
+ },
159
+ ],
160
+ },
161
+ ])
162
+ })
163
+ })
@@ -0,0 +1,143 @@
1
+ import {
2
+ isKeySegment,
3
+ isPortableTextSpan,
4
+ isPortableTextTextBlock,
5
+ type PortableTextBlock,
6
+ } from '@sanity/types'
7
+ import type {EditorSelection} from '../selectors'
8
+
9
+ /**
10
+ * @public
11
+ */
12
+ export function sliceBlocks({
13
+ blocks,
14
+ selection,
15
+ }: {
16
+ blocks: Array<PortableTextBlock>
17
+ selection: EditorSelection
18
+ }): Array<PortableTextBlock> {
19
+ const slice: Array<PortableTextBlock> = []
20
+
21
+ if (!selection) {
22
+ return slice
23
+ }
24
+
25
+ let startBlock: PortableTextBlock | undefined
26
+ const middleBlocks: PortableTextBlock[] = []
27
+ let endBlock: PortableTextBlock | undefined
28
+
29
+ const startPoint = selection.backward ? selection.focus : selection.anchor
30
+ const endPoint = selection.backward ? selection.anchor : selection.focus
31
+
32
+ const startBlockKey = isKeySegment(startPoint.path[0])
33
+ ? startPoint.path[0]._key
34
+ : undefined
35
+ const endBlockKey = isKeySegment(endPoint.path[0])
36
+ ? endPoint.path[0]._key
37
+ : undefined
38
+ const startChildKey = isKeySegment(startPoint.path[2])
39
+ ? startPoint.path[2]._key
40
+ : undefined
41
+ const endChildKey = isKeySegment(endPoint.path[2])
42
+ ? endPoint.path[2]._key
43
+ : undefined
44
+
45
+ if (!startBlockKey || !endBlockKey) {
46
+ return slice
47
+ }
48
+
49
+ for (const block of blocks) {
50
+ if (block._key === startBlockKey) {
51
+ if (isPortableTextTextBlock(block) && startChildKey) {
52
+ for (const child of block.children) {
53
+ if (child._key === startChildKey) {
54
+ if (isPortableTextSpan(child)) {
55
+ const text =
56
+ child._key === endChildKey
57
+ ? child.text.slice(startPoint.offset, endPoint.offset)
58
+ : child.text.slice(startPoint.offset)
59
+
60
+ startBlock = {
61
+ ...block,
62
+ children: [
63
+ {
64
+ ...child,
65
+ text,
66
+ },
67
+ ],
68
+ }
69
+ break
70
+ }
71
+
72
+ startBlock = {
73
+ ...block,
74
+ children: [child],
75
+ }
76
+ break
77
+ }
78
+
79
+ if (startBlock && isPortableTextTextBlock(startBlock)) {
80
+ startBlock.children.push(child)
81
+
82
+ if (
83
+ block._key === endBlockKey &&
84
+ endChildKey &&
85
+ child._key === endChildKey
86
+ ) {
87
+ break
88
+ }
89
+ }
90
+ }
91
+
92
+ if (startBlockKey === endBlockKey) {
93
+ break
94
+ }
95
+
96
+ continue
97
+ }
98
+
99
+ startBlock = block
100
+ }
101
+
102
+ if (block._key === endBlockKey) {
103
+ if (isPortableTextTextBlock(block) && endBlockKey) {
104
+ endBlock = {
105
+ ...block,
106
+ children: [],
107
+ }
108
+
109
+ for (const child of block.children) {
110
+ if (endBlock && isPortableTextTextBlock(endBlock)) {
111
+ if (child._key === endChildKey && isPortableTextSpan(child)) {
112
+ endBlock.children.push({
113
+ ...child,
114
+ text: child.text.slice(endPoint.offset),
115
+ })
116
+ break
117
+ }
118
+
119
+ endBlock.children.push(child)
120
+
121
+ if (endChildKey && child._key === endChildKey) {
122
+ break
123
+ }
124
+ }
125
+ }
126
+
127
+ continue
128
+ }
129
+
130
+ endBlock = block
131
+
132
+ break
133
+ }
134
+
135
+ middleBlocks.push(block)
136
+ }
137
+
138
+ return [
139
+ ...(startBlock ? [startBlock] : []),
140
+ ...middleBlocks,
141
+ ...(endBlock ? [endBlock] : []),
142
+ ]
143
+ }
@@ -1 +0,0 @@
1
- {"version":3,"file":"util.get-block-start-point.cjs","sources":["../../src/utils/util.reverse-selection.ts","../../src/utils/util.get-block-start-point.ts"],"sourcesContent":["import type {EditorSelection} from '../types/editor'\n\n/**\n * @public\n */\nexport function reverseSelection(\n selection: NonNullable<EditorSelection>,\n): NonNullable<EditorSelection> {\n if (selection.backward) {\n return {\n anchor: selection.focus,\n focus: selection.anchor,\n backward: false,\n }\n }\n\n return {\n anchor: selection.focus,\n focus: selection.anchor,\n backward: true,\n }\n}\n","import {\n isPortableTextTextBlock,\n type KeyedSegment,\n type PortableTextBlock,\n} from '@sanity/types'\nimport type {EditorSelectionPoint} from '../types/editor'\n\n/**\n * @public\n */\nexport function getBlockStartPoint({\n node,\n path,\n}: {\n node: PortableTextBlock\n path: [KeyedSegment]\n}): EditorSelectionPoint {\n if (isPortableTextTextBlock(node)) {\n return {\n path: [...path, 'children', {_key: node.children[0]._key}],\n offset: 0,\n }\n }\n\n return {\n path,\n offset: 0,\n }\n}\n"],"names":["reverseSelection","selection","backward","anchor","focus","getBlockStartPoint","node","path","isPortableTextTextBlock","_key","children","offset"],"mappings":";;AAKO,SAASA,iBACdC,WAC8B;AAC9B,SAAIA,UAAUC,WACL;AAAA,IACLC,QAAQF,UAAUG;AAAAA,IAClBA,OAAOH,UAAUE;AAAAA,IACjBD,UAAU;AAAA,EAAA,IAIP;AAAA,IACLC,QAAQF,UAAUG;AAAAA,IAClBA,OAAOH,UAAUE;AAAAA,IACjBD,UAAU;AAAA,EACZ;AACF;ACXO,SAASG,mBAAmB;AAAA,EACjCC;AAAAA,EACAC;AAIF,GAAyB;AACnBC,SAAAA,MAAAA,wBAAwBF,IAAI,IACvB;AAAA,IACLC,MAAM,CAAC,GAAGA,MAAM,YAAY;AAAA,MAACE,MAAMH,KAAKI,SAAS,CAAC,EAAED;AAAAA,IAAAA,CAAK;AAAA,IACzDE,QAAQ;AAAA,EAAA,IAIL;AAAA,IACLJ;AAAAA,IACAI,QAAQ;AAAA,EACV;AACF;;;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"util.get-block-start-point.js","sources":["../../src/utils/util.reverse-selection.ts","../../src/utils/util.get-block-start-point.ts"],"sourcesContent":["import type {EditorSelection} from '../types/editor'\n\n/**\n * @public\n */\nexport function reverseSelection(\n selection: NonNullable<EditorSelection>,\n): NonNullable<EditorSelection> {\n if (selection.backward) {\n return {\n anchor: selection.focus,\n focus: selection.anchor,\n backward: false,\n }\n }\n\n return {\n anchor: selection.focus,\n focus: selection.anchor,\n backward: true,\n }\n}\n","import {\n isPortableTextTextBlock,\n type KeyedSegment,\n type PortableTextBlock,\n} from '@sanity/types'\nimport type {EditorSelectionPoint} from '../types/editor'\n\n/**\n * @public\n */\nexport function getBlockStartPoint({\n node,\n path,\n}: {\n node: PortableTextBlock\n path: [KeyedSegment]\n}): EditorSelectionPoint {\n if (isPortableTextTextBlock(node)) {\n return {\n path: [...path, 'children', {_key: node.children[0]._key}],\n offset: 0,\n }\n }\n\n return {\n path,\n offset: 0,\n }\n}\n"],"names":["reverseSelection","selection","backward","anchor","focus","getBlockStartPoint","node","path","isPortableTextTextBlock","_key","children","offset"],"mappings":";AAKO,SAASA,iBACdC,WAC8B;AAC9B,SAAIA,UAAUC,WACL;AAAA,IACLC,QAAQF,UAAUG;AAAAA,IAClBA,OAAOH,UAAUE;AAAAA,IACjBD,UAAU;AAAA,EAAA,IAIP;AAAA,IACLC,QAAQF,UAAUG;AAAAA,IAClBA,OAAOH,UAAUE;AAAAA,IACjBD,UAAU;AAAA,EACZ;AACF;ACXO,SAASG,mBAAmB;AAAA,EACjCC;AAAAA,EACAC;AAIF,GAAyB;AACnBC,SAAAA,wBAAwBF,IAAI,IACvB;AAAA,IACLC,MAAM,CAAC,GAAGA,MAAM,YAAY;AAAA,MAACE,MAAMH,KAAKI,SAAS,CAAC,EAAED;AAAAA,IAAAA,CAAK;AAAA,IACzDE,QAAQ;AAAA,EAAA,IAIL;AAAA,IACLJ;AAAAA,IACAI,QAAQ;AAAA,EACV;AACF;"}