@portabletext/editor 1.48.14 → 1.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/lib/_chunks-cjs/editor-provider.cjs +117 -34
  2. package/lib/_chunks-cjs/editor-provider.cjs.map +1 -1
  3. package/lib/_chunks-cjs/util.slice-blocks.cjs +2 -0
  4. package/lib/_chunks-cjs/util.slice-blocks.cjs.map +1 -1
  5. package/lib/_chunks-es/editor-provider.js +117 -34
  6. package/lib/_chunks-es/editor-provider.js.map +1 -1
  7. package/lib/_chunks-es/util.slice-blocks.js +2 -0
  8. package/lib/_chunks-es/util.slice-blocks.js.map +1 -1
  9. package/lib/behaviors/index.d.cts +222 -208
  10. package/lib/behaviors/index.d.ts +222 -208
  11. package/lib/index.cjs +346 -257
  12. package/lib/index.cjs.map +1 -1
  13. package/lib/index.d.cts +222 -216
  14. package/lib/index.d.ts +222 -216
  15. package/lib/index.js +353 -264
  16. package/lib/index.js.map +1 -1
  17. package/lib/plugins/index.d.cts +222 -216
  18. package/lib/plugins/index.d.ts +222 -216
  19. package/lib/selectors/index.d.cts +222 -208
  20. package/lib/selectors/index.d.ts +222 -208
  21. package/lib/utils/index.d.cts +222 -208
  22. package/lib/utils/index.d.ts +222 -208
  23. package/package.json +1 -1
  24. package/src/behaviors/behavior.config.ts +7 -0
  25. package/src/behaviors/behavior.core.block-element.ts +108 -0
  26. package/src/behaviors/behavior.core.ts +6 -2
  27. package/src/converters/converter.portable-text.ts +4 -1
  28. package/src/converters/converter.text-html.ts +4 -1
  29. package/src/converters/converter.text-plain.ts +4 -1
  30. package/src/editor/Editable.tsx +2 -4
  31. package/src/editor/__tests__/PortableTextEditor.test.tsx +6 -0
  32. package/src/editor/components/Leaf.tsx +8 -1
  33. package/src/editor/components/render-block-object.tsx +90 -0
  34. package/src/editor/components/render-default-object.tsx +21 -0
  35. package/src/editor/components/render-element.tsx +140 -0
  36. package/src/editor/components/render-inline-object.tsx +93 -0
  37. package/src/editor/components/render-text-block.tsx +148 -0
  38. package/src/editor/components/use-core-block-element-behaviors.ts +39 -0
  39. package/src/editor/create-editor.ts +17 -5
  40. package/src/editor/editor-machine.ts +21 -18
  41. package/src/internal-utils/parse-blocks.ts +2 -2
  42. package/src/internal-utils/slate-utils.ts +1 -1
  43. package/src/priority/priority.core.ts +3 -0
  44. package/src/priority/priority.sort.test.ts +319 -0
  45. package/src/priority/priority.sort.ts +121 -0
  46. package/src/priority/priority.types.ts +24 -0
  47. package/src/editor/components/DefaultObject.tsx +0 -21
  48. package/src/editor/components/Element.tsx +0 -435
