@portabletext/editor 2.14.2 → 2.14.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.
@@ -1,5 +1,5 @@
1
1
  import { Behavior, Editor, EditorEmittedEvent, EditorSchema } from "../_chunks-dts/behavior.types.action.js";
2
- import * as react22 from "react";
2
+ import * as react21 from "react";
3
3
  import React from "react";
4
4
  /**
5
5
  * @beta
@@ -181,7 +181,7 @@ type MarkdownPluginConfig = MarkdownBehaviorsConfig & {
181
181
  */
182
182
  declare function MarkdownPlugin(props: {
183
183
  config: MarkdownPluginConfig;
184
- }): react22.JSX.Element;
184
+ }): react21.JSX.Element;
185
185
  /**
186
186
  * @beta
187
187
  * Restrict the editor to one line. The plugin takes care of blocking
@@ -192,5 +192,5 @@ declare function MarkdownPlugin(props: {
192
192
  *
193
193
  * @deprecated Install the plugin from `@portabletext/plugin-one-line`
194
194
  */
195
- declare function OneLinePlugin(): react22.JSX.Element;
195
+ declare function OneLinePlugin(): react21.JSX.Element;
196
196
  export { BehaviorPlugin, DecoratorShortcutPlugin, EditorRefPlugin, EventListenerPlugin, MarkdownPlugin, MarkdownPluginConfig, OneLinePlugin };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@portabletext/editor",
3
- "version": "2.14.2",
3
+ "version": "2.14.3",
4
4
  "description": "Portable Text Editor made in React",
