@portabletext/editor 1.49.1 → 1.49.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 (95) hide show
  1. package/lib/_chunks-cjs/selector.get-text-before.cjs +2 -2
  2. package/lib/_chunks-cjs/selector.get-text-before.cjs.map +1 -1
  3. package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs +40 -230
  4. package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs.map +1 -1
  5. package/lib/_chunks-cjs/selector.is-selection-expanded.cjs +201 -0
  6. package/lib/_chunks-cjs/selector.is-selection-expanded.cjs.map +1 -0
  7. package/lib/_chunks-cjs/use-editor.cjs +28 -0
  8. package/lib/_chunks-cjs/use-editor.cjs.map +1 -0
  9. package/lib/_chunks-cjs/util.child-selection-point-to-block-offset.cjs +79 -0
  10. package/lib/_chunks-cjs/util.child-selection-point-to-block-offset.cjs.map +1 -0
  11. package/lib/_chunks-cjs/util.is-equal-selection-points.cjs +34 -0
  12. package/lib/_chunks-cjs/util.is-equal-selection-points.cjs.map +1 -0
  13. package/lib/_chunks-cjs/util.merge-text-blocks.cjs +2 -1
  14. package/lib/_chunks-cjs/util.merge-text-blocks.cjs.map +1 -1
  15. package/lib/_chunks-cjs/util.selection-point-to-block-offset.cjs +6 -78
  16. package/lib/_chunks-cjs/util.selection-point-to-block-offset.cjs.map +1 -1
  17. package/lib/_chunks-cjs/util.slice-blocks.cjs +26 -39
  18. package/lib/_chunks-cjs/util.slice-blocks.cjs.map +1 -1
  19. package/lib/_chunks-es/selector.get-text-before.js +1 -1
  20. package/lib/_chunks-es/selector.is-selecting-entire-blocks.js +13 -201
  21. package/lib/_chunks-es/selector.is-selecting-entire-blocks.js.map +1 -1
  22. package/lib/_chunks-es/selector.is-selection-expanded.js +203 -0
  23. package/lib/_chunks-es/selector.is-selection-expanded.js.map +1 -0
  24. package/lib/_chunks-es/use-editor.js +25 -0
  25. package/lib/_chunks-es/use-editor.js.map +1 -0
  26. package/lib/_chunks-es/util.child-selection-point-to-block-offset.js +80 -0
  27. package/lib/_chunks-es/util.child-selection-point-to-block-offset.js.map +1 -0
  28. package/lib/_chunks-es/util.is-equal-selection-points.js +35 -0
  29. package/lib/_chunks-es/util.is-equal-selection-points.js.map +1 -0
  30. package/lib/_chunks-es/util.merge-text-blocks.js +2 -1
  31. package/lib/_chunks-es/util.merge-text-blocks.js.map +1 -1
  32. package/lib/_chunks-es/util.selection-point-to-block-offset.js +6 -77
  33. package/lib/_chunks-es/util.selection-point-to-block-offset.js.map +1 -1
  34. package/lib/_chunks-es/util.slice-blocks.js +26 -39
  35. package/lib/_chunks-es/util.slice-blocks.js.map +1 -1
  36. package/lib/index.cjs +9004 -292
  37. package/lib/index.cjs.map +1 -1
  38. package/lib/index.d.cts +2 -2
  39. package/lib/index.d.ts +2 -2
  40. package/lib/index.js +8947 -220
  41. package/lib/index.js.map +1 -1
  42. package/lib/plugins/index.cjs +23 -23
  43. package/lib/plugins/index.cjs.map +1 -1
  44. package/lib/plugins/index.js +3 -3
  45. package/lib/plugins/index.js.map +1 -1
  46. package/lib/selectors/index.cjs +22 -22
  47. package/lib/selectors/index.cjs.map +1 -1
  48. package/lib/selectors/index.js +4 -3
  49. package/lib/selectors/index.js.map +1 -1
  50. package/lib/utils/index.cjs +10 -10
  51. package/lib/utils/index.cjs.map +1 -1
  52. package/lib/utils/index.js +6 -4
  53. package/lib/utils/index.js.map +1 -1
  54. package/package.json +14 -14
  55. package/src/behaviors/behavior.abstract.split.ts +2 -2
  56. package/src/converters/converter.portable-text.ts +1 -0
  57. package/src/converters/converter.text-html.ts +1 -0
  58. package/src/converters/converter.text-plain.ts +1 -0
  59. package/src/editor/Editable.tsx +1 -0
  60. package/src/editor/components/render-element.tsx +3 -3
  61. package/src/editor/create-editor.ts +2 -58
  62. package/src/editor/editor-context.tsx +1 -1
  63. package/src/editor/editor-provider.tsx +4 -31
  64. package/src/editor/editor-selector.ts +2 -1
  65. package/src/editor/use-editor.ts +27 -0
  66. package/src/editor-event-listener.tsx +1 -1
  67. package/src/editor.ts +57 -0
  68. package/src/index.ts +9 -9
  69. package/src/internal-utils/parse-blocks.test.ts +20 -20
  70. package/src/internal-utils/parse-blocks.ts +57 -20
  71. package/src/internal-utils/text-selection.test.ts +11 -0
  72. package/src/operations/behavior.operation.annotation.add.ts +1 -1
  73. package/src/operations/behavior.operation.block.set.ts +1 -1
  74. package/src/operations/behavior.operation.block.unset.ts +2 -2
  75. package/src/operations/behavior.operation.insert-inline-object.ts +1 -1
  76. package/src/operations/behavior.operation.insert.block.ts +1 -1
  77. package/src/plugins/plugin.behavior.tsx +1 -1
  78. package/src/plugins/plugin.decorator-shortcut.ts +2 -2
  79. package/src/plugins/plugin.editor-ref.tsx +2 -2
  80. package/src/plugins/plugin.event-listener.tsx +1 -1
  81. package/src/plugins/plugin.markdown.tsx +1 -1
  82. package/src/selectors/selector.get-trimmed-selection.test.ts +1 -0
  83. package/src/utils/util.merge-text-blocks.ts +1 -1
  84. package/lib/_chunks-cjs/editor-provider.cjs +0 -8745
  85. package/lib/_chunks-cjs/editor-provider.cjs.map +0 -1
  86. package/lib/_chunks-cjs/selector.get-focus-inline-object.cjs +0 -11
  87. package/lib/_chunks-cjs/selector.get-focus-inline-object.cjs.map +0 -1
  88. package/lib/_chunks-cjs/util.is-selection-collapsed.cjs +0 -6
  89. package/lib/_chunks-cjs/util.is-selection-collapsed.cjs.map +0 -1
  90. package/lib/_chunks-es/editor-provider.js +0 -8771
  91. package/lib/_chunks-es/editor-provider.js.map +0 -1
  92. package/lib/_chunks-es/selector.get-focus-inline-object.js +0 -13
  93. package/lib/_chunks-es/selector.get-focus-inline-object.js.map +0 -1
  94. package/lib/_chunks-es/util.is-selection-collapsed.js +0 -7
  95. package/lib/_chunks-es/util.is-selection-collapsed.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/utils/util.is-equal-selections.ts","../../src/utils/util.split-text-block.ts"],"sourcesContent":["import type {EditorSelection} from '../types/editor'\nimport {isEqualSelectionPoints} from './util.is-equal-selection-points'\n\n/**\n * @public\n */\nexport function isEqualSelections(a: EditorSelection, b: EditorSelection) {\n if (!a && !b) {\n return true\n }\n\n if (!a || !b) {\n return false\n }\n\n return (\n isEqualSelectionPoints(a.anchor, b.anchor) &&\n isEqualSelectionPoints(a.focus, b.focus)\n )\n}\n","import type {PortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelectionPoint} from '..'\nimport type {EditorContext} from '../editor/editor-snapshot'\nimport {isSpan} from './util.is-span'\nimport {isTextBlock} from './util.is-text-block'\nimport {sliceBlocks} from './util.slice-blocks'\n\n/**\n * @beta\n */\nexport function splitTextBlock({\n context,\n block,\n point,\n}: {\n context: Pick<EditorContext, 'schema'>\n block: PortableTextTextBlock\n point: EditorSelectionPoint\n}): {before: PortableTextTextBlock; after: PortableTextTextBlock} | undefined {\n const firstChild = block.children.at(0)\n const lastChild = block.children.at(block.children.length - 1)\n\n if (!firstChild || !lastChild) {\n return undefined\n }\n\n const before = sliceBlocks({\n context: {\n schema: context.schema,\n selection: {\n anchor: {\n path: [{_key: block._key}, 'children', {_key: firstChild._key}],\n offset: 0,\n },\n focus: point,\n },\n },\n blocks: [block],\n }).at(0)\n const after = sliceBlocks({\n context: {\n schema: context.schema,\n selection: {\n anchor: point,\n focus: {\n path: [{_key: block._key}, 'children', {_key: lastChild._key}],\n offset: isSpan(context, lastChild) ? lastChild.text.length : 0,\n },\n },\n },\n blocks: [block],\n }).at(0)\n\n if (!before || !after) {\n return undefined\n }\n\n if (!isTextBlock(context, before) || !isTextBlock(context, after)) {\n return undefined\n }\n\n return {before, after}\n}\n"],"names":["isEqualSelections","a","b","isEqualSelectionPoints","anchor","focus","splitTextBlock","context","block","point","firstChild","children","at","lastChild","length","before","sliceBlocks","schema","selection","path","_key","offset","blocks","after","isSpan","text","isTextBlock"],"mappings":";;;;;;AAMgBA,SAAAA,kBAAkBC,GAAoBC,GAAoB;AACpE,SAAA,CAACD,KAAK,CAACC,IACF,KAGL,CAACD,KAAK,CAACC,IACF,KAIPC,uBAAuBF,EAAEG,QAAQF,EAAEE,MAAM,KACzCD,uBAAuBF,EAAEI,OAAOH,EAAEG,KAAK;AAE3C;ACTO,SAASC,eAAe;AAAA,EAC7BC;AAAAA,EACAC;AAAAA,EACAC;AAKF,GAA8E;AAC5E,QAAMC,aAAaF,MAAMG,SAASC,GAAG,CAAC,GAChCC,YAAYL,MAAMG,SAASC,GAAGJ,MAAMG,SAASG,SAAS,CAAC;AAEzD,MAAA,CAACJ,cAAc,CAACG;AAClB;AAGF,QAAME,SAASC,YAAY;AAAA,IACzBT,SAAS;AAAA,MACPU,QAAQV,QAAQU;AAAAA,MAChBC,WAAW;AAAA,QACTd,QAAQ;AAAA,UACNe,MAAM,CAAC;AAAA,YAACC,MAAMZ,MAAMY;AAAAA,aAAO,YAAY;AAAA,YAACA,MAAMV,WAAWU;AAAAA,UAAAA,CAAK;AAAA,UAC9DC,QAAQ;AAAA,QACV;AAAA,QACAhB,OAAOI;AAAAA,MAAAA;AAAAA,IAEX;AAAA,IACAa,QAAQ,CAACd,KAAK;AAAA,EACf,CAAA,EAAEI,GAAG,CAAC,GACDW,QAAQP,YAAY;AAAA,IACxBT,SAAS;AAAA,MACPU,QAAQV,QAAQU;AAAAA,MAChBC,WAAW;AAAA,QACTd,QAAQK;AAAAA,QACRJ,OAAO;AAAA,UACLc,MAAM,CAAC;AAAA,YAACC,MAAMZ,MAAMY;AAAAA,aAAO,YAAY;AAAA,YAACA,MAAMP,UAAUO;AAAAA,UAAAA,CAAK;AAAA,UAC7DC,QAAQG,OAAOjB,SAASM,SAAS,IAAIA,UAAUY,KAAKX,SAAS;AAAA,QAAA;AAAA,MAC/D;AAAA,IAEJ;AAAA,IACAQ,QAAQ,CAACd,KAAK;AAAA,EAAA,CACf,EAAEI,GAAG,CAAC;AAEP,MAAI,EAACG,CAAAA,UAAU,CAACQ,UAIZ,EAACG,CAAAA,YAAYnB,SAASQ,MAAM,KAAK,CAACW,YAAYnB,SAASgB,KAAK;AAIzD,WAAA;AAAA,MAACR;AAAAA,MAAQQ;AAAAA,IAAK;AACvB;"}