@@ -2197,7 +2197,8 @@ const converterJson = {
2197
2197
  snapshot,
2198
2198
  event
2199
2199
  }) => {
2200
- if (!(snapshot.beta.internalDrag?.origin.selection ?? snapshot.context.selection))
2200
+ const selection = snapshot.beta.internalDrag?.origin.selection ?? snapshot.context.selection;
2201
+ if (!selection)
2201
2202
  return {
2202
2203
  type: "serialization.failure",
2203
2204
  mimeType: "application/x-portable-text",
@@ -2205,7 +2206,10 @@ const converterJson = {
2205
2206
  reason: "No selection"
2206
2207
  };
2207
2208
  const blocks = util_sliceBlocks.sliceBlocks({
2208
- context: snapshot.context,
2209
+ context: {
2210
+ selection,
2211
+ schema: snapshot.context.schema
2212
+ },
2209
2213
  blocks: snapshot.context.value
2210
2214
  });
2211
2215
  return blocks.length === 0 ? {
@@ -2263,7 +2267,8 @@ function createConverterTextHtml(legacySchema) {
2263
2267
  snapshot,
2264
2268
  event
2265
2269
  }) => {
2266
- if (!(snapshot.beta.internalDrag?.origin.selection ?? snapshot.context.selection))
2270
+ const selection = snapshot.beta.internalDrag?.origin.selection ?? snapshot.context.selection;
2271
+ if (!selection)
2267
2272
  return {
2268
2273
  type: "serialization.failure",
2269
2274
  mimeType: "text/html",
@@ -2271,7 +2276,10 @@ function createConverterTextHtml(legacySchema) {
2271
2276
  reason: "No selection"
2272
2277
  };
2273
2278
  const blocks = util_sliceBlocks.sliceBlocks({
2274
- context: snapshot.context,
2279
+ context: {
2280
+ selection,
2281
+ schema: snapshot.context.schema
2282
+ },
2275
2283
  blocks: snapshot.context.value
2276
2284
  }), html = toHtml.toHTML(blocks, {
2277
2285
  onMissingComponent: !1,
@@ -2328,21 +2336,27 @@ function createConverterTextPlain(legacySchema) {
2328
2336
  serialize: ({
2329
2337
  snapshot,
2330
2338
  event
2331
- }) => snapshot.beta.internalDrag?.origin.selection ?? snapshot.context.selection ? {
2332
- type: "serialization.success",
2333
- data: util_sliceBlocks.sliceBlocks({
2334
- context: snapshot.context,
2335
- blocks: snapshot.context.value
2336
- }).map((block) => util_sliceBlocks.isTextBlock(snapshot.context, block) ? block.children.map((child) => child._type === snapshot.context.schema.span.name ? child.text : snapshot.beta.hasTag("dragging internally") ? `[${snapshot.context.schema.inlineObjects.find((inlineObjectType) => inlineObjectType.name === child._type)?.title ?? "Object"}]` : "").join("") : snapshot.beta.hasTag("dragging internally") ? `[${snapshot.context.schema.blockObjects.find((blockObjectType) => blockObjectType.name === block._type)?.title ?? "Object"}]` : "").filter((block) => block !== "").join(`
2339
+ }) => {
2340
+ const selection = snapshot.beta.internalDrag?.origin.selection ?? snapshot.context.selection;
2341
+ return selection ? {
2342
+ type: "serialization.success",
2343
+ data: util_sliceBlocks.sliceBlocks({
2344
+ context: {
2345
+ selection,
2346
+ schema: snapshot.context.schema
2347
+ },
2348
+ blocks: snapshot.context.value
2349
+ }).map((block) => util_sliceBlocks.isTextBlock(snapshot.context, block) ? block.children.map((child) => child._type === snapshot.context.schema.span.name ? child.text : snapshot.beta.hasTag("dragging internally") ? `[${snapshot.context.schema.inlineObjects.find((inlineObjectType) => inlineObjectType.name === child._type)?.title ?? "Object"}]` : "").join("") : snapshot.beta.hasTag("dragging internally") ? `[${snapshot.context.schema.blockObjects.find((blockObjectType) => blockObjectType.name === block._type)?.title ?? "Object"}]` : "").filter((block) => block !== "").join(`
2337
2350
 
2338
2351
  `),
2339
- mimeType: "text/plain",
2340
- originEvent: event.originEvent
2341
- } : {
2342
- type: "serialization.failure",
2343
- mimeType: "text/plain",
2344
- originEvent: event.originEvent,
2345
- reason: "No selection"
2352
+ mimeType: "text/plain",
2353
+ originEvent: event.originEvent
2354
+ } : {
2355
+ type: "serialization.failure",
2356
+ mimeType: "text/plain",
2357
+ originEvent: event.originEvent,
2358
+ reason: "No selection"
2359
+ };
2346
2360
  },
2347
2361
  deserialize: ({
2348
2362
  snapshot,
@@ -2394,7 +2408,16 @@ function compileType(rawType) {
2394
2408
  types: [rawType]
2395
2409
  }).get(rawType.name);
2396
2410
  }
2397
- const debug$b = debugWithName("operationToPatches");
2411
+ function createEditorPriority(config) {
2412
+ return {
2413
+ id: defaultKeyGenerator(),
2414
+ name: config?.name,
2415
+ reference: config?.reference
2416
+ };
2417
+ }
2418
+ const corePriority = createEditorPriority({
2419
+ name: "core"
2420
+ }), debug$b = debugWithName("operationToPatches");
2398
2421
  function createOperationToPatches(editorActor) {
2399
2422
  const textBlockName = editorActor.getSnapshot().context.schema.block.name;
2400
2423
  function insertTextPatch(editor, operation, beforeValue) {
@@ -5710,19 +5733,29 @@ function createInternalEditor(editorActor) {
5710
5733
  editorActorSnapshot: editorActor.getSnapshot(),
5711
5734
  slateEditorInstance: slateEditor.instance
5712
5735
  }),
5713
- registerBehavior: (config) => (editorActor.send({
5714
- type: "add behavior",
5715
- behavior: config.behavior
5716
- }), () => {
5717
- editorActor.send({
5718
- type: "remove behavior",
5719
- behavior: config.behavior
5720
- });
5721
- }),
5736
+ registerBehavior: (behaviorConfig) => {
5737
+ const priority = createEditorPriority({
5738
+ name: "custom",
5739
+ reference: {
5740
+ priority: corePriority,
5741
+ importance: "higher"
5742
+ }
5743
+ }), behaviorConfigWithPriority = {
5744
+ ...behaviorConfig,
5745
+ priority
5746
+ };
5747
+ return editorActor.send({
5748
+ type: "add behavior",
5749
+ behaviorConfig: behaviorConfigWithPriority
5750
+ }), () => {
5751
+ editorActor.send({
5752
+ type: "remove behavior",
5753
+ behaviorConfig: behaviorConfigWithPriority
5754
+ });
5755
+ };
5756
+ },
5722
5757
  send: (event) => {
5723
5758
  switch (event.type) {
5724
- case "add behavior":
5725
- case "remove behavior":
5726
5759
  case "update key generator":
5727
5760
  case "update readOnly":
5728
5761
  case "patches":
@@ -6466,7 +6499,10 @@ const arrowDownOnLonelyBlockObject = behaviors_index.defineBehavior({
6466
6499
  clearListOnEnter,
6467
6500
  indentListOnTab,
6468
6501
  unindentListOnShiftTab
6469
- }, coreBehaviors = [coreAnnotationBehaviors.addAnnotationOnCollapsedSelection, coreDecoratorBehaviors.strongShortcut, coreDecoratorBehaviors.emShortcut, coreDecoratorBehaviors.underlineShortcut, coreDecoratorBehaviors.codeShortcut, ...coreDndBehaviors, coreBlockObjectBehaviors.clickingAboveLonelyBlockObject, coreBlockObjectBehaviors.clickingBelowLonelyBlockObject, coreBlockObjectBehaviors.arrowDownOnLonelyBlockObject, coreBlockObjectBehaviors.arrowUpOnLonelyBlockObject, coreBlockObjectBehaviors.breakingBlockObject, coreBlockObjectBehaviors.deletingEmptyTextBlockAfterBlockObject, coreBlockObjectBehaviors.deletingEmptyTextBlockBeforeBlockObject, coreListBehaviors.clearListOnBackspace, coreListBehaviors.unindentListOnBackspace, coreListBehaviors.clearListOnEnter, coreListBehaviors.indentListOnTab, coreListBehaviors.unindentListOnShiftTab, coreInsertBreakBehaviors.breakingAtTheEndOfTextBlock, coreInsertBreakBehaviors.breakingAtTheStartOfTextBlock, coreInsertBreakBehaviors.breakingEntireDocument, coreInsertBreakBehaviors.breakingEntireBlocks], abstractAnnotationBehaviors = [behaviors_index.defineBehavior({
6502
+ }, coreBehaviorsConfig = [coreAnnotationBehaviors.addAnnotationOnCollapsedSelection, coreDecoratorBehaviors.strongShortcut, coreDecoratorBehaviors.emShortcut, coreDecoratorBehaviors.underlineShortcut, coreDecoratorBehaviors.codeShortcut, ...coreDndBehaviors, coreBlockObjectBehaviors.clickingAboveLonelyBlockObject, coreBlockObjectBehaviors.clickingBelowLonelyBlockObject, coreBlockObjectBehaviors.arrowDownOnLonelyBlockObject, coreBlockObjectBehaviors.arrowUpOnLonelyBlockObject, coreBlockObjectBehaviors.breakingBlockObject, coreBlockObjectBehaviors.deletingEmptyTextBlockAfterBlockObject, coreBlockObjectBehaviors.deletingEmptyTextBlockBeforeBlockObject, coreListBehaviors.clearListOnBackspace, coreListBehaviors.unindentListOnBackspace, coreListBehaviors.clearListOnEnter, coreListBehaviors.indentListOnTab, coreListBehaviors.unindentListOnShiftTab, coreInsertBreakBehaviors.breakingAtTheEndOfTextBlock, coreInsertBreakBehaviors.breakingAtTheStartOfTextBlock, coreInsertBreakBehaviors.breakingEntireDocument, coreInsertBreakBehaviors.breakingEntireBlocks].map((behavior) => ({
6503
+ behavior,
6504
+ priority: corePriority
6505
+ })), abstractAnnotationBehaviors = [behaviors_index.defineBehavior({
6470
6506
  on: "annotation.toggle",
6471
6507
  guard: ({
6472
6508
  snapshot,
@@ -7542,6 +7578,49 @@ function performEvent({
7542
7578
  });
7543
7579
  }), editor.onChange()) : nativeEventPrevented && nativeEvent?.preventDefault();
7544
7580
  }
7581
+ function sortByPriority(items) {
7582
+ if (items.length === 0)
7583
+ return [];
7584
+ const itemsWithPriority = items.filter((item) => item.priority !== void 0), itemsWithoutPriority = items.filter((item) => item.priority === void 0);
7585
+ if (itemsWithPriority.length === 0)
7586
+ return items;
7587
+ const itemsByPriorityId = new Map(itemsWithPriority.map((item) => [item.priority.id, item])), graph = /* @__PURE__ */ new Map(), inDegree = /* @__PURE__ */ new Map();
7588
+ function ensureNode(id) {
7589
+ graph.has(id) || (graph.set(id, /* @__PURE__ */ new Set()), inDegree.set(id, 0));
7590
+ }
7591
+ for (const item of itemsWithPriority) {
7592
+ const id = item.priority.id;
7593
+ ensureNode(id);
7594
+ }
7595
+ function addEdge(fromId, toId) {
7596
+ !graph.has(fromId) || !graph.has(toId) || (graph.get(fromId)?.add(toId), inDegree.set(toId, (inDegree.get(toId) ?? 0) + 1));
7597
+ }
7598
+ for (const item of itemsWithPriority) {
7599
+ const id = item.priority.id, visited = /* @__PURE__ */ new Set();
7600
+ let ref = item.priority.reference;
7601
+ for (; ref; ) {
7602
+ const refId = ref.priority.id;
7603
+ if (ensureNode(refId), visited.has(refId))
7604
+ throw new Error("Circular dependency detected in priorities");
7605
+ visited.add(refId), ref.importance === "higher" ? addEdge(id, refId) : addEdge(refId, id), ref = ref.priority.reference;
7606
+ }
7607
+ }
7608
+ const queue = [];
7609
+ for (const [id, degree] of inDegree)
7610
+ degree === 0 && queue.push(id);
7611
+ const result = [];
7612
+ for (; queue.length > 0; ) {
7613
+ const currentId = queue.shift(), currentItem = itemsByPriorityId.get(currentId);
7614
+ currentItem && result.push(currentItem);
7615
+ for (const neighborId of graph.get(currentId) ?? []) {
7616
+ const newDegree = (inDegree.get(neighborId) ?? 0) - 1;
7617
+ inDegree.set(neighborId, newDegree), newDegree === 0 && queue.push(neighborId);
7618
+ }
7619
+ }
7620
+ for (const item of itemsWithPriority)
7621
+ result.includes(item) || result.push(item);
7622
+ return [...result, ...itemsWithoutPriority];
7623
+ }
7545
7624
  function createEditorSnapshot({
7546
7625
  converters,
7547
7626
  editor,
@@ -7588,13 +7667,13 @@ const editorMachine = xstate.setup({
7588
7667
  behaviors: ({
7589
7668
  context,
7590
7669
  event
7591
- }) => (xstate.assertEvent(event, "add behavior"), /* @__PURE__ */ new Set([...context.behaviors, event.behavior]))
7670
+ }) => (xstate.assertEvent(event, "add behavior"), /* @__PURE__ */ new Set([...context.behaviors, event.behaviorConfig]))
7592
7671
  }),
7593
7672
  "remove behavior from context": xstate.assign({
7594
7673
  behaviors: ({
7595
7674
  context,
7596
7675
  event
7597
- }) => (xstate.assertEvent(event, "remove behavior"), context.behaviors.delete(event.behavior), /* @__PURE__ */ new Set([...context.behaviors]))
7676
+ }) => (xstate.assertEvent(event, "remove behavior"), context.behaviors.delete(event.behaviorConfig), /* @__PURE__ */ new Set([...context.behaviors]))
7598
7677
  }),
7599
7678
  "assign schema": xstate.assign({
7600
7679
  schema: ({
@@ -7688,10 +7767,11 @@ const editorMachine = xstate.setup({
7688
7767
  }) => {
7689
7768
  xstate.assertEvent(event, ["behavior event"]);
7690
7769
  try {
7770
+ const behaviors = sortByPriority([...context.behaviors.values(), ...coreBehaviorsConfig]).map((config) => config.behavior);
7691
7771
  performEvent({
7692
7772
  mode: "raise",
7693
- behaviors: [...context.behaviors.values(), ...coreBehaviors],
7694
- remainingEventBehaviors: [...context.behaviors.values(), ...coreBehaviors],
7773
+ behaviors,
7774
+ remainingEventBehaviors: behaviors,
7695
7775
  event: event.behaviorEvent,
7696
7776
  editor: event.editor,
7697
7777
  keyGenerator: context.keyGenerator,
@@ -8642,6 +8722,8 @@ exports.EditorActorContext = EditorActorContext;
8642
8722
  exports.EditorProvider = EditorProvider;
8643
8723
  exports.KEY_TO_VALUE_ELEMENT = KEY_TO_VALUE_ELEMENT;
8644
8724
  exports.PortableTextEditor = PortableTextEditor;
8725
+ exports.corePriority = corePriority;
8726
+ exports.createEditorPriority = createEditorPriority;
8645
8727
  exports.debugWithName = debugWithName;
8646
8728
  exports.defaultKeyGenerator = defaultKeyGenerator;
8647
8729
  exports.defineSchema = defineSchema;
@@ -8650,6 +8732,7 @@ exports.getEditorSnapshot = getEditorSnapshot;
8650
8732
  exports.getFirstBlock = getFirstBlock;
8651
8733
  exports.getLastBlock = getLastBlock;
8652
8734
  exports.getNodeBlock = getNodeBlock;
8735
+ exports.getPointBlock = getPointBlock;
8653
8736
  exports.isEqualToEmptyEditor = isEqualToEmptyEditor;
8654
8737
  exports.isHotkey = isHotkey;
8655
8738
  exports.moveRangeByOperation = moveRangeByOperation;