5
5
  "keywords": [
6
6
  "sanity",
@@ -24,7 +24,7 @@ import {
24
24
  import type {ActorRefFrom} from 'xstate'
25
25
  import {debugWithName} from '../internal-utils/debug'
26
26
  import {validateValue} from '../internal-utils/validateValue'
27
- import {toSlateValue, VOID_CHILD_KEY} from '../internal-utils/values'
27
+ import {toSlateBlock, VOID_CHILD_KEY} from '../internal-utils/values'
28
28
  import type {PickFromUnion} from '../type-utils'
29
29
  import type {
30
30
  InvalidValueResolution,
@@ -467,10 +467,6 @@ async function updateValue({
467
467
  }
468
468
  // Remove, replace or add nodes according to what is changed.
469
469
  if (value && value.length > 0) {
470
- const slateValueFromProps = toSlateValue(value, {
471
- schemaTypes: context.schema,
472
- })
473
-
474
470
  if (streamBlocks) {
475
471
  await new Promise<void>((resolve) => {
476
472
  Editor.withoutNormalizing(slateEditor, () => {
@@ -483,7 +479,7 @@ async function updateValue({
483
479
 
484
480
  isChanged = removeExtraBlocks({
485
481
  slateEditor,
486
- slateValueFromProps,
482
+ value,
487
483
  })
488
484
 
489
485
  const processBlocks = async () => {
@@ -491,7 +487,7 @@ async function updateValue({
491
487
  currentBlock,
492
488
  currentBlockIndex,
493
489
  ] of getStreamedBlocks({
494
- slateValue: slateValueFromProps,
490
+ value,
495
491
  })) {
496
492
  const {blockChanged, blockValid} = syncBlock({
497
493
  context,
@@ -528,12 +524,12 @@ async function updateValue({
528
524
 
529
525
  isChanged = removeExtraBlocks({
530
526
  slateEditor,
531
- slateValueFromProps,
527
+ value,
532
528
  })
533
529
 
534
530
  let index = 0
535
531
 
536
- for (const currentBlock of slateValueFromProps) {
532
+ for (const currentBlock of value) {
537
533
  const {blockChanged, blockValid} = syncBlock({
538
534
  context,
539
535
  sendBack,
@@ -598,17 +594,17 @@ async function updateValue({
598
594
 
599
595
  function removeExtraBlocks({
600
596
  slateEditor,
601
- slateValueFromProps,
597
+ value,
602
598
  }: {
603
599
  slateEditor: PortableTextSlateEditor
604
- slateValueFromProps: Array<Descendant>
600
+ value: Array<PortableTextBlock>
605
601
  }) {
606
602
  let isChanged = false
607
603
  const childrenLength = slateEditor.children.length
608
604
 
609
605
  // Remove blocks that have become superfluous
610
- if (slateValueFromProps.length < childrenLength) {
611
- for (let i = childrenLength - 1; i > slateValueFromProps.length - 1; i--) {
606
+ if (value.length < childrenLength) {
607
+ for (let i = childrenLength - 1; i > value.length - 1; i--) {
612
608
  Transforms.removeNodes(slateEditor, {
613
609
  at: [i],
614
610
  })
@@ -618,13 +614,9 @@ function removeExtraBlocks({
618
614
  return isChanged
619
615
  }
620
616
 
621
- async function* getStreamedBlocks({
622
- slateValue,
623
- }: {
624
- slateValue: Array<Descendant>
625
- }) {
617
+ async function* getStreamedBlocks({value}: {value: Array<PortableTextBlock>}) {
626
618
  let index = 0
627
- for await (const block of slateValue) {
619
+ for await (const block of value) {
628
620
  if (index % 10 === 0) {
629
621
  await new Promise<void>((resolve) => setTimeout(resolve, 0))
630
622
  }
@@ -648,7 +640,7 @@ function syncBlock({
648
640
  schema: EditorSchema
649
641
  }
650
642
  sendBack: (event: SyncValueEvent) => void
651
- block: Descendant
643
+ block: PortableTextBlock
652
644
  index: number
653
645
  slateEditor: PortableTextSlateEditor
654
646
  value: Array<PortableTextBlock>
@@ -692,18 +684,17 @@ function syncBlock({
692
684
  }
693
685
  }
694
686
  if (validation.valid || validation.resolution?.autoResolve) {
687
+ const slateBlock = toSlateBlock(currentBlock, {
688
+ schemaTypes: context.schema,
689
+ })
690
+
695
691
  if (oldBlock._key === currentBlock._key) {
696
692
  if (debug.enabled) debug('Updating block', oldBlock, currentBlock)
697
- _updateBlock(
698
- slateEditor,
699
- currentBlock,
700
- oldBlock,
701
- currentBlockIndex,
702
- )
693
+ _updateBlock(slateEditor, slateBlock, oldBlock, currentBlockIndex)
703
694
  } else {
704
695
  if (debug.enabled)
705
696
  debug('Replacing block', oldBlock, currentBlock)
706
- _replaceBlock(slateEditor, currentBlock, currentBlockIndex)
697
+ _replaceBlock(slateEditor, slateBlock, currentBlockIndex)
707
698
  }
708
699
  blockChanged = true
709
700
  } else {
@@ -717,7 +708,7 @@ function syncBlock({
717
708
  }
718
709
 
719
710
  if (!oldBlock && blockValid) {
720
- const validationValue = [value[currentBlockIndex]]
711
+ const validationValue = [currentBlock]
721
712
  const validation = validateValue(
722
713
  validationValue,
723
714
  context.schema,
@@ -729,7 +720,10 @@ function syncBlock({
729
720
  currentBlock,
730
721
  )
731
722
  if (validation.valid || validation.resolution?.autoResolve) {
732
- Transforms.insertNodes(slateEditor, currentBlock, {
723
+ const slateBlock = toSlateBlock(currentBlock, {
724
+ schemaTypes: context.schema,
725
+ })
726
+ Transforms.insertNodes(slateEditor, slateBlock, {
733
727
  at: [currentBlockIndex],
734
728
  })
735
729
  } else {
@@ -1,5 +1,5 @@
1
1
  import {insert, set, setIfMissing, unset} from '@portabletext/patches'
2
- import {isTextBlock} from '@portabletext/schema'
2
+ import {isSpan, isTextBlock} from '@portabletext/schema'
3
3
  import type {
4
4
  PortableTextBlock,
5
5
  PortableTextSpan,
@@ -228,9 +228,9 @@ export function validateValue(
228
228
  const allUsedMarks = uniq(
229
229
  flatten(
230
230
  textBlock.children
231
- .filter((cld) => cld._type === types.span.name)
231
+ .filter((child) => isSpan({schema: types}, child))
232
232
  .map((cld) => cld.marks || []),
233
- ) as string[],
233
+ ),
234
234
  )
235
235
 
236
236
  // Test that all markDefs are in use (remove orphaned markDefs)
@@ -30,82 +30,92 @@ export function toSlateValue(
30
30
  keyMap: Record<string, any> = {},
31
31
  ): Descendant[] {
32
32
  if (value && Array.isArray(value)) {
33
- return value.map((block) => {
34
- const {_type, _key, ...rest} = block
35
- const isPortableText = block && block._type === schemaTypes.block.name
36
- if (isPortableText) {
37
- const textBlock = block as PortableTextTextBlock
38
- let hasInlines = false
39
- const hasMissingStyle = typeof textBlock.style === 'undefined'
40
- const hasMissingMarkDefs = typeof textBlock.markDefs === 'undefined'
41
- const hasMissingChildren = typeof textBlock.children === 'undefined'
33
+ return value.map((block) => toSlateBlock(block, {schemaTypes}, keyMap))
34
+ }
35
+ return []
36
+ }
37
+
38
+ export function toSlateBlock(
39
+ block: PortableTextBlock,
40
+ {schemaTypes}: {schemaTypes: EditorSchema},
41
+ keyMap: Record<string, any> = {},
42
+ ): Descendant {
43
+ const {_type, _key, ...rest} = block
44
+ const isPortableText = block && block._type === schemaTypes.block.name
45
+ if (isPortableText) {
46
+ const textBlock = block as PortableTextTextBlock
47
+ let hasInlines = false
48
+ const hasMissingStyle = typeof textBlock.style === 'undefined'
49
+ const hasMissingMarkDefs = typeof textBlock.markDefs === 'undefined'
50
+ const hasMissingChildren = typeof textBlock.children === 'undefined'
42
51
 
43
- const children = (textBlock.children || []).map((child) => {
44
- const {_type: cType, _key: cKey, ...cRest} = child
45
- // Return 'slate' version of inline object where the actual
46
- // value is stored in the `value` property.
47
- // In slate, inline objects are represented as regular
48
- // children with actual text node in order to be able to
49
- // be selected the same way as the rest of the (text) content.
50
- if (cType !== 'span') {
51
- hasInlines = true
52
- return keepObjectEquality(
52
+ const children = (textBlock.children || []).map((child) => {
53
+ const {_type: cType, _key: cKey, ...cRest} = child
54
+ // Return 'slate' version of inline object where the actual
55
+ // value is stored in the `value` property.
56
+ // In slate, inline objects are represented as regular
57
+ // children with actual text node in order to be able to
58
+ // be selected the same way as the rest of the (text) content.
59
+ if (cType !== 'span') {
60
+ hasInlines = true
61
+ return keepObjectEquality(
62
+ {
63
+ _type: cType,
64
+ _key: cKey,
65
+ children: [
53
66
  {
54
- _type: cType,
55
- _key: cKey,
56
- children: [
57
- {
58
- _key: VOID_CHILD_KEY,
59
- _type: 'span',
60
- text: '',
61
- marks: [],
62
- },
63
- ],
64
- value: cRest,
65
- __inline: true,
67
+ _key: VOID_CHILD_KEY,
68
+ _type: 'span',
69
+ text: '',
70
+ marks: [],
66
71
  },
67
- keyMap,
68
- )
69
- }
70
- // Original child object (span)
71
- return child
72
- })
73
- // Return original block
74
- if (
75
- !hasMissingStyle &&
76
- !hasMissingMarkDefs &&
77
- !hasMissingChildren &&
78
- !hasInlines &&
79
- Element.isElement(block)
80
- ) {
81
- // Original object
82
- return block
83
- }
84
- // TODO: remove this when we have a better way to handle missing style
85
- if (hasMissingStyle) {
86
- rest.style = schemaTypes.styles[0].name
87
- }
88
- return keepObjectEquality({_type, _key, ...rest, children}, keyMap)
72
+ ],
73
+ value: cRest,
74
+ __inline: true,
75
+ },
76
+ keyMap,
77
+ )
89
78
  }
90
- return keepObjectEquality(
79
+ // Original child object (span)
80
+ return child
81
+ })
82
+ // Return original block
83
+ if (
84
+ !hasMissingStyle &&
85
+ !hasMissingMarkDefs &&
86
+ !hasMissingChildren &&
87
+ !hasInlines &&
88
+ Element.isElement(block)
89
+ ) {
90
+ // Original object
91
+ return block
92
+ }
93
+ // TODO: remove this when we have a better way to handle missing style
94
+ if (hasMissingStyle) {
95
+ rest.style = schemaTypes.styles[0].name
96
+ }
97
+ return keepObjectEquality(
98
+ {_type, _key, ...rest, children},
99
+ keyMap,
100
+ ) as Descendant
101
+ }
102
+
103
+ return keepObjectEquality(
104
+ {
105
+ _type,
106
+ _key,
107
+ children: [
91
108
  {
92
- _type,
93
- _key,
94
- children: [
95
- {
96
- _key: VOID_CHILD_KEY,
97
- _type: 'span',
98
- text: '',
99
- marks: [],
100
- },
101
- ],
102
- value: rest,
109
+ _key: VOID_CHILD_KEY,
110
+ _type: 'span',
111
+ text: '',
112
+ marks: [],
103
113
  },
104
- keyMap,
105
- )
106
- }) as Descendant[]
107
- }
108
- return []
114
+ ],
115
+ value: rest,
116
+ },
117
+ keyMap,
118
+ ) as Descendant
109
119
  }
110
120
 
111
121
  export function fromSlateValue(