1
+ {"version":3,"file":"index.js","sources":["../../src/utils/util.is-equal-selections.ts","../../src/utils/util.split-text-block.ts"],"sourcesContent":["import type {EditorSelection} from '../types/editor'\nimport {isEqualSelectionPoints} from './util.is-equal-selection-points'\n\n/**\n * @public\n */\nexport function isEqualSelections(a: EditorSelection, b: EditorSelection) {\n if (!a && !b) {\n return true\n }\n\n if (!a || !b) {\n return false\n }\n\n return (\n isEqualSelectionPoints(a.anchor, b.anchor) &&\n isEqualSelectionPoints(a.focus, b.focus)\n )\n}\n","import type {PortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelectionPoint} from '..'\nimport type {EditorContext} from '../editor/editor-snapshot'\nimport {isSpan} from './util.is-span'\nimport {isTextBlock} from './util.is-text-block'\nimport {sliceBlocks} from './util.slice-blocks'\n\n/**\n * @beta\n */\nexport function splitTextBlock({\n context,\n block,\n point,\n}: {\n context: Pick<EditorContext, 'schema'>\n block: PortableTextTextBlock\n point: EditorSelectionPoint\n}): {before: PortableTextTextBlock; after: PortableTextTextBlock} | undefined {\n const firstChild = block.children.at(0)\n const lastChild = block.children.at(block.children.length - 1)\n\n if (!firstChild || !lastChild) {\n return undefined\n }\n\n const before = sliceBlocks({\n context: {\n schema: context.schema,\n selection: {\n anchor: {\n path: [{_key: block._key}, 'children', {_key: firstChild._key}],\n offset: 0,\n },\n focus: point,\n },\n },\n blocks: [block],\n }).at(0)\n const after = sliceBlocks({\n context: {\n schema: context.schema,\n selection: {\n anchor: point,\n focus: {\n path: [{_key: block._key}, 'children', {_key: lastChild._key}],\n offset: isSpan(context, lastChild) ? lastChild.text.length : 0,\n },\n },\n },\n blocks: [block],\n }).at(0)\n\n if (!before || !after) {\n return undefined\n }\n\n if (!isTextBlock(context, before) || !isTextBlock(context, after)) {\n return undefined\n }\n\n return {before, after}\n}\n"],"names":["isEqualSelections","a","b","isEqualSelectionPoints","anchor","focus","splitTextBlock","context","block","point","firstChild","children","at","lastChild","length","before","sliceBlocks","schema","selection","path","_key","offset","blocks","after","isSpan","text","isTextBlock"],"mappings":";;;;;;;;AAMgBA,SAAAA,kBAAkBC,GAAoBC,GAAoB;AACpE,SAAA,CAACD,KAAK,CAACC,IACF,KAGL,CAACD,KAAK,CAACC,IACF,KAIPC,uBAAuBF,EAAEG,QAAQF,EAAEE,MAAM,KACzCD,uBAAuBF,EAAEI,OAAOH,EAAEG,KAAK;AAE3C;ACTO,SAASC,eAAe;AAAA,EAC7BC;AAAAA,EACAC;AAAAA,EACAC;AAKF,GAA8E;AAC5E,QAAMC,aAAaF,MAAMG,SAASC,GAAG,CAAC,GAChCC,YAAYL,MAAMG,SAASC,GAAGJ,MAAMG,SAASG,SAAS,CAAC;AAEzD,MAAA,CAACJ,cAAc,CAACG;AAClB;AAGF,QAAME,SAASC,YAAY;AAAA,IACzBT,SAAS;AAAA,MACPU,QAAQV,QAAQU;AAAAA,MAChBC,WAAW;AAAA,QACTd,QAAQ;AAAA,UACNe,MAAM,CAAC;AAAA,YAACC,MAAMZ,MAAMY;AAAAA,aAAO,YAAY;AAAA,YAACA,MAAMV,WAAWU;AAAAA,UAAAA,CAAK;AAAA,UAC9DC,QAAQ;AAAA,QACV;AAAA,QACAhB,OAAOI;AAAAA,MAAAA;AAAAA,IAEX;AAAA,IACAa,QAAQ,CAACd,KAAK;AAAA,EACf,CAAA,EAAEI,GAAG,CAAC,GACDW,QAAQP,YAAY;AAAA,IACxBT,SAAS;AAAA,MACPU,QAAQV,QAAQU;AAAAA,MAChBC,WAAW;AAAA,QACTd,QAAQK;AAAAA,QACRJ,OAAO;AAAA,UACLc,MAAM,CAAC;AAAA,YAACC,MAAMZ,MAAMY;AAAAA,aAAO,YAAY;AAAA,YAACA,MAAMP,UAAUO;AAAAA,UAAAA,CAAK;AAAA,UAC7DC,QAAQG,OAAOjB,SAASM,SAAS,IAAIA,UAAUY,KAAKX,SAAS;AAAA,QAAA;AAAA,MAC/D;AAAA,IAEJ;AAAA,IACAQ,QAAQ,CAACd,KAAK;AAAA,EAAA,CACf,EAAEI,GAAG,CAAC;AAEP,MAAI,EAACG,CAAAA,UAAU,CAACQ,UAIZ,EAACG,CAAAA,YAAYnB,SAASQ,MAAM,KAAK,CAACW,YAAYnB,SAASgB,KAAK;AAIzD,WAAA;AAAA,MAACR;AAAAA,MAAQQ;AAAAA,IAAK;AACvB;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@portabletext/editor",
3
- "version": "1.49.1",
3
+ "version": "1.49.3",
4
4
  "description": "Portable Text Editor made in React",
5
5
  "keywords": [
6
6
  "sanity",
@@ -79,43 +79,43 @@
79
79
  "slate-react": "0.114.2",
80
80
  "use-effect-event": "^1.0.2",
81
81
  "xstate": "^5.19.2",
82
- "@portabletext/patches": "1.1.3",
83
- "@portabletext/block-tools": "1.1.24"
82
+ "@portabletext/block-tools": "1.1.25",
83
+ "@portabletext/patches": "1.1.3"
84
84
  },
85
85
  "devDependencies": {
86
86
  "@portabletext/toolkit": "^2.0.17",
87
87
  "@sanity/diff-match-patch": "^3.2.0",
88
88
  "@sanity/pkg-utils": "^7.2.2",
89
- "@sanity/schema": "^3.88.0",
90
- "@sanity/types": "^3.88.0",
89
+ "@sanity/schema": "^3.88.2",
90
+ "@sanity/types": "^3.88.2",
91
91
  "@testing-library/jest-dom": "^6.6.3",
92
92
  "@testing-library/react": "^16.3.0",
93
93
  "@types/debug": "^4.1.12",
94
94
  "@types/lodash": "^4.17.16",
95
95
  "@types/lodash.startcase": "^4.4.9",
96
- "@types/react": "^19.1.2",
96
+ "@types/react": "^19.1.3",
97
97
  "@types/react-dom": "^19.1.3",
98
- "@typescript-eslint/eslint-plugin": "^8.29.0",
99
- "@typescript-eslint/parser": "^8.29.0",
98
+ "@typescript-eslint/eslint-plugin": "^8.32.0",
99
+ "@typescript-eslint/parser": "^8.32.0",
100
100
  "@vitejs/plugin-react": "^4.4.1",
101
- "@vitest/browser": "^3.1.2",
102
- "@vitest/coverage-istanbul": "^3.1.2",
101
+ "@vitest/browser": "^3.1.3",
102
+ "@vitest/coverage-istanbul": "^3.1.3",
103
103
  "babel-plugin-react-compiler": "19.1.0-rc.1",
104
104
  "eslint": "8.57.1",
105
- "eslint-plugin-react-hooks": "0.0.0-experimental-0038c501-20250429",
105
+ "eslint-plugin-react-hooks": "0.0.0-experimental-7a2c7045-20250506",
106
106
  "jsdom": "^26.0.0",
107
107
  "react": "^19.1.0",
108
108
  "react-dom": "^19.1.0",
109
109
  "rxjs": "^7.8.2",
110
110
  "typescript": "5.8.3",
111
111
  "vite": "^6.2.5",
112
- "vitest": "^3.1.2",
112
+ "vitest": "^3.1.3",
113
113
  "vitest-browser-react": "^0.1.1",
114
114
  "racejar": "1.2.4"
115
115
  },
116
116
  "peerDependencies": {
117
- "@sanity/schema": "^3.88.0",
118
- "@sanity/types": "^3.88.0",
117
+ "@sanity/schema": "^3.88.2",
118
+ "@sanity/types": "^3.88.2",
119
119
  "react": "^16.9 || ^17 || ^18 || ^19",
120
120
  "rxjs": "^7.8.2"
121
121
  },
@@ -49,7 +49,7 @@ export const abstractSplitBehaviors = [
49
49
  blocks: [focusTextBlock.node],
50
50
  }).at(0),
