@mdxeditor/editor
Version:
React component for rich text markdown editing
107 lines (106 loc) • 4.73 kB
JavaScript
import { $getNodeByKey, $createParagraphNode } from "lexical";
import React__default from "react";
import { useCodeBlockEditorContext } from "../codeblock/CodeBlockNode.js";
import { activeEditor$, editorInFocus$ } from "../core/index.js";
import { useCellValue, usePublisher } from "@mdxeditor/gurx";
function useCodeMirrorRef(nodeKey, editorType, language, focusEmitter) {
const activeEditor = useCellValue(activeEditor$);
const setEditorInFocus = usePublisher(editorInFocus$);
const codeMirrorRef = React__default.useRef(null);
const { lexicalNode } = useCodeBlockEditorContext();
const atBottom = React__default.useRef(false);
const atTop = React__default.useRef(false);
const onFocusHandler = React__default.useCallback(() => {
setEditorInFocus({
editorType,
rootNode: lexicalNode
});
}, [editorType, lexicalNode, setEditorInFocus]);
const onKeyDownHandler = React__default.useCallback(
(e) => {
var _a, _b, _c, _d, _e, _f;
if (e.key === "ArrowDown") {
const state = (_b = (_a = codeMirrorRef.current) == null ? void 0 : _a.getCodemirror()) == null ? void 0 : _b.state;
if (state) {
const docLength = state.doc.length;
const selectionEnd = state.selection.ranges[0].to;
if (docLength === selectionEnd) {
if (!atBottom.current) {
atBottom.current = true;
} else {
activeEditor == null ? void 0 : activeEditor.update(() => {
var _a2, _b2;
const node = $getNodeByKey(nodeKey);
const nextSibling = node.getNextSibling();
if (nextSibling) {
(_b2 = (_a2 = codeMirrorRef.current) == null ? void 0 : _a2.getCodemirror()) == null ? void 0 : _b2.contentDOM.blur();
node.selectNext();
} else {
node.insertAfter($createParagraphNode());
}
});
atBottom.current = false;
}
}
}
} else if (e.key === "ArrowUp") {
const state = (_d = (_c = codeMirrorRef.current) == null ? void 0 : _c.getCodemirror()) == null ? void 0 : _d.state;
if (state) {
const selectionStart = state.selection.ranges[0].from;
if (selectionStart === 0) {
if (!atTop.current) {
atTop.current = true;
} else {
activeEditor == null ? void 0 : activeEditor.update(() => {
var _a2, _b2;
const node = $getNodeByKey(nodeKey);
const previousSibling = node.getPreviousSibling();
if (previousSibling) {
(_b2 = (_a2 = codeMirrorRef.current) == null ? void 0 : _a2.getCodemirror()) == null ? void 0 : _b2.contentDOM.blur();
node.selectPrevious();
}
});
atTop.current = false;
}
}
}
} else if (e.key === "Enter") {
e.stopPropagation();
} else if (e.key === "Backspace" || e.key === "Delete") {
const state = (_f = (_e = codeMirrorRef.current) == null ? void 0 : _e.getCodemirror()) == null ? void 0 : _f.state;
const docLength = state == null ? void 0 : state.doc.length;
if (docLength === 0) {
activeEditor == null ? void 0 : activeEditor.update(() => {
const node = $getNodeByKey(nodeKey);
node.remove();
});
}
}
},
[activeEditor, nodeKey]
);
React__default.useEffect(() => {
const codeMirror = codeMirrorRef.current;
setTimeout(() => {
var _a, _b;
(_a = codeMirror == null ? void 0 : codeMirror.getCodemirror()) == null ? void 0 : _a.contentDOM.addEventListener("focus", onFocusHandler);
(_b = codeMirror == null ? void 0 : codeMirror.getCodemirror()) == null ? void 0 : _b.contentDOM.addEventListener("keydown", onKeyDownHandler);
}, 300);
return () => {
var _a, _b;
(_a = codeMirror == null ? void 0 : codeMirror.getCodemirror()) == null ? void 0 : _a.contentDOM.removeEventListener("focus", onFocusHandler);
(_b = codeMirror == null ? void 0 : codeMirror.getCodemirror()) == null ? void 0 : _b.contentDOM.removeEventListener("keydown", onKeyDownHandler);
};
}, [codeMirrorRef, onFocusHandler, onKeyDownHandler, language]);
React__default.useEffect(() => {
focusEmitter.subscribe(() => {
var _a, _b;
(_b = (_a = codeMirrorRef.current) == null ? void 0 : _a.getCodemirror()) == null ? void 0 : _b.focus();
onFocusHandler();
});
}, [focusEmitter, codeMirrorRef, nodeKey, onFocusHandler]);
return codeMirrorRef;
}
export {
useCodeMirrorRef
};