@portabletext/editor 1.20.0 → 1.21.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 (128) hide show
  1. package/lib/_chunks-cjs/behavior.core.cjs +8 -68
  2. package/lib/_chunks-cjs/behavior.core.cjs.map +1 -1
  3. package/lib/_chunks-cjs/selector.get-text-before.cjs +11 -39
  4. package/lib/_chunks-cjs/selector.get-text-before.cjs.map +1 -1
  5. package/lib/_chunks-cjs/util.get-block-start-point.cjs +30 -0
  6. package/lib/_chunks-cjs/util.get-block-start-point.cjs.map +1 -0
  7. package/lib/_chunks-cjs/util.is-empty-text-block.cjs +71 -0
  8. package/lib/_chunks-cjs/util.is-empty-text-block.cjs.map +1 -0
  9. package/lib/_chunks-cjs/util.is-keyed-segment.cjs +6 -0
  10. package/lib/_chunks-cjs/util.is-keyed-segment.cjs.map +1 -0
  11. package/lib/_chunks-es/behavior.core.js +7 -66
  12. package/lib/_chunks-es/behavior.core.js.map +1 -1
  13. package/lib/_chunks-es/selector.get-text-before.js +5 -31
  14. package/lib/_chunks-es/selector.get-text-before.js.map +1 -1
  15. package/lib/_chunks-es/util.get-block-start-point.js +31 -0
  16. package/lib/_chunks-es/util.get-block-start-point.js.map +1 -0
  17. package/lib/_chunks-es/util.is-empty-text-block.js +73 -0
  18. package/lib/_chunks-es/util.is-empty-text-block.js.map +1 -0
  19. package/lib/_chunks-es/util.is-keyed-segment.js +7 -0
  20. package/lib/_chunks-es/util.is-keyed-segment.js.map +1 -0
  21. package/lib/behaviors/index.cjs +7 -7
  22. package/lib/behaviors/index.cjs.map +1 -1
  23. package/lib/behaviors/index.d.cts +179 -119
  24. package/lib/behaviors/index.d.ts +179 -119
  25. package/lib/behaviors/index.js +3 -2
  26. package/lib/behaviors/index.js.map +1 -1
  27. package/lib/index.cjs +29 -6
  28. package/lib/index.cjs.map +1 -1
  29. package/lib/index.d.cts +844 -141
  30. package/lib/index.d.ts +844 -141
  31. package/lib/index.js +28 -4
  32. package/lib/index.js.map +1 -1
  33. package/lib/selectors/index.cjs +73 -1
  34. package/lib/selectors/index.cjs.map +1 -1
  35. package/lib/selectors/index.d.cts +14 -0
  36. package/lib/selectors/index.d.ts +14 -0
  37. package/lib/selectors/index.js +73 -0
  38. package/lib/selectors/index.js.map +1 -1
  39. package/lib/utils/index.cjs +11 -0
  40. package/lib/utils/index.cjs.map +1 -0
  41. package/lib/utils/index.d.cts +87 -0
  42. package/lib/utils/index.d.ts +87 -0
  43. package/lib/utils/index.js +13 -0
  44. package/lib/utils/index.js.map +1 -0
  45. package/package.json +15 -9
  46. package/src/behavior-actions/behavior.action-utils.insert-block.ts +1 -1
  47. package/src/behavior-actions/behavior.action.insert-block-object.ts +1 -1
  48. package/src/behavior-actions/behavior.action.insert-inline-object.ts +1 -1
  49. package/src/behavior-actions/behavior.action.text-block.set.ts +1 -1
  50. package/src/behavior-actions/behavior.action.text-block.unset.ts +1 -1
  51. package/src/behavior-actions/behavior.actions.ts +5 -5
  52. package/src/behaviors/behavior.code-editor.ts +1 -1
  53. package/src/behaviors/behavior.core.block-objects.ts +2 -2
  54. package/src/behaviors/behavior.core.decorators.ts +1 -1
  55. package/src/behaviors/behavior.core.lists.ts +2 -2
  56. package/src/behaviors/behavior.emoji-picker.ts +1 -1
  57. package/src/behaviors/behavior.links.ts +1 -1
  58. package/src/behaviors/behavior.markdown.ts +2 -2
  59. package/src/behaviors/behavior.types.ts +52 -19
  60. package/src/behaviors/index.ts +1 -0
  61. package/src/editor/Editable.tsx +12 -12
  62. package/src/editor/PortableTextEditor.tsx +2 -2
  63. package/src/editor/components/DraggableBlock.tsx +2 -2
  64. package/src/editor/components/Element.tsx +3 -3
  65. package/src/editor/components/Leaf.tsx +1 -1
  66. package/src/editor/components/Synchronizer.tsx +1 -1
  67. package/src/editor/create-editor.ts +22 -20
  68. package/src/editor/create-slate-editor.tsx +5 -2
  69. package/src/editor/editor-machine.ts +42 -14
  70. package/src/editor/get-value.ts +2 -2
  71. package/src/editor/hooks/usePortableTextEditorSelection.tsx +1 -1
  72. package/src/editor/mutation-machine.ts +2 -2
  73. package/src/editor/plugins/create-with-event-listeners.ts +11 -3
  74. package/src/editor/plugins/createWithEditableAPI.ts +7 -7
  75. package/src/editor/plugins/createWithHotKeys.ts +2 -2
  76. package/src/editor/plugins/createWithInsertData.ts +7 -7
  77. package/src/editor/plugins/createWithMaxBlocks.ts +2 -2
  78. package/src/editor/plugins/createWithObjectKeys.ts +2 -2
  79. package/src/editor/plugins/createWithPatches.ts +10 -10
  80. package/src/editor/plugins/createWithPlaceholderBlock.ts +3 -3
  81. package/src/editor/plugins/createWithPortableTextBlockStyle.ts +1 -1
  82. package/src/editor/plugins/createWithPortableTextMarkModel.ts +4 -4
  83. package/src/editor/plugins/createWithPortableTextSelections.ts +6 -6
  84. package/src/editor/plugins/createWithSchemaTypes.ts +1 -1
  85. package/src/editor/plugins/createWithUndoRedo.ts +5 -5
  86. package/src/editor/plugins/createWithUtils.ts +2 -2
  87. package/src/editor/plugins/with-plugins.ts +1 -1
  88. package/src/editor/sync-machine.ts +8 -5
  89. package/src/index.ts +5 -1
  90. package/src/selectors/index.ts +2 -0
  91. package/src/selectors/selector.get-selection-text.test.ts +75 -0
  92. package/src/selectors/selector.get-selection-text.ts +3 -3
  93. package/src/selectors/selector.get-text-before.ts +7 -4
  94. package/src/selectors/selector.is-point-after-selection.ts +82 -0
  95. package/src/selectors/selector.is-point-before-selection.ts +82 -0
  96. package/src/utils/_exports/index.ts +1 -0
  97. package/src/utils/index.ts +11 -0
  98. package/src/{editor/utils/utils.block-offset.test.ts → utils/util.block-offset.test.ts} +1 -1
  99. package/src/{editor/utils/utils.block-offset.ts → utils/util.block-offset.ts} +23 -7
  100. package/src/{editor/utils/utils.get-start-point.ts → utils/util.get-block-start-point.ts} +5 -2
  101. package/src/utils/util.get-text-block-text.ts +8 -0
  102. package/src/{editor/utils/utils.ts → utils/util.is-empty-text-block.ts} +4 -5
  103. package/src/{editor/utils/utils.is-keyed-segment.ts → utils/util.is-keyed-segment.ts} +3 -0
  104. package/src/{editor/utils/utils.reverse-selection.ts → utils/util.reverse-selection.ts} +4 -1
  105. /package/src/{utils → internal-utils}/__tests__/dmpToOperations.test.ts +0 -0
  106. /package/src/{utils → internal-utils}/__tests__/operationToPatches.test.ts +0 -0
  107. /package/src/{utils → internal-utils}/__tests__/patchToOperations.test.ts +0 -0
  108. /package/src/{utils → internal-utils}/__tests__/ranges.test.ts +0 -0
  109. /package/src/{utils → internal-utils}/__tests__/valueNormalization.test.tsx +0 -0
  110. /package/src/{utils → internal-utils}/__tests__/values.test.ts +0 -0
  111. /package/src/{utils → internal-utils}/applyPatch.ts +0 -0
  112. /package/src/{utils → internal-utils}/debug.ts +0 -0
  113. /package/src/{utils → internal-utils}/is-hotkey.test.ts +0 -0
  114. /package/src/{utils → internal-utils}/is-hotkey.ts +0 -0
  115. /package/src/{utils → internal-utils}/looks-like-url.test.ts +0 -0
  116. /package/src/{utils → internal-utils}/looks-like-url.ts +0 -0
  117. /package/src/{utils → internal-utils}/operationToPatches.ts +0 -0
  118. /package/src/{utils → internal-utils}/paths.ts +0 -0
  119. /package/src/{utils → internal-utils}/ranges.ts +0 -0
  120. /package/src/{utils → internal-utils}/schema.ts +0 -0
  121. /package/src/{utils → internal-utils}/selection.ts +0 -0
  122. /package/src/{utils → internal-utils}/sibling-utils.ts +0 -0
  123. /package/src/{utils → internal-utils}/validateValue.ts +0 -0
  124. /package/src/{utils → internal-utils}/values.ts +0 -0
  125. /package/src/{utils → internal-utils}/weakMaps.ts +0 -0
  126. /package/src/{utils → internal-utils}/withChanges.ts +0 -0
  127. /package/src/{utils → internal-utils}/withUndoRedo.ts +0 -0
  128. /package/src/{utils → internal-utils}/withoutPatching.ts +0 -0