51
51
  context: snapshot.context,
52
- options: {refreshKeys: true},
52
+ options: {refreshKeys: true, validateFields: true},
53
53
  })
54
54
 
55
55
  if (!newTextBlock || !isTextBlock(snapshot.context, newTextBlock)) {
@@ -84,7 +84,7 @@ export const abstractSplitBehaviors = [
84
84
  children: [],
85
85
  },
86
86
  context: snapshot.context,
87
- options: {refreshKeys: true},
87
+ options: {refreshKeys: true, validateFields: true},
88
88
  })
89
89
 
90
90
  if (!newTextBlock) {
@@ -62,6 +62,7 @@ export const converterPortableText = defineConverter({
62
62
  * dropped portable text as is.
63
63
  */
64
64
  refreshKeys: !snapshot.beta.hasTag?.('dragging internally'),
65
+ validateFields: false,
65
66
  },
66
67
  })
67
68
  return parsedBlock ? [parsedBlock] : []
@@ -70,6 +70,7 @@ export function createConverterTextHtml(
70
70
  block,
71
71
  options: {
72
72
  refreshKeys: false,
73
+ validateFields: true,
73
74
  },
74
75
  })
75
76
  return parsedBlock ? [parsedBlock] : []
@@ -93,6 +93,7 @@ export function createConverterTextPlain(
93
93
  block,
94
94
  options: {
95
95
  refreshKeys: false,
96
+ validateFields: true,
96
97
  },
97
98
  })
