@portabletext/editor 1.44.1 → 1.44.3

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 (60) hide show
  1. package/lib/_chunks-cjs/behavior.core.cjs +3 -3
  2. package/lib/_chunks-cjs/behavior.core.cjs.map +1 -1
  3. package/lib/_chunks-cjs/editor-provider.cjs +315 -368
  4. package/lib/_chunks-cjs/editor-provider.cjs.map +1 -1
  5. package/lib/_chunks-es/behavior.core.js +3 -3
  6. package/lib/_chunks-es/behavior.core.js.map +1 -1
  7. package/lib/_chunks-es/editor-provider.js +317 -370
  8. package/lib/_chunks-es/editor-provider.js.map +1 -1
  9. package/lib/behaviors/index.cjs +2 -2
  10. package/lib/behaviors/index.cjs.map +1 -1
  11. package/lib/behaviors/index.d.cts +7951 -15846
  12. package/lib/behaviors/index.d.ts +7951 -15846
  13. package/lib/behaviors/index.js +4 -4
  14. package/lib/behaviors/index.js.map +1 -1
  15. package/lib/index.cjs +19 -7
  16. package/lib/index.cjs.map +1 -1
  17. package/lib/index.d.cts +1742 -15478
  18. package/lib/index.d.ts +1742 -15478
  19. package/lib/index.js +20 -8
  20. package/lib/index.js.map +1 -1
  21. package/lib/plugins/index.d.cts +1742 -15479
  22. package/lib/plugins/index.d.ts +1742 -15479
  23. package/lib/selectors/index.d.cts +1739 -15475
  24. package/lib/selectors/index.d.ts +1739 -15475
  25. package/lib/utils/index.d.cts +1739 -15475
  26. package/lib/utils/index.d.ts +1739 -15475
  27. package/package.json +9 -9
  28. package/src/behavior-actions/behavior.action.decorator.add.ts +7 -2
  29. package/src/behavior-actions/behavior.actions.ts +0 -18
  30. package/src/behaviors/{behavior.internal.annotation.ts → behavior.abstract.annotation.ts} +1 -1
  31. package/src/behaviors/{behavior.internal.decorator.ts → behavior.abstract.decorator.ts} +1 -1
  32. package/src/behaviors/{behavior.internal.insert.ts → behavior.abstract.insert.ts} +1 -1
  33. package/src/behaviors/{behavior.internal.list-item.ts → behavior.abstract.list-item.ts} +1 -1
  34. package/src/behaviors/behavior.abstract.move.ts +78 -0
  35. package/src/behaviors/{behavior.internal.select.ts → behavior.abstract.select.ts} +1 -1
  36. package/src/behaviors/{behavior.internal.style.ts → behavior.abstract.style.ts} +1 -1
  37. package/src/behaviors/behavior.code-editor.ts +13 -8
  38. package/src/behaviors/behavior.default.ts +14 -12
  39. package/src/behaviors/behavior.perform-event.ts +4 -4
  40. package/src/behaviors/behavior.types.action.ts +3 -3
  41. package/src/behaviors/behavior.types.behavior.ts +4 -3
  42. package/src/behaviors/behavior.types.event.ts +153 -153
  43. package/src/editor/Editable.tsx +17 -17
  44. package/src/editor/components/Leaf.tsx +2 -2
  45. package/src/editor/create-editor.ts +37 -11
  46. package/src/editor/editor-machine.ts +4 -76
  47. package/src/editor/editor-selector.ts +5 -2
  48. package/src/editor/editor-snapshot.ts +10 -9
  49. package/src/editor/plugins/create-with-event-listeners.ts +6 -75
  50. package/src/editor/plugins/createWithEditableAPI.ts +32 -44
  51. package/src/editor/plugins/createWithPortableTextSelections.ts +8 -13
  52. package/src/editor/plugins/with-plugins.ts +3 -8
  53. package/src/internal-utils/event-position.ts +10 -7
  54. package/src/internal-utils/paths.ts +1 -37
  55. package/src/internal-utils/ranges.ts +3 -37
  56. package/src/internal-utils/slate-children-to-blocks.ts +49 -0
  57. package/src/internal-utils/slate-utils.ts +108 -9
  58. package/src/type-utils.ts +2 -0
  59. package/src/behavior-actions/behavior.action.move.block-down.ts +0 -48
  60. package/src/behavior-actions/behavior.action.move.block-up.ts +0 -53
@@ -1,42 +1,6 @@
1
1
  import {isKeySegment, type Path} from '@sanity/types'
