@portabletext/editor 1.1.7 → 1.1.8

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.
package/lib/index.js CHANGED
@@ -1594,11 +1594,11 @@ function createWithInsertBreak(editorActor, types2) {
1594
1594
  (mark) => !types2.decorators.some((decorator) => decorator.value === mark)
1595
1595
  ) ?? [], focusBlockPath = editor.selection.focus.path.slice(0, 1), focusBlock = slate.Node.descendant(editor, focusBlockPath);
1596
1596
  if (editor.isTextBlock(focusBlock)) {
1597
- const [start, end] = slate.Range.edges(editor.selection), isEndAtStartOfBlock = isEqual__default.default(end, {
1597
+ const [start, end] = slate.Range.edges(editor.selection), atTheStartOfBlock = isEqual__default.default(end, {
1598
1598
  path: [...focusBlockPath, 0],
1599
1599
  offset: 0
1600
1600
  });
1601
- if (isEndAtStartOfBlock && slate.Range.isCollapsed(editor.selection)) {
1601
+ if (atTheStartOfBlock && slate.Range.isCollapsed(editor.selection)) {
1602
1602
  slate.Editor.insertNode(
1603
1603
  editor,
1604
1604
  editor.pteCreateTextBlock({
@@ -1609,32 +1609,28 @@ function createWithInsertBreak(editorActor, types2) {
1609
1609
  slate.Transforms.select(editor, {
1610
1610
  anchor: { path: [nextBlockPath, 0], offset: 0 },
1611
1611
  focus: { path: [nextBlockPath, 0], offset: 0 }
1612
- }), editor.onChange();
1612
+ });
1613
1613
  return;
1614
1614
  }
1615
- const lastFocusBlockChild = focusBlock.children[focusBlock.children.length - 1], isStartAtEndOfBlock = isEqual__default.default(start, {
1615
+ const lastFocusBlockChild = focusBlock.children[focusBlock.children.length - 1], atTheEndOfBlock = isEqual__default.default(start, {
1616
1616
  path: [...focusBlockPath, focusBlock.children.length - 1],
1617
1617
  offset: editor.isTextSpan(lastFocusBlockChild) ? lastFocusBlockChild.text.length : 0
1618
1618
  });
1619
- if (isStartAtEndOfBlock && slate.Range.isCollapsed(editor.selection) && focusDecorators.length > 0 && focusAnnotations.length > 0) {
1620
- slate.Editor.withoutNormalizing(editor, () => {
1621
- if (!editor.selection)
1622
- return;
1623
- slate.Editor.insertNode(
1624
- editor,
1625
- editor.pteCreateTextBlock({
1626
- decorators: []
1627
- })
1628
- );
1629
- const [nextBlockPath] = slate.Path.next(focusBlockPath);
1630
- slate.Transforms.setSelection(editor, {
1631
- anchor: { path: [nextBlockPath, 0], offset: 0 },
1632
- focus: { path: [nextBlockPath, 0], offset: 0 }
1633
- });
1634
- }), editor.onChange();
1619
+ if (atTheEndOfBlock && slate.Range.isCollapsed(editor.selection)) {
1620
+ slate.Editor.insertNode(
1621
+ editor,
1622
+ editor.pteCreateTextBlock({
1623
+ decorators: []
1624
+ })
1625
+ );
1626
+ const [nextBlockPath] = slate.Path.next(focusBlockPath);
1627
+ slate.Transforms.setSelection(editor, {
1628
+ anchor: { path: [nextBlockPath, 0], offset: 0 },
1629
+ focus: { path: [nextBlockPath, 0], offset: 0 }
1630
+ });
1635
1631
  return;
1636
1632
  }
1637
- if (!isEndAtStartOfBlock && !isStartAtEndOfBlock) {
1633
+ if (!atTheStartOfBlock && !atTheEndOfBlock) {
1638
1634
  slate.Editor.withoutNormalizing(editor, () => {
1639
1635
  if (!editor.selection)
1640
1636
  return;
@@ -3797,7 +3793,7 @@ const debug$8 = debugWithName("plugin:withHotKeys"), DEFAULT_HOTKEYS = {
3797
3793
  },
3798
3794
  custom: {}
3799
3795
  };
3800
- function createWithHotkeys(types$1, portableTextEditor, hotkeysFromOptions) {
3796
+ function createWithHotkeys(portableTextEditor, hotkeysFromOptions) {
3801
3797
  const reservedHotkeys = ["enter", "tab", "shift", "delete", "end"], activeHotkeys = hotkeysFromOptions || DEFAULT_HOTKEYS;
3802
3798
  return function(editor) {
3803
3799
  return editor.pteWithHotKeys = (event) => {
@@ -3878,16 +3874,6 @@ function createWithHotkeys(types$1, portableTextEditor, hotkeysFromOptions) {
3878
3874
  editor.pteEndList() && event.preventDefault();
3879
3875
  return;
3880
3876
  }
3881
- if (editor.isTextBlock(focusBlock) && focusBlock.style && focusBlock.style !== types$1.styles[0].value) {
3882
- const [, end] = slate.Range.edges(editor.selection);
3883
- if (slate.Editor.isEnd(editor, end, end.path)) {
3884
- slate.Editor.insertNode(
3885
- editor,
3886
- editor.pteCreateTextBlock({ decorators: [] })
3887
- ), event.preventDefault(), editor.onChange();
3888
- return;
3889
- }
3890
- }
3891
3877
  }
3892
3878
  }, editor;
3893
3879
  };
@@ -4371,7 +4357,7 @@ function _insertFragment(editor, fragment, schemaTypes) {
4371
4357
  }), editor.onChange();
4372
4358
  }
4373
4359
  const originalFnMap = /* @__PURE__ */ new WeakMap(), withPlugins = (editor, options) => {
4374
- const e = editor, { portableTextEditor, patches$, readOnly, maxBlocks } = options, { editorActor, schemaTypes } = portableTextEditor;
4360
+ const e = editor, { editorActor, portableTextEditor, patches$, readOnly, maxBlocks } = options, { schemaTypes } = portableTextEditor;
4375
4361
  e.subscriptions = [], e.destroy ? e.destroy() : originalFnMap.set(e, {
4376
4362
  apply: e.apply,
4377
4363
  onChange: e.onChange,
@@ -4469,9 +4455,10 @@ const originalFnMap = /* @__PURE__ */ new WeakMap(), withPlugins = (editor, opti
4469
4455
  };
4470
4456
  }, debug$6 = debugWithName("component:PortableTextEditor:SlateContainer");
4471
4457
  function SlateContainer(props) {
4472
- const { patches$, portableTextEditor, readOnly, maxBlocks } = props, [[slateEditor, subscribe]] = react.useState(() => {
4458
+ const { editorActor, patches$, portableTextEditor, readOnly, maxBlocks } = props, [[slateEditor, subscribe]] = react.useState(() => {
4473
4459
  debug$6("Creating new Slate editor instance");
4474
4460
  const { editor, subscribe: _sub } = withPlugins(slateReact.withReact(slate.createEditor()), {
4461
+ editorActor,
4475
4462
  maxBlocks,
4476
4463
  patches$,
4477
4464
  portableTextEditor,
@@ -4486,6 +4473,7 @@ function SlateContainer(props) {
4486
4473
  };
4487
4474
  }, [subscribe]), react.useEffect(() => {
4488
4475
  debug$6("Re-initializing plugin chain"), withPlugins(slateEditor, {
4476
+ editorActor,
4489
4477
  maxBlocks,
4490
4478
  patches$,
4491
4479
  portableTextEditor,
@@ -4506,7 +4494,7 @@ const PortableTextEditorReadOnlyContext = react.createContext(!1), usePortableTe
4506
4494
  return readOnly;
4507
4495
  }, debug$5 = debugWithName("hook:useSyncValue"), CURRENT_VALUE = /* @__PURE__ */ new WeakMap();
4508
4496
  function useSyncValue(props) {
4509
- const { editorActor, portableTextEditor, readOnly } = props, { schemaTypes } = portableTextEditor, previousValue = react.useRef(), slateEditor = slateReact.useSlate(), updateValueFunctionRef = react.useRef(), updateFromCurrentValue = react.useCallback(() => {
4497
+ const { editorActor, portableTextEditor, readOnly } = props, schemaTypes = editorActor.getSnapshot().context.schema, previousValue = react.useRef(), slateEditor = slateReact.useSlate(), updateValueFunctionRef = react.useRef(), updateFromCurrentValue = react.useCallback(() => {
4510
4498
  const currentValue = CURRENT_VALUE.get(portableTextEditor);
4511
4499
  if (previousValue.current === currentValue) {
4512
4500
  debug$5("Value is the same object as previous, not need to sync");
@@ -4813,30 +4801,40 @@ ${JSON.stringify(pendingPatches.current, null, 2)}`);
4813
4801
  debug$4("Value from props changed, syncing new value"), syncValue(value), isInitialValueFromProps.current && (editorActor.send({ type: "ready" }), isInitialValueFromProps.current = !1);
4814
4802
  }, [editorActor, syncValue, value]), null;
4815
4803
  }
4816
- function inserText({
4817
- event
4818
- }) {
4819
- slate.Editor.insertText(event.editor, event.text);
4820
- }
4821
- function inserTextBlock({
4822
- context,
4823
- event
4824
- }) {
4825
- slate.Editor.insertNode(event.editor, {
4826
- _key: context.keyGenerator(),
4827
- _type: context.schema.block.name,
4828
- style: context.schema.styles[0].value ?? "normal",
4829
- markDefs: [],
4830
- children: [
4831
- {
4832
- _key: context.keyGenerator(),
4833
- _type: "span",
4834
- text: ""
4835
- }
4836
- ]
4837
- });
4838
- }
4839
- const networkLogic = xstate.fromCallback(({ sendBack }) => {
4804
+ const EditorActorContext = react.createContext({}), behaviorActionImplementations = {
4805
+ "apply block style": ({ event }) => {
4806
+ for (const path of event.paths) {
4807
+ const at = toSlateRange(
4808
+ { anchor: { path, offset: 0 }, focus: { path, offset: 0 } },
4809
+ event.editor
4810
+ );
4811
+ slate.Transforms.setNodes(event.editor, { style: event.style }, { at });
4812
+ }
4813
+ },
4814
+ "delete text": ({ event }) => {
4815
+ slate.Transforms.delete(event.editor, {
4816
+ at: toSlateRange(event.selection, event.editor)
4817
+ });
4818
+ },
4819
+ "insert text": ({ event }) => {
4820
+ slate.Editor.insertText(event.editor, event.text);
4821
+ },
4822
+ "insert text block": ({ context, event }) => {
4823
+ slate.Editor.insertNode(event.editor, {
4824
+ _key: context.keyGenerator(),
4825
+ _type: context.schema.block.name,
4826
+ style: context.schema.styles[0].value ?? "normal",
4827
+ markDefs: [],
4828
+ children: [
4829
+ {
4830
+ _key: context.keyGenerator(),
4831
+ _type: "span",
4832
+ text: ""
4833
+ }
4834
+ ]
4835
+ });
4836
+ }
4837
+ }, networkLogic = xstate.fromCallback(({ sendBack }) => {
4840
4838
  const onlineHandler = () => {
4841
4839
  sendBack({ type: "online" });
4842
4840
  }, offlineHandler = () => {
@@ -4853,12 +4851,6 @@ const networkLogic = xstate.fromCallback(({ sendBack }) => {
4853
4851
  input: {}
4854
4852
  },
4855
4853
  actions: {
4856
- "apply:insert text": ({ context, event }) => {
4857
- xstate.assertEvent(event, "insert text"), inserText({ context, event });
4858
- },
4859
- "apply:insert text block": ({ context, event }) => {
4860
- xstate.assertEvent(event, "insert text block"), inserTextBlock({ context, event });
4861
- },
4862
4854
  "assign schema": xstate.assign({
4863
4855
  schema: ({ event }) => (xstate.assertEvent(event, "update schema"), event.schema)
4864
4856
  }),
@@ -4875,7 +4867,7 @@ const networkLogic = xstate.fromCallback(({ sendBack }) => {
4875
4867
  pendingEvents: []
4876
4868
  }),
4877
4869
  "handle behavior event": xstate.enqueueActions(({ context, event, enqueue }) => {
4878
- xstate.assertEvent(event, ["key down"]);
4870
+ xstate.assertEvent(event, ["key down", "before insert text"]);
4879
4871
  const eventBehaviors = context.behaviors.filter(
4880
4872
  (behavior) => behavior.on === event.type
4881
4873
  );
@@ -4951,11 +4943,20 @@ const networkLogic = xstate.fromCallback(({ sendBack }) => {
4951
4943
  "key down": {
4952
4944
  actions: ["handle behavior event"]
4953
4945
  },
4946
+ "before insert text": {
4947
+ actions: ["handle behavior event"]
4948
+ },
4949
+ "apply block style": {
4950
+ actions: [behaviorActionImplementations["apply block style"]]
4951
+ },
4952
+ "delete text": {
4953
+ actions: [behaviorActionImplementations["delete text"]]
4954
+ },
4954
4955
  "insert text": {
4955
- actions: ["apply:insert text"]
4956
+ actions: [behaviorActionImplementations["insert text"]]
4956
4957
  },
4957
4958
  "insert text block": {
4958
- actions: ["apply:insert text block"]
4959
+ actions: [behaviorActionImplementations["insert text block"]]
4959
4960
  }
4960
4961
  },
4961
4962
  initial: "pristine",
@@ -5029,11 +5030,6 @@ function PortableTextEditorSelectionProvider(props) {
5029
5030
  }
5030
5031
  const defaultKeyGenerator = () => content.randomKey(12), debug$2 = debugWithName("component:PortableTextEditor");
5031
5032
  class PortableTextEditor extends react.Component {
5032
- /**
5033
- * @internal
5034
- * Don't use this API directly. It's subject to change.
5035
- */
5036
- editorActor;
5037
5033
  /**
5038
5034
  * An observable of all the editor changes.
5039
5035
  */
@@ -5046,6 +5042,7 @@ class PortableTextEditor extends react.Component {
5046
5042
  * The editor API (currently implemented with Slate).
5047
5043
  */
5048
5044
  editable;
5045
+ editorActor;
5049
5046
  constructor(props) {
5050
5047
  if (super(props), !props.schemaType)
5051
5048
  throw new Error('PortableTextEditor: missing "schemaType" property');
@@ -5078,29 +5075,36 @@ class PortableTextEditor extends react.Component {
5078
5075
  };
5079
5076
  render() {
5080
5077
  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;
5081
- return /* @__PURE__ */ jsxRuntime.jsx(
5078
+ return /* @__PURE__ */ jsxRuntime.jsx(EditorActorContext.Provider, { value: this.editorActor, children: /* @__PURE__ */ jsxRuntime.jsx(
5082
5079
  SlateContainer,
5083
5080
  {
5081
+ editorActor: this.editorActor,
5084
5082
  maxBlocks,
5085
5083
  patches$: _patches$,
5086
5084
  portableTextEditor: this,
5087
5085
  readOnly,
5088
- children: /* @__PURE__ */ jsxRuntime.jsx(PortableTextEditorContext.Provider, { value: this, children: /* @__PURE__ */ jsxRuntime.jsx(PortableTextEditorReadOnlyContext.Provider, { value: readOnly, children: /* @__PURE__ */ jsxRuntime.jsxs(PortableTextEditorSelectionProvider, { editorActor: this.editorActor, children: [
5089
- /* @__PURE__ */ jsxRuntime.jsx(
5090
- Synchronizer,
5091
- {
5092
- editorActor: this.editorActor,
5093
- getValue: this.getValue,
5094
- onChange: (change) => {
5095
- this.props.onChange(change), this.change$.next(change);
5096
- },
5097
- value
5098
- }
5099
- ),
5100
- children
5101
- ] }) }) })
5086
+ children: /* @__PURE__ */ jsxRuntime.jsx(PortableTextEditorContext.Provider, { value: this, children: /* @__PURE__ */ jsxRuntime.jsx(PortableTextEditorReadOnlyContext.Provider, { value: readOnly, children: /* @__PURE__ */ jsxRuntime.jsxs(
5087
+ PortableTextEditorSelectionProvider,
5088
+ {
5089
+ editorActor: this.editorActor,
5090
+ children: [
5091
+ /* @__PURE__ */ jsxRuntime.jsx(
5092
+ Synchronizer,
5093
+ {
5094
+ editorActor: this.editorActor,
5095
+ getValue: this.getValue,
5096
+ onChange: (change) => {
5097
+ this.props.onChange(change), this.change$.next(change);
5098
+ },
5099
+ value
5100
+ }
5101
+ ),
5102
+ children
5103
+ ]
5104
+ }
5105
+ ) }) })
5102
5106
  }
5103
- );
5107
+ ) });
5104
5108
  }
5105
5109
  // Static API methods
5106
5110
  static activeAnnotations = (editor) => editor && editor.editable ? editor.editable.activeAnnotations() : [];
@@ -5154,6 +5158,7 @@ class PortableTextEditor extends react.Component {
5154
5158
  }
5155
5159
  const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (props) => {
5156
5160
  const {
5161
+ editorActor,
5157
5162
  attributes,
5158
5163
  children,
5159
5164
  leaf,
@@ -5208,17 +5213,14 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
5208
5213
  react.useEffect(() => {
5209
5214
  if (!shouldTrackSelectionAndFocus)
5210
5215
  return;
5211
- const onBlur = portableTextEditor.editorActor.on("blur", () => {
5216
+ const onBlur = editorActor.on("blur", () => {
5212
5217
  setFocused(!1), setSelected(!1);
5213
- }), onFocus = portableTextEditor.editorActor.on("focus", () => {
5218
+ }), onFocus = editorActor.on("focus", () => {
5214
5219
  const sel = PortableTextEditor.getSelection(portableTextEditor);
5215
5220
  sel && isEqual__default.default(sel.focus.path, path) && PortableTextEditor.isCollapsedSelection(portableTextEditor) && setFocused(!0), setSelectedFromRange();
5216
- }), onSelection = portableTextEditor.editorActor.on(
5217
- "selection",
5218
- (event) => {
5219
- event.selection && isEqual__default.default(event.selection.focus.path, path) && PortableTextEditor.isCollapsedSelection(portableTextEditor) ? setFocused(!0) : setFocused(!1), setSelectedFromRange();
5220
- }
5221
- );
5221
+ }), onSelection = editorActor.on("selection", (event) => {
5222
+ event.selection && isEqual__default.default(event.selection.focus.path, path) && PortableTextEditor.isCollapsedSelection(portableTextEditor) ? setFocused(!0) : setFocused(!1), setSelectedFromRange();
5223
+ });
5222
5224
  return () => {
5223
5225
  onBlur.unsubscribe(), onFocus.unsubscribe(), onSelection.unsubscribe();
5224
5226
  };
@@ -5371,12 +5373,12 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
5371
5373
  forwardedRef,
5372
5374
  () => ref.current
5373
5375
  );
5374
- const rangeDecorationsRef = react.useRef(rangeDecorations), { editorActor, schemaTypes } = portableTextEditor, slateEditor = slateReact.useSlate(), blockTypeName = schemaTypes.block.name, withInsertData = react.useMemo(
5376
+ const rangeDecorationsRef = react.useRef(rangeDecorations), editorActor = react.useContext(EditorActorContext), { schemaTypes } = portableTextEditor, slateEditor = slateReact.useSlate(), blockTypeName = schemaTypes.block.name, withInsertData = react.useMemo(
5375
5377
  () => createWithInsertData(editorActor, schemaTypes),
5376
5378
  [editorActor, schemaTypes]
5377
5379
  ), withHotKeys = react.useMemo(
5378
- () => createWithHotkeys(schemaTypes, portableTextEditor, hotkeys),
5379
- [hotkeys, portableTextEditor, schemaTypes]
5380
+ () => createWithHotkeys(portableTextEditor, hotkeys),
5381
+ [hotkeys, portableTextEditor]
5380
5382
  );
5381
5383
  react.useMemo(() => readOnly ? (debug("Editable is in read only mode"), withInsertData(slateEditor)) : (debug("Editable is in edit mode"), withInsertData(withHotKeys(slateEditor))), [readOnly, slateEditor, withHotKeys, withInsertData]);
5382
5384
  const renderElement = react.useCallback(
@@ -5409,6 +5411,7 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
5409
5411
  Leaf,
5410
5412
  {
5411
5413
  ...lProps,
5414
+ editorActor,
5412
5415
  schemaTypes,
5413
5416
  renderAnnotation,
5414
5417
  renderChild,
@@ -5585,7 +5588,11 @@ const debug$1 = debugWithName("components:Leaf"), EMPTY_MARKS = [], Leaf = (prop
5585
5588
  [editorActor, onBlur]
5586
5589
  ), handleOnBeforeInput = react.useCallback(
5587
5590
  (event) => {
5588
- onBeforeInput && onBeforeInput(event);
5591
+ onBeforeInput && onBeforeInput(event), !event.defaultPrevented && event.inputType === "insertText" && editorActor.send({
5592
+ type: "before insert text",
5593
+ nativeEvent: event,
5594
+ editor: slateEditor
5595
+ });
5589
5596
  },
5590
5597
  [onBeforeInput]
5591
5598
  ), validateSelection = react.useCallback(() => {