98
99
  return parsedBlock ? [parsedBlock] : []
@@ -480,6 +480,7 @@ export const PortableTextEditable = forwardRef<
480
480
  blocks: result.insert,
481
481
  options: {
482
482
  refreshKeys: true,
483
+ validateFields: true,
483
484
  },
484
485
  }),
485
486
  placement: 'auto',
@@ -40,7 +40,7 @@ export function RenderElement(props: {
40
40
  keyGenerator: () => '',
41
41
  schema,
42
42
  },
43
- options: {refreshKeys: false},
43
+ options: {refreshKeys: false, validateFields: false},
44
44
  inlineObject: {
45
45
  _key: props.element._key,
46
46
  _type: props.element._type,
@@ -79,7 +79,7 @@ export function RenderElement(props: {
79
79
  keyGenerator: () => '',
80
80
  schema,
81
81
  },
82
- options: {refreshKeys: false},
82
+ options: {refreshKeys: false, validateFields: false},
83
83
  block: props.element,
84
84
  })
85
85
 
@@ -105,7 +105,7 @@ export function RenderElement(props: {
105
105
  keyGenerator: () => '',
106
106
  schema,
107
107
  },
108
- options: {refreshKeys: false},
108
+ options: {refreshKeys: false, validateFields: false},
109
109
  blockObject: {
110
110
  _key: props.element._key,
111
111
  _type: props.element._type,
@@ -1,76 +1,20 @@
1
- import type {
2
- ArrayDefinition,
3
- ArraySchemaType,
4
- PortableTextBlock,
5
- } from '@sanity/types'
6
- import type {ActorRef, EventObject, Snapshot} from 'xstate'
7
- import type {Behavior} from '../behaviors/behavior.types.behavior'
8
- import type {ExternalBehaviorEvent} from '../behaviors/behavior.types.event'
9
1
  import {createCoreConverters} from '../converters/converters.core'
2
+ import type {Editor, EditorConfig} from '../editor'
10
3
  import {compileType} from '../internal-utils/schema'
11
4
  import {corePriority} from '../priority/priority.core'
12
5
  import {createEditorPriority} from '../priority/priority.types'
13
6
  import type {EditableAPI} from '../types/editor'
14
7
  import {createSlateEditor, type SlateEditor} from './create-slate-editor'
15
- import type {
16
- EditorActor,
17
- EditorEmittedEvent,
18
- ExternalEditorEvent,
19
- } from './editor-machine'
8
+ import type {EditorActor} from './editor-machine'
20
9
  import {
21
10
  compileSchemaDefinitionToLegacySchema,
22
11
  legacySchemaToEditorSchema,
23
- type SchemaDefinition,
24
12
  } from './editor-schema'
25
13
  import {getEditorSnapshot} from './editor-selector'
26
- import type {EditorSnapshot} from './editor-snapshot'
27
14
  import {defaultKeyGenerator} from './key-generator'
28
15
  import {createLegacySchema} from './legacy-schema'
29
16
  import {createEditableAPI} from './plugins/createWithEditableAPI'
30
17
 
31
- /**
32
- * @public
33
- */
34
- export type EditorConfig = {
35
- /**
36
- * @beta
37
- */
38
- keyGenerator?: () => string
39
- /**
40
- * @deprecated Will be removed in the next major version
41
- */
42
- maxBlocks?: number
43
- readOnly?: boolean
44
- initialValue?: Array<PortableTextBlock>
45
- } & (
46
- | {
47
- schemaDefinition: SchemaDefinition
48
- schema?: undefined
49
- }
50
- | {
51
- schemaDefinition?: undefined
52
- schema: ArraySchemaType<PortableTextBlock> | ArrayDefinition
53
- }
54
- )
55
-
56
- /**
57
- * @public
58
- */
59
- export type EditorEvent = ExternalEditorEvent | ExternalBehaviorEvent
60
-
61
- /**
62
- * @public
63
- */
64
- export type Editor = {
65
- getSnapshot: () => EditorSnapshot
66
- /**
67
- * @beta
68
- */
69
- registerBehavior: (config: {behavior: Behavior}) => () => void
70
- send: (event: EditorEvent) => void
71
- on: ActorRef<Snapshot<unknown>, EventObject, EditorEmittedEvent>['on']
72
- }
73
-
74
18
  export type InternalEditor = Editor & {
75
19
  _internal: {
76
20
  editable: EditableAPI
@@ -1,5 +1,5 @@
1
+ import type {Editor} from '../editor'
1
2
  import {createGloballyScopedContext} from '../internal-utils/globally-scoped-context'
2
- import type {Editor} from './create-editor'
3
3
 
4
4
  export const EditorContext = createGloballyScopedContext<Editor | null>(
5
5
  '@portabletext/editor/context/editor',
@@ -1,12 +1,10 @@
1
1
  import {useActorRef} from '@xstate/react'
2
- import React, {useMemo} from 'react'
2
+ import type React from 'react'
3
+ import {useMemo} from 'react'
3
4
  import {Slate} from 'slate-react'
5
+ import type {EditorConfig} from '../editor'
4
6
  import {Synchronizer} from './components/Synchronizer'
5
- import {
6
- createInternalEditor,
7
- editorConfigToMachineInput,
8
- type EditorConfig,
9
- } from './create-editor'
7
+ import {createInternalEditor, editorConfigToMachineInput} from './create-editor'
10
8
  import {EditorActorContext} from './editor-actor-context'
11
9
  import {EditorContext} from './editor-context'
12
10
  import {editorMachine} from './editor-machine'
@@ -87,28 +85,3 @@ export function EditorProvider(props: EditorProviderProps) {
87
85
  </EditorContext.Provider>
88
86
  )
89
87
  }
90
-
91
- /**
92
- * @public
93
- * Get the current editor context from the `EditorProvider`.
94
- * Must be used inside the `EditorProvider` component.
95
- * @returns The current editor object.
96
- * @example
97
- * ```tsx
98
- * import { useEditor } from '@portabletext/editor'
99
- *
100
- * function MyComponent() {
101
- * const editor = useEditor()
102
- * }
103
- * ```
104
- * @group Hooks
105
- */
106
- export function useEditor() {
107
- const editor = React.useContext(EditorContext)
108
-
109
- if (!editor) {
110
- throw new Error('No Editor set. Use EditorProvider to set one.')
111
- }
112
-
113
- return editor
114
- }
@@ -1,7 +1,8 @@
1
1
  import {useSelector} from '@xstate/react'
2
+ import type {Editor} from '../editor'
2
3
  import {slateChildrenToBlocks} from '../internal-utils/slate-children-to-blocks'
3
4
  import type {PortableTextSlateEditor} from '../types/editor'
4
- import type {Editor, InternalEditor} from './create-editor'
5
+ import type {InternalEditor} from './create-editor'
5
6
  import type {EditorActor} from './editor-machine'
6
7
  import type {EditorSnapshot} from './editor-snapshot'
7
8
  import {getActiveDecorators} from './get-active-decorators'
@@ -0,0 +1,27 @@
1
+ import React from 'react'
2
+ import {EditorContext} from './editor-context'
3
+
4
+ /**
5
+ * @public
6
+ * Get the current editor context from the `EditorProvider`.
7
+ * Must be used inside the `EditorProvider` component.
8
+ * @returns The current editor object.
9
+ * @example
10
+ * ```tsx
11
+ * import { useEditor } from '@portabletext/editor'
12
+ *
13
+ * function MyComponent() {
14
+ * const editor = useEditor()
15
+ * }
16
+ * ```
17
+ * @group Hooks
18
+ */
19
+ export function useEditor() {
20
+ const editor = React.useContext(EditorContext)
21
+
22
+ if (!editor) {
23
+ throw new Error('No Editor set. Use EditorProvider to set one.')
24
+ }
25
+
26
+ return editor
27
+ }
@@ -1,7 +1,7 @@
1
1
  import {useEffect} from 'react'
2
2
  import {useEffectEvent} from 'use-effect-event'
3
3
  import type {EditorEmittedEvent} from './editor/editor-machine'
4
- import {useEditor} from './editor/editor-provider'
4
+ import {useEditor} from './editor/use-editor'
5
5
 
6
6
  /**
7
7
  * @public
package/src/editor.ts ADDED
@@ -0,0 +1,57 @@
1
+ import type {
2
+ ArrayDefinition,
3
+ ArraySchemaType,
4
+ PortableTextBlock,
5
+ } from '@sanity/types'
6
+ import type {ActorRef, EventObject, Snapshot} from 'xstate'
7
+ import type {Behavior} from './behaviors/behavior.types.behavior'
8
+ import type {ExternalBehaviorEvent} from './behaviors/behavior.types.event'
9
+ import type {
10
+ EditorEmittedEvent,
11
+ ExternalEditorEvent,
12
+ } from './editor/editor-machine'
13
+ import type {SchemaDefinition} from './editor/editor-schema'
14
+ import type {EditorSnapshot} from './editor/editor-snapshot'
15
+
16
+ /**
17
+ * @public
18
+ */
19
+ export type EditorConfig = {
20
+ /**
21
+ * @beta
22
+ */
23
+ keyGenerator?: () => string
24
+ /**
25
+ * @deprecated Will be removed in the next major version
26
+ */
27
+ maxBlocks?: number
28
+ readOnly?: boolean
29
+ initialValue?: Array<PortableTextBlock>
30
+ } & (
31
+ | {
32
+ schemaDefinition: SchemaDefinition
33
+ schema?: undefined
34
+ }
35
+ | {
36
+ schemaDefinition?: undefined
37
+ schema: ArraySchemaType<PortableTextBlock> | ArrayDefinition
38
+ }
39
+ )
40
+
41
+ /**
42
+ * @public
43
+ */
44
+ export type EditorEvent = ExternalEditorEvent | ExternalBehaviorEvent
45
+
46
+ /**
47
+ * @public
48
+ */
49
+ export type Editor = {
50
+ getSnapshot: () => EditorSnapshot
51
+ /**
52
+ * @beta
53
+ */
54
+ registerBehavior: (config: {behavior: Behavior}) => () => void
55
+ send: (event: EditorEvent) => void
56
+ on: ActorRef<Snapshot<unknown>, EventObject, EditorEmittedEvent>['on']
57
+ }
package/src/index.ts CHANGED
@@ -4,15 +4,8 @@ export type {
4
4
  PortableTextChild,
5
5
  PortableTextSpan,
6
6
  } from '@sanity/types'
7
- export type {AddedAnnotationPaths} from './operations/behavior.operation.annotation.add'
8
7
  export {EditorEventListener} from './editor-event-listener'
9
- export type {Editor, EditorConfig, EditorEvent} from './editor/create-editor'
10
- export {
11
- defineSchema,
12
- type BaseDefinition,
13
- type SchemaDefinition,
14
- } from './editor/editor-schema'
15
- export type {EditorSchema} from './editor/editor-schema'
8
+ export type {Editor, EditorConfig, EditorEvent} from './editor'
16
9
  export {PortableTextEditable} from './editor/Editable'
17
10
  export type {PortableTextEditableProps} from './editor/Editable'
18
11
  export type {
@@ -22,9 +15,14 @@ export type {
22
15
  } from './editor/editor-machine'
23
16
  export {
24
17
  EditorProvider,
25
- useEditor,
26
18
  type EditorProviderProps,
27
19
  } from './editor/editor-provider'
20
+ export {
21
+ defineSchema,
22
+ type BaseDefinition,
23
+ type SchemaDefinition,
24
+ } from './editor/editor-schema'
25
+ export type {EditorSchema} from './editor/editor-schema'
28
26
  export {useEditorSelector, type EditorSelector} from './editor/editor-selector'
29
27
  export type {EditorContext, EditorSnapshot} from './editor/editor-snapshot'
30
28
  export {usePortableTextEditor} from './editor/hooks/usePortableTextEditor'
@@ -32,6 +30,8 @@ export {usePortableTextEditorSelection} from './editor/hooks/usePortableTextEdit
32
30
  export {defaultKeyGenerator as keyGenerator} from './editor/key-generator'
33
31
  export {PortableTextEditor} from './editor/PortableTextEditor'
34
32
  export type {PortableTextEditorProps} from './editor/PortableTextEditor'
33
+ export {useEditor} from './editor/use-editor'
34
+ export type {AddedAnnotationPaths} from './operations/behavior.operation.annotation.add'
35
35
  export type {BlockOffset} from './types/block-offset'
36
36
  export type {
37
37
  BlockAnnotationRenderProps,
@@ -12,7 +12,7 @@ describe(parseBlock.name, () => {
12
12
  keyGenerator: createTestKeyGenerator(),
13
13
  schema: compileSchemaDefinition(defineSchema({})),
14
14
  },
15
- options: {refreshKeys: false},
15
+ options: {refreshKeys: false, validateFields: true},
16
16
  }),
17
17
  ).toBe(undefined)
18
18
  })
@@ -25,7 +25,7 @@ describe(parseBlock.name, () => {
25
25
  keyGenerator: createTestKeyGenerator(),
26
26
  schema: compileSchemaDefinition(defineSchema({})),
27
27
  },
28
- options: {refreshKeys: false},
28
+ options: {refreshKeys: false, validateFields: true},
29
29
  }),
30
30
  ).toBe(undefined)
31
31
  })