2
2
  import {isEqual} from 'lodash'
3
- import {
4
- Editor,
5
- Element,
6
- type Descendant,
7
- type Point,
8
- type Path as SlatePath,
9
- } from 'slate'
10
- import type {PortableTextMemberSchemaTypes} from '../types/editor'
11
- import type {ObjectWithKeyAndType} from './ranges'
12
-
13
- export function createKeyedPath(
14
- point: Point,
15
- value: ObjectWithKeyAndType[] | undefined,
16
- types: PortableTextMemberSchemaTypes,
17
- ): Path | null {
18
- const blockPath = [point.path[0]]
19
- if (!value) {
20
- return null
21
- }
22
- const block = value[blockPath[0]]
23
- if (!block) {
24
- return null
25
- }
26
- const keyedBlockPath = [{_key: block._key}]
27
- if (block._type !== types.block.name) {
28
- return keyedBlockPath as Path
29
- }
30
- let keyedChildPath: Path | undefined
31
- const childPath = point.path.slice(0, 2)
32
- const child = Array.isArray(block.children) && block.children[childPath[1]]
33
- if (child) {
34
- keyedChildPath = ['children', {_key: child._key}]
35
- }
36
- return (
37
- keyedChildPath ? [...keyedBlockPath, ...keyedChildPath] : keyedBlockPath
38
- ) as Path
39
- }
3
+ import {Editor, Element, type Descendant, type Path as SlatePath} from 'slate'
40
4
 
