@portabletext/editor 1.1.4 → 1.1.6

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 (38) hide show
  1. package/README.md +4 -0
  2. package/lib/index.d.mts +631 -30
  3. package/lib/index.d.ts +631 -30
  4. package/lib/index.esm.js +303 -200
  5. package/lib/index.esm.js.map +1 -1
  6. package/lib/index.js +295 -192
  7. package/lib/index.js.map +1 -1
  8. package/lib/index.mjs +303 -200
  9. package/lib/index.mjs.map +1 -1
  10. package/package.json +30 -25
  11. package/src/editor/Editable.tsx +11 -11
  12. package/src/editor/PortableTextEditor.tsx +37 -32
  13. package/src/editor/__tests__/self-solving.test.tsx +1 -1
  14. package/src/editor/behavior/behavior.actions.ts +39 -0
  15. package/src/editor/behavior/behavior.core.ts +37 -0
  16. package/src/editor/behavior/behavior.types.ts +106 -0
  17. package/src/editor/behavior/behavior.utils.ts +34 -0
  18. package/src/editor/components/SlateContainer.tsx +2 -13
  19. package/src/editor/components/Synchronizer.tsx +0 -3
  20. package/src/editor/editor-machine.ts +120 -3
  21. package/src/editor/hooks/useSyncValue.ts +3 -5
  22. package/src/editor/key-generator.ts +6 -0
  23. package/src/editor/plugins/createWithEditableAPI.ts +8 -5
  24. package/src/editor/plugins/createWithHotKeys.ts +1 -32
  25. package/src/editor/plugins/createWithInsertBreak.ts +6 -2
  26. package/src/editor/plugins/createWithInsertData.ts +7 -4
  27. package/src/editor/plugins/createWithObjectKeys.ts +12 -5
  28. package/src/editor/plugins/createWithPatches.ts +0 -1
  29. package/src/editor/plugins/createWithPortableTextMarkModel.ts +85 -114
  30. package/src/editor/plugins/createWithSchemaTypes.ts +3 -4
  31. package/src/editor/plugins/createWithUtils.ts +5 -4
  32. package/src/editor/plugins/index.ts +5 -13
  33. package/src/index.ts +11 -2
  34. package/src/types/options.ts +0 -1
  35. package/src/utils/__tests__/operationToPatches.test.ts +0 -2
  36. package/src/utils/__tests__/patchToOperations.test.ts +1 -2
  37. package/src/utils/sibling-utils.ts +55 -0
  38. package/src/editor/hooks/usePortableTextEditorKeyGenerator.ts +0 -27
package/lib/index.esm.js CHANGED
@@ -5,23 +5,23 @@ import { useRef, useState, useMemo, useEffect, useCallback, createContext, useCo
5
5
  import { Editor, Element as Element$1, Range, Point, Text, Path, Transforms, Node, Operation, createEditor } from "slate";
6
6
  import { useSlateStatic, ReactEditor, useSelected, withReact, Slate, useSlate, Editable } from "slate-react";
7
7
  import debug$m from "debug";
8
- import { isKeySegment, isPortableTextSpan as isPortableTextSpan$1, isPortableTextTextBlock, isPortableTextListBlock } from "@sanity/types";
8
+ import { isKeySegment, isPortableTextTextBlock, isPortableTextSpan, isPortableTextListBlock } from "@sanity/types";
9
9
  import { styled } from "styled-components";
10
10
  import uniq from "lodash/uniq.js";
11
11
  import { Subject } from "rxjs";
12
- import { fromCallback, setup, emit, assertEvent, assign, enqueueActions, createActor } from "xstate";
12
+ import { fromCallback, setup, assertEvent, assign, emit, enqueueActions, createActor } from "xstate";
13
13
  import { Schema } from "@sanity/schema";
14
+ import { isHotkey } from "is-hotkey-esm";
14
15
  import { diffMatchPatch as diffMatchPatch$1, set, insert, setIfMissing, unset, applyAll } from "@portabletext/patches";
15
16
  import get from "lodash/get.js";
16
17
  import isUndefined from "lodash/isUndefined.js";
17
18
  import omitBy from "lodash/omitBy.js";
18
19
  import flatten from "lodash/flatten.js";
19
- import { isHotkey } from "is-hotkey-esm";
20
20
  import { htmlToBlocks, normalizeBlock } from "@sanity/block-tools";
21
21
  import isPlainObject from "lodash/isPlainObject.js";
22
22
  import throttle from "lodash/throttle.js";
23
- import { randomKey } from "@sanity/util/content";
24
23
  import debounce from "lodash/debounce.js";
24
+ import { randomKey } from "@sanity/util/content";
25
25
  const rootName = "sanity-pte:";
26
26
  debug$m(rootName);
27
27
  function debugWithName(name) {
@@ -808,7 +808,28 @@ function compileType(rawType) {
808
808
  types: [rawType]
809
809
  }).get(rawType.name);
810
810
  }