@@ -39,7 +39,7 @@ describe(parseBlock.name, () => {
39
39
  keyGenerator: createTestKeyGenerator(),
40
40
  schema: compileSchemaDefinition(defineSchema({})),
41
41
  },
42
- options: {refreshKeys: false},
42
+ options: {refreshKeys: false, validateFields: true},
43
43
  }),
44
44
  ).toBe(undefined)
45
45
  })
@@ -54,7 +54,7 @@ describe(parseBlock.name, () => {
54
54
  defineSchema({blockObjects: [{name: 'image'}]}),
55
55
  ),
56
56
  },
57
- options: {refreshKeys: false},
57
+ options: {refreshKeys: false, validateFields: true},
58
58
  }),
59
59
  ).toBe(undefined)
60
60
  })
@@ -69,7 +69,7 @@ describe(parseBlock.name, () => {
69
69
  defineSchema({blockObjects: [{name: 'image'}]}),
70
70
  ),
71
71
  },
72
- options: {refreshKeys: false},
72
+ options: {refreshKeys: false, validateFields: true},
73
73
  }),
74
74
  ).toEqual({
75
75
  _key: 'k0',
@@ -87,7 +87,7 @@ describe(parseBlock.name, () => {
87
87
  keyGenerator: createTestKeyGenerator(),
88
88
  schema: compileSchemaDefinition(defineSchema({})),
89
89
  },
90
- options: {refreshKeys: false},
90
+ options: {refreshKeys: false, validateFields: true},
91
91
  }),
92
92
  ).toEqual({
93
93
  _key: 'k0',
@@ -114,7 +114,7 @@ describe(parseBlock.name, () => {
114
114
  keyGenerator: createTestKeyGenerator(),
115
115
  schema: {...schema, block: {...schema.block, name: 'text'}},
116
116
  },
117
- options: {refreshKeys: false},
117
+ options: {refreshKeys: false, validateFields: true},
118
118
  }),
119
119
  ).toEqual({
120
120
  _key: 'k0',
@@ -149,7 +149,7 @@ describe(parseBlock.name, () => {
149
149
  keyGenerator: createTestKeyGenerator(),
150
150
  schema: compileSchemaDefinition(defineSchema({})),
151
151
  },
152
- options: {refreshKeys: false},
152
+ options: {refreshKeys: false, validateFields: true},
153
153
  }),
154
154
  ).toBe(undefined)
