@bigbinary/neeto-editor 1.42.1 → 1.43.1

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.
@@ -9,7 +9,7 @@ var Editor = require('./Editor.cjs.js');
9
9
  var jsxRuntime = require('react/jsx-runtime');
10
10
  require('@babel/runtime/helpers/toConsumableArray');
11
11
  require('@babel/runtime/helpers/slicedToArray');
12
- require('./chunk-4b866a12.cjs.js');
12
+ require('./chunk-62a3a743.cjs.js');
13
13
  require('ramda');
14
14
  require('./chunk-da9ee471.cjs.js');
15
15
  require('i18next');
@@ -5,7 +5,7 @@ require('@babel/runtime/helpers/toConsumableArray');
5
5
  require('@babel/runtime/helpers/slicedToArray');
6
6
  require('react');
7
7
  require('ramda');
8
- var Menu = require('./chunk-4b866a12.cjs.js');
8
+ var Menu = require('./chunk-62a3a743.cjs.js');
9
9
  require('./chunk-b18ba907.cjs.js');
10
10
  require('react/jsx-runtime');
11
11
  require('./chunk-da9ee471.cjs.js');
@@ -11525,7 +11525,11 @@ function createNodeFromContent(content, schema, options) {
11525
11525
  if (isArrayContent) {
11526
11526
  return utils.Fragment.fromArray(content.map(item => schema.nodeFromJSON(item)));
11527
11527
  }
11528
- return schema.nodeFromJSON(content);
11528
+ const node = schema.nodeFromJSON(content);
11529
+ if (options.errorOnInvalidContent) {
11530
+ node.check();
11531
+ }
11532
+ return node;
11529
11533
  }
