Files
notesnook/packages/editor/src/hooks/use-editor.ts

103 lines
2.7 KiB
TypeScript
Raw Normal View History

/*
This file is part of the Notesnook project (https://notesnook.com/)
Copyright (C) 2022 Streetwriters (Private) Limited
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
2022-08-30 16:13:11 +05:00
2022-07-04 13:00:13 +05:00
import { EditorOptions } from "@tiptap/core";
2022-07-02 11:57:52 +05:00
import { DependencyList, useEffect, useRef, useState } from "react";
2022-07-04 13:00:13 +05:00
import { Editor } from "../types";
2022-07-01 18:02:53 +05:00
function useForceUpdate() {
const [, setValue] = useState(0);
return () => setValue((value) => value + 1);
}
export const useEditor = (
options: Partial<EditorOptions> = {},
deps: DependencyList = []
) => {
2022-07-04 13:00:13 +05:00
const [editor, setEditor] = useState<Editor | null>(null);
2022-07-01 18:02:53 +05:00
const forceUpdate = useForceUpdate();
2022-07-04 13:00:13 +05:00
const editorRef = useRef<Editor | null>(editor);
2022-07-01 18:02:53 +05:00
2022-08-30 16:13:11 +05:00
useEffect(
() => {
let isMounted = true;
2022-07-01 18:02:53 +05:00
2022-08-30 16:13:11 +05:00
const instance = new Editor(options);
2022-07-01 18:02:53 +05:00
2022-08-30 16:13:11 +05:00
setEditor(instance);
2022-07-01 18:02:53 +05:00
2022-08-30 16:13:11 +05:00
instance.on("transaction", () => {
2022-07-01 18:02:53 +05:00
requestAnimationFrame(() => {
2022-08-30 16:13:11 +05:00
requestAnimationFrame(() => {
if (isMounted) {
forceUpdate();
}
});
2022-07-01 18:02:53 +05:00
});
});
2022-08-30 16:13:11 +05:00
return () => {
instance.destroy();
isMounted = false;
};
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[...deps, forceUpdate, options]
);
2022-07-01 18:02:53 +05:00
2022-07-02 11:57:52 +05:00
useEffect(() => {
editorRef.current = editor;
2022-07-04 13:00:13 +05:00
if (!editor) return;
if (!editor.current) {
2022-07-02 11:57:52 +05:00
Object.defineProperty(editor, "current", {
get: () => editorRef.current
2022-07-02 11:57:52 +05:00
});
2022-07-04 13:00:13 +05:00
}
// if (!editor.executor) {
// Object.defineProperty(editor, "executor", {
// get: () => (id?: string) => {
// console.log(id);
// return editorRef.current;
// },
// });
// }
2022-07-02 11:57:52 +05:00
}, [editor]);
useEffect(() => {
// this is required for the drag/drop to work properly
// in the editor.
function onDragEnter(event: DragEvent) {
if (editor?.view.dragging) {
2022-07-02 11:57:52 +05:00
event.preventDefault();
return true;
}
}
editor?.view.dom.addEventListener("dragenter", onDragEnter);
return () => {
editor?.view.dom.removeEventListener("dragenter", onDragEnter);
};
2022-08-30 16:13:11 +05:00
}, [editor?.view.dom, editor?.view.dragging]);
2022-07-02 11:57:52 +05:00
return editor;
2022-07-01 18:02:53 +05:00
};