155
155
  })
@@ -188,7 +188,7 @@ describe(parseBlock.name, () => {
188
188
  }),
189
189
  ),
190
190
  },
191
- options: {refreshKeys: false},
191
+ options: {refreshKeys: false, validateFields: true},
192
192
  }),
193
193
  ).toEqual({
194
194
  _key: 'k0',
@@ -238,7 +238,7 @@ describe(parseBlock.name, () => {
238
238
  defineSchema({lists: [{name: 'bullet'}]}),
239
239
  ),
240
240
  },
241
- options: {refreshKeys: false},
241
+ options: {refreshKeys: false, validateFields: true},
242
242
  }),
243
243
  ).toEqual({
244
244
  _key: 'k0',
@@ -267,7 +267,7 @@ describe(parseBlock.name, () => {
267
267
  defineSchema({lists: [{name: 'bullet'}]}),
268
268
  ),
269
269
  },
270
- options: {refreshKeys: false},
270
+ options: {refreshKeys: false, validateFields: true},
271
271
  }),
272
272
  ).toEqual({
273
273
  _key: 'k0',
@@ -297,7 +297,7 @@ describe(parseSpan.name, () => {
297
297
  schema: compileSchemaDefinition(defineSchema({})),
298
298
  },
299
299
  markDefKeyMap: new Map(),
300
- options: {refreshKeys: false},
300
+ options: {refreshKeys: false, validateFields: true},
301
301
  }),
302
302
  ).toBe(undefined)