41
5
  export function toSlatePath(path: Path, editor: Editor): SlatePath {
42
6
  if (!editor) {
@@ -1,10 +1,6 @@
1
- import {Point, Range, type BaseRange, type Editor, type Operation} from 'slate'
2
- import type {
3
- EditorSelection,
4
- EditorSelectionPoint,
5
- PortableTextMemberSchemaTypes,
6
- } from '../types/editor'
7
- import {createKeyedPath, toSlatePath} from './paths'
1
+ import {Point, type Editor, type Operation, type Range} from 'slate'
2
+ import type {EditorSelection} from '../types/editor'
3
+ import {toSlatePath} from './paths'
8
4
 
9
5
  export interface ObjectWithKeyAndType {
10
6
  _key: string
@@ -12,36 +8,6 @@ export interface ObjectWithKeyAndType {
12
8
  children?: ObjectWithKeyAndType[]
13
9
  }
14
10
 
15
- export function toPortableTextRange(
16
- value: ObjectWithKeyAndType[] | undefined,
17
- range: BaseRange | Partial<BaseRange> | null,
18
- types: PortableTextMemberSchemaTypes,
19
- ): EditorSelection {
20
- if (!range) {
21
- return null
22
- }
23
- let anchor: EditorSelectionPoint | null = null
24
- let focus: EditorSelectionPoint | null = null
25
- const anchorPath = range.anchor && createKeyedPath(range.anchor, value, types)
26
- if (anchorPath && range.anchor) {
27
- anchor = {
28
- path: anchorPath,
29
- offset: range.anchor.offset,
30
- }
31
- }
32
- const focusPath = range.focus && createKeyedPath(range.focus, value, types)
33
- if (focusPath && range.focus) {
34
- focus = {
35
- path: focusPath,
36
- offset: range.focus.offset,
37
- }
38
- }
39
- const backward = Boolean(
40
- Range.isRange(range) ? Range.isBackward(range) : undefined,
41
- )
42
- return anchor && focus ? {anchor, focus, backward} : null
43
- }
44
-
45
11
  export function toSlateRange(
46
12
  selection: EditorSelection,
47
13
  editor: Editor,
@@ -0,0 +1,49 @@
1
+ import type {PortableTextBlock} from '@sanity/types'
2
+ import type {Descendant} from 'slate'
3
+ import type {EditorSchema} from '../editor/define-schema'
4
+
5
+ export function slateChildrenToBlocks(
6
+ schema: EditorSchema,
7
+ value: Array<Descendant>,
8
+ ): Array<PortableTextBlock> {
9
+ const blocks: Array<PortableTextBlock> = new Array(value.length)
10
+
11
+ for (let blockIndex = 0; blockIndex < value.length; blockIndex++) {
12
+ const descendant = value[blockIndex]
13
+
14
+ if (descendant._type !== schema.block.name) {
15
+ blocks[blockIndex] = {
16
+ _key: descendant._key,
17
+ _type: descendant._type,
18
+ ...('value' in descendant && typeof descendant.value === 'object'
19
+ ? descendant.value
20
+ : {}),
21
+ }
22
+ continue
23
+ }
24
+
25
+ const children = 'children' in descendant ? descendant.children : []
26
+ const processedChildren = new Array(children.length)
27
+
28
+ for (let childIndex = 0; childIndex < children.length; childIndex++) {
29
+ const child = children[childIndex]
30
+ processedChildren[childIndex] =
31
+ child._type === schema.span.name
32
+ ? child
33
+ : {
34
+ _key: child._key,
35
+ _type: child._type,
36
+ ...('value' in child && typeof child.value === 'object'
37
+ ? child.value
38
+ : {}),
39
+ }
40
+ }
41
+
42
+ blocks[blockIndex] = {
43
+ ...descendant,
44
+ children: processedChildren,
45
+ }
46
+ }
47
+
48
+ return blocks
49
+ }
@@ -1,6 +1,6 @@
1
- import {Editor, Element, Node, type Path} from 'slate'
1
+ import {Editor, Element, Node, Range, type Path, type Point} from 'slate'
2
2
  import type {EditorSchema} from '../editor/define-schema'
3
- import type {PortableTextSlateEditor} from '../types/editor'
3
+ import type {EditorSelection, PortableTextSlateEditor} from '../types/editor'
4
4
  import {fromSlateValue} from './values'
5
5
 
6
6
  export function getFocusBlock({
@@ -12,14 +12,26 @@ export function getFocusBlock({
12
12
  return [undefined, undefined]
13
13
  }
14
14
 
15
- const focusBlock = Array.from(
16
- Editor.nodes(editor, {
17
- at: editor.selection.focus.path.slice(0, 1),
18
- match: (n) => !Editor.isEditor(n),
19
- }),
20
- ).at(0)
15
+ return (
16
+ Editor.node(editor, editor.selection.focus.path.slice(0, 1)) ?? [
17
+ undefined,
18
+ undefined,
19
+ ]
20
+ )
21
+ }
21
22
 
22
- return focusBlock ?? [undefined, undefined]
23
+ function getPointBlock({
24
+ editor,
25
+ point,
26
+ }: {
27
+ editor: PortableTextSlateEditor
28
+ point: Point
29
+ }): [node: Node, path: Path] | [undefined, undefined] {
30
+ const [block] = Editor.node(editor, point.path.slice(0, 1)) ?? [
31
+ undefined,
32
+ undefined,
33
+ ]
34
+ return block ? [block, point.path] : [undefined, undefined]
23
35
  }
24
36
 
25
37
  export function getFocusChild({
@@ -41,6 +53,31 @@ export function getFocusChild({
41
53
  : [undefined, undefined]
42
54
  }
43
55
 
56
+ function getPointChild({
57
+ editor,
58
+ point,
59
+ }: {
60
+ editor: PortableTextSlateEditor
61
+ point: Point
62
+ }): [node: Node, path: Path] | [undefined, undefined] {
63
+ const [block, blockPath] = getPointBlock({editor, point})
64
+ const childIndex = point.path.at(1)
65
+
66
+ if (!block || !blockPath || childIndex === undefined) {
67
+ return [undefined, undefined]
68
+ }
69
+
70
+ try {
71
+ const pointChild = Node.child(block, childIndex)
72
+
73
+ return pointChild
74
+ ? [pointChild, [...blockPath, childIndex]]
75
+ : [undefined, undefined]
76
+ } catch {
77
+ return [undefined, undefined]
78
+ }
79
+ }
80
+
44
81
  export function getFirstBlock({
45
82
  editor,
46
83
  }: {
@@ -178,3 +215,65 @@ export function isStyleActive({
178
215
 
179
216
  return false
180
217
  }
218
+
219
+ export function slateRangeToSelection({
220
+ schema,
221
+ editor,
222
+ range,
223
+ }: {
224
+ schema: EditorSchema
225
+ editor: PortableTextSlateEditor
226
+ range: Range
227
+ }): EditorSelection {
228
+ const [anchorBlock] = getPointBlock({
229
+ editor,
230
+ point: range.anchor,
231
+ })
232
+ const [focusBlock] = getPointBlock({
233
+ editor,
234
+ point: range.focus,
235
+ })
236
+
237
+ if (!anchorBlock || !focusBlock) {
238
+ return null
239
+ }
240
+
241
+ const [anchorChild] =
242
+ anchorBlock._type === schema.block.name
243
+ ? getPointChild({
244
+ editor,
245
+ point: range.anchor,
246
+ })
247
+ : [undefined, undefined]
248
+ const [focusChild] =
249
+ focusBlock._type === schema.block.name
250
+ ? getPointChild({
251
+ editor,
252
+ point: range.focus,
253
+ })
254
+ : [undefined, undefined]
255
+
256
+ const selection: EditorSelection = {
257
+ anchor: {
258
+ path: [{_key: anchorBlock._key}],
259
+ offset: range.anchor.offset,
260
+ },
261
+ focus: {
262
+ path: [{_key: focusBlock._key}],
263
+ offset: range.focus.offset,
264
+ },
265
+ backward: Range.isBackward(range),
266
+ }
267
+
268
+ if (anchorChild) {
269
+ selection.anchor.path.push('children')
270
+ selection.anchor.path.push({_key: anchorChild._key})
271
+ }
272
+
273
+ if (focusChild) {
274
+ selection.focus.path.push('children')
275
+ selection.focus.path.push({_key: focusChild._key})
276
+ }
277
+
278
+ return selection
279
+ }
package/src/type-utils.ts CHANGED
@@ -25,3 +25,5 @@ export type NamespaceEvent<TEvent, TNamespace extends string> = TEvent extends {
25
25
  : TEvent[K]
26
26
  }
27
27
  : never
28
+
29
+ export type StrictExtract<T, U extends T> = U
@@ -1,48 +0,0 @@
1
- import {Path} from 'slate'
2
- import {toSlatePath} from '../internal-utils/paths'
3
- import {toPortableTextRange} from '../internal-utils/ranges'
4
- import {isKeyedSegment} from '../utils'
5
- import {moveBlockActionImplementation} from './behavior.action.move.block'
6
- import type {BehaviorActionImplementation} from './behavior.actions'
7
-
8
- export const moveBlockDownActionImplementation: BehaviorActionImplementation<
9
- 'move.block down'
10
- > = ({context, action}) => {
11
- const at = [toSlatePath(action.at, action.editor)[0]]
12
- const to = [Path.next(at)[0]]
13
- const selection = toPortableTextRange(
14
- action.editor.children,
15
- {
16
- anchor: {
17
- path: to,
18
- offset: 0,
19
- },
20
- focus: {
21
- path: to,
22
- offset: 0,
23
- },
24
- },
25
- context.schema,
26
- )
27
-
28
- const destinationBlockKey = selection
29
- ? isKeyedSegment(selection.focus.path[0])
30
- ? selection.focus.path[0]._key
31
- : undefined
32
- : undefined
33
-
34
- if (destinationBlockKey === undefined) {
35
- console.error('Could not find destination block key')
36
- return
37
- }
38
-
39
- moveBlockActionImplementation({
40
- context,
41
- action: {
42
- type: 'move.block',
43
- at: action.at,
44
- to: [{_key: destinationBlockKey}],
45
- editor: action.editor,
46
- },
47
- })
48
- }
@@ -1,53 +0,0 @@
1
- import {Path} from 'slate'
2
- import {toSlatePath} from '../internal-utils/paths'
3
- import {toPortableTextRange} from '../internal-utils/ranges'
4
- import {isKeyedSegment} from '../utils'
5
- import {moveBlockActionImplementation} from './behavior.action.move.block'
6
- import type {BehaviorActionImplementation} from './behavior.actions'
7
-
8
- export const moveBlockUpActionImplementation: BehaviorActionImplementation<
9
- 'move.block up'
10
- > = ({context, action}) => {
11
- const at = [toSlatePath(action.at, action.editor)[0]]
12
-
13
- if (!Path.hasPrevious(at)) {
14
- return
15
- }
16
-
17
- const to = [Path.previous(at)[0]]
18
- const selection = toPortableTextRange(
19
- action.editor.children,
20
- {
21
- anchor: {
22
- path: to,
23
- offset: 0,
24
- },
25
- focus: {
26
- path: to,
27
- offset: 0,
28
- },
29
- },
30
- context.schema,
31
- )
32
-
33
- const destinationBlockKey = selection
34
- ? isKeyedSegment(selection.focus.path[0])
35
- ? selection.focus.path[0]._key
36
- : undefined
37
- : undefined
38
-
39
- if (destinationBlockKey === undefined) {
40
- console.error('Could not find destination block key')
41
- return
42
- }
43
-
44
- moveBlockActionImplementation({
45
- context,
46
- action: {
47
- type: 'move.block',
48
- at: action.at,
49
- to: [{_key: destinationBlockKey}],
50
- editor: action.editor,
51
- },
52
- })
53
- }