811
- const debug$k = debugWithName("operationToPatches");
811
+ function getFocusBlock(context) {
812
+ const key = context.selection && isKeySegment(context.selection.focus.path[0]) ? context.selection.focus.path[0]._key : void 0, node = key ? context.value.find((block) => block._key === key) : void 0;
813
+ return node && key ? { node, path: [{ _key: key }] } : void 0;
814
+ }
815
+ function getFocusBlockObject(context) {
816
+ const focusBlock = getFocusBlock(context);
817
+ return focusBlock && !isPortableTextTextBlock(focusBlock.node) ? { node: focusBlock.node, path: focusBlock.path } : void 0;
818
+ }
819
+ const overwriteSoftReturn = {
820
+ on: "key down",
821
+ guard: ({ event }) => isHotkey("shift+enter", event.nativeEvent),
822
+ actions: [
823
+ ({ event }) => (event.nativeEvent.preventDefault(), { type: "insert text", text: `
824
+ ` })
825
+ ]
826
+ }, enterOnVoidBlock = {
827
+ on: "key down",
828
+ guard: ({ context, event }) => isHotkey("enter", event.nativeEvent) ? !!getFocusBlockObject(context) : !1,
829
+ actions: [
830
+ ({ event }) => (event.nativeEvent.preventDefault(), { type: "insert text block", decorators: [] })
831
+ ]
832
+ }, coreBehaviors = [overwriteSoftReturn, enterOnVoidBlock], debug$k = debugWithName("operationToPatches");
812
833
  function createOperationToPatches(types) {
813
834
  const textBlockName = types.block.name;
814
835
  function insertTextPatch(editor, operation, beforeValue) {
@@ -1084,7 +1105,7 @@ function createOperationToPatches(types) {
1084
1105
  };
1085
1106
  }
1086
1107
  const debug$j = debugWithName("API:editable");
1087
- function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
1108
+ function createWithEditableAPI(editorActor, portableTextEditor, types) {
1088
1109
  return function(editor) {
1089
1110
  return portableTextEditor.setEditable({
1090
1111
  focus: () => {
@@ -1164,11 +1185,11 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
1164
1185
  const child = toSlateValue(
1165
1186
  [
1166
1187
  {
1167
- _key: keyGenerator(),
1188
+ _key: editorActor.getSnapshot().context.keyGenerator(),
1168
1189
  _type: types.block.name,
1169
1190
  children: [
1170
1191
  {
1171
- _key: keyGenerator(),
1192
+ _key: editorActor.getSnapshot().context.keyGenerator(),
1172
1193
  _type: type.name,
1173
1194
  ...value || {}
1174
1195
  }
@@ -1196,7 +1217,7 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
1196
1217
  const block = toSlateValue(
1197
1218
  [
1198
1219
  {
1199
- _key: keyGenerator(),
1220
+ _key: editorActor.getSnapshot().context.keyGenerator(),
1200
1221
  _type: type.name,
1201
1222
  ...value || {}
1202
1223
  }
@@ -1329,14 +1350,14 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
1329
1350
  })
1330
1351
  ];
1331
1352
  if (spans.length === 0 || spans.some(
1332
- ([span]) => !isPortableTextSpan$1(span) || !span.marks || span.marks?.length === 0
1353
+ ([span]) => !isPortableTextSpan(span) || !span.marks || span.marks?.length === 0
1333
1354
  ))
1334
1355
  return !1;
1335
1356
  const selectionMarkDefs = spans.reduce((accMarkDefs, [, path]) => {
1336
1357
  const [block] = Editor.node(editor, path, { depth: 1 });
1337
1358
  return editor.isTextBlock(block) && block.markDefs ? [...accMarkDefs, ...block.markDefs] : accMarkDefs;
1338
1359
  }, []);
1339
- return spans.every(([span]) => isPortableTextSpan$1(span) ? span.marks?.map(
1360
+ return spans.every(([span]) => isPortableTextSpan(span) ? span.marks?.map(
1340
1361
  (markKey) => selectionMarkDefs.find((def) => def?._key === markKey)?._type
1341
1362
  )?.includes(annotationType) : !1);
1342
1363
  } catch {
@@ -1360,7 +1381,7 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
1360
1381
  for (const [block, blockPath] of selectedBlocks) {
1361
1382
  if (block.children.length === 0 || block.children.length === 1 && block.children[0].text === "")
1362
1383
  continue;
1363
- const annotationKey = keyGenerator(), markDefs = block.markDefs ?? [];
1384
+ const annotationKey = editorActor.getSnapshot().context.keyGenerator(), markDefs = block.markDefs ?? [];
1364
1385
  markDefs.find(
1365
1386
  (markDef) => markDef._type === type.name && markDef._key === annotationKey
1366
1387
  ) === void 0 && (Transforms.setNodes(
@@ -1569,7 +1590,7 @@ function createWithEditableAPI(portableTextEditor, types, keyGenerator) {
1569
1590
  }), editor;
1570
1591
  };
1571
1592
  }
1572
- function createWithInsertBreak(types, keyGenerator) {
1593
+ function createWithInsertBreak(editorActor, types) {
1573
1594
  return function(editor) {
1574
1595
  const { insertBreak } = editor;
1575
1596
  return editor.insertBreak = () => {
@@ -1658,7 +1679,10 @@ function createWithInsertBreak(types, keyGenerator) {
1658
1679
  (decorator) => decorator.value === mark
1659
1680
  ) || prevNodeSpans.some(
1660
1681
  (prevNodeSpan) => prevNodeSpan.marks?.includes(mark)
1661
- ) && !newMarkDefKeys.has(mark) && newMarkDefKeys.set(mark, keyGenerator());
1682
+ ) && !newMarkDefKeys.has(mark) && newMarkDefKeys.set(
1683
+ mark,
1684
+ editorActor.getSnapshot().context.keyGenerator()
1685
+ );
1662
1686
  const newMarks = marks.map(
1663
1687
  (mark) => newMarkDefKeys.get(mark) ?? mark
1664
1688
  );
@@ -1739,7 +1763,7 @@ function createWithMaxBlocks(maxBlocks) {
1739
1763
  }, editor;
1740
1764
  };
1741
1765
  }
1742
- function createWithObjectKeys(editorActor, schemaTypes, keyGenerator) {
1766
+ function createWithObjectKeys(editorActor, schemaTypes) {
1743
1767
  return function(editor) {
1744
1768
  const { apply: apply2, normalizeNode } = editor;
1745
1769
  return editor.apply = (operation) => {
@@ -1756,7 +1780,7 @@ function createWithObjectKeys(editorActor, schemaTypes, keyGenerator) {
1756
1780
  ...operation,
1757
1781
  properties: {
1758
1782
  ...operation.properties,
1759
- _key: keyGenerator()
1783
+ _key: editorActor.getSnapshot().context.keyGenerator()
1760
1784
  }
1761
1785
  });
1762
1786
  return;
@@ -1766,7 +1790,7 @@ function createWithObjectKeys(editorActor, schemaTypes, keyGenerator) {
1766
1790
  ...operation,
1767
1791
  node: {
1768
1792
  ...operation.node,
1769
- _key: keyGenerator()
1793
+ _key: editorActor.getSnapshot().context.keyGenerator()
1770
1794
  }
1771
1795
  });
1772
1796
  return;
@@ -1776,12 +1800,20 @@ function createWithObjectKeys(editorActor, schemaTypes, keyGenerator) {
1776
1800
  const [node, path] = entry;
1777
1801
  if (Element$1.isElement(node) && node._type === schemaTypes.block.name) {
1778
1802
  if (!node._key) {
1779
- editorActor.send({ type: "normalizing" }), Transforms.setNodes(editor, { _key: keyGenerator() }, { at: path }), editorActor.send({ type: "done normalizing" });
1803
+ editorActor.send({ type: "normalizing" }), Transforms.setNodes(
1804
+ editor,
1805
+ { _key: editorActor.getSnapshot().context.keyGenerator() },
1806
+ { at: path }
1807
+ ), editorActor.send({ type: "done normalizing" });
1780
1808
  return;
1781
1809
  }
1782
1810
  for (const [child, childPath] of Node.children(editor, path))
1783
1811
  if (!child._key) {
1784
- editorActor.send({ type: "normalizing" }), Transforms.setNodes(editor, { _key: keyGenerator() }, { at: childPath }), editorActor.send({ type: "done normalizing" });
1812
+ editorActor.send({ type: "normalizing" }), Transforms.setNodes(
1813
+ editor,
1814
+ { _key: editorActor.getSnapshot().context.keyGenerator() },
1815
+ { at: childPath }
1816
+ ), editorActor.send({ type: "done normalizing" });
1785
1817
  return;
1786
1818
  }
1787
1819
  }
@@ -3257,9 +3289,6 @@ function createWithPortableTextLists(types) {
3257
3289
  }, editor;
3258
3290
  };
3259
3291
  }
3260
- function isPortableTextSpan(node) {
3261
- return node._type === "span" && "text" in node && typeof node.text == "string" && (typeof node.marks > "u" || Array.isArray(node.marks) && node.marks.every((mark) => typeof mark == "string"));
3262
- }
3263
3292
  function isPortableTextBlock(node) {
3264
3293
  return (
3265
3294
  // A block doesn't _have_ to be named 'block' - to differentiate between
@@ -3272,8 +3301,36 @@ function isPortableTextBlock(node) {
3272
3301
  node.children.every((child) => typeof child == "object" && "_type" in child)
3273
3302
  );
3274
3303
  }
3304
+ function getPreviousSpan({
3305
+ editor,
3306
+ blockPath,
3307
+ spanPath
3308
+ }) {
3309
+ let previousSpan;
3310
+ for (const [child, childPath] of Node.children(editor, blockPath, {
3311
+ reverse: !0
3312
+ }))
3313
+ if (editor.isTextSpan(child) && Path.isBefore(childPath, spanPath)) {
3314
+ previousSpan = child;
3315
+ break;
3316
+ }
3317
+ return previousSpan;
3318
+ }
3319
+ function getNextSpan({
3320
+ editor,
3321
+ blockPath,
3322
+ spanPath
3323
+ }) {
3324
+ let nextSpan;
3325
+ for (const [child, childPath] of Node.children(editor, blockPath))
3326
+ if (editor.isTextSpan(child) && Path.isAfter(childPath, spanPath)) {
3327
+ nextSpan = child;
3328
+ break;
3329
+ }
3330
+ return nextSpan;
3331
+ }
3275
3332
  const debug$c = debugWithName("plugin:withPortableTextMarkModel");
3276
- function createWithPortableTextMarkModel(editorActor, types, keyGenerator) {
3333
+ function createWithPortableTextMarkModel(editorActor, types) {
3277
3334
  return function(editor) {
3278
3335
  const { apply: apply2, normalizeNode } = editor, decorators = types.decorators.map((t) => t.value), forceNewSelection = () => {
3279
3336
  editor.selection && (Transforms.select(editor, { ...editor.selection }), editor.selection = { ...editor.selection });
@@ -3411,98 +3468,85 @@ function createWithPortableTextMarkModel(editorActor, types, keyGenerator) {
3411
3468
  })
3412
3469
  )[0] ?? [void 0, void 0], marks = span.marks ?? [], marksWithoutAnnotations = marks.filter(
3413
3470
  (mark) => decorators.includes(mark)
3414
- ), spanHasAnnotations = marks.length > marksWithoutAnnotations.length, spanIsEmpty = span.text.length === 0, atTheBeginningOfSpan = selection.anchor.offset === 0, atTheEndOfSpan = selection.anchor.offset === span.text.length;
3415
- let previousSpan, nextSpan;
3416
- for (const [child, childPath] of Node.children(editor, blockPath, {
3417
- reverse: !0
3418
- }))
3419
- if (editor.isTextSpan(child) && Path.isBefore(childPath, spanPath)) {
3420
- previousSpan = child;
3421
- break;
3422
- }
3423
- for (const [child, childPath] of Node.children(editor, blockPath))
3424
- if (editor.isTextSpan(child) && Path.isAfter(childPath, spanPath)) {
3425
- nextSpan = child;
3426
- break;
3427
- }
3428
- const previousSpanHasSameAnnotation = previousSpan ? previousSpan.marks?.some(
3471
+ ), spanHasAnnotations = marks.length > marksWithoutAnnotations.length, spanIsEmpty = span.text.length === 0, atTheBeginningOfSpan = selection.anchor.offset === 0, atTheEndOfSpan = selection.anchor.offset === span.text.length, previousSpan = getPreviousSpan({ editor, blockPath, spanPath }), nextSpan = getNextSpan({ editor, blockPath, spanPath }), nextSpanAnnotations = nextSpan?.marks?.filter((mark) => !decorators.includes(mark)) ?? [], spanAnnotations = marks.filter(
3472
+ (mark) => !decorators.includes(mark)
3473
+ ), previousSpanHasSameAnnotation = previousSpan ? previousSpan.marks?.some(
3429
3474
  (mark) => !decorators.includes(mark) && marks.includes(mark)
3430
- ) : !1, previousSpanHasSameMarks = previousSpan ? previousSpan.marks?.every((mark) => marks.includes(mark)) : !1, nextSpanHasSameAnnotation = nextSpan ? nextSpan.marks?.some(
3431
- (mark) => !decorators.includes(mark) && marks.includes(mark)
3432
- ) : !1, nextSpanHasSameMarks = nextSpan ? nextSpan.marks?.every((mark) => marks.includes(mark)) : !1;
3475
+ ) : !1, previousSpanHasSameMarks = previousSpan ? previousSpan.marks?.every((mark) => marks.includes(mark)) : !1, nextSpanSharesSomeAnnotations = spanAnnotations.some(
3476
+ (mark) => nextSpanAnnotations?.includes(mark)
3477
+ );
3433
3478
  if (spanHasAnnotations && !spanIsEmpty) {
3434
3479
  if (atTheBeginningOfSpan) {
3435
3480
  previousSpanHasSameMarks ? Transforms.insertNodes(editor, {
3436
3481
  _type: "span",
3437
- _key: keyGenerator(),
3482
+ _key: editorActor.getSnapshot().context.keyGenerator(),
3438
3483
  text: op.text,
3439
3484
  marks: previousSpan?.marks ?? []
3440
3485
  }) : previousSpanHasSameAnnotation ? apply2(op) : Transforms.insertNodes(editor, {
3441
3486
  _type: "span",
3442
- _key: keyGenerator(),
3487
+ _key: editorActor.getSnapshot().context.keyGenerator(),
3443
3488
  text: op.text,
3444
3489
  marks: []
3445
3490
  });
3446
3491
  return;
3447
3492
  }
3448
3493
  if (atTheEndOfSpan) {
3449
- nextSpanHasSameMarks ? Transforms.insertNodes(editor, {
3450
- _type: "span",
3451
- _key: keyGenerator(),
3452
- text: op.text,
3453
- marks: nextSpan?.marks ?? []
3454
- }) : nextSpanHasSameAnnotation ? apply2(op) : Transforms.insertNodes(editor, {
3455
- _type: "span",
3456
- _key: keyGenerator(),
3457
- text: op.text,
3458
- marks: []
3459
- });
3460
- return;
3494
+ if (nextSpan && nextSpanSharesSomeAnnotations && nextSpanAnnotations.length < spanAnnotations.length || !nextSpanSharesSomeAnnotations) {
3495
+ Transforms.insertNodes(editor, {
3496
+ _type: "span",
3497
+ _key: editorActor.getSnapshot().context.keyGenerator(),
3498
+ text: op.text,
3499
+ marks: nextSpan?.marks ?? []
3500
+ });
3501
+ return;
3502
+ }
3503
+ if (!nextSpan) {
3504
+ Transforms.insertNodes(editor, {
3505
+ _type: "span",
3506
+ _key: editorActor.getSnapshot().context.keyGenerator(),
3507
+ text: op.text,
3508
+ marks: []
3509
+ });
3510
+ return;
3511
+ }
3461
3512
  }
3462
3513
  }
3463
3514
  }
3464
3515
  }
3465
3516
  if (op.type === "remove_text") {
3466
- const node = Array.from(
3467
- Editor.nodes(editor, {
3468
- mode: "lowest",
3469
- at: { path: op.path, offset: op.offset },
3470
- match: (n) => n._type === types.span.name,
3471
- voids: !1
3472
- })
3473
- )[0][0], block = Editor.node(editor, Path.parent(op.path))[0];
3474
- if (node && isPortableTextSpan(node) && block && isPortableTextBlock(block)) {
3475
- const markDefs = block.markDefs ?? [], nodeHasAnnotations = (node.marks ?? []).some(
3476
- (mark) => markDefs.find((markDef) => markDef._key === mark)
3477
- ), deletingPartOfTheNode = op.offset !== 0, deletingFromTheEnd = op.offset + op.text.length === node.text.length;
3478
- if (nodeHasAnnotations && deletingPartOfTheNode && deletingFromTheEnd) {
3479
- Editor.withoutNormalizing(editor, () => {
3480
- Transforms.splitNodes(editor, {
3481
- match: Text.isText,
3482
- at: { path: op.path, offset: op.offset }
3483
- }), Transforms.removeNodes(editor, { at: Path.next(op.path) });
3484
- }), editor.onChange();
3485
- return;
3486
- }
3487
- const deletingAllText = op.offset === 0 && deletingFromTheEnd;
3488
- if (nodeHasAnnotations && deletingAllText) {
3489
- const marksWithoutAnnotationMarks = ({
3490
- ...Editor.marks(editor) || {}
3491
- }.marks || []).filter((mark) => decorators.includes(mark));
3492
- Editor.withoutNormalizing(editor, () => {
3493
- apply2(op), Transforms.setNodes(
3494
- editor,
3495
- { marks: marksWithoutAnnotationMarks },
3496
- { at: op.path }
3497
- );
3498
- }), editor.onChange();
3499
- return;
3500
- }
3501
- if (node.marks !== void 0 && node.marks.length > 0 && deletingAllText) {
3502
- Editor.withoutNormalizing(editor, () => {
3503
- apply2(op), Transforms.setNodes(editor, { marks: [] }, { at: op.path });
3504
- }), editor.onChange();
3505
- return;
3517
+ const { selection } = editor;
3518
+ if (selection && Range.isExpanded(selection)) {
3519
+ const [block, blockPath] = Editor.node(editor, selection, {
3520
+ depth: 1
3521
+ }), [span, spanPath] = Array.from(
3522
+ Editor.nodes(editor, {
3523
+ mode: "lowest",
3524
+ at: { path: op.path, offset: op.offset },
3525
+ match: (n) => editor.isTextSpan(n),
3526
+ voids: !1
3527
+ })
3528
+ )[0] ?? [void 0, void 0];
3529
+ if (span && block && isPortableTextBlock(block)) {
3530
+ const markDefs = block.markDefs ?? [], marks = span.marks ?? [], spanHasAnnotations = marks.some(
3531
+ (mark) => markDefs.find((markDef) => markDef._key === mark)
3532
+ ), deletingFromTheEnd = op.offset + op.text.length === span.text.length, deletingAllText = op.offset === 0 && deletingFromTheEnd, previousSpan = getPreviousSpan({ editor, blockPath, spanPath }), nextSpan = getNextSpan({ editor, blockPath, spanPath }), previousSpanHasSameAnnotation = previousSpan ? previousSpan.marks?.some(
3533
+ (mark) => !decorators.includes(mark) && marks.includes(mark)
3534
+ ) : !1, nextSpanHasSameAnnotation = nextSpan ? nextSpan.marks?.some(
3535
+ (mark) => !decorators.includes(mark) && marks.includes(mark)
3536
+ ) : !1;
3537
+ if (spanHasAnnotations && deletingAllText && !previousSpanHasSameAnnotation && !nextSpanHasSameAnnotation) {
3538
+ const marksWithoutAnnotationMarks = ({
3539
+ ...Editor.marks(editor) || {}
3540
+ }.marks || []).filter((mark) => decorators.includes(mark));
3541
+ Editor.withoutNormalizing(editor, () => {
3542
+ apply2(op), Transforms.setNodes(
3543
+ editor,
3544
+ { marks: marksWithoutAnnotationMarks },
3545
+ { at: op.path }
3546
+ );
3547
+ }), editor.onChange();
3548
+ return;
3549
+ }
3506
3550
  }
3507
3551
  }
3508
3552
  }
@@ -3686,17 +3730,16 @@ function createWithPortableTextSelections(editorActor, types) {
3686
3730
  const debug$a = debugWithName("plugin:withSchemaTypes");
3687
3731
  function createWithSchemaTypes({
3688
3732
  editorActor,
3689
- schemaTypes,
3690
- keyGenerator
3733
+ schemaTypes
3691
3734
  }) {
3692
3735
  return function(editor) {
3693
- editor.isTextBlock = (value) => isPortableTextTextBlock(value) && value._type === schemaTypes.block.name, editor.isTextSpan = (value) => isPortableTextSpan$1(value) && value._type === schemaTypes.span.name, editor.isListBlock = (value) => isPortableTextListBlock(value) && value._type === schemaTypes.block.name, editor.isVoid = (element) => schemaTypes.block.name !== element._type && (schemaTypes.blockObjects.map((obj) => obj.name).includes(element._type) || schemaTypes.inlineObjects.map((obj) => obj.name).includes(element._type)), editor.isInline = (element) => schemaTypes.inlineObjects.map((obj) => obj.name).includes(element._type) && "__inline" in element && element.__inline === !0;
3736
+ editor.isTextBlock = (value) => isPortableTextTextBlock(value) && value._type === schemaTypes.block.name, editor.isTextSpan = (value) => isPortableTextSpan(value) && value._type === schemaTypes.span.name, editor.isListBlock = (value) => isPortableTextListBlock(value) && value._type === schemaTypes.block.name, editor.isVoid = (element) => schemaTypes.block.name !== element._type && (schemaTypes.blockObjects.map((obj) => obj.name).includes(element._type) || schemaTypes.inlineObjects.map((obj) => obj.name).includes(element._type)), editor.isInline = (element) => schemaTypes.inlineObjects.map((obj) => obj.name).includes(element._type) && "__inline" in element && element.__inline === !0;
3694
3737
  const { normalizeNode } = editor;
3695
3738
  return editor.normalizeNode = (entry) => {
3696
3739
  const [node, path] = entry;
3697
3740
  if (node._type === void 0 && path.length === 2) {
3698
3741
  debug$a("Setting span type on text node without a type");
3699
- const span = node, key = span._key || keyGenerator();
3742
+ const span = node, key = span._key || editorActor.getSnapshot().context.keyGenerator();
3700
3743
  editorActor.send({ type: "normalizing" }), Transforms.setNodes(
3701
3744
  editor,
3702
3745
  { ...span, _type: schemaTypes.span.name, _key: key },
@@ -3706,7 +3749,7 @@ function createWithSchemaTypes({
3706
3749
  }
3707
3750
  if (node._key === void 0 && (path.length === 1 || path.length === 2)) {
3708
3751
  debug$a("Setting missing key on child node without a key");
3709
- const key = keyGenerator();
3752
+ const key = editorActor.getSnapshot().context.keyGenerator();
3710
3753
  editorActor.send({ type: "normalizing" }), Transforms.setNodes(editor, { _key: key }, { at: path }), editorActor.send({ type: "done normalizing" });
3711
3754
  return;
3712
3755
  }
@@ -3716,8 +3759,8 @@ function createWithSchemaTypes({
3716
3759
  }
3717
3760
  const debug$9 = debugWithName("plugin:withUtils");
3718
3761
  function createWithUtils({
3762
+ editorActor,
3719
3763
  schemaTypes,
3720
- keyGenerator,
3721
3764
  portableTextEditor
3722
3765
  }) {
3723
3766
  return function(editor) {
@@ -3743,13 +3786,13 @@ function createWithUtils({
3743
3786
  [
3744
3787
  {
3745
3788
  _type: schemaTypes.block.name,
3746
- _key: keyGenerator(),
3789
+ _key: editorActor.getSnapshot().context.keyGenerator(),
3747
3790
  style: schemaTypes.styles[0].value || "normal",
3748
3791
  markDefs: [],
3749
3792
  children: [
3750
3793
  {
3751
3794
  _type: "span",
3752
- _key: keyGenerator(),
3795
+ _key: editorActor.getSnapshot().context.keyGenerator(),
3753
3796
  text: "",
3754
3797
  marks: options.decorators.filter(
3755
3798
  (decorator) => schemaTypes.decorators.find(({ value }) => value === decorator)
@@ -3817,7 +3860,7 @@ function createWithHotkeys(types, portableTextEditor, hotkeysFromOptions) {
3817
3860
  {
3818
3861
  at: nextPath
3819
3862
  }
3820
- ), editor.onChange();
3863
+ ), Transforms.select(editor, { path: [...nextPath, 0], offset: 0 }), editor.onChange();
3821
3864
  return;
3822
3865
  }
3823
3866
  }
@@ -3841,10 +3884,10 @@ function createWithHotkeys(types, portableTextEditor, hotkeysFromOptions) {
3841
3884
  if ((isTab || isShiftTab) && editor.selection) {
3842
3885
  const [focusChild] = Editor.node(editor, editor.selection.focus, {
3843
3886
  depth: 2
3844
- }), [focusBlock] = isPortableTextSpan$1(focusChild) ? Editor.node(editor, editor.selection.focus, { depth: 1 }) : [], hasAnnotationFocus = focusChild && isPortableTextTextBlock(focusBlock) && isPortableTextSpan$1(focusChild) && (focusChild.marks || []).filter(
3887
+ }), [focusBlock] = isPortableTextSpan(focusChild) ? Editor.node(editor, editor.selection.focus, { depth: 1 }) : [], hasAnnotationFocus = focusChild && isPortableTextTextBlock(focusBlock) && isPortableTextSpan(focusChild) && (focusChild.marks || []).filter(
3845
3888
  (m) => (focusBlock.markDefs || []).map((def) => def._key).includes(m)
3846
3889
  ).length > 0, [start] = Range.edges(editor.selection), atStartOfNode = Editor.isStart(editor, start, start.path);
3847
- focusChild && isPortableTextSpan$1(focusChild) && (!hasAnnotationFocus || atStartOfNode) && editor.pteIncrementBlockLevels(isShiftTab) && event.preventDefault();
3890
+ focusChild && isPortableTextSpan(focusChild) && (!hasAnnotationFocus || atStartOfNode) && editor.pteIncrementBlockLevels(isShiftTab) && event.preventDefault();
3848
3891
  }
3849
3892
  if (isEnter && !isShiftEnter && editor.selection) {
3850
3893
  const focusBlockPath = editor.selection.focus.path.slice(0, 1), focusBlock = Node.descendant(editor, focusBlockPath);
@@ -3862,22 +3905,7 @@ function createWithHotkeys(types, portableTextEditor, hotkeysFromOptions) {
3862
3905
  return;
3863
3906
  }
3864
3907
  }
3865
- if (focusBlock && Editor.isVoid(editor, focusBlock)) {
3866
- Editor.insertNode(editor, editor.pteCreateTextBlock({ decorators: [] })), event.preventDefault(), editor.onChange();
3867
- return;
3868
- }
3869
- event.preventDefault(), editor.insertBreak(), editor.onChange();
3870
- }
3871
- if (isShiftEnter) {
3872
- event.preventDefault(), editor.insertText(`
3873
- `);
3874
- return;
3875
3908
  }
3876
- if (isHotkey("mod+z", event.nativeEvent)) {
3877
- event.preventDefault(), editor.undo();
3878
- return;
3879
- }
3880
- (isHotkey("mod+y", event.nativeEvent) || isHotkey("mod+shift+z", event.nativeEvent)) && (event.preventDefault(), editor.redo());
3881
3909
  }, editor;
3882
3910
  };
3883
3911
  }
@@ -4160,7 +4188,7 @@ function validateValue(value, types, keyGenerator) {
4160
4188
  }) && (valid = !1), { valid, resolution, value });
4161
4189
  }
4162
4190
  const debug$7 = debugWithName("plugin:withInsertData");
4163
- function createWithInsertData(editorActor, schemaTypes, keyGenerator) {
4191
+ function createWithInsertData(editorActor, schemaTypes) {
4164
4192
  return function(editor) {
4165
4193
  const blockTypeName = schemaTypes.block.name, spanTypeName = schemaTypes.span.name, whitespaceOnPasteMode = schemaTypes.block.options.unstable_whitespaceOnPasteMode, toPlainText = (blocks) => blocks.map((block) => editor.isTextBlock(block) ? block.children.map((child) => child._type === spanTypeName ? child.text : `[${schemaTypes.inlineObjects.find((t) => t.name === child._type)?.title || "Object"}]`).join("") : `[${schemaTypes.blockObjects.find((t) => t.name === block._type)?.title || "Object"}]`).join(`
4166
4194
 
@@ -4208,10 +4236,14 @@ function createWithInsertData(editorActor, schemaTypes, keyGenerator) {
4208
4236
  const slateValue = _regenerateKeys(
4209
4237
  editor,
4210
4238
  toSlateValue(parsed, { schemaTypes }),
4211
- keyGenerator,
4239
+ editorActor.getSnapshot().context.keyGenerator,
4212
4240
  spanTypeName,
4213
4241
  schemaTypes
4214
- ), validation = validateValue(parsed, schemaTypes, keyGenerator);
4242
+ ), validation = validateValue(
4243
+ parsed,
4244
+ schemaTypes,
4245
+ editorActor.getSnapshot().context.keyGenerator
4246
+ );
4215
4247
  if (!validation.valid && !validation.resolution?.autoResolve) {
4216
4248
  const errorDescription = `${validation.resolution?.description}`;
4217
4249
  return editorActor.send({
@@ -4252,7 +4284,7 @@ function createWithInsertData(editorActor, schemaTypes, keyGenerator) {
4252
4284
  const validation = validateValue(
4253
4285
  portableText,
4254
4286
  schemaTypes,
4255
- keyGenerator
4287
+ editorActor.getSnapshot().context.keyGenerator
4256
4288
  );
4257
4289
  if (!validation.valid) {
4258
4290
  const errorDescription = `Could not validate the resulting portable text to insert.
@@ -4356,27 +4388,21 @@ function _insertFragment(editor, fragment, schemaTypes) {
4356
4388
  }), editor.onChange();
4357
4389
  }
4358
4390
  const originalFnMap = /* @__PURE__ */ new WeakMap(), withPlugins = (editor, options) => {
4359
- const e = editor, { keyGenerator, portableTextEditor, patches$, readOnly, maxBlocks } = options, { editorActor, schemaTypes } = portableTextEditor;
4391
+ const e = editor, { portableTextEditor, patches$, readOnly, maxBlocks } = options, { editorActor, schemaTypes } = portableTextEditor;
4360
4392
  e.subscriptions = [], e.destroy ? e.destroy() : originalFnMap.set(e, {
4361
4393
  apply: e.apply,
4362
4394
  onChange: e.onChange,
4363
4395
  normalizeNode: e.normalizeNode
4364
4396
  });
4365
- const operationToPatches = createOperationToPatches(schemaTypes), withObjectKeys = createWithObjectKeys(
4397
+ const operationToPatches = createOperationToPatches(schemaTypes), withObjectKeys = createWithObjectKeys(editorActor, schemaTypes), withSchemaTypes = createWithSchemaTypes({
4366
4398
  editorActor,
4367
- schemaTypes,
4368
- keyGenerator
4369
- ), withSchemaTypes = createWithSchemaTypes({
4370
- editorActor,
4371
- schemaTypes,
4372
- keyGenerator
4399
+ schemaTypes
4373
4400
  }), withEditableAPI = createWithEditableAPI(
4401
+ editorActor,
4374
4402
  portableTextEditor,
4375
- schemaTypes,
4376
- keyGenerator
4403
+ schemaTypes
4377
4404
  ), withPatches = createWithPatches({
4378
4405
  editorActor,
4379
- keyGenerator,
4380
4406
  patches$,
4381
4407
  patchFunctions: operationToPatches,
4382
4408
  readOnly,
@@ -4387,13 +4413,12 @@ const originalFnMap = /* @__PURE__ */ new WeakMap(), withPlugins = (editor, opti
4387
4413
  blockSchemaType: schemaTypes.block
4388
4414
  }), withPortableTextMarkModel = createWithPortableTextMarkModel(
4389
4415
  editorActor,
4390
- schemaTypes,
4391
- keyGenerator
4416
+ schemaTypes
4392
4417
  ), withPortableTextBlockStyle = createWithPortableTextBlockStyle(
4393
4418
  editorActor,
4394
4419
  schemaTypes
4395
- ), withPlaceholderBlock = createWithPlaceholderBlock(), withInsertBreak = createWithInsertBreak(schemaTypes, keyGenerator), withUtils = createWithUtils({
4396
- keyGenerator,
4420
+ ), withPlaceholderBlock = createWithPlaceholderBlock(), withInsertBreak = createWithInsertBreak(editorActor, schemaTypes), withUtils = createWithUtils({
4421
+ editorActor,
4397
4422
  schemaTypes,
4398
4423
  portableTextEditor
4399
4424
  }), withPortableTextSelections = createWithPortableTextSelections(
@@ -4461,10 +4486,9 @@ const originalFnMap = /* @__PURE__ */ new WeakMap(), withPlugins = (editor, opti
4461
4486
  };
4462
4487
  }, debug$6 = debugWithName("component:PortableTextEditor:SlateContainer");
4463
4488
  function SlateContainer(props) {
4464
- const { patches$, portableTextEditor, readOnly, maxBlocks, keyGenerator } = props, [[slateEditor, subscribe]] = useState(() => {
4489
+ const { patches$, portableTextEditor, readOnly, maxBlocks } = props, [[slateEditor, subscribe]] = useState(() => {
4465
4490
  debug$6("Creating new Slate editor instance");
4466
4491
  const { editor, subscribe: _sub } = withPlugins(withReact(createEditor()), {
4467
- keyGenerator,
4468
4492
  maxBlocks,
4469
4493
  patches$,
4470
4494
  portableTextEditor,
@@ -4479,33 +4503,18 @@ function SlateContainer(props) {
4479
4503
  };
4480
4504
  }, [subscribe]), useEffect(() => {
4481
4505
  debug$6("Re-initializing plugin chain"), withPlugins(slateEditor, {
4482
- keyGenerator,
4483
4506
  maxBlocks,
4484
4507
  patches$,
4485
4508
  portableTextEditor,
4486
4509
  readOnly
4487
4510
  });
4488
- }, [
4489
- keyGenerator,
4490
- portableTextEditor,
4491
- maxBlocks,
4492
- readOnly,
4493
- patches$,
4494
- slateEditor
4495
- ]);
4511
+ }, [portableTextEditor, maxBlocks, readOnly, patches$, slateEditor]);
4496
4512
  const initialValue = useMemo(() => [slateEditor.pteCreateTextBlock({ decorators: [] })], [slateEditor]);
4497
4513
  return useEffect(() => () => {
4498
4514
  debug$6("Destroying Slate editor"), slateEditor.destroy();
4499
4515
  }, [slateEditor]), /* @__PURE__ */ jsx(Slate, { editor: slateEditor, initialValue, children: props.children });
4500
4516
  }
4501
- const defaultKeyGenerator = () => randomKey(12), PortableTextEditorKeyGeneratorContext = createContext(defaultKeyGenerator), usePortableTextEditorKeyGenerator = () => {
4502
- const keyGenerator = useContext(PortableTextEditorKeyGeneratorContext);
4503
- if (keyGenerator === void 0)
4504
- throw new Error(
4505
- "The `usePortableTextEditorKeyGenerator` hook must be used inside the <PortableTextEditor> component's context."
4506
- );
4507
- return keyGenerator;
4508
- }, PortableTextEditorReadOnlyContext = createContext(!1), usePortableTextEditorReadOnlyStatus = () => {
4517
+ const PortableTextEditorReadOnlyContext = createContext(!1), usePortableTextEditorReadOnlyStatus = () => {
4509
4518
  const readOnly = useContext(PortableTextEditorReadOnlyContext);
4510
4519
  if (readOnly === void 0)
4511
4520
  throw new Error(
@@ -4514,7 +4523,7 @@ const defaultKeyGenerator = () => randomKey(12), PortableTextEditorKeyGeneratorC
4514
4523
  return readOnly;
4515
4524
  }, debug$5 = debugWithName("hook:useSyncValue"), CURRENT_VALUE = /* @__PURE__ */ new WeakMap();
4516
4525
  function useSyncValue(props) {
4517
- const { editorActor, portableTextEditor, readOnly, keyGenerator } = props, { schemaTypes } = portableTextEditor, previousValue = useRef(), slateEditor = useSlate(), updateValueFunctionRef = useRef(), updateFromCurrentValue = useCallback(() => {
4526
+ const { editorActor, portableTextEditor, readOnly } = props, { schemaTypes } = portableTextEditor, previousValue = useRef(), slateEditor = useSlate(), updateValueFunctionRef = useRef(), updateFromCurrentValue = useCallback(() => {
4518
4527
  const currentValue = CURRENT_VALUE.get(portableTextEditor);
4519
4528
  if (previousValue.current === currentValue) {
4520
4529
  debug$5("Value is the same object as previous, not need to sync");
@@ -4580,7 +4589,7 @@ function useSyncValue(props) {
4580
4589
  const validationValue = [value[currentBlockIndex]], validation = validateValue(
4581
4590
  validationValue,
4582
4591
  schemaTypes,
4583
- keyGenerator
4592
+ editorActor.getSnapshot().context.keyGenerator
4584
4593
  );
4585
4594
  !validation.valid && validation.resolution?.autoResolve && validation.resolution?.patches.length > 0 && !readOnly && previousValue.current && previousValue.current !== value && (console.warn(
4586
4595
  `${validation.resolution.action} for block with _key '${validationValue[0]._key}'. ${validation.resolution?.description}`
@@ -4605,7 +4614,7 @@ function useSyncValue(props) {
4605
4614
  const validationValue = [value[currentBlockIndex]], validation = validateValue(
4606
4615
  validationValue,
4607
4616
  schemaTypes,
4608
- keyGenerator
4617
+ editorActor.getSnapshot().context.keyGenerator
4609
4618
  );
4610
4619
  debug$5.enabled && debug$5(
4611
4620
  "Validating and inserting new block in the end of the value",
@@ -4652,7 +4661,6 @@ function useSyncValue(props) {
4652
4661
  return updateValueFunctionRef.current = updateFunction, updateFunction;
4653
4662
  }, [
4654
4663
  editorActor,
4655
- keyGenerator,
4656
4664
  portableTextEditor,
4657
4665
  readOnly,
4658
4666
  schemaTypes,
@@ -4720,9 +4728,8 @@ function _updateBlock(slateEditor, currentBlock, oldBlock, currentBlockIndex) {
4720
4728
  }
4721
4729
  const debug$4 = debugWithName("component:PortableTextEditor:Synchronizer"), debugVerbose$1 = debug$4.enabled && !1, FLUSH_PATCHES_THROTTLED_MS = process.env.NODE_ENV === "test" ? 500 : 1e3;
4722
4730
  function Synchronizer(props) {
4723
- const portableTextEditor = usePortableTextEditor(), keyGenerator = usePortableTextEditorKeyGenerator(), readOnly = usePortableTextEditorReadOnlyStatus(), { editorActor, getValue, onChange, value } = props, pendingPatches = useRef([]), syncValue = useSyncValue({
4731
+ const portableTextEditor = usePortableTextEditor(), readOnly = usePortableTextEditorReadOnlyStatus(), { editorActor, getValue, onChange, value } = props, pendingPatches = useRef([]), syncValue = useSyncValue({
4724
4732
  editorActor,
4725
- keyGenerator,
4726
4733
  portableTextEditor,
4727
4734
  readOnly
4728
4735
  }), slateEditor = useSlate();
@@ -4823,6 +4830,29 @@ ${JSON.stringify(pendingPatches.current, null, 2)}`);
4823
4830
  debug$4("Value from props changed, syncing new value"), syncValue(value), isInitialValueFromProps.current && (editorActor.send({ type: "ready" }), isInitialValueFromProps.current = !1);
4824
4831
  }, [editorActor, syncValue, value]), null;
4825
4832
  }
4833
+ function inserText({
4834
+ event
4835
+ }) {
4836
+ Editor.insertText(event.editor, event.text);
4837
+ }
4838
+ function inserTextBlock({
4839
+ context,
4840
+ event
4841
+ }) {
4842
+ Editor.insertNode(event.editor, {
4843
+ _key: context.keyGenerator(),
4844
+ _type: context.schema.block.name,
4845
+ style: context.schema.styles[0].value ?? "normal",
4846
+ markDefs: [],
4847
+ children: [
4848
+ {
4849
+ _key: context.keyGenerator(),
4850
+ _type: "span",
4851
+ text: ""
4852
+ }
4853
+ ]
4854
+ });
4855
+ }
4826
4856
  const networkLogic = fromCallback(({ sendBack }) => {
4827
4857
  const onlineHandler = () => {
4828
4858
  sendBack({ type: "online" });
@@ -4836,9 +4866,19 @@ const networkLogic = fromCallback(({ sendBack }) => {
4836
4866
  types: {
4837
4867
  context: {},
4838
4868
  events: {},
4839
- emitted: {}
4869
+ emitted: {},
4870
+ input: {}
4840
4871
  },
4841
4872
  actions: {
4873
+ "apply:insert text": ({ context, event }) => {
4874
+ assertEvent(event, "insert text"), inserText({ context, event });
4875
+ },
4876
+ "apply:insert text block": ({ context, event }) => {
4877
+ assertEvent(event, "insert text block"), inserTextBlock({ context, event });
4878
+ },
4879
+ "assign schema": assign({
4880
+ schema: ({ event }) => (assertEvent(event, "update schema"), event.schema)
4881
+ }),
4842
4882
  "emit patch event": emit(({ event }) => (assertEvent(event, "patch"), event)),
4843
4883
  "emit mutation event": emit(({ event }) => (assertEvent(event, "mutation"), event)),
4844
4884
  "defer event": assign({
@@ -4850,6 +4890,50 @@ const networkLogic = fromCallback(({ sendBack }) => {
4850
4890
  }),
4851
4891
  "clear pending events": assign({
4852
4892
  pendingEvents: []
4893
+ }),
4894
+ "handle behavior event": enqueueActions(({ context, event, enqueue }) => {
4895
+ assertEvent(event, ["key down"]);
4896
+ const eventBehaviors = context.behaviors.filter(
4897
+ (behavior) => behavior.on === event.type
4898
+ );
4899
+ if (eventBehaviors.length === 0)
4900
+ return;
4901
+ const value = fromSlateValue(
4902
+ event.editor.children,
4903
+ context.schema.block.name,
4904
+ KEY_TO_VALUE_ELEMENT.get(event.editor)
4905
+ ), selection = toPortableTextRange(
4906
+ value,
4907
+ event.editor.selection,
4908
+ context.schema
4909
+ );
4910
+ if (!selection) {
4911
+ console.warn(
4912
+ `Unable to handle event ${event.type} due to missing selection`
4913
+ );
4914
+ return;
4915
+ }
4916
+ const behaviorContext = {
4917
+ schema: context.schema,
4918
+ value,
4919
+ selection
4920
+ };
4921
+ for (const eventBehavior of eventBehaviors) {
4922
+ const shouldRun = eventBehavior.guard?.({
4923
+ context: behaviorContext,
4924
+ event
4925
+ }) ?? !0;
4926
+ if (!shouldRun)
4927
+ continue;
4928
+ const actions = eventBehavior.actions.map(
4929
+ (action) => action({ context: behaviorContext, event }, shouldRun)
4930
+ );
4931
+ for (const action of actions)
4932
+ typeof action == "object" && enqueue.raise({
4933
+ ...action,
4934
+ editor: event.editor
4935
+ });
4936
+ }
4853
4937
  })
4854
4938
  },
4855
4939
  actors: {
@@ -4857,9 +4941,12 @@ const networkLogic = fromCallback(({ sendBack }) => {
4857
4941
  }
4858
4942
  }).createMachine({
4859
4943
  id: "editor",
4860
- context: {
4861
- pendingEvents: []
4862
- },
4944
+ context: ({ input }) => ({
4945
+ behaviors: input.behaviors,
4946
+ keyGenerator: input.keyGenerator,
4947
+ pendingEvents: [],
4948
+ schema: input.schema
4949
+ }),
4863
4950
  invoke: {
4864
4951
  id: "networkLogic",
4865
4952
  src: "networkLogic"
@@ -4876,7 +4963,17 @@ const networkLogic = fromCallback(({ sendBack }) => {
4876
4963
  online: { actions: emit({ type: "online" }) },
4877
4964
  offline: { actions: emit({ type: "offline" }) },
4878
4965
  loading: { actions: emit({ type: "loading" }) },
4879
- "done loading": { actions: emit({ type: "done loading" }) }
4966
+ "done loading": { actions: emit({ type: "done loading" }) },
4967
+ "update schema": { actions: "assign schema" },
4968
+ "key down": {
4969
+ actions: ["handle behavior event"]
4970
+ },
4971
+ "insert text": {
4972
+ actions: ["apply:insert text"]
4973
+ },
4974
+ "insert text block": {
4975
+ actions: ["apply:insert text block"]
4976
+ }
4880
4977
  },
4881
4978
  initial: "pristine",
4882
4979
  states: {
@@ -4947,7 +5044,7 @@ function PortableTextEditorSelectionProvider(props) {
4947
5044
  };
4948
5045
  }, [props.editorActor]), /* @__PURE__ */ jsx(PortableTextEditorSelectionContext.Provider, { value: selection, children: props.children });
4949
5046
  }
4950
- const debug$2 = debugWithName("component:PortableTextEditor");
5047
+ const defaultKeyGenerator = () => randomKey(12), debug$2 = debugWithName("component:PortableTextEditor");
4951
5048
  class PortableTextEditor extends Component {
4952
5049
  /**
4953
5050
  * @internal
@@ -4971,14 +5068,23 @@ class PortableTextEditor extends Component {
4971
5068
  throw new Error('PortableTextEditor: missing "schemaType" property');
4972
5069
  props.incomingPatches$ && console.warn(
4973
5070
  "The prop 'incomingPatches$' is deprecated and renamed to 'patches$'"
4974
- ), this.editorActor = createActor(editorMachine), this.editorActor.start(), this.schemaTypes = getPortableTextMemberSchemaTypes(
5071
+ ), this.schemaTypes = getPortableTextMemberSchemaTypes(
4975
5072
  props.schemaType.hasOwnProperty("jsonType") ? props.schemaType : compileType(props.schemaType)
4976
- );
5073
+ ), this.editorActor = createActor(editorMachine, {
5074
+ input: {
5075
+ behaviors: coreBehaviors,
5076
+ keyGenerator: props.keyGenerator || defaultKeyGenerator,
5077
+ schema: this.schemaTypes
5078
+ }
5079
+ }), this.editorActor.start();
4977
5080
  }
4978
5081
  componentDidUpdate(prevProps) {
4979
5082
  this.props.schemaType !== prevProps.schemaType && (this.schemaTypes = getPortableTextMemberSchemaTypes(
4980
5083
  this.props.schemaType.hasOwnProperty("jsonType") ? this.props.schemaType : compileType(this.props.schemaType)
4981
- )), this.props.editorRef !== prevProps.editorRef && this.props.editorRef && (this.props.editorRef.current = this);
5084
+ ), this.editorActor.send({
5085
+ type: "update schema",
5086
+ schema: this.schemaTypes
5087
+ })), this.props.editorRef !== prevProps.editorRef && this.props.editorRef && (this.props.editorRef.current = this);
4982
5088
  }
4983
5089
  setEditable = (editable) => {
4984
5090
  this.editable = { ...this.editable, ...editable };
@@ -4988,35 +5094,28 @@ class PortableTextEditor extends Component {
4988
5094
  return this.editable.getValue();
4989
5095
  };
4990
5096
  render() {
4991
- const { value, children, patches$, incomingPatches$ } = this.props, _patches$ = incomingPatches$ || patches$, maxBlocks = typeof this.props.maxBlocks > "u" ? void 0 : Number.parseInt(this.props.maxBlocks.toString(), 10) || void 0, readOnly = !!this.props.readOnly, keyGenerator = this.props.keyGenerator || defaultKeyGenerator;
5097
+ const { value, children, patches$, incomingPatches$ } = this.props, _patches$ = incomingPatches$ || patches$, maxBlocks = typeof this.props.maxBlocks > "u" ? void 0 : Number.parseInt(this.props.maxBlocks.toString(), 10) || void 0, readOnly = !!this.props.readOnly;
4992
5098
  return /* @__PURE__ */ jsx(
4993
5099
  SlateContainer,
4994
5100
  {
4995
- keyGenerator,
4996
5101
  maxBlocks,
4997
5102
  patches$: _patches$,
4998
5103
  portableTextEditor: this,
4999
5104
  readOnly,
5000
- children: /* @__PURE__ */ jsx(PortableTextEditorKeyGeneratorContext.Provider, { value: keyGenerator, children: /* @__PURE__ */ jsx(PortableTextEditorContext.Provider, { value: this, children: /* @__PURE__ */ jsx(PortableTextEditorReadOnlyContext.Provider, { value: readOnly, children: /* @__PURE__ */ jsxs(
5001
- PortableTextEditorSelectionProvider,
5002
- {
5003
- editorActor: this.editorActor,
5004
- children: [
5005
- /* @__PURE__ */ jsx(
5006
- Synchronizer,
5007
- {
5008
- editorActor: this.editorActor,
5009
- getValue: this.getValue,
5010
- onChange: (change) => {
5011
- this.props.onChange(change), this.change$.next(change);
5012
- },
5013
- value
5014
- }
5015
- ),
5016
- children
5017
- ]
5018
- }
5019
- ) }) }) })
5105
+ children: /* @__PURE__ */ jsx(PortableTextEditorContext.Provider, { value: this, children: /* @__PURE__ */ jsx(PortableTextEditorReadOnlyContext.Provider, { value: readOnly, children: /* @__PURE__ */ jsxs(PortableTextEditorSelectionProvider, { editorActor: this.editorActor, children: [
5106
+ /* @__PURE__ */ jsx(
5107
+ Synchronizer,
5108
+ {
5109
+ editorActor: this.editorActor,
5110
+ getValue: this.getValue,
5111
+ onChange: (change) => {
5112
+ this.props.onChange(change), this.change$.next(change);
5113
+ },
5114
+ value
5115
+ }
5116
+ ),
5117
+ children
5118
+ ] }) }) })
5020
5119
  }
5021
5120
  );
5022
5121
  }
@@ -5282,7 +5381,7 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
5282
5381
  scrollSelectionIntoView,
5283
5382
  spellCheck,
5284
5383
  ...restProps
5285
- } = props, portableTextEditor = usePortableTextEditor(), readOnly = usePortableTextEditorReadOnlyStatus(), keyGenerator = usePortableTextEditorKeyGenerator(), ref = useRef(null), [editableElement, setEditableElement] = useState(
5384
+ } = props, portableTextEditor = usePortableTextEditor(), readOnly = usePortableTextEditorReadOnlyStatus(), ref = useRef(null), [editableElement, setEditableElement] = useState(
5286
5385
  null
5287
5386
  ), [hasInvalidValue, setHasInvalidValue] = useState(!1), [rangeDecorationState, setRangeDecorationsState] = useState([]);
5288
5387
  useImperativeHandle(
@@ -5290,8 +5389,8 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
5290
5389
  () => ref.current
5291
5390
  );
5292
5391
  const rangeDecorationsRef = useRef(rangeDecorations), { editorActor, schemaTypes } = portableTextEditor, slateEditor = useSlate(), blockTypeName = schemaTypes.block.name, withInsertData = useMemo(
5293
- () => createWithInsertData(editorActor, schemaTypes, keyGenerator),
5294
- [editorActor, keyGenerator, schemaTypes]
5392
+ () => createWithInsertData(editorActor, schemaTypes),
5393
+ [editorActor, schemaTypes]
5295
5394
  ), withHotKeys = useMemo(
5296
5395
  () => createWithHotkeys(schemaTypes, portableTextEditor, hotkeys),
5297
5396
  [hotkeys, portableTextEditor, schemaTypes]
@@ -5542,7 +5641,11 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
5542
5641
  }, [validateSelection, editableElement]);
5543
5642
  const handleKeyDown = useCallback(
5544
5643
  (event) => {
5545
- props.onKeyDown && props.onKeyDown(event), event.isDefaultPrevented() || slateEditor.pteWithHotKeys(event);
5644
+ props.onKeyDown && props.onKeyDown(event), event.isDefaultPrevented() || (editorActor.send({
5645
+ type: "key down",
5646
+ nativeEvent: event.nativeEvent,
5647
+ editor: slateEditor
5648
+ }), slateEditor.pteWithHotKeys(event));
5546
5649
  },
5547
5650
  [props, slateEditor]
5548
5651
  ), scrollSelectionIntoViewToSlate = useMemo(() => {