303
303
  })
@@ -311,7 +311,7 @@ describe(parseSpan.name, () => {
311
311
  schema: compileSchemaDefinition(defineSchema({})),
312
312
  },
313
313
  markDefKeyMap: new Map(),
314
- options: {refreshKeys: false},
314
+ options: {refreshKeys: false, validateFields: true},
315
315
  }),
316
316
  ).toBe(undefined)
317
317
  })
@@ -325,7 +325,7 @@ describe(parseSpan.name, () => {
325
325
  schema: compileSchemaDefinition(defineSchema({})),
326
326
  },
327
327
  markDefKeyMap: new Map(),
328
- options: {refreshKeys: false},
328
+ options: {refreshKeys: false, validateFields: true},
329
329
  }),
330
330
  ).toBe(undefined)
331
331
  })
@@ -339,7 +339,7 @@ describe(parseSpan.name, () => {
339
339
  schema: compileSchemaDefinition(defineSchema({})),
340
340
  },
341
341
  markDefKeyMap: new Map(),
342
- options: {refreshKeys: false},
342
+ options: {refreshKeys: false, validateFields: true},
343
343
  }),
344
344
  ).toBe(undefined)
345
345
  })
@@ -353,7 +353,7 @@ describe(parseSpan.name, () => {
353
353
  schema: compileSchemaDefinition(defineSchema({})),
354
354
  },
355
355
  markDefKeyMap: new Map(),
356
- options: {refreshKeys: false},
356
+ options: {refreshKeys: false, validateFields: true},
357
357
  }),