@@ -5,8 +5,8 @@ import {
5
5
  useEffect,
6
6
  useState,
7
7
  } from 'react'
8
+ import {debugWithName} from '../../internal-utils/debug'
8
9
  import type {EditorSelection} from '../../types/editor'
9
- import {debugWithName} from '../../utils/debug'
10
10
  import type {EditorActor} from '../editor-machine'
11
11
 
12
12
  /**
@@ -2,9 +2,9 @@ import type {Patch} from '@portabletext/patches'
2
2
  import type {PortableTextBlock} from '@sanity/types'
3
3
  import {Editor} from 'slate'
4
4
  import {assign, emit, setup} from 'xstate'
5
+ import {fromSlateValue} from '../internal-utils/values'
6
+ import {KEY_TO_VALUE_ELEMENT} from '../internal-utils/weakMaps'
5
7
  import type {PortableTextSlateEditor} from '../types/editor'
6
- import {fromSlateValue} from '../utils/values'
7
- import {KEY_TO_VALUE_ELEMENT} from '../utils/weakMaps'
8
8
  import type {EditorSchema} from './define-schema'
9
9
 
10
10
  const FLUSH_PATCHES_THROTTLED_MS = process.env.NODE_ENV === 'test' ? 500 : 1000
@@ -1,7 +1,7 @@
1
1
  import {Editor} from 'slate'
2
- import {toPortableTextRange} from '../../utils/ranges'
3
- import {fromSlateValue} from '../../utils/values'
4
- import {KEY_TO_VALUE_ELEMENT} from '../../utils/weakMaps'
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
5
  import type {EditorActor} from '../editor-machine'
6
6
  import {isApplyingBehaviorActions} from '../with-applying-behavior-actions'
7
7
 
@@ -49,6 +49,14 @@ export function createWithEventListeners(
49
49
  })
50
50
  break
51
51
  }
52
+ case 'custom.*': {
53
+ editorActor.send({
54
+ type: 'custom behavior event',
55
+ behaviorEvent: event.event,
56
+ editor,
57
+ })
58
+ break
59
+ }
52
60
  case 'decorator.toggle': {
53
61
  editorActor.send({
54
62
  type: 'behavior event',
@@ -21,19 +21,19 @@ import {ReactEditor} from 'slate-react'
21
21
  import {isListItemActive} from '../../behavior-actions/behavior.action.list-item'
22
22
  import {isStyleActive} from '../../behavior-actions/behavior.action.style'
23
23
  import type {BehaviorActionImplementation} from '../../behavior-actions/behavior.actions'
24
+ import {debugWithName} from '../../internal-utils/debug'
25
+ import {toPortableTextRange, toSlateRange} from '../../internal-utils/ranges'
26
+ import {fromSlateValue, toSlateValue} from '../../internal-utils/values'
27
+ import {
28
+ KEY_TO_VALUE_ELEMENT,
29
+ SLATE_TO_PORTABLE_TEXT_RANGE,
30
+ } from '../../internal-utils/weakMaps'
24
31
  import type {
25
32
  EditableAPI,
26
33
  EditableAPIDeleteOptions,
27
34
  EditorSelection,
28
35
  PortableTextSlateEditor,
29
36
  } from '../../types/editor'
30
- import {debugWithName} from '../../utils/debug'
31
- import {toPortableTextRange, toSlateRange} from '../../utils/ranges'
32
- import {fromSlateValue, toSlateValue} from '../../utils/values'
33
- import {
34
- KEY_TO_VALUE_ELEMENT,
35
- SLATE_TO_PORTABLE_TEXT_RANGE,
36
- } from '../../utils/weakMaps'
37
37
  import type {EditorActor} from '../editor-machine'
38
38
  import {isDecoratorActive} from './createWithPortableTextMarkModel'
39
39
 
@@ -1,9 +1,9 @@
1
1
  import type {KeyboardEvent} from 'react'
2
2
  import type {ReactEditor} from 'slate-react'
3
+ import {debugWithName} from '../../internal-utils/debug'
4
+ import {isHotkey} from '../../internal-utils/is-hotkey'
3
5
  import type {PortableTextSlateEditor} from '../../types/editor'
4
6
  import type {HotkeyOptions} from '../../types/options'
5
- import {debugWithName} from '../../utils/debug'
6
- import {isHotkey} from '../../utils/is-hotkey'
7
7
  import type {EditorActor} from '../editor-machine'
8
8
  import type {PortableTextEditor} from '../PortableTextEditor'
9
9
 
@@ -3,17 +3,17 @@ 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'
5
5
  import {ReactEditor} from 'slate-react'
6
- import type {
7
- PortableTextMemberSchemaTypes,
8
- PortableTextSlateEditor,
9
- } from '../../types/editor'
10
- import {debugWithName} from '../../utils/debug'
11
- import {validateValue} from '../../utils/validateValue'
6
+ import {debugWithName} from '../../internal-utils/debug'
7
+ import {validateValue} from '../../internal-utils/validateValue'
12
8
  import {
13
9
  fromSlateValue,
14
10
  isEqualToEmptyEditor,
15
11
  toSlateValue,
16
- } from '../../utils/values'
12
+ } from '../../internal-utils/values'
13
+ import type {
14
+ PortableTextMemberSchemaTypes,
15
+ PortableTextSlateEditor,
16
+ } from '../../types/editor'
17
17
  import type {EditorActor} from '../editor-machine'
18
18
 
19
19
  const debug = debugWithName('plugin:withInsertData')
@@ -1,6 +1,6 @@
1
+ import {isChangingRemotely} from '../../internal-utils/withChanges'
2
+ import {isRedoing, isUndoing} from '../../internal-utils/withUndoRedo'
1
3
  import type {PortableTextSlateEditor} from '../../types/editor'
2
- import {isChangingRemotely} from '../../utils/withChanges'
3
- import {isRedoing, isUndoing} from '../../utils/withUndoRedo'
4
4
  import type {EditorActor} from '../editor-machine'
5
5
 
6
6
  /**
@@ -1,10 +1,10 @@
1
1
  import {Editor, Element, Node, Transforms} from 'slate'
2
+ import {isChangingRemotely} from '../../internal-utils/withChanges'
3
+ import {isRedoing, isUndoing} from '../../internal-utils/withUndoRedo'
2
4
  import type {
3
5
  PortableTextMemberSchemaTypes,
4
6
  PortableTextSlateEditor,
5
7
  } from '../../types/editor'
6
- import {isChangingRemotely} from '../../utils/withChanges'
7
- import {isRedoing, isUndoing} from '../../utils/withUndoRedo'
8
8
  import type {EditorActor} from '../editor-machine'
9
9
 
10
10
  /**
@@ -12,23 +12,23 @@ import {
12
12
  type SetNodeOperation,
13
13
  type SplitNodeOperation,
14
14
  } from 'slate'
15
- import type {
16
- PortableTextMemberSchemaTypes,
17
- PortableTextSlateEditor,
18
- } from '../../types/editor'
19
- import {createApplyPatch} from '../../utils/applyPatch'
20
- import {debugWithName} from '../../utils/debug'
21
- import {fromSlateValue, isEqualToEmptyEditor} from '../../utils/values'
15
+ import {createApplyPatch} from '../../internal-utils/applyPatch'
16
+ import {debugWithName} from '../../internal-utils/debug'
17
+ import {fromSlateValue, isEqualToEmptyEditor} from '../../internal-utils/values'
22
18
  import {
23
19
  IS_PROCESSING_REMOTE_CHANGES,
24
20
  KEY_TO_VALUE_ELEMENT,
25
- } from '../../utils/weakMaps'
26
- import {withRemoteChanges} from '../../utils/withChanges'
21
+ } from '../../internal-utils/weakMaps'
22
+ import {withRemoteChanges} from '../../internal-utils/withChanges'
27
23
  import {
28
24
  isPatching,
29
25
  PATCHING,
30
26
  withoutPatching,
31
- } from '../../utils/withoutPatching'
27
+ } from '../../internal-utils/withoutPatching'
28
+ import type {
29
+ PortableTextMemberSchemaTypes,
30
+ PortableTextSlateEditor,
31
+ } from '../../types/editor'
32
32
  import type {EditorActor} from '../editor-machine'
33
33
  import {withoutSaving} from './createWithUndoRedo'
34
34
 
@@ -1,9 +1,9 @@
1
1
  import {Editor, Path} from 'slate'
2
+ import {debugWithName} from '../../internal-utils/debug'
3
+ import {isChangingRemotely} from '../../internal-utils/withChanges'
4
+ import {isRedoing, isUndoing} from '../../internal-utils/withUndoRedo'
2
5
  import type {PortableTextSlateEditor} from '../../types/editor'
3
6
  import type {SlateTextBlock, VoidElement} from '../../types/slate'
4
- import {debugWithName} from '../../utils/debug'
5
- import {isChangingRemotely} from '../../utils/withChanges'
6
- import {isRedoing, isUndoing} from '../../utils/withUndoRedo'
7
7
  import type {EditorActor} from '../editor-machine'
8
8
 
9
9
  const debug = debugWithName('plugin:withPlaceholderBlock')
@@ -1,9 +1,9 @@
1
1
  import {Editor, Path, Text as SlateText, Transforms} from 'slate'
2
+ import {debugWithName} from '../../internal-utils/debug'
2
3
  import type {
3
4
  PortableTextMemberSchemaTypes,
4
5
  PortableTextSlateEditor,
5
6
  } from '../../types/editor'
6
- import {debugWithName} from '../../utils/debug'
7
7
  import type {EditorActor} from '../editor-machine'
8
8
 
9
9
  const debug = debugWithName('plugin:withPortableTextBlockStyle')
@@ -9,14 +9,14 @@ import type {PortableTextObject, PortableTextSpan} from '@sanity/types'
9
9
  import {isEqual, uniq} from 'lodash'
10
10
  import {Editor, Element, Node, Path, Range, Text, Transforms} from 'slate'
11
11
  import type {BehaviorActionImplementation} from '../../behavior-actions/behavior.actions'
12
+ import {debugWithName} from '../../internal-utils/debug'
13
+ import {getNextSpan, getPreviousSpan} from '../../internal-utils/sibling-utils'
14
+ import {isChangingRemotely} from '../../internal-utils/withChanges'
15
+ import {isRedoing, isUndoing} from '../../internal-utils/withUndoRedo'
12
16
  import type {
13
17
  PortableTextMemberSchemaTypes,
14
18
  PortableTextSlateEditor,
15
19
  } from '../../types/editor'
16
- import {debugWithName} from '../../utils/debug'
17
- import {getNextSpan, getPreviousSpan} from '../../utils/sibling-utils'
18
- import {isChangingRemotely} from '../../utils/withChanges'
19
- import {isRedoing, isUndoing} from '../../utils/withUndoRedo'
20
20
  import type {EditorActor} from '../editor-machine'
21
21
 
22
22
  const debug = debugWithName('plugin:withPortableTextMarkModel')
@@ -1,15 +1,15 @@
1
1
  import type {BaseRange} from 'slate'
2
+ import {debugWithName} from '../../internal-utils/debug'
3
+ import {
4
+ toPortableTextRange,
5
+ type ObjectWithKeyAndType,
6
+ } from '../../internal-utils/ranges'
7
+ import {SLATE_TO_PORTABLE_TEXT_RANGE} from '../../internal-utils/weakMaps'
2
8
  import type {
3
9
  EditorSelection,
4
10
  PortableTextMemberSchemaTypes,
5
11
  PortableTextSlateEditor,
6
12
  } from '../../types/editor'
7
- import {debugWithName} from '../../utils/debug'
8
- import {
9
- toPortableTextRange,
10
- type ObjectWithKeyAndType,
11
- } from '../../utils/ranges'
12
- import {SLATE_TO_PORTABLE_TEXT_RANGE} from '../../utils/weakMaps'
13
13
  import type {EditorActor} from '../editor-machine'
14
14
 
15
15
  const debug = debugWithName('plugin:withPortableTextSelections')
@@ -7,11 +7,11 @@ import {
7
7
  type PortableTextTextBlock,
8
8
  } from '@sanity/types'
9
9
  import {Transforms, type Element} from 'slate'
10
+ import {debugWithName} from '../../internal-utils/debug'
10
11
  import type {
11
12
  PortableTextMemberSchemaTypes,
12
13
  PortableTextSlateEditor,
13
14
  } from '../../types/editor'
14
- import {debugWithName} from '../../utils/debug'
15
15
  import type {EditorActor} from '../editor-machine'
16
16
 
17
17
  const debug = debugWithName('plugin:withSchemaTypes')
@@ -20,10 +20,9 @@ import {
20
20
  type Descendant,
21
21
  type SelectionOperation,
22
22
  } from 'slate'
23
- import type {PortableTextSlateEditor} from '../../types/editor'
24
- import {debugWithName} from '../../utils/debug'
25
- import {fromSlateValue} from '../../utils/values'
26
- import {isChangingRemotely} from '../../utils/withChanges'
23
+ import {debugWithName} from '../../internal-utils/debug'
24
+ import {fromSlateValue} from '../../internal-utils/values'
25
+ import {isChangingRemotely} from '../../internal-utils/withChanges'
27
26
  import {
28
27
  isRedoing,
29
28
  isUndoing,
@@ -31,7 +30,8 @@ import {
31
30
  setIsUndoing,
32
31
  withRedoing,
33
32
  withUndoing,
34
- } from '../../utils/withUndoRedo'
33
+ } from '../../internal-utils/withUndoRedo'
34
+ import type {PortableTextSlateEditor} from '../../types/editor'
35
35
  import type {EditorActor} from '../editor-machine'
36
36
 
37
37
  const debug = debugWithName('plugin:withUndoRedo')
@@ -1,10 +1,10 @@
1
1
  import {Editor, Range, Text, Transforms} from 'slate'
2
+ import {debugWithName} from '../../internal-utils/debug'
3
+ import {toSlateValue} from '../../internal-utils/values'
2
4
  import type {
3
5
  PortableTextMemberSchemaTypes,
4
6
  PortableTextSlateEditor,
5
7
  } from '../../types/editor'
6
- import {debugWithName} from '../../utils/debug'
7
- import {toSlateValue} from '../../utils/values'
8
8
  import type {EditorActor} from '../editor-machine'
9
9
 
10
10
  const debug = debugWithName('plugin:withUtils')
@@ -1,6 +1,6 @@
1
1
  import type {BaseOperation, Editor, Node, NodeEntry} from 'slate'
2
+ import {createOperationToPatches} from '../../internal-utils/operationToPatches'
2
3
  import type {PortableTextSlateEditor} from '../../types/editor'
3
- import {createOperationToPatches} from '../../utils/operationToPatches'
4
4
  import type {EditorActor} from '../editor-machine'
5
5
  import {createWithEventListeners} from './create-with-event-listeners'
6
6
  import {createWithMaxBlocks} from './createWithMaxBlocks'
@@ -11,16 +11,19 @@ import {
11
11
  type AnyEventObject,
12
12
  type CallbackLogicFunction,
13
13
  } from 'xstate'
14
+ import {debugWithName} from '../internal-utils/debug'
15
+ import {validateValue} from '../internal-utils/validateValue'
16
+ import {toSlateValue, VOID_CHILD_KEY} from '../internal-utils/values'
17
+ import {
18
+ isChangingRemotely,
19
+ withRemoteChanges,
20
+ } from '../internal-utils/withChanges'
21
+ import {withoutPatching} from '../internal-utils/withoutPatching'
14
22
  import type {PickFromUnion} from '../type-utils'
15
23
  import type {
16
24
  InvalidValueResolution,
17
25
  PortableTextSlateEditor,
18
26
  } from '../types/editor'
19
- import {debugWithName} from '../utils/debug'
20
- import {validateValue} from '../utils/validateValue'
21
- import {toSlateValue, VOID_CHILD_KEY} from '../utils/values'
22
- import {isChangingRemotely, withRemoteChanges} from '../utils/withChanges'
23
- import {withoutPatching} from '../utils/withoutPatching'
24
27
  import type {EditorSchema} from './define-schema'
25
28
  import {withoutSaving} from './plugins/createWithUndoRedo'
26
29
 
package/src/index.ts CHANGED
@@ -1,5 +1,9 @@
1
1
  export type {Patch} from '@portabletext/patches'
2
- export type {PortableTextBlock, PortableTextChild} from '@sanity/types'
2
+ export type {
3
+ PortableTextBlock,
4
+ PortableTextChild,
5
+ PortableTextSpan,
6
+ } from '@sanity/types'
3
7
  export type {
4
8
  Behavior,
5
9
  BehaviorActionIntend,
@@ -16,6 +16,8 @@ export {isActiveAnnotation} from './selector.is-active-annotation'
16
16
  export {isActiveDecorator} from './selector.is-active-decorator'
17
17
  export {isActiveListItem} from './selector.is-active-list-item'
18
18
  export {isActiveStyle} from './selector.is-active-style'
19
+ export {isPointAfterSelection} from './selector.is-point-after-selection'
20
+ export {isPointBeforeSelection} from './selector.is-point-before-selection'
19
21
  export {isSelectionCollapsed} from './selector.is-selection-collapsed'
20
22
  export {isSelectionExpanded} from './selector.is-selection-expanded'
21
23
  export * from './selectors'
@@ -0,0 +1,75 @@
1
+ import {expect, test} from 'vitest'
2
+ import type {EditorSchema, EditorSelection, EditorSnapshot} from '.'
3
+ import {getSelectionText} from './selector.get-selection-text'
4
+
5
+ test(getSelectionText.name, () => {
6
+ function snapshot(selection: EditorSelection): EditorSnapshot {
7
+ return {
8
+ context: {
9
+ schema: {} as EditorSchema,
10
+ keyGenerator: () => '',
11
+ activeDecorators: [],
12
+ value: [
13
+ {
14
+ _type: 'block',
15
+ _key: 'e0-k8',
16
+ style: 'normal',
17
+ markDefs: [],
18
+ children: [
19
+ {
20
+ _type: 'span',
21
+ _key: 'e0-k7',
22
+ text: ':b',
23
+ marks: [],
24
+ },
25
+ {
26
+ text: 'a',
27
+ _type: 'span',
28
+ _key: 'e0-k9',
29
+ marks: ['strong'],
30
+ },
31
+ {
32
+ text: 'r',
33
+ marks: [],
34
+ _type: 'span',
35
+ _key: 'e0-k10',
36
+ },
37
+ ],
38
+ },
39
+ ],
40
+ selection,
41
+ },
42
+ }
43
+ }
44
+
45
+ expect(
46
+ getSelectionText(
47
+ snapshot({
48
+ anchor: {
49
+ path: [
50
+ {
51
+ _key: 'e0-k8',
52
+ },
53
+ 'children',
54
+ {
55
+ _key: 'e0-k7',
56
+ },
57
+ ],
58
+ offset: 0,
59
+ },
60
+ focus: {
61
+ path: [
62
+ {
63
+ _key: 'e0-k8',
64
+ },
65
+ 'children',
66
+ {
67
+ _key: 'e0-k10',
68
+ },
69
+ ],
70
+ offset: 1,
71
+ },
72
+ }),
73
+ ),
74
+ ).toBe(':bar')
75
+ })
@@ -1,7 +1,7 @@
1
1
  import {isPortableTextSpan, isPortableTextTextBlock} from '@sanity/types'
2
2
  import type {EditorSelector} from '../editor/editor-selector'
3
- import {isKeyedSegment} from '../editor/utils/utils.is-keyed-segment'
4
- import {reverseSelection} from '../editor/utils/utils.reverse-selection'
3
+ import {isKeyedSegment} from '../utils/util.is-keyed-segment'
4
+ import {reverseSelection} from '../utils/util.reverse-selection'
5
5
 
6
6
  /**
7
7
  * @public
@@ -70,7 +70,7 @@ export const getSelectionText: EditorSelector<string> = ({context}) => {
70
70
  }
71
71
 
72
72
  if (text.length > 0) {
73
- text + child.text
73
+ text = text + child.text
74
74
  }
75
75
  }
76
76
  }
@@ -1,7 +1,7 @@
1
1
  import type {EditorSelector} from '../editor/editor-selector'
2
- import {getStartPoint} from '../editor/utils/utils.get-start-point'
3
- import {isKeyedSegment} from '../editor/utils/utils.is-keyed-segment'
4
- import {reverseSelection} from '../editor/utils/utils.reverse-selection'
2
+ import {getBlockStartPoint} from '../utils/util.get-block-start-point'
3
+ import {isKeyedSegment} from '../utils/util.is-keyed-segment'
4
+ import {reverseSelection} from '../utils/util.reverse-selection'
5
5
  import {getSelectionText} from './selector.get-selection-text'
6
6
 
7
7
  /**
@@ -26,7 +26,10 @@ export const getBlockTextBefore: EditorSelector<string> = ({context}) => {
26
26
  return ''
27
27
  }
28
28
 
29
- const startOfBlock = getStartPoint({node: block, path: [{_key: block._key}]})
29
+ const startOfBlock = getBlockStartPoint({
30
+ node: block,
31
+ path: [{_key: block._key}],
32
+ })
30
33
 
31
34
  return getSelectionText({
32
35
  context: {
@@ -0,0 +1,82 @@
1
+ import {isKeySegment, isPortableTextTextBlock} from '@sanity/types'
2
+ import type {EditorSelector} from '../editor/editor-selector'
3
+ import type {EditorSelectionPoint} from '../types/editor'
4
+ import {reverseSelection} from '../utils/util.reverse-selection'
5
+
6
+ /**
7
+ * @public
8
+ */
9
+ export function isPointAfterSelection(
10
+ point: EditorSelectionPoint,
11
+ ): EditorSelector<boolean> {
12
+ return (snapshot) => {
13
+ if (!snapshot.context.selection) {
14
+ return false
15
+ }
16
+
17
+ const selection = reverseSelection(snapshot.context.selection)
18
+
19
+ const pointBlockKey = isKeySegment(point.path[0])
20
+ ? point.path[0]._key
21
+ : undefined
22
+ const pointChildKey = isKeySegment(point.path[2])
23
+ ? point.path[2]._key
24
+ : undefined
25
+
26
+ const endBlockKey = isKeySegment(selection.focus.path[0])
27
+ ? selection.focus.path[0]._key
28
+ : undefined
29
+ const endChildKey = isKeySegment(selection.focus.path[2])
30
+ ? selection.focus.path[2]._key
31
+ : undefined
32
+
33
+ if (!pointBlockKey || !endBlockKey) {
34
+ return false
35
+ }
36
+
37
+ let after = false
38
+
39
+ for (const block of snapshot.context.value) {
40
+ if (block._key === endBlockKey) {
41
+ if (block._key !== pointBlockKey) {
42
+ after = true
43
+ break
44
+ }
45
+
46
+ // Both the point and the selection end in this block
47
+
48
+ if (!isPortableTextTextBlock(block)) {
49
+ break
50
+ }
51
+
52
+ if (!pointChildKey || !endChildKey) {
53
+ break
54
+ }
55
+
56
+ for (const child of block.children) {
57
+ if (child._key === endChildKey) {
58
+ if (child._key !== pointChildKey) {
59
+ after = true
60
+ break
61
+ }
62
+
63
+ // Both the point and the selection end in this child
64
+
65
+ after = point.offset > selection.focus.offset
66
+ break
67
+ }
68
+
69
+ if (child._key === pointChildKey) {
70
+ break
71
+ }
72
+ }
73
+ }
74
+
75
+ if (block._key === pointBlockKey) {
76
+ break
77
+ }
78
+ }
79
+
80
+ return after
81
+ }
82
+ }
@@ -0,0 +1,82 @@
1
+ import {isKeySegment, isPortableTextTextBlock} from '@sanity/types'
2
+ import type {EditorSelector} from '../editor/editor-selector'
3
+ import type {EditorSelectionPoint} from '../types/editor'
4
+ import {reverseSelection} from '../utils/util.reverse-selection'
5
+
6
+ /**
7
+ * @public
8
+ */
9
+ export function isPointBeforeSelection(
10
+ point: EditorSelectionPoint,
11
+ ): EditorSelector<boolean> {
12
+ return (snapshot) => {
13
+ if (!snapshot.context.selection) {
14
+ return false
15
+ }
16
+
17
+ const selection = reverseSelection(snapshot.context.selection)
18
+
19
+ const pointBlockKey = isKeySegment(point.path[0])
20
+ ? point.path[0]._key
21
+ : undefined
22
+ const pointChildKey = isKeySegment(point.path[2])
23
+ ? point.path[2]._key
24
+ : undefined
25
+
26
+ const startBlockKey = isKeySegment(selection.anchor.path[0])
27
+ ? selection.anchor.path[0]._key
28
+ : undefined
29
+ const startChildKey = isKeySegment(selection.anchor.path[2])
30
+ ? selection.anchor.path[2]._key
31
+ : undefined
32
+
33
+ if (!pointBlockKey || !startBlockKey) {
34
+ return false
35
+ }
36
+
37
+ let before = false
38
+
39
+ for (const block of snapshot.context.value) {
40
+ if (block._key === pointBlockKey) {
41
+ if (block._key !== startBlockKey) {
42
+ before = true
43
+ break
44
+ }
45
+
46
+ // Both the point and the selection start in this block
47
+
48
+ if (!isPortableTextTextBlock(block)) {
49
+ break
50
+ }
51
+
52
+ if (!pointChildKey || !startChildKey) {
53
+ break
54
+ }
55
+
56
+ for (const child of block.children) {
57
+ if (child._key === pointChildKey) {
58
+ if (child._key !== startChildKey) {
59
+ before = true
60
+ break
61
+ }
62
+
63
+ // Both the point and the selection start in this child
64
+
65
+ before = point.offset < selection.anchor.offset
66
+ break
67
+ }
68
+
69
+ if (child._key === startChildKey) {
70
+ break
71
+ }
72
+ }
73
+ }
74
+
75
+ if (block._key === startBlockKey) {
76
+ break
77
+ }
78
+ }
79
+
80
+ return before
81
+ }
82
+ }
@@ -0,0 +1 @@
1
+ export * from '../index'
@@ -0,0 +1,11 @@
1
+ export type {BlockOffset} from '../behaviors/behavior.types'
2
+ export type {EditorSelection, EditorSelectionPoint} from '../types/editor'
3
+ export {
4
+ blockOffsetToSpanSelectionPoint,
5
+ spanSelectionPointToBlockOffset,
6
+ } from './util.block-offset'
7
+ export {getBlockStartPoint} from './util.get-block-start-point'
8
+ export {getTextBlockText} from './util.get-text-block-text'
9
+ export {isEmptyTextBlock} from './util.is-empty-text-block'
10
+ export {isKeyedSegment} from './util.is-keyed-segment'
11
+ export {reverseSelection} from './util.reverse-selection'
@@ -1,6 +1,6 @@
1
1
  import type {PortableTextBlock} from '@sanity/types'
2
2
  import {expect, test} from 'vitest'
3
- import {blockOffsetToSpanSelectionPoint} from './utils.block-offset'
3
+ import {blockOffsetToSpanSelectionPoint} from './util.block-offset'
4
4
 
5
5
  test(blockOffsetToSpanSelectionPoint.name, () => {
6
6
  const value: Array<PortableTextBlock> = [