11530
11534
  catch (error) {
11531
11535
  if (options.errorOnInvalidContent) {
@@ -12728,7 +12732,7 @@ const splitBlock = ({ keepMarks = true } = {}) => ({ tr, state, dispatch, editor
12728
12732
  return can;
12729
12733
  };
12730
12734
 
12731
- const splitListItem = typeOrName => ({ tr, state, dispatch, editor, }) => {
12735
+ const splitListItem = (typeOrName, overrideAttrs = {}) => ({ tr, state, dispatch, editor, }) => {
12732
12736
  var _a;
12733
12737
  const type = getNodeType$1(typeOrName, state.schema);
12734
12738
  const { $from, $to } = state.selection;
@@ -12764,7 +12768,10 @@ const splitListItem = typeOrName => ({ tr, state, dispatch, editor, }) => {
12764
12768
  // eslint-disable-next-line
12765
12769
  const depthAfter = $from.indexAfter(-1) < $from.node(-2).childCount ? 1 : $from.indexAfter(-2) < $from.node(-3).childCount ? 2 : 3;
12766
12770
  // Add a second list item with an empty default start node
12767
- const newNextTypeAttributes = getSplittedAttributes(extensionAttributes, $from.node().type.name, $from.node().attrs);
12771
+ const newNextTypeAttributes = {
12772
+ ...getSplittedAttributes(extensionAttributes, $from.node().type.name, $from.node().attrs),
12773
+ ...overrideAttrs,
12774
+ };
12768
12775
  const nextType = ((_a = type.contentMatch.defaultType) === null || _a === void 0 ? void 0 : _a.createAndFill(newNextTypeAttributes)) || undefined;
12769
12776
  wrap = wrap.append(utils.Fragment.from(type.createAndFill(null, nextType) || undefined));
12770
12777
  const start = $from.before($from.depth - (depthBefore - 1));
@@ -12786,8 +12793,14 @@ const splitListItem = typeOrName => ({ tr, state, dispatch, editor, }) => {
12786
12793
  return true;
12787
12794
  }
12788
12795
  const nextType = $to.pos === $from.end() ? grandParent.contentMatchAt(0).defaultType : null;
12789
- const newTypeAttributes = getSplittedAttributes(extensionAttributes, grandParent.type.name, grandParent.attrs);
12790
- const newNextTypeAttributes = getSplittedAttributes(extensionAttributes, $from.node().type.name, $from.node().attrs);
12796
+ const newTypeAttributes = {
12797
+ ...getSplittedAttributes(extensionAttributes, grandParent.type.name, grandParent.attrs),
12798
+ ...overrideAttrs,
12799
+ };
12800
+ const newNextTypeAttributes = {
12801
+ ...getSplittedAttributes(extensionAttributes, $from.node().type.name, $from.node().attrs),
12802
+ ...overrideAttrs,
12803
+ };
12791
12804
  tr.delete($from.pos, $to.pos);
12792
12805
  const types = nextType
12793
12806
  ? [
@@ -13513,8 +13526,8 @@ img.ProseMirror-separator {
13513
13526
  display: inline !important;
13514
13527
  border: none !important;
13515
13528
  margin: 0 !important;
13516
- width: 1px !important;
13517
- height: 1px !important;
13529
+ width: 0 !important;
13530
+ height: 0 !important;
13518
13531
  }
13519
13532
 
13520
13533
  .ProseMirror-gapcursor {
@@ -13575,10 +13588,14 @@ function createStyleTag(style, nonce, suffix) {
13575
13588
  return styleNode;
13576
13589
  }
13577
13590
 
13578
- class Editor$1 extends EventEmitter {
13591
+ class Editor extends EventEmitter {
13579
13592
  constructor(options = {}) {
13580
13593
  super();
13581
13594
  this.isFocused = false;
13595
+ /**
13596
+ * The editor is considered initialized after the `create` event has been emitted.
13597
+ */
13598
+ this.isInitialized = false;
13582
13599
  this.extensionStorage = {};
13583
13600
  this.options = {
13584
13601
  element: document.createElement('div'),
@@ -13629,6 +13646,7 @@ class Editor$1 extends EventEmitter {
13629
13646
  }
13630
13647
  this.commands.focus(this.options.autofocus);
13631
13648
  this.emit('create', { editor: this });
13649
+ this.isInitialized = true;
13632
13650
  }, 0);
13633
13651
  }
13634
13652
  /**
@@ -14762,6 +14780,36 @@ Extension.create({
14762
14780
  },
14763
14781
  });
14764
14782
 
14783
+ var shim = {exports: {}};
14784
+
14785
+ var useSyncExternalStoreShim_production_min = {};
14786
+
14787
+ /**
14788
+ * @license React
14789
+ * use-sync-external-store-shim.production.min.js
14790
+ *
14791
+ * Copyright (c) Facebook, Inc. and its affiliates.
14792
+ *
14793
+ * This source code is licensed under the MIT license found in the
14794
+ * LICENSE file in the root directory of this source tree.
14795
+ */
14796
+
14797
+ var hasRequiredUseSyncExternalStoreShim_production_min;
14798
+
14799
+ function requireUseSyncExternalStoreShim_production_min () {
14800
+ if (hasRequiredUseSyncExternalStoreShim_production_min) return useSyncExternalStoreShim_production_min;
14801
+ hasRequiredUseSyncExternalStoreShim_production_min = 1;
14802
+ var e=React__default["default"];function h(a,b){return a===b&&(0!==a||1/a===1/b)||a!==a&&b!==b}var k="function"===typeof Object.is?Object.is:h,l=e.useState,m=e.useEffect,n=e.useLayoutEffect,p=e.useDebugValue;function q(a,b){var d=b(),f=l({inst:{value:d,getSnapshot:b}}),c=f[0].inst,g=f[1];n(function(){c.value=d;c.getSnapshot=b;r(c)&&g({inst:c});},[a,d,b]);m(function(){r(c)&&g({inst:c});return a(function(){r(c)&&g({inst:c});})},[a]);p(d);return d}
14803
+ function r(a){var b=a.getSnapshot;a=a.value;try{var d=b();return !k(a,d)}catch(f){return !0}}function t(a,b){return b()}var u="undefined"===typeof window||"undefined"===typeof window.document||"undefined"===typeof window.document.createElement?t:q;useSyncExternalStoreShim_production_min.useSyncExternalStore=void 0!==e.useSyncExternalStore?e.useSyncExternalStore:u;
14804
+ return useSyncExternalStoreShim_production_min;
14805
+ }
14806
+
14807
+ {
14808
+ shim.exports = requireUseSyncExternalStoreShim_production_min();
14809
+ }
14810
+
14811
+ var shimExports = shim.exports;
14812
+
14765
14813
  const mergeRefs = (...refs) => {
14766
14814
  return (node) => {
14767
14815
  refs.forEach(ref => {
@@ -14774,18 +14822,63 @@ const mergeRefs = (...refs) => {
14774
14822
  });
14775
14823
  };
14776
14824
  };
14777
- const Portals = ({ renderers }) => {
14778
- return (React__default["default"].createElement(React__default["default"].Fragment, null, Object.entries(renderers).map(([key, renderer]) => {
14779
- return ReactDOM__default["default"].createPortal(renderer.reactElement, renderer.element, key);
14780
- })));
14825
+ /**
14826
+ * This component renders all of the editor's node views.
14827
+ */
14828
+ const Portals = ({ contentComponent, }) => {
14829
+ // For performance reasons, we render the node view portals on state changes only
14830
+ const renderers = shimExports.useSyncExternalStore(contentComponent.subscribe, contentComponent.getSnapshot, contentComponent.getServerSnapshot);
14831
+ // This allows us to directly render the portals without any additional wrapper
14832
+ return (React__default["default"].createElement(React__default["default"].Fragment, null, Object.values(renderers)));
14781
14833
  };
14834
+ function getInstance() {
14835
+ const subscribers = new Set();
14836
+ let renderers = {};
14837
+ return {
14838
+ /**
14839
+ * Subscribe to the editor instance's changes.
14840
+ */
14841
+ subscribe(callback) {
14842
+ subscribers.add(callback);
14843
+ return () => {
14844
+ subscribers.delete(callback);
14845
+ };
14846
+ },
14847
+ getSnapshot() {
14848
+ return renderers;
14849
+ },
14850
+ getServerSnapshot() {
14851
+ return renderers;
14852
+ },
14853
+ /**
14854
+ * Adds a new NodeView Renderer to the editor.
14855
+ */
14856
+ setRenderer(id, renderer) {
14857
+ renderers = {
14858
+ ...renderers,
14859
+ [id]: ReactDOM__default["default"].createPortal(renderer.reactElement, renderer.element, id),
14860
+ };
14861
+ subscribers.forEach(subscriber => subscriber());
14862
+ },
14863
+ /**
14864
+ * Removes a NodeView Renderer from the editor.
14865
+ */
14866
+ removeRenderer(id) {
14867
+ const nextRenderers = { ...renderers };
14868
+ delete nextRenderers[id];
14869
+ renderers = nextRenderers;
14870
+ subscribers.forEach(subscriber => subscriber());
14871
+ },
14872
+ };
14873
+ }
14782
14874
  class PureEditorContent extends React__default["default"].Component {
14783
14875
  constructor(props) {
14876
+ var _a;
14784
14877
  super(props);
14785
14878
  this.editorContentRef = React__default["default"].createRef();
14786
14879
  this.initialized = false;
14787
14880
  this.state = {
14788
- renderers: {},
14881
+ hasContentComponentInitialized: Boolean((_a = props.editor) === null || _a === void 0 ? void 0 : _a.contentComponent),
14789
14882
  };
14790
14883
  }
14791
14884
  componentDidMount() {
@@ -14795,7 +14888,7 @@ class PureEditorContent extends React__default["default"].Component {
14795
14888
  this.init();
14796
14889
  }
14797
14890
  init() {
14798
- const { editor } = this.props;
14891
+ const editor = this.props.editor;
14799
14892
  if (editor && !editor.isDestroyed && editor.options.element) {
14800
14893
  if (editor.contentComponent) {
14801
14894
  return;
@@ -14805,44 +14898,31 @@ class PureEditorContent extends React__default["default"].Component {
14805
14898
  editor.setOptions({
14806
14899
  element,
14807
14900
  });
14808
- editor.contentComponent = this;
14901
+ editor.contentComponent = getInstance();
14902
+ // Has the content component been initialized?
14903
+ if (!this.state.hasContentComponentInitialized) {
14904
+ // Subscribe to the content component
14905
+ this.unsubscribeToContentComponent = editor.contentComponent.subscribe(() => {
14906
+ this.setState(prevState => {
14907
+ if (!prevState.hasContentComponentInitialized) {
14908
+ return {
14909
+ hasContentComponentInitialized: true,
14910
+ };
14911
+ }
14912
+ return prevState;
14913
+ });
14914
+ // Unsubscribe to previous content component
14915
+ if (this.unsubscribeToContentComponent) {
14916
+ this.unsubscribeToContentComponent();
14917
+ }
14918
+ });
14919
+ }
14809
14920
  editor.createNodeViews();
14810
14921
  this.initialized = true;
14811
14922
  }
14812
14923
  }
14813
- maybeFlushSync(fn) {
14814
- // Avoid calling flushSync until the editor is initialized.
14815
- // Initialization happens during the componentDidMount or componentDidUpdate
14816
- // lifecycle methods, and React doesn't allow calling flushSync from inside
14817
- // a lifecycle method.
14818
- if (this.initialized) {
14819
- ReactDOM.flushSync(fn);
14820
- }
14821
- else {
14822
- fn();
14823
- }
14824
- }
14825
- setRenderer(id, renderer) {
14826
- this.maybeFlushSync(() => {
14827
- this.setState(({ renderers }) => ({
14828
- renderers: {
14829
- ...renderers,
14830
- [id]: renderer,
14831
- },
14832
- }));
14833
- });
14834
- }
14835
- removeRenderer(id) {
14836
- this.maybeFlushSync(() => {
14837
- this.setState(({ renderers }) => {
14838
- const nextRenderers = { ...renderers };
14839
- delete nextRenderers[id];
14840
- return { renderers: nextRenderers };
14841
- });
14842
- });
14843
- }
14844
14924
  componentWillUnmount() {
14845
- const { editor } = this.props;
14925
+ const editor = this.props.editor;
14846
14926
  if (!editor) {
14847
14927
  return;
14848
14928
  }
@@ -14852,6 +14932,9 @@ class PureEditorContent extends React__default["default"].Component {
14852
14932
  nodeViews: {},
14853
14933
  });
14854
14934
  }
14935
+ if (this.unsubscribeToContentComponent) {
14936
+ this.unsubscribeToContentComponent();
14937
+ }
14855
14938
  editor.contentComponent = null;
14856
14939
  if (!editor.options.element.firstChild) {
14857
14940
  return;
@@ -14866,13 +14949,14 @@ class PureEditorContent extends React__default["default"].Component {
14866
14949
  const { editor, innerRef, ...rest } = this.props;
14867
14950
  return (React__default["default"].createElement(React__default["default"].Fragment, null,
14868
14951
  React__default["default"].createElement("div", { ref: mergeRefs(innerRef, this.editorContentRef), ...rest }),
14869
- React__default["default"].createElement(Portals, { renderers: this.state.renderers })));
14952
+ (editor === null || editor === void 0 ? void 0 : editor.contentComponent) && React__default["default"].createElement(Portals, { contentComponent: editor.contentComponent })));
14870
14953
  }
14871
14954
  }
14872
14955
  // EditorContent should be re-created whenever the Editor instance changes
14873
14956
  const EditorContentWithKey = React.forwardRef((props, ref) => {
14874
14957
  const key = React__default["default"].useMemo(() => {
14875
- return Math.floor(Math.random() * 0xFFFFFFFF).toString();
14958
+ return Math.floor(Math.random() * 0xffffffff).toString();
14959
+ // eslint-disable-next-line react-hooks/exhaustive-deps
14876
14960
  }, [props.editor]);
14877
14961
  // Can't use JSX here because it conflicts with the type definition of Vue's JSX, so use createElement
14878
14962
  return React__default["default"].createElement(PureEditorContent, {
@@ -14883,43 +14967,6 @@ const EditorContentWithKey = React.forwardRef((props, ref) => {
14883
14967
  });
14884
14968
  const EditorContent = React__default["default"].memo(EditorContentWithKey);
14885
14969
 
14886
- var shim = {exports: {}};
14887
-
14888
- var useSyncExternalStoreShim_production_min = {};
14889
-
14890
- /**
14891
- * @license React
14892
- * use-sync-external-store-shim.production.min.js
14893
- *
14894
- * Copyright (c) Facebook, Inc. and its affiliates.
14895
- *
14896
- * This source code is licensed under the MIT license found in the
14897
- * LICENSE file in the root directory of this source tree.
14898
- */
14899
-
14900
- var hasRequiredUseSyncExternalStoreShim_production_min;
14901
-
14902
- function requireUseSyncExternalStoreShim_production_min () {
14903
- if (hasRequiredUseSyncExternalStoreShim_production_min) return useSyncExternalStoreShim_production_min;
14904
- hasRequiredUseSyncExternalStoreShim_production_min = 1;
14905
- var e=React__default["default"];function h(a,b){return a===b&&(0!==a||1/a===1/b)||a!==a&&b!==b}var k="function"===typeof Object.is?Object.is:h,l=e.useState,m=e.useEffect,n=e.useLayoutEffect,p=e.useDebugValue;function q(a,b){var d=b(),f=l({inst:{value:d,getSnapshot:b}}),c=f[0].inst,g=f[1];n(function(){c.value=d;c.getSnapshot=b;r(c)&&g({inst:c});},[a,d,b]);m(function(){r(c)&&g({inst:c});return a(function(){r(c)&&g({inst:c});})},[a]);p(d);return d}
14906
- function r(a){var b=a.getSnapshot;a=a.value;try{var d=b();return !k(a,d)}catch(f){return !0}}function t(a,b){return b()}var u="undefined"===typeof window||"undefined"===typeof window.document||"undefined"===typeof window.document.createElement?t:q;useSyncExternalStoreShim_production_min.useSyncExternalStore=void 0!==e.useSyncExternalStore?e.useSyncExternalStore:u;
14907
- return useSyncExternalStoreShim_production_min;
14908
- }
14909
-
14910
- {
14911
- shim.exports = requireUseSyncExternalStoreShim_production_min();
14912
- }
14913
-
14914
- var shimExports = shim.exports;
14915
-
14916
- class Editor extends Editor$1 {
14917
- constructor() {
14918
- super(...arguments);
14919
- this.contentComponent = null;
14920
- }
14921
- }
14922
-
14923
14970
  var withSelector = {exports: {}};
14924
14971
 
14925
14972
  var withSelector_production_min = {};
@@ -15060,6 +15107,7 @@ class EditorInstanceManager {
15060
15107
  this.options = options;
15061
15108
  this.subscriptions = new Set();
15062
15109
  this.setEditor(this.getInitialEditor());
15110
+ this.scheduleDestroy();
15063
15111
  this.getEditor = this.getEditor.bind(this);
15064
15112
  this.getServerSnapshot = this.getServerSnapshot.bind(this);
15065
15113
  this.subscribe = this.subscribe.bind(this);
@@ -15096,17 +15144,20 @@ class EditorInstanceManager {
15096
15144
  * Create a new editor instance. And attach event listeners.
15097
15145
  */
15098
15146
  createEditor() {
15099
- const editor = new Editor(this.options.current);
15100
- // Always call the most recent version of the callback function by default
15101
- editor.on('beforeCreate', (...args) => { var _a, _b; return (_b = (_a = this.options.current).onBeforeCreate) === null || _b === void 0 ? void 0 : _b.call(_a, ...args); });
15102
- editor.on('blur', (...args) => { var _a, _b; return (_b = (_a = this.options.current).onBlur) === null || _b === void 0 ? void 0 : _b.call(_a, ...args); });
15103
- editor.on('create', (...args) => { var _a, _b; return (_b = (_a = this.options.current).onCreate) === null || _b === void 0 ? void 0 : _b.call(_a, ...args); });
15104
- editor.on('destroy', (...args) => { var _a, _b; return (_b = (_a = this.options.current).onDestroy) === null || _b === void 0 ? void 0 : _b.call(_a, ...args); });
15105
- editor.on('focus', (...args) => { var _a, _b; return (_b = (_a = this.options.current).onFocus) === null || _b === void 0 ? void 0 : _b.call(_a, ...args); });
15106
- editor.on('selectionUpdate', (...args) => { var _a, _b; return (_b = (_a = this.options.current).onSelectionUpdate) === null || _b === void 0 ? void 0 : _b.call(_a, ...args); });
15107
- editor.on('transaction', (...args) => { var _a, _b; return (_b = (_a = this.options.current).onTransaction) === null || _b === void 0 ? void 0 : _b.call(_a, ...args); });
15108
- editor.on('update', (...args) => { var _a, _b; return (_b = (_a = this.options.current).onUpdate) === null || _b === void 0 ? void 0 : _b.call(_a, ...args); });
15109
- editor.on('contentError', (...args) => { var _a, _b; return (_b = (_a = this.options.current).onContentError) === null || _b === void 0 ? void 0 : _b.call(_a, ...args); });
15147
+ const optionsToApply = {
15148
+ ...this.options.current,
15149
+ // Always call the most recent version of the callback function by default
15150
+ onBeforeCreate: (...args) => { var _a, _b; return (_b = (_a = this.options.current).onBeforeCreate) === null || _b === void 0 ? void 0 : _b.call(_a, ...args); },
15151
+ onBlur: (...args) => { var _a, _b; return (_b = (_a = this.options.current).onBlur) === null || _b === void 0 ? void 0 : _b.call(_a, ...args); },
15152
+ onCreate: (...args) => { var _a, _b; return (_b = (_a = this.options.current).onCreate) === null || _b === void 0 ? void 0 : _b.call(_a, ...args); },
15153
+ onDestroy: (...args) => { var _a, _b; return (_b = (_a = this.options.current).onDestroy) === null || _b === void 0 ? void 0 : _b.call(_a, ...args); },
15154
+ onFocus: (...args) => { var _a, _b; return (_b = (_a = this.options.current).onFocus) === null || _b === void 0 ? void 0 : _b.call(_a, ...args); },
15155
+ onSelectionUpdate: (...args) => { var _a, _b; return (_b = (_a = this.options.current).onSelectionUpdate) === null || _b === void 0 ? void 0 : _b.call(_a, ...args); },
15156
+ onTransaction: (...args) => { var _a, _b; return (_b = (_a = this.options.current).onTransaction) === null || _b === void 0 ? void 0 : _b.call(_a, ...args); },
15157
+ onUpdate: (...args) => { var _a, _b; return (_b = (_a = this.options.current).onUpdate) === null || _b === void 0 ? void 0 : _b.call(_a, ...args); },
15158
+ onContentError: (...args) => { var _a, _b; return (_b = (_a = this.options.current).onContentError) === null || _b === void 0 ? void 0 : _b.call(_a, ...args); },
15159
+ };
15160
+ const editor = new Editor(optionsToApply);
15110
15161
  // no need to keep track of the event listeners, they will be removed when the editor is destroyed
15111
15162
  return editor;
15112
15163
  }
@@ -15195,10 +15246,10 @@ class EditorInstanceManager {
15195
15246
  scheduleDestroy() {
15196
15247
  const currentInstanceId = this.instanceId;
15197
15248
  const currentEditor = this.editor;
15198
- // Wait a tick to see if the component is still mounted
15249
+ // Wait two ticks to see if the component is still mounted
15199
15250
  this.scheduledDestructionTimeout = setTimeout(() => {
15200
15251
  if (this.isComponentMounted && this.instanceId === currentInstanceId) {
15201
- // If still mounted on the next tick, with the same instanceId, do not destroy the editor
15252
+ // If still mounted on the following tick, with the same instanceId, do not destroy the editor
15202
15253
  if (currentEditor) {
15203
15254
  // just re-apply options as they might have changed
15204
15255
  currentEditor.setOptions(this.options.current);
@@ -15211,7 +15262,9 @@ class EditorInstanceManager {
15211
15262
  this.setEditor(null);
15212
15263
  }
15213
15264
  }
15214
- }, 0);
15265
+ // This allows the effect to run again between ticks
15266
+ // which may save us from having to re-create the editor
15267
+ }, 1);
15215
15268
  }
15216
15269
  }
15217
15270
  function useEditor(options = {}, deps = []) {
@@ -15290,7 +15343,9 @@ const useReactNodeView = () => React.useContext(ReactNodeViewContext);
15290
15343
  const NodeViewContent = props => {
15291
15344
  const Tag = props.as || 'div';
15292
15345
  const { nodeViewContentRef } = useReactNodeView();
15293
- return (React__default["default"].createElement(Tag, { ...props, ref: nodeViewContentRef, "data-node-view-content": "", style: {
15346
+ return (
15347
+ // @ts-ignore
15348
+ React__default["default"].createElement(Tag, { ...props, ref: nodeViewContentRef, "data-node-view-content": "", style: {
15294
15349
  whiteSpace: 'pre-wrap',
15295
15350
  ...props.style,
15296
15351
  } }));
@@ -15299,7 +15354,9 @@ const NodeViewContent = props => {
15299
15354
  const NodeViewWrapper = React__default["default"].forwardRef((props, ref) => {
15300
15355
  const { onDragStart } = useReactNodeView();
15301
15356
  const Tag = props.as || 'div';
15302
- return (React__default["default"].createElement(Tag, { ...props, ref: ref, "data-node-view-wrapper": "", onDragStart: onDragStart, style: {
15357
+ return (
15358
+ // @ts-ignore
15359
+ React__default["default"].createElement(Tag, { ...props, ref: ref, "data-node-view-wrapper": "", onDragStart: onDragStart, style: {
15303
15360
  whiteSpace: 'normal',
15304
15361
  ...props.style,
15305
15362
  } }));
@@ -15353,19 +15410,29 @@ class ReactRenderer {
15353
15410
  this.element.setAttribute(key, attrs[key]);
15354
15411
  });
15355
15412
  }
15356
- this.render();
15413
+ if (this.editor.isInitialized) {
15414
+ // On first render, we need to flush the render synchronously
15415
+ // Renders afterwards can be async, but this fixes a cursor positioning issue
15416
+ ReactDOM.flushSync(() => {
15417
+ this.render();
15418
+ });
15419
+ }
15420
+ else {
15421
+ this.render();
15422
+ }
15357
15423
  }
15358
15424
  render() {
15359
- var _a, _b;
15425
+ var _a;
15360
15426
  const Component = this.component;
15361
15427
  const props = this.props;
15428
+ const editor = this.editor;
15362
15429
  if (isClassComponent(Component) || isForwardRefComponent(Component)) {
15363
15430
  props.ref = (ref) => {
15364
15431
  this.ref = ref;
15365
15432
  };
15366
15433
  }
15367
- this.reactElement = React__default["default"].createElement(Component, { ...props });
15368
- (_b = (_a = this.editor) === null || _a === void 0 ? void 0 : _a.contentComponent) === null || _b === void 0 ? void 0 : _b.setRenderer(this.id, this);
15434
+ this.reactElement = React__default["default"].createElement(Component, props);
15435
+ (_a = editor === null || editor === void 0 ? void 0 : editor.contentComponent) === null || _a === void 0 ? void 0 : _a.setRenderer(this.id, this);
15369
15436
  }
15370
15437
  updateProps(props = {}) {
15371
15438
  this.props = {
@@ -15375,8 +15442,9 @@ class ReactRenderer {
15375
15442
  this.render();
15376
15443
  }
15377
15444
  destroy() {
15378
- var _a, _b;
15379
- (_b = (_a = this.editor) === null || _a === void 0 ? void 0 : _a.contentComponent) === null || _b === void 0 ? void 0 : _b.removeRenderer(this.id);
15445
+ var _a;
15446
+ const editor = this.editor;
15447
+ (_a = editor === null || editor === void 0 ? void 0 : editor.contentComponent) === null || _a === void 0 ? void 0 : _a.removeRenderer(this.id);
15380
15448
  }
15381
15449
  }
15382
15450
 
@@ -15398,18 +15466,19 @@ class ReactNodeView extends NodeView {
15398
15466
  };
15399
15467
  this.component.displayName = capitalizeFirstChar(this.extension.name);
15400
15468
  }
15401
- const ReactNodeViewProvider = componentProps => {
15402
- const Component = this.component;
15403
- const onDragStart = this.onDragStart.bind(this);
15404
- const nodeViewContentRef = element => {
15405
- if (element && this.contentDOMElement && element.firstChild !== this.contentDOMElement) {
15406
- element.appendChild(this.contentDOMElement);
15407
- }
15408
- };
15409
- return (React__default["default"].createElement(React__default["default"].Fragment, null,
15410
- React__default["default"].createElement(ReactNodeViewContext.Provider, { value: { onDragStart, nodeViewContentRef } },
15411
- React__default["default"].createElement(Component, { ...componentProps }))));
15469
+ const onDragStart = this.onDragStart.bind(this);
15470
+ const nodeViewContentRef = element => {
15471
+ if (element && this.contentDOMElement && element.firstChild !== this.contentDOMElement) {
15472
+ element.appendChild(this.contentDOMElement);
15473
+ }
15412
15474
  };
15475
+ const context = { onDragStart, nodeViewContentRef };
15476
+ const Component = this.component;
15477
+ // For performance reasons, we memoize the provider component
15478
+ // And all of the things it requires are declared outside of the component, so it doesn't need to re-render
15479
+ const ReactNodeViewProvider = React__default["default"].memo(componentProps => {
15480
+ return (React__default["default"].createElement(ReactNodeViewContext.Provider, { value: context }, React__default["default"].createElement(Component, componentProps)));
15481
+ });
15413
15482
  ReactNodeViewProvider.displayName = 'ReactNodeView';
15414
15483
  if (this.node.isLeaf) {
15415
15484
  this.contentDOMElement = null;
@@ -19446,4 +19515,4 @@ exports.useEditor = useEditor;
19446
19515
  exports.useEditorState = useEditorState$1;
19447
19516
  exports.validateUrl = validateUrl;
19448
19517
  exports.wrappingInputRule = wrappingInputRule;
19449
- //# sourceMappingURL=chunk-4b866a12.cjs.js.map
19518
+ //# sourceMappingURL=chunk-62a3a743.cjs.js.map