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