chore: update IME mode checks

This commit is contained in:
Steven 2024-04-28 00:12:44 +08:00
parent f9942002f9
commit 8bba7f706e
3 changed files with 34 additions and 50 deletions

View file

@ -1,6 +1,7 @@
import classNames from "classnames";
import { forwardRef, ReactNode, useCallback, useEffect, useImperativeHandle, useRef } from "react";
import { useAutoComplete } from "../hooks";
import { last } from "lodash-es";
import { forwardRef, ReactNode, useCallback, useEffect, useImperativeHandle, useRef, useState } from "react";
import { NodeType, OrderedListNode, TaskListNode, UnorderedListNode } from "@/types/node";
import TagSuggestions from "./TagSuggestions";
export interface EditorRefActions {
@ -30,6 +31,7 @@ interface Props {
const Editor = forwardRef(function Editor(props: Props, ref: React.ForwardedRef<EditorRefActions>) {
const { className, initialContent, placeholder, onPaste, onContentChange: handleContentChangeCallback } = props;
const [isInIME, setIsInIME] = useState(false);
const editorRef = useRef<HTMLTextAreaElement>(null);
useEffect(() => {
@ -133,8 +135,6 @@ const Editor = forwardRef(function Editor(props: Props, ref: React.ForwardedRef<
},
};
useAutoComplete(editorActions);
useImperativeHandle(ref, () => editorActions, []);
const updateEditorHeight = () => {
@ -149,6 +149,33 @@ const Editor = forwardRef(function Editor(props: Props, ref: React.ForwardedRef<
updateEditorHeight();
}, []);
const handleEditorKeyDown = (event: React.KeyboardEvent<HTMLTextAreaElement>) => {
if (event.key === "Enter" && !isInIME) {
const cursorPosition = editorActions.getCursorPosition();
const prevContent = editorActions.getContent().substring(0, cursorPosition);
const lastNode = last(window.parse(prevContent));
if (!lastNode) {
return;
}
let insertText = "";
if (lastNode.type === NodeType.TASK_LIST) {
const { complete } = lastNode.value as TaskListNode;
insertText = complete ? "- [x] " : "- [ ] ";
} else if (lastNode.type === NodeType.UNORDERED_LIST) {
const { symbol } = lastNode.value as UnorderedListNode;
insertText = `${symbol} `;
} else if (lastNode.type === NodeType.ORDERED_LIST) {
const { number } = lastNode.value as OrderedListNode;
insertText = `${Number(number) + 1}. `;
}
if (insertText) {
editorActions.insertText(`\n${insertText}`);
event.preventDefault();
}
}
};
return (
<div
className={classNames(
@ -163,6 +190,9 @@ const Editor = forwardRef(function Editor(props: Props, ref: React.ForwardedRef<
ref={editorRef}
onPaste={onPaste}
onInput={handleEditorInput}
onKeyDown={handleEditorKeyDown}
onCompositionStart={() => setIsInIME(true)}
onCompositionEnd={() => setTimeout(() => setIsInIME(false))}
></textarea>
<TagSuggestions editorRef={editorRef} editorActions={ref} />
</div>

View file

@ -1,3 +0,0 @@
import useAutoComplete from "./useAutoComplete";
export { useAutoComplete };

View file

@ -1,43 +0,0 @@
import { last } from "lodash-es";
import { useEffect } from "react";
import { NodeType, OrderedListNode, TaskListNode, UnorderedListNode } from "@/types/node";
import { EditorRefActions } from "../Editor";
const useAutoComplete = (actions: EditorRefActions) => {
useEffect(() => {
const editor = actions.getEditor();
if (!editor) return;
editor.addEventListener("keydown", (event) => {
if (event.key === "Enter") {
if (event.isComposing) {
return;
}
const cursorPosition = actions.getCursorPosition();
const prevContent = actions.getContent().substring(0, cursorPosition);
const lastNode = last(window.parse(prevContent));
if (!lastNode) {
return;
}
let insertText = "";
if (lastNode.type === NodeType.TASK_LIST) {
const { complete } = lastNode.value as TaskListNode;
insertText = complete ? "- [x] " : "- [ ] ";
} else if (lastNode.type === NodeType.UNORDERED_LIST) {
const { symbol } = lastNode.value as UnorderedListNode;
insertText = `${symbol} `;
} else if (lastNode.type === NodeType.ORDERED_LIST) {
const { number } = lastNode.value as OrderedListNode;
insertText = `${Number(number) + 1}. `;
}
if (insertText) {
actions.insertText(`\n${insertText}`);
event.preventDefault();
}
}
});
}, []);
};
export default useAutoComplete;