@tiptap/react 2.5.8 → 2.5.9
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/dist/index.cjs +253 -137
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +253 -137
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +253 -137
- package/dist/index.umd.js.map +1 -1
- package/dist/packages/core/src/Extension.d.ts +1 -1
- package/dist/packages/core/src/Mark.d.ts +1 -1
- package/dist/packages/core/src/Node.d.ts +1 -1
- package/dist/packages/core/src/helpers/isNodeEmpty.d.ts +10 -4
- package/package.json +7 -7
- package/src/useEditor.ts +241 -87
- package/src/useEditorState.ts +75 -60
package/dist/index.js
CHANGED
|
@@ -126,17 +126,6 @@ const EditorContentWithKey = forwardRef((props, ref) => {
|
|
|
126
126
|
});
|
|
127
127
|
const EditorContent = React.memo(EditorContentWithKey);
|
|
128
128
|
|
|
129
|
-
class Editor extends Editor$1 {
|
|
130
|
-
constructor() {
|
|
131
|
-
super(...arguments);
|
|
132
|
-
this.contentComponent = null;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
var withSelector = {exports: {}};
|
|
137
|
-
|
|
138
|
-
var withSelector_production_min = {};
|
|
139
|
-
|
|
140
129
|
var shim = {exports: {}};
|
|
141
130
|
|
|
142
131
|
var useSyncExternalStoreShim_production_min = {};
|
|
@@ -407,20 +396,25 @@ function requireUseSyncExternalStoreShim_development () {
|
|
|
407
396
|
return useSyncExternalStoreShim_development;
|
|
408
397
|
}
|
|
409
398
|
|
|
410
|
-
|
|
399
|
+
if (process.env.NODE_ENV === 'production') {
|
|
400
|
+
shim.exports = requireUseSyncExternalStoreShim_production_min();
|
|
401
|
+
} else {
|
|
402
|
+
shim.exports = requireUseSyncExternalStoreShim_development();
|
|
403
|
+
}
|
|
411
404
|
|
|
412
|
-
|
|
413
|
-
if (hasRequiredShim) return shim.exports;
|
|
414
|
-
hasRequiredShim = 1;
|
|
405
|
+
var shimExports = shim.exports;
|
|
415
406
|
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
return shim.exports;
|
|
407
|
+
class Editor extends Editor$1 {
|
|
408
|
+
constructor() {
|
|
409
|
+
super(...arguments);
|
|
410
|
+
this.contentComponent = null;
|
|
411
|
+
}
|
|
422
412
|
}
|
|
423
413
|
|
|
414
|
+
var withSelector = {exports: {}};
|
|
415
|
+
|
|
416
|
+
var withSelector_production_min = {};
|
|
417
|
+
|
|
424
418
|
/**
|
|
425
419
|
* @license React
|
|
426
420
|
* use-sync-external-store-shim/with-selector.production.min.js
|
|
@@ -436,7 +430,7 @@ var hasRequiredWithSelector_production_min;
|
|
|
436
430
|
function requireWithSelector_production_min () {
|
|
437
431
|
if (hasRequiredWithSelector_production_min) return withSelector_production_min;
|
|
438
432
|
hasRequiredWithSelector_production_min = 1;
|
|
439
|
-
var h=React,n=
|
|
433
|
+
var h=React,n=shimExports;function p(a,b){return a===b&&(0!==a||1/a===1/b)||a!==a&&b!==b}var q="function"===typeof Object.is?Object.is:p,r=n.useSyncExternalStore,t=h.useRef,u=h.useEffect,v=h.useMemo,w=h.useDebugValue;
|
|
440
434
|
withSelector_production_min.useSyncExternalStoreWithSelector=function(a,b,e,l,g){var c=t(null);if(null===c.current){var f={hasValue:!1,value:null};c.current=f;}else f=c.current;c=v(function(){function a(a){if(!c){c=!0;d=a;a=l(a);if(void 0!==g&&f.hasValue){var b=f.value;if(g(b,a))return k=b}return k=a}b=k;if(q(d,a))return b;var e=l(a);if(void 0!==g&&g(b,e))return b;d=a;return k=e}var c=!1,d,k,m=void 0===e?null:e;return [function(){return a(b())},null===m?void 0:function(){return a(m())}]},[b,e,l,g]);var d=r(a,c[0],c[1]);
|
|
441
435
|
u(function(){f.hasValue=!0;f.value=d;},[d]);w(d);return d};
|
|
442
436
|
return withSelector_production_min;
|
|
@@ -472,7 +466,7 @@ function requireWithSelector_development () {
|
|
|
472
466
|
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error());
|
|
473
467
|
}
|
|
474
468
|
var React$1 = React;
|
|
475
|
-
var shim =
|
|
469
|
+
var shim = shimExports;
|
|
476
470
|
|
|
477
471
|
/**
|
|
478
472
|
* inlined Object.is polyfill to avoid requiring consumers ship their own
|
|
@@ -626,71 +620,75 @@ var withSelectorExports = withSelector.exports;
|
|
|
626
620
|
* To synchronize the editor instance with the component state,
|
|
627
621
|
* we need to create a separate instance that is not affected by the component re-renders.
|
|
628
622
|
*/
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
623
|
+
class EditorStateManager {
|
|
624
|
+
constructor(initialEditor) {
|
|
625
|
+
this.transactionNumber = 0;
|
|
626
|
+
this.lastTransactionNumber = 0;
|
|
627
|
+
this.subscribers = new Set();
|
|
628
|
+
this.editor = initialEditor;
|
|
629
|
+
this.lastSnapshot = { editor: initialEditor, transactionNumber: 0 };
|
|
630
|
+
this.getSnapshot = this.getSnapshot.bind(this);
|
|
631
|
+
this.getServerSnapshot = this.getServerSnapshot.bind(this);
|
|
632
|
+
this.watch = this.watch.bind(this);
|
|
633
|
+
this.subscribe = this.subscribe.bind(this);
|
|
634
|
+
}
|
|
635
|
+
/**
|
|
636
|
+
* Get the current editor instance.
|
|
637
|
+
*/
|
|
638
|
+
getSnapshot() {
|
|
639
|
+
if (this.transactionNumber === this.lastTransactionNumber) {
|
|
640
|
+
return this.lastSnapshot;
|
|
641
|
+
}
|
|
642
|
+
this.lastTransactionNumber = this.transactionNumber;
|
|
643
|
+
this.lastSnapshot = { editor: this.editor, transactionNumber: this.transactionNumber };
|
|
644
|
+
return this.lastSnapshot;
|
|
645
|
+
}
|
|
646
|
+
/**
|
|
647
|
+
* Always disable the editor on the server-side.
|
|
648
|
+
*/
|
|
649
|
+
getServerSnapshot() {
|
|
650
|
+
return { editor: null, transactionNumber: 0 };
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* Subscribe to the editor instance's changes.
|
|
654
|
+
*/
|
|
655
|
+
subscribe(callback) {
|
|
656
|
+
this.subscribers.add(callback);
|
|
657
|
+
return () => {
|
|
658
|
+
this.subscribers.delete(callback);
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
/**
|
|
662
|
+
* Watch the editor instance for changes.
|
|
663
|
+
*/
|
|
664
|
+
watch(nextEditor) {
|
|
665
|
+
this.editor = nextEditor;
|
|
666
|
+
if (this.editor) {
|
|
667
|
+
/**
|
|
668
|
+
* This will force a re-render when the editor state changes.
|
|
669
|
+
* This is to support things like `editor.can().toggleBold()` in components that `useEditor`.
|
|
670
|
+
* This could be more efficient, but it's a good trade-off for now.
|
|
671
|
+
*/
|
|
672
|
+
const fn = () => {
|
|
673
|
+
this.transactionNumber += 1;
|
|
674
|
+
this.subscribers.forEach(callback => callback());
|
|
675
|
+
};
|
|
676
|
+
const currentEditor = this.editor;
|
|
677
|
+
currentEditor.on('transaction', fn);
|
|
658
678
|
return () => {
|
|
659
|
-
|
|
679
|
+
currentEditor.off('transaction', fn);
|
|
660
680
|
};
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
*/
|
|
665
|
-
watch(nextEditor) {
|
|
666
|
-
editor = nextEditor;
|
|
667
|
-
if (editor) {
|
|
668
|
-
/**
|
|
669
|
-
* This will force a re-render when the editor state changes.
|
|
670
|
-
* This is to support things like `editor.can().toggleBold()` in components that `useEditor`.
|
|
671
|
-
* This could be more efficient, but it's a good trade-off for now.
|
|
672
|
-
*/
|
|
673
|
-
const fn = () => {
|
|
674
|
-
transactionNumber += 1;
|
|
675
|
-
subscribers.forEach(callback => callback());
|
|
676
|
-
};
|
|
677
|
-
const currentEditor = editor;
|
|
678
|
-
currentEditor.on('transaction', fn);
|
|
679
|
-
return () => {
|
|
680
|
-
currentEditor.off('transaction', fn);
|
|
681
|
-
};
|
|
682
|
-
}
|
|
683
|
-
},
|
|
684
|
-
};
|
|
685
|
-
return editorInstance;
|
|
681
|
+
}
|
|
682
|
+
return undefined;
|
|
683
|
+
}
|
|
686
684
|
}
|
|
687
685
|
function useEditorState(options) {
|
|
688
|
-
const [editorInstance] = useState(() =>
|
|
686
|
+
const [editorInstance] = useState(() => new EditorStateManager(options.editor));
|
|
689
687
|
// Using the `useSyncExternalStore` hook to sync the editor instance with the component state
|
|
690
688
|
const selectedState = withSelectorExports.useSyncExternalStoreWithSelector(editorInstance.subscribe, editorInstance.getSnapshot, editorInstance.getServerSnapshot, options.selector, options.equalityFn);
|
|
691
689
|
useEffect(() => {
|
|
692
690
|
return editorInstance.watch(options.editor);
|
|
693
|
-
}, [options.editor]);
|
|
691
|
+
}, [options.editor, editorInstance]);
|
|
694
692
|
useDebugValue(selectedState);
|
|
695
693
|
return selectedState;
|
|
696
694
|
}
|
|
@@ -699,25 +697,50 @@ const isDev = process.env.NODE_ENV !== 'production';
|
|
|
699
697
|
const isSSR = typeof window === 'undefined';
|
|
700
698
|
const isNext = isSSR || Boolean(typeof window !== 'undefined' && window.next);
|
|
701
699
|
/**
|
|
702
|
-
*
|
|
700
|
+
* This class handles the creation, destruction, and re-creation of the editor instance.
|
|
703
701
|
*/
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
702
|
+
class EditorInstanceManager {
|
|
703
|
+
constructor(options) {
|
|
704
|
+
/**
|
|
705
|
+
* The current editor instance.
|
|
706
|
+
*/
|
|
707
|
+
this.editor = null;
|
|
708
|
+
/**
|
|
709
|
+
* The subscriptions to notify when the editor instance
|
|
710
|
+
* has been created or destroyed.
|
|
711
|
+
*/
|
|
712
|
+
this.subscriptions = new Set();
|
|
713
|
+
/**
|
|
714
|
+
* Whether the editor has been mounted.
|
|
715
|
+
*/
|
|
716
|
+
this.isComponentMounted = false;
|
|
717
|
+
/**
|
|
718
|
+
* The most recent dependencies array.
|
|
719
|
+
*/
|
|
720
|
+
this.previousDeps = null;
|
|
721
|
+
/**
|
|
722
|
+
* The unique instance ID. This is used to identify the editor instance. And will be re-generated for each new instance.
|
|
723
|
+
*/
|
|
724
|
+
this.instanceId = '';
|
|
725
|
+
this.options = options;
|
|
726
|
+
this.subscriptions = new Set();
|
|
727
|
+
this.setEditor(this.getInitialEditor());
|
|
728
|
+
this.getEditor = this.getEditor.bind(this);
|
|
729
|
+
this.getServerSnapshot = this.getServerSnapshot.bind(this);
|
|
730
|
+
this.subscribe = this.subscribe.bind(this);
|
|
731
|
+
this.refreshEditorInstance = this.refreshEditorInstance.bind(this);
|
|
732
|
+
this.scheduleDestroy = this.scheduleDestroy.bind(this);
|
|
733
|
+
this.onRender = this.onRender.bind(this);
|
|
734
|
+
this.createEditor = this.createEditor.bind(this);
|
|
735
|
+
}
|
|
736
|
+
setEditor(editor) {
|
|
737
|
+
this.editor = editor;
|
|
738
|
+
this.instanceId = Math.random().toString(36).slice(2, 9);
|
|
739
|
+
// Notify all subscribers that the editor instance has been created
|
|
740
|
+
this.subscriptions.forEach(cb => cb());
|
|
741
|
+
}
|
|
742
|
+
getInitialEditor() {
|
|
743
|
+
if (this.options.current.immediatelyRender === undefined) {
|
|
721
744
|
if (isSSR || isNext) {
|
|
722
745
|
// TODO in the next major release, we should throw an error here
|
|
723
746
|
if (isDev) {
|
|
@@ -731,55 +754,148 @@ function useEditor(options = {}, deps = []) {
|
|
|
731
754
|
return null;
|
|
732
755
|
}
|
|
733
756
|
// Default to immediately rendering when client-side rendering
|
|
734
|
-
return createEditor(
|
|
757
|
+
return this.createEditor();
|
|
735
758
|
}
|
|
736
|
-
if (options.immediatelyRender && isSSR && isDev) {
|
|
759
|
+
if (this.options.current.immediatelyRender && isSSR && isDev) {
|
|
737
760
|
// Warn in development, to make sure the developer is aware that tiptap cannot be SSR'd, set `immediatelyRender` to `false` to avoid hydration mismatches.
|
|
738
761
|
throw new Error('Tiptap Error: SSR has been detected, and `immediatelyRender` has been set to `true` this is an unsupported configuration that may result in errors, explicitly set `immediatelyRender` to `false` to avoid hydration mismatches.');
|
|
739
762
|
}
|
|
740
|
-
if (options.immediatelyRender) {
|
|
741
|
-
return createEditor(
|
|
763
|
+
if (this.options.current.immediatelyRender) {
|
|
764
|
+
return this.createEditor();
|
|
742
765
|
}
|
|
743
766
|
return null;
|
|
744
|
-
}
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
767
|
+
}
|
|
768
|
+
/**
|
|
769
|
+
* Create a new editor instance. And attach event listeners.
|
|
770
|
+
*/
|
|
771
|
+
createEditor() {
|
|
772
|
+
const editor = new Editor(this.options.current);
|
|
773
|
+
// Always call the most recent version of the callback function by default
|
|
774
|
+
editor.on('beforeCreate', (...args) => { var _a, _b; return (_b = (_a = this.options.current).onBeforeCreate) === null || _b === void 0 ? void 0 : _b.call(_a, ...args); });
|
|
775
|
+
editor.on('blur', (...args) => { var _a, _b; return (_b = (_a = this.options.current).onBlur) === null || _b === void 0 ? void 0 : _b.call(_a, ...args); });
|
|
776
|
+
editor.on('create', (...args) => { var _a, _b; return (_b = (_a = this.options.current).onCreate) === null || _b === void 0 ? void 0 : _b.call(_a, ...args); });
|
|
777
|
+
editor.on('destroy', (...args) => { var _a, _b; return (_b = (_a = this.options.current).onDestroy) === null || _b === void 0 ? void 0 : _b.call(_a, ...args); });
|
|
778
|
+
editor.on('focus', (...args) => { var _a, _b; return (_b = (_a = this.options.current).onFocus) === null || _b === void 0 ? void 0 : _b.call(_a, ...args); });
|
|
779
|
+
editor.on('selectionUpdate', (...args) => { var _a, _b; return (_b = (_a = this.options.current).onSelectionUpdate) === null || _b === void 0 ? void 0 : _b.call(_a, ...args); });
|
|
780
|
+
editor.on('transaction', (...args) => { var _a, _b; return (_b = (_a = this.options.current).onTransaction) === null || _b === void 0 ? void 0 : _b.call(_a, ...args); });
|
|
781
|
+
editor.on('update', (...args) => { var _a, _b; return (_b = (_a = this.options.current).onUpdate) === null || _b === void 0 ? void 0 : _b.call(_a, ...args); });
|
|
782
|
+
editor.on('contentError', (...args) => { var _a, _b; return (_b = (_a = this.options.current).onContentError) === null || _b === void 0 ? void 0 : _b.call(_a, ...args); });
|
|
783
|
+
// no need to keep track of the event listeners, they will be removed when the editor is destroyed
|
|
784
|
+
return editor;
|
|
785
|
+
}
|
|
786
|
+
/**
|
|
787
|
+
* Get the current editor instance.
|
|
788
|
+
*/
|
|
789
|
+
getEditor() {
|
|
790
|
+
return this.editor;
|
|
791
|
+
}
|
|
792
|
+
/**
|
|
793
|
+
* Always disable the editor on the server-side.
|
|
794
|
+
*/
|
|
795
|
+
getServerSnapshot() {
|
|
796
|
+
return null;
|
|
797
|
+
}
|
|
798
|
+
/**
|
|
799
|
+
* Subscribe to the editor instance's changes.
|
|
800
|
+
*/
|
|
801
|
+
subscribe(onStoreChange) {
|
|
802
|
+
this.subscriptions.add(onStoreChange);
|
|
803
|
+
return () => {
|
|
804
|
+
this.subscriptions.delete(onStoreChange);
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
/**
|
|
808
|
+
* On each render, we will create, update, or destroy the editor instance.
|
|
809
|
+
* @param deps The dependencies to watch for changes
|
|
810
|
+
* @returns A cleanup function
|
|
811
|
+
*/
|
|
812
|
+
onRender(deps) {
|
|
813
|
+
// The returned callback will run on each render
|
|
814
|
+
return () => {
|
|
815
|
+
this.isComponentMounted = true;
|
|
816
|
+
// Cleanup any scheduled destructions, since we are currently rendering
|
|
817
|
+
clearTimeout(this.scheduledDestructionTimeout);
|
|
818
|
+
if (this.editor && !this.editor.isDestroyed && deps.length === 0) {
|
|
819
|
+
// if the editor does exist & deps are empty, we don't need to re-initialize the editor
|
|
820
|
+
// we can fast-path to update the editor options on the existing instance
|
|
821
|
+
this.editor.setOptions(this.options.current);
|
|
822
|
+
}
|
|
823
|
+
else {
|
|
824
|
+
// When the editor:
|
|
825
|
+
// - does not yet exist
|
|
826
|
+
// - is destroyed
|
|
827
|
+
// - the deps array changes
|
|
828
|
+
// We need to destroy the editor instance and re-initialize it
|
|
829
|
+
this.refreshEditorInstance(deps);
|
|
761
830
|
}
|
|
831
|
+
return () => {
|
|
832
|
+
this.isComponentMounted = false;
|
|
833
|
+
this.scheduleDestroy();
|
|
834
|
+
};
|
|
762
835
|
};
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
836
|
+
}
|
|
837
|
+
/**
|
|
838
|
+
* Recreate the editor instance if the dependencies have changed.
|
|
839
|
+
*/
|
|
840
|
+
refreshEditorInstance(deps) {
|
|
841
|
+
if (this.editor && !this.editor.isDestroyed) {
|
|
842
|
+
// Editor instance already exists
|
|
843
|
+
if (this.previousDeps === null) {
|
|
844
|
+
// If lastDeps has not yet been initialized, reuse the current editor instance
|
|
845
|
+
this.previousDeps = deps;
|
|
846
|
+
return;
|
|
847
|
+
}
|
|
848
|
+
const depsAreEqual = this.previousDeps.length === deps.length
|
|
849
|
+
&& this.previousDeps.every((dep, index) => dep === deps[index]);
|
|
850
|
+
if (depsAreEqual) {
|
|
851
|
+
// deps exist and are equal, no need to recreate
|
|
852
|
+
return;
|
|
853
|
+
}
|
|
768
854
|
}
|
|
769
|
-
if (
|
|
770
|
-
//
|
|
771
|
-
|
|
772
|
-
editorInstance.setOptions(options);
|
|
773
|
-
return () => destroyUnusedEditor(editorInstance);
|
|
855
|
+
if (this.editor && !this.editor.isDestroyed) {
|
|
856
|
+
// Destroy the editor instance if it exists
|
|
857
|
+
this.editor.destroy();
|
|
774
858
|
}
|
|
775
|
-
|
|
776
|
-
//
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
859
|
+
this.setEditor(this.createEditor());
|
|
860
|
+
// Update the lastDeps to the current deps
|
|
861
|
+
this.previousDeps = deps;
|
|
862
|
+
}
|
|
863
|
+
/**
|
|
864
|
+
* Schedule the destruction of the editor instance.
|
|
865
|
+
* This will only destroy the editor if it was not mounted on the next tick.
|
|
866
|
+
* This is to avoid destroying the editor instance when it's actually still mounted.
|
|
867
|
+
*/
|
|
868
|
+
scheduleDestroy() {
|
|
869
|
+
const currentInstanceId = this.instanceId;
|
|
870
|
+
const currentEditor = this.editor;
|
|
871
|
+
// Wait a tick to see if the component is still mounted
|
|
872
|
+
this.scheduledDestructionTimeout = setTimeout(() => {
|
|
873
|
+
if (this.isComponentMounted && this.instanceId === currentInstanceId) {
|
|
874
|
+
// If still mounted on the next tick, with the same instanceId, do not destroy the editor
|
|
875
|
+
if (currentEditor) {
|
|
876
|
+
// just re-apply options as they might have changed
|
|
877
|
+
currentEditor.setOptions(this.options.current);
|
|
878
|
+
}
|
|
879
|
+
return;
|
|
880
|
+
}
|
|
881
|
+
if (currentEditor && !currentEditor.isDestroyed) {
|
|
882
|
+
currentEditor.destroy();
|
|
883
|
+
if (this.instanceId === currentInstanceId) {
|
|
884
|
+
this.setEditor(null);
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
}, 0);
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
function useEditor(options = {}, deps = []) {
|
|
891
|
+
const mostRecentOptions = useRef(options);
|
|
892
|
+
mostRecentOptions.current = options;
|
|
893
|
+
const [instanceManager] = useState(() => new EditorInstanceManager(mostRecentOptions));
|
|
894
|
+
const editor = shimExports.useSyncExternalStore(instanceManager.subscribe, instanceManager.getEditor, instanceManager.getServerSnapshot);
|
|
895
|
+
useDebugValue(editor);
|
|
896
|
+
// This effect will handle creating/updating the editor instance
|
|
897
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
898
|
+
useEffect(instanceManager.onRender(deps));
|
|
783
899
|
// The default behavior is to re-render on each transaction
|
|
784
900
|
// This is legacy behavior that will be removed in future versions
|
|
785
901
|
useEditorState({
|