358
358
  ).toEqual({
359
359
  _key: 'k0',
@@ -372,7 +372,7 @@ describe(parseSpan.name, () => {
372
372
  schema: compileSchemaDefinition(defineSchema({})),
373
373
  },
374
374
  markDefKeyMap: new Map(),
375
- options: {refreshKeys: false},
375
+ options: {refreshKeys: false, validateFields: true},
376
376
  }),
377
377
  ).toEqual({
378
378
  _key: 'k0',
@@ -394,7 +394,7 @@ describe(parseSpan.name, () => {
394
394
  schema: compileSchemaDefinition(defineSchema({})),
395
395
  },
396
396
  markDefKeyMap: new Map(),
397
- options: {refreshKeys: false},
397
+ options: {refreshKeys: false, validateFields: true},
398
398
  }),
399
399
  ).toEqual({
400
400
  _key: 'k0',
@@ -418,7 +418,7 @@ describe(parseSpan.name, () => {
418
418
  ),
419
419
  },
420
420
  markDefKeyMap: new Map(),
421
- options: {refreshKeys: false},
421
+ options: {refreshKeys: false, validateFields: true},
422
422
  }),
423
423
  ).toEqual({
424
424
  _key: 'k0',
@@ -442,7 +442,7 @@ describe(parseSpan.name, () => {
442
442
  ),
443
443
  },
444
444
  markDefKeyMap: new Map(),
445
- options: {refreshKeys: false},
445
+ options: {refreshKeys: false, validateFields: true},
446
446
  }),
447
447
  ).toEqual({
448
448
  _key: 'k0',